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