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