File:  [Research Unix] / researchv9 / cmd / sun / pcc / float.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 17:21:59 2018 UTC (8 years, 1 month ago) by root
Branches: belllabs, MAIN
CVS tags: researchv9-SUN3_old, researchv9-SUN3, HEAD
researchv9-SUN3(old)

#ifndef lint
static	char sccsid[] = "@(#)float.c 1.1 86/02/03 Copyr 1983 Sun Micro";
#endif

/*
 * Copyright (c) 1983 by Sun Microsystems, Inc.
 */

/*
 *	float.c
 */

#include "cpass1.h"

/* routine for decoding from "native", CC-internal floating point format
 * to object format -- in this case MOTOROLA FFP.
 * This gets invoked in local.68 if fpflag is not the same as NATIVEFP.
 */
fpdecoder( p, sz )
    register * p;
{

    struct mit { 
	unsigned
	    sign:1,
	    exp :8,
	    fract:23; /* has hidden high-order bit! */
    };
    struct motor {
	unsigned
	    fract:24, /* no hidden bit here */
	    sign :1,
	    exp  :7;
    };
    struct doubleieee {
	unsigned
	    sign:1,
	    exp: 11,
	    fract: 20,
	    fmore;
    };
    struct doubleint {
	unsigned n,m;
    };
#define MITEXCESS	(1<<7)
#define MOTOREXCESS	(1<<6)
/* 
 * the following two constants appear to be one two low. This is
 * deceiving. The hidden bit in IEEE form is on the left-hand-side
 * of the decimal point. The hidden bit in MIT form is on the 
 * right-hand-side of the decimal point. Thus the discrepiency.
 */
#define IEEEXCESS	(126)
#define DPEXCESS	(1022)
    union {
	struct motor motor;
	struct doubleieee dp;
	struct mit mit;
	struct doubleint i;
    } new;
    union {
	struct mit mit;
	struct doubleint i;
    } old;
    int x;

    if (NATIVEFP == MIT)
    switch( fpflag ){
    case Motorola:
	old.i.n = *p;
	if (old.i.n == 0) return;
	new.motor.sign = old.mit.sign;
	x = old.mit.exp - MITEXCESS;
	if (x >= MOTOREXCESS || x <= -MOTOREXCESS)
	    uerror("floating-point constant out of range");
	new.motor.exp = x + MOTOREXCESS;
	x = old.mit.fract | (1<<23); /* restore hidden bit */
	new.motor.fract = x;
	*p = new.i.n;
	*(p+1) = 0; /* s-p only, thank you */
	return;
    case IEEE:
	if (sz == SZDOUBLE ){
	    old.i.n = *p;
	    old.i.m = *(p+1);
	    if (old.i.n == 0 && old.i.m == 0) return;
	    new.dp.sign = old.mit.sign;
	    new.dp.exp  = old.mit.exp -MITEXCESS + DPEXCESS;
	    new.dp.fract = old.mit.fract >> 3;
	    new.dp.fmore = (old.mit.fract << 29) | (old.i.m >>3);
	    /* not actually a good approximation, but ... */
	    *p     = new.i.n;
	    *(p+1) = new.i.m;
	    return;
	} else {
	    /* trivial conversion */
	    new.i.n = *p;
	    if (new.i.n == 0) return;
	    new.mit.exp += IEEEXCESS - MITEXCESS;
	    *p = new.i.n;
	    return;
	}
    }
    cerror("incomprehensable floating-point conversion");
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.