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) 6/5/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