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