|
|
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.