|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)float.c 1.1 86/02/03 Copyr 1983 Sun Micro";
3: #endif
4:
5: /*
6: * Copyright (c) 1983 by Sun Microsystems, Inc.
7: */
8:
9: /*
10: * float.c
11: */
12:
13: #include "cpass1.h"
14:
15: /* routine for decoding from "native", CC-internal floating point format
16: * to object format -- in this case MOTOROLA FFP.
17: * This gets invoked in local.68 if fpflag is not the same as NATIVEFP.
18: */
19: fpdecoder( p, sz )
20: register * p;
21: {
22:
23: struct mit {
24: unsigned
25: sign:1,
26: exp :8,
27: fract:23; /* has hidden high-order bit! */
28: };
29: struct motor {
30: unsigned
31: fract:24, /* no hidden bit here */
32: sign :1,
33: exp :7;
34: };
35: struct doubleieee {
36: unsigned
37: sign:1,
38: exp: 11,
39: fract: 20,
40: fmore;
41: };
42: struct doubleint {
43: unsigned n,m;
44: };
45: #define MITEXCESS (1<<7)
46: #define MOTOREXCESS (1<<6)
47: /*
48: * the following two constants appear to be one two low. This is
49: * deceiving. The hidden bit in IEEE form is on the left-hand-side
50: * of the decimal point. The hidden bit in MIT form is on the
51: * right-hand-side of the decimal point. Thus the discrepiency.
52: */
53: #define IEEEXCESS (126)
54: #define DPEXCESS (1022)
55: union {
56: struct motor motor;
57: struct doubleieee dp;
58: struct mit mit;
59: struct doubleint i;
60: } new;
61: union {
62: struct mit mit;
63: struct doubleint i;
64: } old;
65: int x;
66:
67: if (NATIVEFP == MIT)
68: switch( fpflag ){
69: case Motorola:
70: old.i.n = *p;
71: if (old.i.n == 0) return;
72: new.motor.sign = old.mit.sign;
73: x = old.mit.exp - MITEXCESS;
74: if (x >= MOTOREXCESS || x <= -MOTOREXCESS)
75: uerror("floating-point constant out of range");
76: new.motor.exp = x + MOTOREXCESS;
77: x = old.mit.fract | (1<<23); /* restore hidden bit */
78: new.motor.fract = x;
79: *p = new.i.n;
80: *(p+1) = 0; /* s-p only, thank you */
81: return;
82: case IEEE:
83: if (sz == SZDOUBLE ){
84: old.i.n = *p;
85: old.i.m = *(p+1);
86: if (old.i.n == 0 && old.i.m == 0) return;
87: new.dp.sign = old.mit.sign;
88: new.dp.exp = old.mit.exp -MITEXCESS + DPEXCESS;
89: new.dp.fract = old.mit.fract >> 3;
90: new.dp.fmore = (old.mit.fract << 29) | (old.i.m >>3);
91: /* not actually a good approximation, but ... */
92: *p = new.i.n;
93: *(p+1) = new.i.m;
94: return;
95: } else {
96: /* trivial conversion */
97: new.i.n = *p;
98: if (new.i.n == 0) return;
99: new.mit.exp += IEEEXCESS - MITEXCESS;
100: *p = new.i.n;
101: return;
102: }
103: }
104: cerror("incomprehensable floating-point conversion");
105: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.