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