1: /* @(#)gen.c 2.2 SCCS id keyword */ 2: /* Copyright (c) 1979 Regents of the University of California */ 3: # 4: /* 5: * pi - Pascal interpreter code translator 6: * 7: * Charles Haley, Bill Joy UCB 8: * Version 1.2 November 1978 9: */ 10: 11: #include "whoami" 12: #include "0.h" 13: #include "tree.h" 14: #include "opcode.h" 15: 16: /* 17: * This array tells the type 18: * returned by an arithmetic 19: * operation. It is indexed 20: * by the logarithm of the 21: * lengths base 2. 22: */ 23: #ifndef DEBUG 24: char arret[] = { 25: T4INT, T4INT, T4INT, TDOUBLE, 26: T4INT, T4INT, T4INT, TDOUBLE, 27: T4INT, T4INT, T4INT, TDOUBLE, 28: TDOUBLE, TDOUBLE, TDOUBLE, TDOUBLE 29: }; 30: #else 31: char arret0[] = { 32: T4INT, T4INT, T4INT, TDOUBLE, 33: T4INT, T4INT, T4INT, TDOUBLE, 34: T4INT, T4INT, T4INT, TDOUBLE, 35: TDOUBLE, TDOUBLE, TDOUBLE, TDOUBLE 36: }; 37: char arret1[] = { 38: T4INT, T4INT, T4INT, TDOUBLE, 39: T4INT, T4INT, T4INT, TDOUBLE, 40: T4INT, T4INT, T4INT, TDOUBLE, 41: TDOUBLE, TDOUBLE, TDOUBLE, TDOUBLE 42: }; 43: char *arret = arret0; 44: #endif 45: 46: /* 47: * These array of arithmetic and set 48: * operators are indexed by the 49: * tree nodes and is highly dependent 50: * on their order. They thus take 51: * on the flavor of magic. 52: */ 53: int arop[] = { 54: 0, O_NEG2, O_MOD2, O_DIV2, O_DVD2, O_MUL2, O_ADD2, O_SUB2, 55: O_REL2, O_REL2, O_REL2, O_REL2, O_REL2, O_REL2 56: }; 57: int setop[] = { 58: O_MULT, O_ADDT, O_SUBT, 59: O_RELT, O_RELT, O_RELT, O_RELT, O_RELT, O_RELT, 60: }; 61: 62: /* 63: * The following array is 64: * used when operating on 65: * two reals since they are 66: * shoved off in a corner in 67: * the interpreter table. 68: */ 69: int ar8op[] = { 70: O_DVD8, O_MUL8, O_ADD8, O_SUB8, 71: O_REL8, O_REL8, O_REL8, O_REL8, O_REL8, O_REL8, 72: }; 73: 74: /* 75: * The following arrays, which are linearizations 76: * of two dimensional arrays, are the offsets for 77: * arithmetic, relational and assignment operations 78: * indexed by the logarithms of the argument widths. 79: */ 80: #ifndef DEBUG 81: char artab[] = { 82: O_ADD2-O_ADD2, O_ADD2-O_ADD2, O_ADD42-O_ADD2, O_ADD82-O_ADD2, 83: O_ADD2-O_ADD2, O_ADD2-O_ADD2, O_ADD42-O_ADD2, O_ADD82-O_ADD2, 84: O_ADD24-O_ADD2, O_ADD24-O_ADD2, O_ADD4-O_ADD2, O_ADD84-O_ADD2, 85: O_ADD28-O_ADD2, O_ADD28-O_ADD2, O_ADD48-O_ADD2, -1 86: }; 87: #else 88: char artab0[] = { 89: O_ADD2-O_ADD2, O_ADD2-O_ADD2, O_ADD42-O_ADD2, O_ADD82-O_ADD2, 90: O_ADD2-O_ADD2, O_ADD2-O_ADD2, O_ADD42-O_ADD2, O_ADD82-O_ADD2, 91: O_ADD24-O_ADD2, O_ADD24-O_ADD2, O_ADD4-O_ADD2, O_ADD84-O_ADD2, 92: O_ADD28-O_ADD2, O_ADD28-O_ADD2, O_ADD48-O_ADD2, -1 93: }; 94: char artab1[] = { 95: O_ADD2-O_ADD2, O_ADD2-O_ADD2, O_ADD2-O_ADD2, O_ADD82-O_ADD2, 96: O_ADD2-O_ADD2, O_ADD2-O_ADD2, O_ADD2-O_ADD2, O_ADD82-O_ADD2, 97: O_ADD2-O_ADD2, O_ADD2-O_ADD2, O_ADD2-O_ADD2, O_ADD84-O_ADD2, 98: O_ADD28-O_ADD2, O_ADD28-O_ADD2, O_ADD28-O_ADD2, -1 99: }; 100: char *artab = artab0; 101: #endif 102: #ifndef DEBUG 103: char reltab[] = { 104: O_REL2-O_REL2, O_REL2-O_REL2, O_REL42-O_REL2, O_REL82-O_REL2, 105: O_REL2-O_REL2, O_REL2-O_REL2, O_REL42-O_REL2, O_REL82-O_REL2, 106: O_REL24-O_REL2, O_REL24-O_REL2, O_REL4-O_REL2, O_REL84-O_REL2, 107: O_REL28-O_REL2, O_REL28-O_REL2, O_REL48-O_REL2, O_REL8-O_REL2 108: }; 109: #else 110: char reltab0[] = { 111: O_REL2-O_REL2, O_REL2-O_REL2, O_REL42-O_REL2, O_REL82-O_REL2, 112: O_REL2-O_REL2, O_REL2-O_REL2, O_REL42-O_REL2, O_REL82-O_REL2, 113: O_REL24-O_REL2, O_REL24-O_REL2, O_REL4-O_REL2, O_REL84-O_REL2, 114: O_REL28-O_REL2, O_REL28-O_REL2, O_REL48-O_REL2, O_REL8-O_REL2 115: }; 116: char reltab1[] = { 117: O_REL2-O_REL2, O_REL2-O_REL2, O_REL2-O_REL2, O_REL82-O_REL2, 118: O_REL2-O_REL2, O_REL2-O_REL2, O_REL2-O_REL2, O_REL82-O_REL2, 119: O_REL2-O_REL2, O_REL2-O_REL2, O_REL2-O_REL2, O_REL82-O_REL2, 120: O_REL28-O_REL2, O_REL28-O_REL2, O_REL28-O_REL2, O_REL8-O_REL2 121: }; 122: char *reltab = reltab0; 123: #endif 124: 125: #ifndef DEBUG 126: char asgntab[] = { 127: O_AS21-O_AS2, O_AS21-O_AS2, O_AS41-O_AS2, -1, 128: O_AS2-O_AS2, O_AS2-O_AS2, O_AS42-O_AS2, -1, 129: O_AS24-O_AS2, O_AS24-O_AS2, O_AS4-O_AS2, -1, 130: O_AS28-O_AS2, O_AS28-O_AS2, O_AS48-O_AS2, O_AS8-O_AS2, 131: }; 132: #else 133: char asgntb0[] = { 134: O_AS21-O_AS2, O_AS21-O_AS2, O_AS41-O_AS2, -1, 135: O_AS2-O_AS2, O_AS2-O_AS2, O_AS42-O_AS2, -1, 136: O_AS24-O_AS2, O_AS24-O_AS2, O_AS4-O_AS2, -1, 137: O_AS28-O_AS2, O_AS28-O_AS2, O_AS48-O_AS2, O_AS8-O_AS2, 138: }; 139: char asgntb1[] = { 140: O_AS21-O_AS2, O_AS21-O_AS2, O_AS21-O_AS2, -1, 141: O_AS2-O_AS2, O_AS2-O_AS2, O_AS2-O_AS2, -1, 142: O_AS2-O_AS2, O_AS2-O_AS2, O_AS2-O_AS2, -1, 143: O_AS28-O_AS2, O_AS28-O_AS2, O_AS28-O_AS2, O_AS4-O_AS2, 144: }; 145: char *asgntab = asgntb0; 146: #endif 147: 148: #ifdef DEBUG 149: genmx() 150: { 151: 152: arret = arret1; 153: artab = artab1; 154: reltab = reltab1; 155: asgntab = asgntb1; 156: } 157: #endif 158: 159: /* 160: * Gen generates code for assignments, 161: * and arithmetic and string operations 162: * and comparisons. 163: */ 164: struct nl * 165: gen(p, o, w1, w2) 166: int p, o, w1, w2; 167: { 168: register i, j; 169: int op, off; 170: 171: switch (p) { 172: case O_AS2: 173: case NIL: 174: i = j = -1; 175: /* 176: * Take the log2 of the widths 177: * and linearize them for indexing. 178: * width for indexing. 179: */ 180: #ifdef DEBUG 181: if (hp21mx) { 182: if (w1 == 4) 183: w1 = 8; 184: if (w2 == 4) 185: w2 = 8; 186: } 187: #endif 188: do i++; while (w1 >>= 1); 189: do j++; while (w2 >>= 1); 190: i <<= 2; 191: i |= j; 192: if (p == O_AS2) { 193: put1(O_AS2 + asgntab[i]); 194: return (NIL); 195: } 196: op = arop[o]; 197: if (op == O_REL2) { 198: put1((op + reltab[i]) | (o - T_EQ) << 9); 199: return (nl+TBOOL); 200: } 201: put1(i == 15 ? ar8op[o-T_DIVD] : op | artab[i]); 202: return (op == O_DVD2 && !divchk ? nl+TDOUBLE : nl+arret[i]); 203: case TSTR: 204: put2(O_RELG | (o - T_EQ) << 9, w1); 205: return (nl+TBOOL); 206: case TSET: 207: op = setop[o-T_MULT]; 208: if (op == O_RELT) 209: op |= (o - T_EQ)<<9; 210: put2(op, w1); 211: return (o >= T_EQ ? nl+TBOOL : nl+TSET); 212: default: 213: panic("gen"); 214: } 215: }