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