|
|
1.1 ! root 1: /* Copyright (c) 1980 Regents of the University of California */ ! 2: static char sccsid[] = "@(#)asexpr.c 4.2 8/15/80"; ! 3: #include <stdio.h> ! 4: #include "as.h" ! 5: #include "asexpr.h" ! 6: ! 7: /* ! 8: * Tables for combination of operands. ! 9: */ ! 10: #define XTXRN 5<<1 /* indexes last row/column when right shifted */ ! 11: ! 12: /* ! 13: * table for + ! 14: */ ! 15: readonly char pltab[6][6] = { ! 16: /* UND ABS TXT DAT BSS EXT */ ! 17: ! 18: /*UND*/ XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF, ! 19: /*ABS*/ XUNDEF, XABS, XTEXT, XDATA, XBSS, XXTRN, ! 20: /*TXT*/ XUNDEF, XTEXT, ERR, ERR, ERR, ERR, ! 21: /*DAT*/ XUNDEF, XDATA, ERR, ERR, ERR, ERR, ! 22: /*BSS*/ XUNDEF, XBSS, ERR, ERR, ERR, ERR, ! 23: /*EXT*/ XUNDEF, XXTRN, ERR, ERR, ERR, ERR, ! 24: }; ! 25: ! 26: /* ! 27: * table for - ! 28: */ ! 29: readonly char mintab[6][6] = { ! 30: /* UND ABS TXT DAT BSS EXT */ ! 31: ! 32: /*UND*/ XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF, ! 33: /*ABS*/ XUNDEF, XABS, ERR, ERR, ERR, ERR, ! 34: /*TXT*/ XUNDEF, XTEXT, XABS, ERR, ERR, ERR, ! 35: /*DAT*/ XUNDEF, XDATA, ERR, XABS, ERR, ERR, ! 36: /*BSS*/ XUNDEF, XBSS, ERR, ERR, XABS, ERR, ! 37: /*EXT*/ XUNDEF, XXTRN, ERR, ERR, ERR, ERR, ! 38: }; ! 39: ! 40: /* ! 41: * table for other operators ! 42: */ ! 43: readonly char othtab[6][6] = { ! 44: /* UND ABS TXT DAT BSS EXT */ ! 45: ! 46: /*UND*/ XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF, ! 47: /*ABS*/ XUNDEF, XABS, ERR, ERR, ERR, ERR, ! 48: /*TXT*/ XUNDEF, ERR, ERR, ERR, ERR, ERR, ! 49: /*DAT*/ XUNDEF, ERR, ERR, ERR, ERR, ERR, ! 50: /*BSS*/ XUNDEF, ERR, ERR, ERR, ERR, ERR, ! 51: /*EXT*/ XUNDEF, ERR, ERR, ERR, ERR, ERR, ! 52: }; ! 53: ! 54: struct exp * ! 55: combine(op, exp1, exp2) ! 56: register struct exp *exp1, *exp2; ! 57: { ! 58: register e1_type, e2_type; ! 59: register back_type; ! 60: ! 61: lastnam=0; /* kludge for jxxx instructions */ ! 62: ! 63: e1_type = exp1->e_xtype&XTYPE; ! 64: e2_type = exp2->e_xtype&XTYPE; ! 65: ! 66: if (exp1->e_xtype==XXTRN+XUNDEF) ! 67: e1_type = XTXRN; ! 68: if (exp2->e_xtype==XXTRN+XUNDEF) ! 69: e2_type = XTXRN; ! 70: if (passno==1) ! 71: if (exp1->e_xloc!=exp2->e_xloc && e1_type==e2_type) ! 72: e1_type = e2_type = XTXRN; /* error on != loc ctrs */ ! 73: e1_type >>= 1; /*dispose of the external (XXTRN) bit*/ ! 74: e2_type >>= 1; ! 75: ! 76: switch (op) { ! 77: case PLUS: ! 78: exp1->e_xvalue += exp2->e_xvalue; ! 79: back_type = pltab[e1_type][e2_type]; ! 80: break; ! 81: case MINUS: ! 82: exp1->e_xvalue -= exp2->e_xvalue; ! 83: back_type = mintab[e1_type][e2_type]; ! 84: break; ! 85: case IOR: ! 86: exp1->e_xvalue |= exp2->e_xvalue; ! 87: goto comm; ! 88: case XOR: ! 89: exp1->e_xvalue ^= exp2->e_xvalue; ! 90: goto comm; ! 91: case AND: ! 92: exp1->e_xvalue &= exp2->e_xvalue; ! 93: goto comm; ! 94: case ORNOT: ! 95: exp1->e_xvalue |= ~exp2->e_xvalue; ! 96: goto comm; ! 97: case LSH: ! 98: exp1->e_xvalue <<= exp2->e_xvalue; ! 99: goto comm; ! 100: case RSH: ! 101: exp1->e_xvalue = exp2->e_xvalue > 0 ? exp1->e_xvalue >> exp2->e_xvalue : exp1->e_xvalue << - exp2->e_xvalue; ! 102: goto comm; ! 103: case TILDE: ! 104: exp1->e_xvalue |= ~ exp2->e_xvalue; ! 105: goto comm; ! 106: case MUL: ! 107: exp1->e_xvalue *= exp2->e_xvalue; ! 108: goto comm; ! 109: case DIV: ! 110: if (exp2->e_xvalue == 0) ! 111: yyerror("Divide check"); ! 112: else ! 113: exp1->e_xvalue /= exp2->e_xvalue; ! 114: goto comm; ! 115: case REGOP: ! 116: if (exp2->e_xvalue == 0) ! 117: yyerror("Divide check (modulo)"); ! 118: else ! 119: exp1->e_xvalue %= exp2->e_xvalue; ! 120: goto comm; ! 121: ! 122: comm: ! 123: back_type = othtab[e1_type][e2_type]; ! 124: break; ! 125: default: ! 126: yyerror("Internal error: unknown operator"); ! 127: } ! 128: ! 129: if (e2_type==(XTXRN>>1)) ! 130: exp1->e_xname = exp2->e_xname; ! 131: exp1->e_xtype = back_type | ( ! 132: (exp1->e_xtype|exp2->e_xtype) & (XFORW|XXTRN) ); ! 133: if (back_type==ERR) ! 134: yyerror("Relocation error"); ! 135: return(exp1); ! 136: } ! 137: ! 138: buildtokensets() ! 139: { ! 140: #define clobber(val, set) tokensets[(val)] |= (set) ! 141: ! 142: clobber(SEMI, LINSTBEGIN); ! 143: clobber(NL, LINSTBEGIN); ! 144: clobber(INT, LINSTBEGIN); ! 145: ! 146: clobber(NAME, YUKKYEXPRBEG + LINSTBEGIN); ! 147: clobber(INSTn, YUKKYEXPRBEG); ! 148: clobber(INST0, YUKKYEXPRBEG); ! 149: clobber(REG, YUKKYEXPRBEG); ! 150: clobber(BFINT, YUKKYEXPRBEG); ! 151: ! 152: clobber(INT, SAFEEXPRBEG); ! 153: clobber(FLTNUM, SAFEEXPRBEG); ! 154: ! 155: clobber(PLUS, ADDOPS); ! 156: clobber(MINUS, ADDOPS + EBEGOPS); ! 157: ! 158: clobber(LP, EBEGOPS); ! 159: ! 160: clobber(IOR, BOOLOPS); ! 161: clobber(XOR, BOOLOPS); ! 162: clobber(AND, BOOLOPS); ! 163: clobber(ORNOT, BOOLOPS); ! 164: ! 165: clobber(TILDE, MULOPS + EBEGOPS); ! 166: clobber(LSH, MULOPS); ! 167: clobber(RSH, MULOPS); ! 168: clobber(MUL, MULOPS); ! 169: clobber(DIV, MULOPS); ! 170: clobber(REGOP, MULOPS); /* % */ ! 171: ! 172: } ! 173: ! 174: /* ! 175: * We keep the current token class in this global variable, so ! 176: * the recursive descent expression analyzers can talk amongst ! 177: * themselves, and so that we may use the macros shift and shift over ! 178: */ ! 179: ! 180: extern int yylval; /*the value of the lexical value*/ ! 181: extern struct exp *xp; /*the next free expression slot*/ ! 182: ! 183: static int val; ! 184: int exprparse(inval, backexpr) /*return the value the read head is sitting on*/ ! 185: int inval; ! 186: struct exp **backexpr; ! 187: { ! 188: register struct exp *lexpr; ! 189: int op; ! 190: ! 191: val = inval; ! 192: lexpr = boolterm(); ! 193: while (INTOKSET(val, ADDOPS)){ ! 194: op = val; ! 195: shift; ! 196: lexpr = combine(op, lexpr, boolterm()); ! 197: } ! 198: *backexpr = lexpr; ! 199: return(val); ! 200: } ! 201: ! 202: struct exp *boolterm() ! 203: { ! 204: register struct exp *lexpr; ! 205: int op; ! 206: ! 207: lexpr = term(); ! 208: while(INTOKSET(val, BOOLOPS)){ ! 209: op = val; ! 210: shift; ! 211: lexpr = combine(op, lexpr, term()); ! 212: } ! 213: return(lexpr); ! 214: } ! 215: ! 216: struct exp *term() ! 217: { ! 218: register struct exp *lexpr; ! 219: int op; ! 220: ! 221: lexpr = factor(); ! 222: while(INTOKSET(val, MULOPS)){ ! 223: op = val; ! 224: shift; ! 225: lexpr = combine(op, lexpr, factor()); ! 226: } ! 227: return(lexpr); ! 228: } ! 229: ! 230: struct exp *factor() ! 231: { ! 232: struct exp *lexpr; ! 233: int op; ! 234: extern int droppedLP; /*called exprparse after consuming an LP*/ ! 235: ! 236: if (val == LP || droppedLP){ ! 237: if (droppedLP) ! 238: droppedLP = 0; ! 239: else ! 240: shift; /*the LP*/ ! 241: val = exprparse(val, &lexpr); ! 242: if (val != RP) ! 243: yyerror("right parenthesis expected"); ! 244: else ! 245: shift; ! 246: } else ! 247: if (INTOKSET(val, YUKKYEXPRBEG)){ ! 248: lexpr = yukkyexpr(val, yylval); ! 249: shift; ! 250: } ! 251: else if (INTOKSET(val, SAFEEXPRBEG)){ ! 252: lexpr = (struct exp *)yylval; ! 253: shift; ! 254: } ! 255: else if ( (val == TILDE) || (val == MINUS) ){ ! 256: op = val; ! 257: shift; ! 258: lexpr = xp++; ! 259: lexpr->e_xtype = XABS; ! 260: lexpr->e_xvalue = 0; ! 261: lexpr = combine(op, lexpr, factor()); ! 262: } ! 263: else { ! 264: yyerror("Bad expression syntax"); ! 265: lexpr = xp++; ! 266: lexpr->e_xtype = XABS; ! 267: lexpr->e_xvalue = 0; ! 268: } ! 269: return(lexpr); ! 270: } ! 271: ! 272: struct exp *yukkyexpr(val, np) ! 273: int val; ! 274: register np; ! 275: { ! 276: register struct exp *locxp; ! 277: extern int exprisname; /*last factor is a name*/ ! 278: extern struct symtab *exprxname; /*another stab in the back*/ ! 279: ! 280: exprisname = 0; ! 281: locxp = xp++; ! 282: if (val == NAME || val == BFINT){ ! 283: if (val == BFINT) { ! 284: int off = 0; ! 285: yylval = ((struct exp *)np)->e_xvalue; ! 286: if (yylval < 0) { ! 287: yylval = -yylval; ! 288: yylval--; ! 289: off = -1; ! 290: if (lgensym[yylval] == 1) ! 291: yyerror("Reference to undefined local label %db", yylval); ! 292: } else { ! 293: yylval--; ! 294: genref[yylval] = 1; ! 295: } ! 296: sprintf(yytext, "L%d\001%d", yylval, lgensym[yylval] + off); ! 297: yylval = np = (int)*lookup(passno == 1); ! 298: lastnam = (struct symtab *)np; ! 299: } ! 300: exprisname++; ! 301: locxp->e_xtype = ((struct symtab *)np)->s_type; ! 302: if (( ((struct symtab *)np)->s_type&XTYPE)==XUNDEF) { /*forward*/ ! 303: locxp->e_xname = (struct symtab *)np; ! 304: locxp->e_xvalue = 0; ! 305: if (passno==1) ! 306: ((struct symtab *)np)->s_type |= XFORW; ! 307: } else { /*otherwise, just get the value*/ ! 308: exprxname = (struct symtab *)np; ! 309: locxp->e_xvalue = ((struct symtab *)np)->s_value; ! 310: locxp->e_xname = NULL; ! 311: } ! 312: } else { /*INSTn or INST0 or REG*/ ! 313: locxp->e_xtype = XABS; ! 314: locxp->e_xvalue = ( (int)np) & 0xFF; ! 315: locxp->e_xloc = 0; ! 316: locxp->e_xname = NULL; ! 317: } ! 318: ! 319: return(locxp); ! 320: } ! 321: ! 322: ! 323: #ifdef DEBUG ! 324: char *tok_name[LASTTOKEN - FIRSTTOKEN + 1]; ! 325: struct Tok_Desc{ ! 326: int tok_which; ! 327: char *tok_name; ! 328: } tok_desc[] = { ! 329: FIRSTTOKEN, "firsttoken", /* 0 */ ! 330: ISPACE, "ispace", /* 1 */ ! 331: IBYTE, "ibyte", /* 2 */ ! 332: IWORD, "iword", /* 3 */ ! 333: IINT, "iint", /* 4 */ ! 334: ILONG, "ilong", /* 5 */ ! 335: IDATA, "idata", /* 6 */ ! 336: IGLOBAL, "iglobal", /* 7 */ ! 337: ISET, "iset", /* 8 */ ! 338: ITEXT, "itext", /* 9 */ ! 339: ICOMM, "icomm", /* 10 */ ! 340: ILCOMM, "ilcomm", /* 11 */ ! 341: IFLOAT, "ifloat", /* 12 */ ! 342: IDOUBLE, "idouble", /* 13 */ ! 343: IORG, "iorg", /* 14 */ ! 344: IASCII, "iascii", /* 15 */ ! 345: IASCIZ, "iasciz", /* 16 */ ! 346: ILSYM, "ilsym", /* 17 */ ! 347: IFILE, "ifile", /* 18 */ ! 348: ILINENO, "ilineno", /* 19 */ ! 349: IABORT, "iabort", /* 20 */ ! 350: ISTAB, "istab", /* 23 */ ! 351: ISTABSTR, "istabstr", /* 24 */ ! 352: ISTABNONE, "istabnone", /* 25 */ ! 353: ISTABDOT, "istabdot", /* 26 */ ! 354: IJXXX, "ijxxx", /* 27 */ ! 355: IALIGN, "ialign", /* 28 */ ! 356: INST0, "inst0", /* 29 */ ! 357: INSTn, "instn", /* 30 */ ! 358: BFINT, "bfint", /* 31 */ ! 359: PARSEEOF, "parseeof", /* 32 */ ! 360: ILINESKIP, "ilineskip", /* 33 */ ! 361: VOID, "void", /* 34 */ ! 362: SKIP, "skip", /* 35 */ ! 363: INT, "int", /* 36 */ ! 364: FLTNUM, "fltnum", /* 37 */ ! 365: NAME, "name", /* 38 */ ! 366: STRING, "string", /* 39 */ ! 367: QUAD, "quad", /* 40 */ ! 368: SIZESPEC, "sizespec", /* 41 */ ! 369: REG, "reg", /* 42 */ ! 370: MUL, "mul", /* 43 */ ! 371: LITOP, "litop", /* 44 */ ! 372: LP, "lp", /* 45 */ ! 373: MP, "mp", /* 46 */ ! 374: NEEDSBUF, "needsbuf", /* 48 */ ! 375: REGOP, "regop", /* 49 */ ! 376: NL, "nl", /* 50 */ ! 377: SCANEOF, "scaneof", /* 51 */ ! 378: BADCHAR, "badchar", /* 52 */ ! 379: SP, "sp", /* 53 */ ! 380: ALPH, "alph", /* 54 */ ! 381: DIG, "dig", /* 55 */ ! 382: SQ, "sq", /* 56 */ ! 383: DQ, "dq", /* 57 */ ! 384: SH, "sh", /* 58 */ ! 385: LSH, "lsh", /* 59 */ ! 386: RSH, "rsh", /* 60 */ ! 387: MINUS, "minus", /* 61 */ ! 388: SIZEQUOTE, "sizequote", /* 62 */ ! 389: XOR, "xor", /* 64 */ ! 390: DIV, "div", /* 65 */ ! 391: SEMI, "semi", /* 66 */ ! 392: COLON, "colon", /* 67 */ ! 393: PLUS, "plus", /* 68 */ ! 394: IOR, "ior", /* 69 */ ! 395: AND, "and", /* 70 */ ! 396: TILDE, "tilde", /* 71 */ ! 397: ORNOT, "ornot", /* 72 */ ! 398: CM, "cm", /* 73 */ ! 399: LB, "lb", /* 74 */ ! 400: RB, "rb", /* 75 */ ! 401: RP, "rp", /* 76 */ ! 402: LASTTOKEN, "lasttoken" /* 80 */ ! 403: }; ! 404: /* ! 405: * turn a token type into a string ! 406: */ ! 407: static int fixed = 0; ! 408: char *tok_to_name(token) ! 409: { ! 410: if (!fixed){ ! 411: int i; ! 412: for (i = FIRSTTOKEN; i <= LASTTOKEN; i++) ! 413: tok_name[i] = "NOT ASSIGNED"; ! 414: for (i = FIRSTTOKEN; i <= sizeof(tok_desc)/sizeof(struct Tok_Desc); i++){ ! 415: tok_name[tok_desc[i].tok_which] = tok_desc[i].tok_name; ! 416: } ! 417: fixed = 1; ! 418: } ! 419: if (FIRSTTOKEN <= token && token <= LASTTOKEN) ! 420: return(tok_name[token]); ! 421: else ! 422: panic("Unknown token number, %d\n", token); ! 423: /*NOTREACHED*/ ! 424: } ! 425: #endif DEBUG
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.