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