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