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