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