1754Speter /* Copyright (c) 1979 Regents of the University of California */ 2754Speter 3*14733Sthien #ifndef lint 4*14733Sthien static char sccsid[] = "@(#)gen.c 1.3 08/19/83"; 5*14733Sthien #endif 6754Speter 7754Speter #include "whoami.h" 8754Speter #ifdef OBJ 9754Speter /* 10754Speter * and the rest of the file 11754Speter */ 12754Speter #include "0.h" 13754Speter #include "tree.h" 14754Speter #include "opcode.h" 15754Speter #include "objfmt.h" 16754Speter 17754Speter /* 18754Speter * This array tells the type 19754Speter * returned by an arithmetic 20754Speter * operation. It is indexed 21754Speter * by the logarithm of the 22754Speter * lengths base 2. 23754Speter */ 24754Speter #ifndef DEBUG 25754Speter char arret[] = { 26754Speter T4INT, T4INT, T4INT, TDOUBLE, 27754Speter T4INT, T4INT, T4INT, TDOUBLE, 28754Speter T4INT, T4INT, T4INT, TDOUBLE, 29754Speter TDOUBLE, TDOUBLE, TDOUBLE, TDOUBLE 30754Speter }; 31754Speter #else 32754Speter char arret0[] = { 33754Speter T4INT, T4INT, T4INT, TDOUBLE, 34754Speter T4INT, T4INT, T4INT, TDOUBLE, 35754Speter T4INT, T4INT, T4INT, TDOUBLE, 36754Speter TDOUBLE, TDOUBLE, TDOUBLE, TDOUBLE 37754Speter }; 38754Speter char arret1[] = { 39754Speter T4INT, T4INT, T4INT, TDOUBLE, 40754Speter T4INT, T4INT, T4INT, TDOUBLE, 41754Speter T4INT, T4INT, T4INT, TDOUBLE, 42754Speter TDOUBLE, TDOUBLE, TDOUBLE, TDOUBLE 43754Speter }; 44754Speter char *arret = arret0; 45754Speter #endif 46754Speter 47754Speter /* 48754Speter * These array of arithmetic and set 49754Speter * operators are indexed by the 50754Speter * tree nodes and is highly dependent 51754Speter * on their order. They thus take 52754Speter * on the flavor of magic. 53754Speter */ 54754Speter int arop[] = { 55754Speter 0, O_NEG2, O_MOD2, O_DIV2, O_DVD2, O_MUL2, O_ADD2, O_SUB2, 56754Speter O_REL2, O_REL2, O_REL2, O_REL2, O_REL2, O_REL2 57754Speter }; 58754Speter int setop[] = { 59754Speter O_MULT, O_ADDT, O_SUBT, 60754Speter O_RELT, O_RELT, O_RELT, O_RELT, O_RELT, O_RELT, 61754Speter }; 62754Speter 63754Speter /* 64754Speter * The following array is 65754Speter * used when operating on 66754Speter * two reals since they are 67754Speter * shoved off in a corner in 68754Speter * the interpreter table. 69754Speter */ 70754Speter int ar8op[] = { 71754Speter O_DVD8, O_MUL8, O_ADD8, O_SUB8, 72754Speter O_REL8, O_REL8, O_REL8, O_REL8, O_REL8, O_REL8, 73754Speter }; 74754Speter 75754Speter /* 76754Speter * The following arrays, which are linearizations 77754Speter * of two dimensional arrays, are the offsets for 78754Speter * arithmetic, relational and assignment operations 79754Speter * indexed by the logarithms of the argument widths. 80754Speter */ 81754Speter #ifndef DEBUG 82754Speter char artab[] = { 83754Speter O_ADD2-O_ADD2, O_ADD2-O_ADD2, O_ADD42-O_ADD2, O_ADD82-O_ADD2, 84754Speter O_ADD2-O_ADD2, O_ADD2-O_ADD2, O_ADD42-O_ADD2, O_ADD82-O_ADD2, 85754Speter O_ADD24-O_ADD2, O_ADD24-O_ADD2, O_ADD4-O_ADD2, O_ADD84-O_ADD2, 86754Speter O_ADD28-O_ADD2, O_ADD28-O_ADD2, O_ADD48-O_ADD2, -1 87754Speter }; 88754Speter #else 89754Speter char artab0[] = { 90754Speter O_ADD2-O_ADD2, O_ADD2-O_ADD2, O_ADD42-O_ADD2, O_ADD82-O_ADD2, 91754Speter O_ADD2-O_ADD2, O_ADD2-O_ADD2, O_ADD42-O_ADD2, O_ADD82-O_ADD2, 92754Speter O_ADD24-O_ADD2, O_ADD24-O_ADD2, O_ADD4-O_ADD2, O_ADD84-O_ADD2, 93754Speter O_ADD28-O_ADD2, O_ADD28-O_ADD2, O_ADD48-O_ADD2, -1 94754Speter }; 95754Speter char artab1[] = { 96754Speter O_ADD2-O_ADD2, O_ADD2-O_ADD2, O_ADD2-O_ADD2, O_ADD82-O_ADD2, 97754Speter O_ADD2-O_ADD2, O_ADD2-O_ADD2, O_ADD2-O_ADD2, O_ADD82-O_ADD2, 98754Speter O_ADD2-O_ADD2, O_ADD2-O_ADD2, O_ADD2-O_ADD2, O_ADD84-O_ADD2, 99754Speter O_ADD28-O_ADD2, O_ADD28-O_ADD2, O_ADD28-O_ADD2, -1 100754Speter }; 101754Speter char *artab = artab0; 102754Speter #endif 103754Speter #ifndef DEBUG 104754Speter char reltab[] = { 105754Speter O_REL2-O_REL2, O_REL2-O_REL2, O_REL42-O_REL2, O_REL82-O_REL2, 106754Speter O_REL2-O_REL2, O_REL2-O_REL2, O_REL42-O_REL2, O_REL82-O_REL2, 107754Speter O_REL24-O_REL2, O_REL24-O_REL2, O_REL4-O_REL2, O_REL84-O_REL2, 108754Speter O_REL28-O_REL2, O_REL28-O_REL2, O_REL48-O_REL2, O_REL8-O_REL2 109754Speter }; 110754Speter #else 111754Speter char reltab0[] = { 112754Speter O_REL2-O_REL2, O_REL2-O_REL2, O_REL42-O_REL2, O_REL82-O_REL2, 113754Speter O_REL2-O_REL2, O_REL2-O_REL2, O_REL42-O_REL2, O_REL82-O_REL2, 114754Speter O_REL24-O_REL2, O_REL24-O_REL2, O_REL4-O_REL2, O_REL84-O_REL2, 115754Speter O_REL28-O_REL2, O_REL28-O_REL2, O_REL48-O_REL2, O_REL8-O_REL2 116754Speter }; 117754Speter char reltab1[] = { 118754Speter O_REL2-O_REL2, O_REL2-O_REL2, O_REL2-O_REL2, O_REL82-O_REL2, 119754Speter O_REL2-O_REL2, O_REL2-O_REL2, O_REL2-O_REL2, O_REL82-O_REL2, 120754Speter O_REL2-O_REL2, O_REL2-O_REL2, O_REL2-O_REL2, O_REL82-O_REL2, 121754Speter O_REL28-O_REL2, O_REL28-O_REL2, O_REL28-O_REL2, O_REL8-O_REL2 122754Speter }; 123754Speter char *reltab = reltab0; 124754Speter #endif 125754Speter 126754Speter #ifndef DEBUG 127754Speter char asgntab[] = { 128754Speter O_AS21-O_AS2, O_AS21-O_AS2, O_AS41-O_AS2, -1, 129754Speter O_AS2-O_AS2, O_AS2-O_AS2, O_AS42-O_AS2, -1, 130754Speter O_AS24-O_AS2, O_AS24-O_AS2, O_AS4-O_AS2, -1, 131754Speter O_AS28-O_AS2, O_AS28-O_AS2, O_AS48-O_AS2, O_AS8-O_AS2, 132754Speter }; 133754Speter #else 134754Speter char asgntb0[] = { 135754Speter O_AS21-O_AS2, O_AS21-O_AS2, O_AS41-O_AS2, -1, 136754Speter O_AS2-O_AS2, O_AS2-O_AS2, O_AS42-O_AS2, -1, 137754Speter O_AS24-O_AS2, O_AS24-O_AS2, O_AS4-O_AS2, -1, 138754Speter O_AS28-O_AS2, O_AS28-O_AS2, O_AS48-O_AS2, O_AS8-O_AS2, 139754Speter }; 140754Speter char asgntb1[] = { 141754Speter O_AS21-O_AS2, O_AS21-O_AS2, O_AS21-O_AS2, -1, 142754Speter O_AS2-O_AS2, O_AS2-O_AS2, O_AS2-O_AS2, -1, 143754Speter O_AS2-O_AS2, O_AS2-O_AS2, O_AS2-O_AS2, -1, 144754Speter O_AS28-O_AS2, O_AS28-O_AS2, O_AS28-O_AS2, O_AS4-O_AS2, 145754Speter }; 146754Speter char *asgntab = asgntb0; 147754Speter #endif 148754Speter 149754Speter #ifdef DEBUG 150754Speter genmx() 151754Speter { 152754Speter 153754Speter arret = arret1; 154754Speter artab = artab1; 155754Speter reltab = reltab1; 156754Speter asgntab = asgntb1; 157754Speter } 158754Speter #endif 159754Speter 160754Speter /* 161754Speter * Gen generates code for assignments, 162754Speter * and arithmetic and string operations 163754Speter * and comparisons. 164754Speter */ 165754Speter struct nl * 166754Speter gen(p, o, w1, w2) 167754Speter int p, o, w1, w2; 168754Speter { 169754Speter register i, j; 170*14733Sthien int op; 171754Speter 172754Speter switch (p) { 173*14733Sthien default: 174*14733Sthien panic("gen"); 175754Speter case O_AS2: 176754Speter case NIL: 177754Speter i = j = -1; 178754Speter /* 179754Speter * Take the log2 of the widths 180754Speter * and linearize them for indexing. 181754Speter * width for indexing. 182754Speter */ 183754Speter #ifdef DEBUG 184754Speter if (hp21mx) { 185754Speter if (w1 == 4) 186754Speter w1 = 8; 187754Speter if (w2 == 4) 188754Speter w2 = 8; 189754Speter } 190754Speter #endif 191754Speter do i++; while (w1 >>= 1); 192754Speter do j++; while (w2 >>= 1); 193754Speter i <<= 2; 194754Speter i |= j; 195754Speter if (p == O_AS2) { 196*14733Sthien (void) put(1, O_AS2 + asgntab[i]); 197754Speter return (NIL); 198754Speter } 199754Speter op = arop[o]; 200754Speter if (op == O_REL2) { 201*14733Sthien (void) put(1, (op + reltab[i]) | (o - T_EQ) << 8+INDX); 202754Speter return (nl+TBOOL); 203754Speter } 204*14733Sthien (void) put(1, i == 15 ? ar8op[o-T_DIVD] : op | artab[i]); 205754Speter return (op == O_DVD2 && !divchk ? nl+TDOUBLE : nl+arret[i]); 206754Speter case TREC: 207754Speter case TSTR: 208*14733Sthien (void) put(2, O_RELG | (o - T_EQ) << 8+INDX, w1); 209754Speter return (nl+TBOOL); 210754Speter case TSET: 211754Speter op = setop[o-T_MULT]; 212754Speter if (op == O_RELT) 213754Speter op |= (o - T_EQ)<<8+INDX; 214*14733Sthien (void) put(2, op, w1); 215754Speter return (o >= T_EQ ? nl+TBOOL : nl+TSET); 216754Speter } 217754Speter } 218754Speter #endif OBJ 219