|
|
1.1 root 1: /*
2: * n1/i386/gen2.c
3: * Generate external and static initializations.
4: * i386.
5: */
6:
7: #ifdef vax
8: #include "INC$LIB:cc1.h"
9: #else
10: #include "cc1.h"
11: #endif
12:
13: static char ilinit[] = "initializer too complex";
14: static dval_t dvalzero;
15:
16: /*
17: * This routine handles blocks of bytes (IBLOCK) items.
18: * It is passed the count.
19: * If the "ZBYTE" could be a machine independent notion,
20: * then this could be moved into "cc1.c".
21: */
22: iblock(n) register int n;
23: {
24: while (n--) {
25: bput(CODE);
26: bput(ZBYTE);
27: iput((ival_t)A_OFFS|A_DIR);
28: iput((ival_t)bget());
29: }
30: }
31:
32: /*
33: * This routine compiles any "IEXPR" trees.
34: * The "INIT" node has been pulled off by "work" (in "cc1.c")
35: * and the tree has been run through the tree optimizer.
36: */
37: iexpr(tp, tt) register TREE *tp; int tt;
38: {
39: register char *dcp;
40: register int op;
41: register int bytes;
42: dval_t d;
43: int mode;
44: lval_t offs;
45: int lidn;
46: SYM *gidp;
47:
48: tp = basenode(tp);
49: if (!isflt(tt)) {
50: mode = A_DIR;
51: offs = 0;
52: if (gencoll(tp, &mode, &offs, &lidn, &gidp, 0, 1) == 0
53: || (mode & A_AMOD) != A_DIR) {
54: cerror(ilinit);
55: return;
56: }
57: /*
58: * A long integer gets put as a LONG opcode.
59: */
60: if (tt==S32 || tt==U32) {
61: if ((mode & (A_LID|A_GID)) != 0) {
62: #if 1
63: /*
64: * Thanks to Ciaran for the following.
65: * This lets "int i = (int)&foo;" work.
66: */
67: tt = PTR;
68: #else
69: /* Previous code, pre-Ciaran. */
70: cerror(ilinit);
71: #endif
72: } else {
73: bput(CODE);
74: bput(ZLONG);
75: iput((ival_t)A_OFFS|mode);
76: iput((ival_t)offs);
77: return;
78: }
79: }
80: bput(CODE);
81: if (tt==PTR || tt==PTB) {
82: if ((mode & (A_LID|A_GID)) == 0 && (ival_t)(offs >> 16) != 0) {
83: bput(ZLONG);
84: iput((ival_t)A_OFFS|mode);
85: iput((ival_t)offs);
86: return;
87: }
88: bput(ZGPTR);
89: }
90: else if (isbyte(tt))
91: bput(ZBYTE);
92: else
93: bput(ZWORD);
94: if (offs == 0)
95: iput((ival_t)mode);
96: else {
97: iput((ival_t)A_OFFS|mode);
98: iput((ival_t)offs);
99: }
100: if ((mode & A_LID) != 0)
101: iput((ival_t)lidn);
102: else if ((mode & A_GID) != 0)
103: sput(gidp->s_id);
104: return;
105: }
106: op = tp->t_op;
107: if (op==ICON || op==LCON) {
108: dcp = (char *) d;
109: dvallval(dcp, grabnval(tp));
110: } else if (op == DCON)
111: dcp = (char *) tp->t_dval;
112: else {
113: cerror(ilinit);
114: dcp = dvalzero;
115: }
116: bytes = 8;
117: if (tt == F32) {
118: bytes = 4;
119: #if IEEE
120: fvaldval(dcp);
121: #endif
122: }
123: while (bytes--) {
124: bput(CODE);
125: bput(ZBYTE);
126: iput((ival_t)A_OFFS|A_DIR);
127: iput((ival_t)dcp[bytes]&0xFF);
128: }
129: }
130:
131: /*
132: * Convert an "lval_t" (a 32 bit integer)
133: * into either IEEE or DECVAX double precision float and
134: * store it into the 8 byte character array to which "dcp" points.
135: * The original pack is written as shifts
136: * (rather than by a pun with a union) because the long
137: * byte order is different on the PDP-11 and the 8086
138: * and the code should work both places.
139: * Assumes 32 bit long and 8 bit bytes.
140: */
141: dvallval(dcp, lval) char *dcp; lval_t lval;
142: {
143: register int bexp, sign;
144: register int i;
145:
146: for (i=0; i<8; dcp[i++]=0)
147: ;
148: if (lval != 0) {
149: sign = 0;
150: if (lval < 0) {
151: lval = -lval;
152: sign = 0200;
153: }
154: dcp[4] = lval >> 24;
155: dcp[5] = lval >> 16;
156: dcp[6] = lval >> 8;
157: dcp[7] = lval;
158: #if IEEE
159: bexp = 1023 + 52;
160: #else
161: bexp = 128 + 56;
162: #endif
163: do {
164: --bexp;
165: shleft(dcp);
166: #if IEEE
167: } while ((dcp[1]&020) == 0);
168: dcp[1] &= ~0360;
169: dcp[1] |= (bexp<<4) & 0360;
170: dcp[0] = sign | ((bexp>>4)&0177);
171: #else
172: } while ((dcp[1]&0200) == 0);
173: dcp[1] &= ~0200;
174: dcp[1] |= (bexp<<7) & 0200;
175: dcp[0] = sign | ((bexp>>1)&0177);
176: #endif
177: }
178: }
179:
180: /*
181: * Shift a 64 bit integer (packed into 8 8-bit bytes)
182: * one position to the left.
183: * Shift a 0 into the empty bit position on the right.
184: */
185: shleft(dcp) register char *dcp;
186: {
187: register int icarry, ocarry;
188: register int i;
189:
190: ocarry = 0;
191: for (i=7; i>=0; --i) {
192: icarry = ocarry;
193: ocarry = 0;
194: if ((dcp[i]&0200) != 0)
195: ++ocarry;
196: dcp[i] <<= 1;
197: dcp[i] |= icarry;
198: }
199: }
200:
201: #if IEEE
202: /*
203: * Convert an IEEE double precision floating point number
204: * (packed into 8 8 bit bytes) into a single precision IEEE floating
205: * point number packed into the first 4 of the 8 bytes.
206: * The exponent must be rebiased.
207: * No simple NATIVEFP conditional version,
208: * because the double byte order is backwards;
209: * it's not worth it to reverse, cast, and reverse again.
210: */
211: fvaldval(dcp) register unsigned char *dcp;
212: {
213: register int sign, bexp;
214:
215: sign = dcp[0]&0200; /* sign */
216: bexp = ((dcp[0]<<4)&03760) + ((dcp[1]>>4)&017);
217: if (bexp != 0)
218: bexp += 127 - 1023; /* biased exponent */
219: shleft(dcp);
220: shleft(dcp);
221: shleft(dcp); /* reposition mantissa */
222: dcp[1] &= ~0200; /* mask off lo exponent bit */
223: if ((dcp[4] & 0x80) != 0 /* round up if appropriate: */
224: && ++dcp[3] == 0 /* bump lo mantissa bit, */
225: && ++dcp[2] == 0 /* and propogate carry; */
226: && ++dcp[1] == 0x80) { /* if it gets to hidden bit, */
227: dcp[1] = 0; /* then new mantissa is 0 */
228: ++bexp; /* and bump the exponent */
229: }
230: if ((bexp&01) != 0)
231: dcp[1] |= 0200; /* pack lo order exponent */
232: dcp[0] = sign | ((bexp>>1)&0177); /* pack sign and hi exponent */
233: }
234: #endif
235:
236: /* end of n1/i386/gen2.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.