1 /* Copyright (c) 1980 Regents of the University of California */ 2 static char sccsid[] = "@(#)asexpr.c 4.2 08/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; 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 279 exprisname = 0; 280 locxp = xp++; 281 if (val == NAME || val == BFINT){ 282 if (val == BFINT) { 283 int off = 0; 284 yylval = ((struct exp *)np)->e_xvalue; 285 if (yylval < 0) { 286 yylval = -yylval; 287 yylval--; 288 off = -1; 289 if (lgensym[yylval] == 1) 290 yyerror("Reference to undefined local label %db", yylval); 291 } else { 292 yylval--; 293 genref[yylval] = 1; 294 } 295 sprintf(yytext, "L%d\001%d", yylval, lgensym[yylval] + off); 296 yylval = np = (int)*lookup(passno == 1); 297 lastnam = (struct symtab *)np; 298 } 299 exprisname++; 300 locxp->e_xtype = ((struct symtab *)np)->s_type; 301 if (( ((struct symtab *)np)->s_type&XTYPE)==XUNDEF) { /*forward*/ 302 locxp->e_xname = (struct symtab *)np; 303 locxp->e_xvalue = 0; 304 if (passno==1) 305 ((struct symtab *)np)->s_type |= XFORW; 306 } else { /*otherwise, just get the value*/ 307 locxp->e_xvalue = ((struct symtab *)np)->s_value; 308 locxp->e_xname = NULL; 309 } 310 } else { /*INSTn or INST0 or REG*/ 311 locxp->e_xtype = XABS; 312 locxp->e_xvalue = ( (int)np) & 0xFF; 313 locxp->e_xloc = 0; 314 locxp->e_xname = NULL; 315 } 316 317 return(locxp); 318 } 319 320 321 #ifdef DEBUG 322 char *tok_name[LASTTOKEN - FIRSTTOKEN + 1]; 323 struct Tok_Desc{ 324 int tok_which; 325 char *tok_name; 326 } tok_desc[] = { 327 FIRSTTOKEN, "firsttoken", /* 0 */ 328 ISPACE, "ispace", /* 1 */ 329 IBYTE, "ibyte", /* 2 */ 330 IWORD, "iword", /* 3 */ 331 IINT, "iint", /* 4 */ 332 ILONG, "ilong", /* 5 */ 333 IDATA, "idata", /* 6 */ 334 IGLOBAL, "iglobal", /* 7 */ 335 ISET, "iset", /* 8 */ 336 ITEXT, "itext", /* 9 */ 337 ICOMM, "icomm", /* 10 */ 338 ILCOMM, "ilcomm", /* 11 */ 339 IFLOAT, "ifloat", /* 12 */ 340 IDOUBLE, "idouble", /* 13 */ 341 IORG, "iorg", /* 14 */ 342 IASCII, "iascii", /* 15 */ 343 IASCIZ, "iasciz", /* 16 */ 344 ILSYM, "ilsym", /* 17 */ 345 IFILE, "ifile", /* 18 */ 346 ILINENO, "ilineno", /* 19 */ 347 IABORT, "iabort", /* 20 */ 348 ISTAB, "istab", /* 23 */ 349 ISTABSTR, "istabstr", /* 24 */ 350 ISTABNONE, "istabnone", /* 25 */ 351 ISTABDOT, "istabdot", /* 26 */ 352 IJXXX, "ijxxx", /* 27 */ 353 IALIGN, "ialign", /* 28 */ 354 INST0, "inst0", /* 29 */ 355 INSTn, "instn", /* 30 */ 356 BFINT, "bfint", /* 31 */ 357 PARSEEOF, "parseeof", /* 32 */ 358 ILINESKIP, "ilineskip", /* 33 */ 359 VOID, "void", /* 34 */ 360 SKIP, "skip", /* 35 */ 361 INT, "int", /* 36 */ 362 FLTNUM, "fltnum", /* 37 */ 363 NAME, "name", /* 38 */ 364 STRING, "string", /* 39 */ 365 QUAD, "quad", /* 40 */ 366 SIZESPEC, "sizespec", /* 41 */ 367 REG, "reg", /* 42 */ 368 MUL, "mul", /* 43 */ 369 LITOP, "litop", /* 44 */ 370 LP, "lp", /* 45 */ 371 MP, "mp", /* 46 */ 372 NEEDSBUF, "needsbuf", /* 48 */ 373 REGOP, "regop", /* 49 */ 374 NL, "nl", /* 50 */ 375 SCANEOF, "scaneof", /* 51 */ 376 BADCHAR, "badchar", /* 52 */ 377 SP, "sp", /* 53 */ 378 ALPH, "alph", /* 54 */ 379 DIG, "dig", /* 55 */ 380 SQ, "sq", /* 56 */ 381 DQ, "dq", /* 57 */ 382 SH, "sh", /* 58 */ 383 LSH, "lsh", /* 59 */ 384 RSH, "rsh", /* 60 */ 385 MINUS, "minus", /* 61 */ 386 SIZEQUOTE, "sizequote", /* 62 */ 387 XOR, "xor", /* 64 */ 388 DIV, "div", /* 65 */ 389 SEMI, "semi", /* 66 */ 390 COLON, "colon", /* 67 */ 391 PLUS, "plus", /* 68 */ 392 IOR, "ior", /* 69 */ 393 AND, "and", /* 70 */ 394 TILDE, "tilde", /* 71 */ 395 ORNOT, "ornot", /* 72 */ 396 CM, "cm", /* 73 */ 397 LB, "lb", /* 74 */ 398 RB, "rb", /* 75 */ 399 RP, "rp", /* 76 */ 400 LASTTOKEN, "lasttoken" /* 80 */ 401 }; 402 /* 403 * turn a token type into a string 404 */ 405 static int fixed = 0; 406 char *tok_to_name(token) 407 { 408 if (!fixed){ 409 int i; 410 for (i = FIRSTTOKEN; i <= LASTTOKEN; i++) 411 tok_name[i] = "NOT ASSIGNED"; 412 for (i = FIRSTTOKEN; i <= sizeof(tok_desc)/sizeof(struct Tok_Desc); i++){ 413 tok_name[tok_desc[i].tok_which] = tok_desc[i].tok_name; 414 } 415 fixed = 1; 416 } 417 if (FIRSTTOKEN <= token && token <= LASTTOKEN) 418 return(tok_name[token]); 419 else 420 panic("Unknown token number, %d\n", token); 421 /*NOTREACHED*/ 422 } 423 #endif DEBUG 424