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