|
|
1.1 ! root 1: /* Copyright (c) 1979 Regents of the University of California */ ! 2: #include <stdio.h> ! 3: #include "as.h" ! 4: #include "asexpr.h" ! 5: ! 6: /* ! 7: * Tables for combination of operands. ! 8: */ ! 9: ! 10: /* ! 11: * table for + ! 12: */ ! 13: readonly char pltab[6][6] = { ! 14: /* UND ABS TXT DAT BSS EXT */ ! 15: ! 16: /*UND*/ XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF, ! 17: /*ABS*/ XUNDEF, XABS, XTEXT, XDATA, XBSS, XXTRN, ! 18: /*TXT*/ XUNDEF, XTEXT, ERR, ERR, ERR, ERR, ! 19: /*DAT*/ XUNDEF, XDATA, ERR, ERR, ERR, ERR, ! 20: /*BSS*/ XUNDEF, XBSS, ERR, ERR, ERR, ERR, ! 21: /*EXT*/ XUNDEF, XXTRN, ERR, ERR, ERR, ERR, ! 22: }; ! 23: ! 24: /* ! 25: * table for - ! 26: */ ! 27: readonly char mintab[6][6] = { ! 28: /* UND ABS TXT DAT BSS EXT */ ! 29: ! 30: /*UND*/ XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF, ! 31: /*ABS*/ XUNDEF, XABS, ERR, ERR, ERR, ERR, ! 32: /*TXT*/ XUNDEF, XTEXT, XABS, ERR, ERR, ERR, ! 33: /*DAT*/ XUNDEF, XDATA, ERR, XABS, ERR, ERR, ! 34: /*BSS*/ XUNDEF, XBSS, ERR, ERR, XABS, ERR, ! 35: /*EXT*/ XUNDEF, XXTRN, ERR, ERR, ERR, ERR, ! 36: }; ! 37: ! 38: /* ! 39: * table for other operators ! 40: */ ! 41: readonly char othtab[6][6] = { ! 42: /* UND ABS TXT DAT BSS EXT */ ! 43: ! 44: /*UND*/ XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF, ! 45: /*ABS*/ XUNDEF, XABS, ERR, ERR, ERR, ERR, ! 46: /*TXT*/ XUNDEF, ERR, ERR, ERR, ERR, ERR, ! 47: /*DAT*/ XUNDEF, ERR, ERR, ERR, ERR, ERR, ! 48: /*BSS*/ XUNDEF, ERR, ERR, ERR, ERR, ERR, ! 49: /*EXT*/ XUNDEF, ERR, ERR, ERR, ERR, ERR, ! 50: }; ! 51: ! 52: struct exp * ! 53: combine(op, exp1, exp2) ! 54: register struct exp *exp1, *exp2; ! 55: { ! 56: register e1_type, e2_type; ! 57: register type; ! 58: ! 59: lastnam=0; /* kludge for jxxx instructions */ ! 60: ! 61: e1_type = exp1->xtype&XTYPE; ! 62: e2_type = exp2->xtype&XTYPE; ! 63: ! 64: if (exp1->xtype==XXTRN+XUNDEF) ! 65: e1_type = XTXRN; ! 66: if (exp2->xtype==XXTRN+XUNDEF) ! 67: e2_type = XTXRN; ! 68: if (passno==1) ! 69: if (exp1->xloc!=exp2->xloc && e1_type==e2_type) ! 70: e1_type = e2_type = XTXRN; /* error on != loc ctrs */ ! 71: e1_type >>= 1; /*dispost of the external (XXTRN) bit*/ ! 72: e2_type >>= 1; ! 73: ! 74: switch (op) { ! 75: case PLUS: ! 76: exp1->xvalue += exp2->xvalue; ! 77: type = pltab[e1_type][e2_type]; ! 78: break; ! 79: case MINUS: ! 80: exp1->xvalue -= exp2->xvalue; ! 81: type = mintab[e1_type][e2_type]; ! 82: break; ! 83: case IOR: ! 84: exp1->xvalue |= exp2->xvalue; ! 85: goto comm; ! 86: case XOR: ! 87: exp1->xvalue ^= exp2->xvalue; ! 88: goto comm; ! 89: case AND: ! 90: exp1->xvalue &= exp2->xvalue; ! 91: goto comm; ! 92: case ORNOT: ! 93: exp1->xvalue |= ~exp2->xvalue; ! 94: goto comm; ! 95: case LSH: ! 96: exp1->xvalue <<= exp2->xvalue; ! 97: goto comm; ! 98: case RSH: ! 99: exp1->xvalue >>= exp2->xvalue; ! 100: goto comm; ! 101: case TILDE: ! 102: exp1->xvalue |= ~ exp2->xvalue; ! 103: goto comm; ! 104: case MUL: ! 105: exp1->xvalue *= exp2->xvalue; ! 106: goto comm; ! 107: case DIV: ! 108: if (exp2->xvalue == 0) ! 109: yyerror("Divide check"); ! 110: else ! 111: exp1->xvalue /= exp2->xvalue; ! 112: goto comm; ! 113: case REGOP: ! 114: if (exp2->xvalue == 0) ! 115: yyerror("Divide check (modulo)"); ! 116: else ! 117: exp1->xvalue %= exp2->xvalue; ! 118: goto comm; ! 119: ! 120: comm: ! 121: type = othtab[e1_type][e2_type]; ! 122: break; ! 123: default: ! 124: yyerror("Internal error: unknown operator"); ! 125: } ! 126: ! 127: if (e2_type==(XTXRN>>1)) ! 128: exp1->xname = exp2->xname; ! 129: exp1->xtype = type | ( ! 130: (exp1->xtype|exp2->xtype) & (XFORW|XXTRN) ); ! 131: if (type==ERR) ! 132: yyerror("Relocation error"); ! 133: return(exp1); ! 134: } ! 135: ! 136: buildtokensets() ! 137: { ! 138: #define clobber(val, set) tokensets[(val)] |= (set) ! 139: ! 140: clobber(SEMI, LINSTBEGIN); ! 141: clobber(NL, LINSTBEGIN); ! 142: ! 143: clobber(NAME, YUKKYEXPRBEG + LINSTBEGIN); ! 144: clobber(INSTn, YUKKYEXPRBEG); ! 145: clobber(INST0, YUKKYEXPRBEG); ! 146: clobber(REG, YUKKYEXPRBEG); ! 147: ! 148: clobber(INT, SAFEEXPRBEG); ! 149: clobber(FLTNUM, SAFEEXPRBEG); ! 150: ! 151: clobber(PLUS, ADDOPS); ! 152: clobber(MINUS, ADDOPS + EBEGOPS); ! 153: ! 154: clobber(LP, EBEGOPS); ! 155: ! 156: clobber(IOR, BOOLOPS); ! 157: clobber(XOR, BOOLOPS); ! 158: clobber(AND, BOOLOPS); ! 159: clobber(ORNOT, BOOLOPS); ! 160: ! 161: clobber(TILDE, MULOPS + EBEGOPS); ! 162: clobber(LSH, MULOPS); ! 163: clobber(RSH, MULOPS); ! 164: clobber(MUL, MULOPS); ! 165: clobber(DIV, MULOPS); ! 166: clobber(REGOP, MULOPS); /* % */ ! 167: } ! 168: ! 169: /* ! 170: * We keep the current token class in this global variable, so ! 171: * the recursive descent expression analyzers can talk amongst ! 172: * themselves, and so that we may use the macros shift and shift over ! 173: */ ! 174: ! 175: extern int yylval; /*the value of the lexical value*/ ! 176: extern struct exp *xp; /*the next free expression slot*/ ! 177: ! 178: static int val; ! 179: int exprparse(inval, backexpr) /*return the value the read head is sitting on*/ ! 180: int inval; ! 181: struct exp **backexpr; ! 182: { ! 183: register struct exp *lexpr; ! 184: int op; ! 185: ! 186: val = inval; ! 187: lexpr = boolterm(); ! 188: while (INTOKSET(val, ADDOPS)){ ! 189: op = val; ! 190: shift; ! 191: lexpr = combine(op, lexpr, boolterm()); ! 192: } ! 193: *backexpr = lexpr; ! 194: return(val); ! 195: } ! 196: ! 197: struct exp *boolterm() ! 198: { ! 199: register struct exp *lexpr; ! 200: int op; ! 201: ! 202: lexpr = term(); ! 203: while(INTOKSET(val, BOOLOPS)){ ! 204: op = val; ! 205: shift; ! 206: lexpr = combine(op, lexpr, term()); ! 207: } ! 208: return(lexpr); ! 209: } ! 210: ! 211: struct exp *term() ! 212: { ! 213: register struct exp *lexpr; ! 214: int op; ! 215: ! 216: lexpr = factor(); ! 217: while(INTOKSET(val, MULOPS)){ ! 218: op = val; ! 219: shift; ! 220: lexpr = combine(op, lexpr, factor()); ! 221: } ! 222: return(lexpr); ! 223: } ! 224: ! 225: struct exp *factor() ! 226: { ! 227: struct exp *lexpr; ! 228: int op; ! 229: extern int droppedLP; /*called exprparse after consuming an LP*/ ! 230: ! 231: if (val == LP || droppedLP){ ! 232: if (droppedLP) ! 233: droppedLP = 0; ! 234: else ! 235: shift; /*the LP*/ ! 236: val = exprparse(val, &lexpr); ! 237: if (val != RP) ! 238: yyerror("right parenthesis expected"); ! 239: else ! 240: shift; ! 241: } else ! 242: if (INTOKSET(val, YUKKYEXPRBEG)){ ! 243: lexpr = yukkyexpr(val, yylval); ! 244: shift; ! 245: } ! 246: else if (INTOKSET(val, SAFEEXPRBEG)){ ! 247: lexpr = (struct exp *)yylval; ! 248: shift; ! 249: } ! 250: else if ( (val == TILDE) || (val == MINUS) ){ ! 251: op = val; ! 252: shift; ! 253: lexpr = xp++; ! 254: lexpr->xtype = XABS; ! 255: lexpr->xvalue = 0; ! 256: lexpr = combine(op, lexpr, factor()); ! 257: } ! 258: else { ! 259: yyerror("Bad expression syntax"); ! 260: lexpr = xp++; ! 261: lexpr->xtype = XABS; ! 262: lexpr->xvalue = 0; ! 263: } ! 264: return(lexpr); ! 265: } ! 266: ! 267: struct exp *yukkyexpr(val, np) ! 268: int val; ! 269: register np; ! 270: { ! 271: register struct exp *locxp; ! 272: extern int exprisname; /*last factor is a name*/ ! 273: ! 274: exprisname = 0; ! 275: locxp = xp++; ! 276: if (val == NAME){ ! 277: exprisname++; ! 278: locxp->xtype = ((struct symtab *)np)->type; ! 279: if (( ((struct symtab *)np)->type&XTYPE)==XUNDEF) { /*forward*/ ! 280: locxp->xname = (struct symtab *)np; ! 281: locxp->xvalue = 0; ! 282: if (passno==1) ! 283: ((struct symtab *)np)->type |= XFORW; ! 284: } else { /*otherwise, just get the value*/ ! 285: locxp->xvalue = ((struct symtab *)np)->value; ! 286: locxp->xname = NULL; ! 287: } ! 288: } else { /*INSTn or INST0 or REG*/ ! 289: locxp->xtype = XABS; ! 290: locxp->xvalue = ( (int)np) & 0xFF; ! 291: locxp->xloc = 0; ! 292: locxp->xname = NULL; ! 293: } ! 294: ! 295: return(locxp); ! 296: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.