1 /* 2 * Copyright (c) 1982 Regents of the University of California 3 */ 4 #ifndef lint 5 static char sccsid[] = "@(#)asparse.c 4.18 10/14/83"; 6 #endif not lint 7 8 #include <stdio.h> 9 #include "as.h" 10 #include "asscan.h" 11 #include "assyms.h" 12 #include "asexpr.h" 13 14 int lgensym[10]; 15 char genref[10]; 16 17 long bitfield; 18 int bitoff; 19 int curlen; /* current length of literals */ 20 21 /* 22 * The following three variables are communication between various 23 * modules to special case a number of things. They are properly 24 * categorized as hacks. 25 */ 26 extern struct symtab *lastnam;/*last name seen by the lexical analyzer*/ 27 int exprisname; /*last factor in an expression was a name*/ 28 int droppedLP; /*one is analyzing an expression beginning with*/ 29 /*a left parenthesis, which has already been*/ 30 /*shifted. (Used to parse (<expr>)(rn)*/ 31 32 char yytext[NCPName+2]; /*the lexical image*/ 33 int yylval; /*the lexical value; sloppy typing*/ 34 struct Opcode yyopcode; /* lexical value for an opcode */ 35 Bignum yybignum; /* lexical value for a big number */ 36 /* 37 * Expression and argument managers 38 */ 39 struct exp *xp; /*next free expression slot, used by expr.c*/ 40 struct exp explist[NEXP]; /*max of 20 expressions in one opcode*/ 41 struct arg arglist[NARG]; /*building up operands in instructions*/ 42 /* 43 * Sets to accelerate token discrimination 44 */ 45 char tokensets[(LASTTOKEN) - (FIRSTTOKEN) + 1]; 46 47 static char UDotsname[64]; /*name of the assembly source*/ 48 49 yyparse() 50 { 51 reg struct exp *locxp; 52 /* 53 * loc1xp and ptrloc1xp are used in the 54 * expression lookahead 55 */ 56 struct exp *loc1xp; /*must be non register*/ 57 struct exp **ptrloc1xp = & loc1xp; 58 struct exp *pval; /*hacking expr:expr*/ 59 60 reg struct symtab *np; 61 reg int argcnt; 62 63 reg inttoktype val; /*what yylex gives*/ 64 reg inttoktype auxval; /*saves val*/ 65 66 reg struct arg *ap; /*first free argument*/ 67 68 reg struct symtab *p; 69 reg struct symtab *stpt; 70 71 struct strdesc *stringp; /*handles string lists*/ 72 73 int regno; /*handles arguments*/ 74 int *ptrregno = ®no; 75 int sawmul; /*saw * */ 76 int sawindex; /*saw [rn]*/ 77 int sawsize; 78 int seg_type; /*the kind of segment: data or text*/ 79 int seg_number; /*the segment number*/ 80 int space_value; /*how much .space needs*/ 81 int fill_rep; /*how many reps for .fill */ 82 int fill_size; /*how many bytes for .fill */ 83 84 int field_width; /*how wide a field is to be*/ 85 int field_value; /*the value to stuff in a field*/ 86 char *stabname; /*name of stab dealing with*/ 87 ptrall stabstart; /*where the stab starts in the buffer*/ 88 int reloc_how; /* how to relocate expressions */ 89 int toconv; /* how to convert bignums */ 90 int incasetable; /* set if in a case table */ 91 92 incasetable = 0; 93 xp = explist; 94 ap = arglist; 95 96 val = yylex(); 97 98 while (val != PARSEEOF){ /* primary loop */ 99 100 while (INTOKSET(val, LINSTBEGIN)){ 101 if (val == INT) { 102 int i = ((struct exp *)yylval)->e_xvalue; 103 shift; 104 if (val != COLON){ 105 yyerror("Local label %d is not followed by a ':' for a label definition", 106 i); 107 goto errorfix; 108 } 109 if (i < 0 || i > 9) { 110 yyerror("Local labels are 0-9"); 111 goto errorfix; 112 } 113 (void)sprintf(yytext, "L%d\001%d", i, lgensym[i]); 114 lgensym[i]++; 115 genref[i] = 0; 116 yylval = (int)*lookup(passno == 1); 117 val = NAME; 118 np = (struct symtab *)yylval; 119 goto restlab; 120 } 121 if (val == NL){ 122 lineno++; 123 shift; 124 } else 125 if (val == SEMI) 126 shift; 127 else { /*its a name, so we have a label or def */ 128 if (val != NAME){ 129 ERROR("Name expected for a label"); 130 } 131 np = (struct symtab *)yylval; 132 shiftover(NAME); 133 if (val != COLON) { 134 yyerror("\"%s\" is not followed by a ':' for a label definition", 135 FETCHNAME(np)); 136 goto errorfix; 137 } 138 restlab: 139 shift; 140 flushfield(NBPW/4); 141 if ((np->s_type&XTYPE)!=XUNDEF) { 142 if ( (np->s_type&XTYPE) != dotp->e_xtype 143 || np->s_value != dotp->e_xvalue 144 || ( passno == 1 145 && np->s_index != dotp->e_xloc) ) { 146 if (passno == 1) 147 yyerror("%s redefined", 148 FETCHNAME(np)); 149 else 150 yyerror("%s redefined: PHASE ERROR, 1st: %d, 2nd: %d", 151 FETCHNAME(np), 152 np->s_value, 153 dotp->e_xvalue); 154 } 155 } 156 np->s_type &= ~(XTYPE|XFORW); 157 np->s_type |= dotp->e_xtype; 158 np->s_value = dotp->e_xvalue; 159 if (passno == 1){ 160 np->s_index = dotp-usedot; 161 if (FETCHNAME(np)[0] == 'L'){ 162 nlabels++; 163 } 164 np->s_tag = LABELID; 165 } 166 } /*end of this being a label*/ 167 } /*end of consuming all labels, NLs and SEMIS */ 168 169 xp = explist; 170 ap = arglist; 171 172 /* 173 * process the INSTRUCTION body 174 */ 175 switch(val){ 176 177 default: 178 ERROR("Unrecognized instruction or directive"); 179 180 case IABORT: 181 shift; 182 sawabort(); 183 /*NOTREACHED*/ 184 break; 185 186 case PARSEEOF: 187 tokptr -= sizeof(bytetoktype); 188 *tokptr++ = VOID; 189 tokptr[1] = VOID; 190 tokptr[2] = PARSEEOF; 191 break; 192 193 case IFILE: 194 shift; 195 stringp = (struct strdesc *)yylval; 196 shiftover(STRING); 197 dotsname = &UDotsname[0]; 198 movestr(dotsname, stringp->sd_string, 199 min(stringp->sd_strlen, sizeof(UDotsname))); 200 break; 201 202 case ILINENO: 203 shift; /*over the ILINENO*/ 204 expr(locxp, val); 205 lineno = locxp->e_xvalue; 206 break; 207 208 case ISET: /* .set <name> , <expr> */ 209 shift; 210 np = (struct symtab *)yylval; 211 shiftover(NAME); 212 shiftover(CM); 213 expr(locxp, val); 214 np->s_type &= (XXTRN|XFORW); 215 np->s_type |= locxp->e_xtype&(XTYPE|XFORW); 216 np->s_value = locxp->e_xvalue; 217 if (passno==1) 218 np->s_index = locxp->e_xloc; 219 if ((locxp->e_xtype&XTYPE) == XUNDEF) 220 yyerror("Illegal set?"); 221 break; 222 223 case ILSYM: /*.lsym name , expr */ 224 shift; 225 np = (struct symtab *)yylval; 226 shiftover(NAME); 227 shiftover(CM); 228 expr(locxp, val); 229 /* 230 * Build the unique occurance of the 231 * symbol. 232 * The character scanner will have 233 * already entered it into the symbol 234 * table, but we should remove it 235 */ 236 if (passno == 1){ 237 stpt = (struct symtab *)symalloc(); 238 stpt->s_name = np->s_name; 239 np->s_tag = OBSOLETE; /*invalidate original */ 240 nforgotten++; 241 np = stpt; 242 if ( (locxp->e_xtype & XTYPE) != XABS) 243 yyerror("Illegal second argument to lsym"); 244 np->s_value = locxp->e_xvalue; 245 np->s_type = XABS; 246 np->s_tag = ILSYM; 247 } 248 break; 249 250 case IGLOBAL: /*.globl <name> */ 251 shift; 252 np = (struct symtab *)yylval; 253 shiftover(NAME); 254 np->s_type |= XXTRN; 255 break; 256 257 case IDATA: /*.data [ <expr> ] */ 258 case ITEXT: /*.text [ <expr> ] */ 259 seg_type = -val; 260 shift; 261 if (INTOKSET(val, EBEGOPS+YUKKYEXPRBEG+SAFEEXPRBEG)){ 262 expr(locxp, val); 263 seg_type = -seg_type; /*now, it is positive*/ 264 } 265 266 if (seg_type < 0) { /*there wasn't an associated expr*/ 267 seg_number = 0; 268 seg_type = -seg_type; 269 } else { 270 if ( ((locxp->e_xtype & XTYPE) != XABS) /* tekmdp */ 271 || (seg_number = locxp->e_xvalue) >= NLOC) { 272 yyerror("illegal location counter"); 273 seg_number = 0; 274 } 275 } 276 if (seg_type == IDATA) 277 seg_number += NLOC; 278 flushfield(NBPW/4); 279 dotp = &usedot[seg_number]; 280 if (passno==2) { /* go salt away in pass 2*/ 281 txtfil = usefile[seg_number]; 282 relfil = rusefile[seg_number]; 283 } 284 break; 285 286 /* 287 * Storage filler directives: 288 * 289 * .byte [<exprlist>] 290 * 291 * exprlist: empty | exprlist outexpr 292 * outexpr: <expr> | <expr> : <expr> 293 */ 294 case IBYTE: curlen = NBPW/4; goto elist; 295 case IWORD: curlen = NBPW/2; goto elist; 296 case IINT: curlen = NBPW; goto elist; 297 case ILONG: curlen = NBPW; goto elist; 298 299 elist: 300 seg_type = val; 301 shift; 302 303 /* 304 * Expression List processing 305 */ 306 if (INTOKSET(val, EBEGOPS+YUKKYEXPRBEG+SAFEEXPRBEG)){ 307 do{ 308 /* 309 * expression list consists of a list of : 310 * <expr> 311 * <expr> : <expr> 312 * (pack expr2 into expr1 bits 313 */ 314 expr(locxp, val); 315 /* 316 * now, pointing at the next token 317 */ 318 if (val == COLON){ 319 shiftover(COLON); 320 expr(pval, val); 321 if ((locxp->e_xtype & XTYPE) != XABS) /* tekmdp */ 322 yyerror("Width not absolute"); 323 field_width = locxp->e_xvalue; 324 locxp = pval; 325 if (bitoff + field_width > curlen) 326 flushfield(curlen); 327 if (field_width > curlen) 328 yyerror("Expression crosses field boundary"); 329 } else { 330 field_width = curlen; 331 flushfield(curlen); 332 } 333 334 if ((locxp->e_xtype & XTYPE) != XABS) { 335 if (bitoff) 336 yyerror("Illegal relocation in field"); 337 switch(curlen){ 338 case NBPW/4: reloc_how = TYPB; break; 339 case NBPW/2: reloc_how = TYPW; break; 340 case NBPW: reloc_how = TYPL; break; 341 } 342 if (passno == 1){ 343 dotp->e_xvalue += ty_nbyte[reloc_how]; 344 } else { 345 outrel(locxp, reloc_how); 346 } 347 } else { 348 /* 349 * 350 * See if we are doing a case instruction. 351 * If so, then see if the branch distance, 352 * stored as a word, 353 * is going to loose sig bits. 354 */ 355 if (passno == 2 && incasetable){ 356 if ( (locxp->e_xvalue < -32768) 357 ||(locxp->e_xvalue > 32767)){ 358 yyerror("Case will branch too far"); 359 } 360 } 361 field_value = locxp->e_xvalue & ( (1L << field_width)-1); 362 bitfield |= field_value << bitoff; 363 bitoff += field_width; 364 } 365 xp = explist; 366 if (auxval = (val == CM)) 367 shift; 368 } while (auxval); 369 } /* there existed an expression at all */ 370 371 flushfield(curlen); 372 if ( ( curlen == NBPW/4) && bitoff) 373 dotp->e_xvalue ++; 374 break; 375 /*end of case IBYTE, IWORD, ILONG, IINT*/ 376 377 case ISPACE: /* .space <expr> */ 378 shift; 379 expr(locxp, val); 380 if ((locxp->e_xtype & XTYPE) != XABS) /* tekmdp */ 381 yyerror("Space size not absolute"); 382 space_value = locxp->e_xvalue; 383 ospace: 384 flushfield(NBPW/4); 385 { 386 static char spacebuf[128]; 387 while (space_value > sizeof(spacebuf)){ 388 outs(spacebuf, sizeof(spacebuf)); 389 space_value -= sizeof(spacebuf); 390 } 391 outs(spacebuf, space_value); 392 } 393 break; 394 395 /* 396 * .fill rep, size, value 397 * repeat rep times: fill size bytes with (truncated) value 398 * size must be between 1 and 8 399 */ 400 case IFILL: 401 shift; 402 expr(locxp, val); 403 if ( (locxp->e_xtype & XTYPE) != XABS) /* tekmdp */ 404 yyerror("Fill repetition count not absolute"); 405 fill_rep = locxp->e_xvalue; 406 shiftover(CM); 407 expr(locxp, val); 408 if ( (locxp->e_xtype & XTYPE) != XABS) /* tekmdp */ 409 yyerror("Fill size not absolute"); 410 fill_size = locxp->e_xvalue; 411 if (fill_size <= 0 || fill_size > 8) 412 yyerror("Fill count not in in 1..8"); 413 shiftover(CM); 414 expr(locxp, val); 415 if (passno == 2 && (locxp->e_xtype & XTYPE) != XABS) /* tekmdp */ 416 yyerror("Fill value not absolute"); 417 flushfield(NBPW/4); 418 if (passno == 1) { 419 dotp->e_xvalue += fill_rep * fill_size; 420 } else { 421 while(fill_rep-- > 0) 422 bwrite((char *)&locxp->e_xvalue, fill_size, txtfil); 423 } 424 break; 425 426 case IASCII: /* .ascii [ <stringlist> ] */ 427 case IASCIZ: /* .asciz [ <stringlist> ] */ 428 auxval = val; 429 shift; 430 /* 431 * Code to consume a string list 432 * 433 * stringlist: empty | STRING | stringlist STRING 434 */ 435 while (val == STRING){ 436 int mystrlen; 437 flushfield(NBPW/4); 438 if (bitoff) 439 dotp->e_xvalue++; 440 stringp = (struct strdesc *)yylval; 441 /* 442 * utilize the string scanner cheat; 443 * the scanner appended a null byte on the string, 444 * but didn't charge it to sd_strlen 445 */ 446 mystrlen = stringp->sd_strlen; 447 mystrlen += (auxval == IASCIZ) ? 1 : 0; 448 if (passno == 2){ 449 if (stringp->sd_place & STR_CORE){ 450 outs(stringp->sd_string, mystrlen); 451 } else { 452 int i, nread; 453 fseek(strfile, stringp->sd_stroff, 0); 454 for (i = 0; i < mystrlen;/*VOID*/){ 455 nread = fread(yytext, 1, 456 min(mystrlen - i, 457 sizeof(yytext)), strfile); 458 outs(yytext, nread); 459 i += nread; 460 } 461 } 462 } else { 463 dotp->e_xvalue += mystrlen; 464 } 465 shift; /*over the STRING*/ 466 if (val == CM) /*could be a split string*/ 467 shift; 468 } 469 break; 470 471 case IORG: /* .org <expr> */ 472 shift; 473 expr(locxp, val); 474 475 if ((locxp->e_xtype & XTYPE) == XABS) /* tekmdp */ 476 orgwarn++; 477 else if ((locxp->e_xtype & ~XXTRN) != dotp->e_xtype) 478 yyerror("Illegal expression to set origin"); 479 space_value = locxp->e_xvalue - dotp->e_xvalue; 480 if (space_value < 0) 481 yyerror("Backwards 'org'"); 482 goto ospace; 483 break; 484 485 /* 486 * 487 * Process stabs. Stabs are created only by the f77 488 * and the C compiler with the -g flag set. 489 * We only look at the stab ONCE, during pass 1, and 490 * virtually remove the stab from the intermediate file 491 * so it isn't seen during pass2. This makes for some 492 * hairy processing to handle labels occuring in 493 * stab entries, but since most expressions in the 494 * stab are integral we save lots of time in the second 495 * pass by not looking at the stabs. 496 * A stab that is tagged floating will be bumped during 497 * the jxxx resolution phase. A stab tagged fixed will 498 * not be be bumped. 499 * 500 * .stab: Old fashioned stabs 501 * .stabn: For stabs without names 502 * .stabs: For stabs with string names 503 * .stabd: For stabs for line numbers or bracketing, 504 * without a string name, without 505 * a final expression. The value of the 506 * final expression is taken to be the current 507 * location counter, and is patched by the 2nd pass 508 * 509 * .stab{<expr>,}*NCPName,<expr>, <expr>, <expr>, <expr> 510 * .stabn <expr>, <expr>, <expr>, <expr> 511 * .stabs STRING, <expr>, <expr>, <expr>, <expr> 512 * .stabd <expr>, <expr>, <expr> # . 513 */ 514 case ISTAB: 515 yyerror(".stab directive no longer supported"); 516 goto errorfix; 517 518 tailstab: 519 expr(locxp, val); 520 if (! (locxp->e_xvalue & STABTYPS)){ 521 yyerror("Invalid type in %s", stabname); 522 goto errorfix; 523 } 524 stpt->s_ptype = locxp->e_xvalue; 525 shiftover(CM); 526 expr(locxp, val); 527 stpt->s_other = locxp->e_xvalue; 528 shiftover(CM); 529 expr(locxp, val); 530 stpt->s_desc = locxp->e_xvalue; 531 shiftover(CM); 532 exprisname = 0; 533 expr(locxp, val); 534 p = locxp->e_xname; 535 if (p == NULL) { /*absolute expr to begin with*/ 536 stpt->s_value = locxp->e_xvalue; 537 stpt->s_index = dotp - usedot; 538 if (exprisname){ 539 switch(stpt->s_ptype){ 540 case N_GSYM: 541 case N_FNAME: 542 case N_RSYM: 543 case N_SSYM: 544 case N_LSYM: 545 case N_PSYM: 546 case N_BCOMM: 547 case N_ECOMM: 548 case N_LENG: 549 stpt->s_tag = STABFIXED; 550 break; 551 default: 552 stpt->s_tag = STABFLOATING; 553 break; 554 } 555 } else 556 stpt->s_tag = STABFIXED; 557 } 558 else { /*really have a name*/ 559 stpt->s_dest = locxp->e_xname; 560 stpt->s_index = p->s_index; 561 stpt->s_type = p->s_type | STABFLAG; 562 /* 563 * We will assign a more accruate 564 * guess of locxp's location when 565 * we sort the symbol table 566 * The final value of value is 567 * given by stabfix() 568 */ 569 /* 570 * For exprs of the form (name + value) one needs to remember locxp->e_xvalue 571 * for use in stabfix. The right place to keep this is in stpt->s_value 572 * however this gets corrupted at an unknown point. 573 * As a bandaid hack the value is preserved in s_desc and s_other (a 574 * short and a char). This destroys these two values and will 575 * be fixed. May 19 ,1983 Alastair Fyfe 576 */ 577 if(locxp->e_xvalue) { 578 stpt->s_other = (locxp->e_xvalue >> 16); 579 stpt->s_desc = (locxp->e_xvalue & 0x0000ffff); 580 stpt->s_tag = STABFLOATING; 581 } 582 } 583 /* 584 * tokptr now points at one token beyond 585 * the current token stored in val and yylval, 586 * which are the next tokens after the end of 587 * this .stab directive. This next token must 588 * be either a SEMI or NL, so is of width just 589 * one. Therefore, to point to the next token 590 * after the end of this stab, just back up one.. 591 */ 592 buildskip(stabstart, (bytetoktype *)tokptr - sizeof(bytetoktype)); 593 break; /*end of the .stab*/ 594 595 case ISTABDOT: 596 stabname = ".stabd"; 597 stpt = (struct symtab *)yylval; 598 /* 599 * We clobber everything after the 600 * .stabd and its pointer... we MUST 601 * be able to get back to this .stabd 602 * so that we can resolve its final value 603 */ 604 stabstart = tokptr; 605 shift; /*over the ISTABDOT*/ 606 if (passno == 1){ 607 expr(locxp, val); 608 if (! (locxp->e_xvalue & STABTYPS)){ 609 yyerror("Invalid type in .stabd"); 610 goto errorfix; 611 } 612 stpt->s_ptype = locxp->e_xvalue; 613 shiftover(CM); 614 expr(locxp, val); 615 stpt->s_other = locxp->e_xvalue; 616 shiftover(CM); 617 expr(locxp, val); 618 stpt->s_desc = locxp->e_xvalue; 619 /* 620 * 621 * Now, clobber everything but the 622 * .stabd pseudo and the pointer 623 * to its symbol table entry 624 * tokptr points to the next token, 625 * build the skip up to this 626 */ 627 buildskip(stabstart, (bytetoktype *)tokptr - sizeof(bytetoktype)); 628 } 629 /* 630 * pass 1: Assign a good guess for its position 631 * (ensures they are sorted into right place)/ 632 * pass 2: Fix the actual value 633 */ 634 stpt->s_value = dotp->e_xvalue; 635 stpt->s_index = dotp - usedot; 636 stpt->s_tag = STABFLOATING; /*although it has no effect in pass 2*/ 637 break; 638 639 case ISTABNONE: stabname = ".stabn"; goto shortstab; 640 641 case ISTABSTR: stabname = ".stabs"; 642 shortstab: 643 auxval = val; 644 if (passno == 2) goto errorfix; 645 stpt = (struct symtab *)yylval; 646 stabstart = tokptr; 647 (bytetoktype *)stabstart -= sizeof(struct symtab *); 648 (bytetoktype *)stabstart -= sizeof(bytetoktype); 649 shift; 650 if (auxval == ISTABSTR){ 651 stringp = (struct strdesc *)yylval; 652 shiftover(STRING); 653 stpt->s_name = (char *)stringp; 654 /* 655 * We want the trailing null included in this string. 656 * We utilize the cheat the string scanner used, 657 * and merely increment the string length 658 */ 659 stringp->sd_strlen += 1; 660 shiftover(CM); 661 } else { 662 stpt->s_name = (char *)savestr("\0", 0, STR_BOTH); 663 } 664 goto tailstab; 665 break; 666 667 case ICOMM: /* .comm <name> , <expr> */ 668 case ILCOMM: /* .lcomm <name> , <expr> */ 669 auxval = val; 670 shift; 671 np = (struct symtab *)yylval; 672 shiftover(NAME); 673 shiftover(CM); 674 expr(locxp, val); 675 676 if ( (locxp->e_xtype & XTYPE) != XABS) /* tekmdp */ 677 yyerror("comm size not absolute"); 678 if (passno == 1 && (np->s_type&XTYPE) != XUNDEF) 679 yyerror("Redefinition of %s", FETCHNAME(np)); 680 if (passno==1) { 681 np->s_value = locxp->e_xvalue; 682 if (auxval == ICOMM) 683 np->s_type |= XXTRN; 684 else { 685 np->s_type &= ~XTYPE; 686 np->s_type |= XBSS; 687 } 688 } 689 break; 690 691 case IALIGN: /* .align <expr> */ 692 stpt = (struct symtab *)yylval; 693 shift; 694 expr(locxp, val); 695 jalign(locxp, stpt); 696 break; 697 698 case INST0: /* instructions w/o arguments*/ 699 incasetable = 0; 700 insout(yyopcode, (struct arg *)0, 0); 701 shift; 702 break; 703 704 case INSTn: /* instructions with arguments*/ 705 case IJXXX: /* UNIX style jump instructions */ 706 auxval = val; 707 /* 708 * Code to process an argument list 709 */ 710 ap = arglist; 711 xp = explist; 712 713 shift; /* bring in the first token for the arg list*/ 714 715 for (argcnt = 1; argcnt <= 6; argcnt++, ap++){ 716 /* 717 * code to process an argument proper 718 */ 719 sawindex = sawmul = sawsize = 0; 720 { 721 switch(val) { 722 723 default: 724 disp: 725 if( !(INTOKSET(val, 726 EBEGOPS 727 +YUKKYEXPRBEG 728 +SAFEEXPRBEG)) ) { 729 ERROR("expression expected"); 730 } 731 expr(ap->a_xp,val); 732 overdisp: 733 if ( val == LP || sawsize){ 734 shiftover(LP); 735 findreg(regno); 736 shiftover(RP); 737 ap->a_atype = ADISP; 738 ap->a_areg1 = regno; 739 } else { 740 ap->a_atype = AEXP; 741 ap->a_areg1 = 0; 742 } 743 goto index; 744 745 case SIZESPEC: 746 sizespec: 747 sawsize = yylval; 748 shift; 749 goto disp; 750 751 case REG: 752 case REGOP: 753 findreg(regno); 754 ap->a_atype = AREG; 755 ap->a_areg1 = regno; 756 break; 757 758 case MUL: 759 sawmul = 1; 760 shift; 761 if (val == LP) goto base; 762 if (val == LITOP) goto imm; 763 if (val == SIZESPEC) goto sizespec; 764 if (INTOKSET(val, 765 EBEGOPS 766 +YUKKYEXPRBEG 767 +SAFEEXPRBEG)) goto disp; 768 ERROR("expression, '(' or '$' expected"); 769 break; 770 771 case LP: 772 base: 773 shift; /*consume the LP*/ 774 /* 775 * hack the ambiguity of 776 * movl (expr) (rn), ... 777 * note that (expr) could also 778 * be (rn) (by special hole in the 779 * grammar), which we ensure 780 * means register indirection, instead 781 * of an expression with value n 782 */ 783 if (val != REG && val != REGOP){ 784 droppedLP = 1; 785 val = exprparse(val, &(ap->a_xp)); 786 droppedLP = 0; 787 goto overdisp; 788 } 789 findreg(regno); 790 shiftover(RP); 791 if (val == PLUS){ 792 shift; 793 ap->a_atype = AINCR; 794 } else 795 ap->a_atype = ABASE; 796 ap->a_areg1 = regno; 797 goto index; 798 799 case LITOP: 800 imm: 801 shift; 802 expr(locxp, val); 803 ap->a_atype = AIMM; 804 ap->a_areg1 = 0; 805 ap->a_xp = locxp; 806 goto index; 807 808 case MP: 809 shift; /* -(reg) */ 810 findreg(regno); 811 shiftover(RP); 812 ap->a_atype = ADECR; 813 ap->a_areg1 = regno; 814 index: /*look for [reg] */ 815 if (val == LB){ 816 shift; 817 findreg(regno); 818 shiftover(RB); 819 sawindex = 1; 820 ap->a_areg2 = regno; 821 } 822 break; 823 824 } /*end of the switch to process an arg*/ 825 } /*end of processing an argument*/ 826 827 if (sawmul){ 828 /* 829 * Make a concession for *(%r) 830 * meaning *0(%r) 831 */ 832 if (ap->a_atype == ABASE) { 833 ap->a_atype = ADISP; 834 xp->e_xtype = XABS; 835 xp->e_number = Znumber; 836 xp->e_number.num_tag = TYPL; 837 xp->e_xloc = 0; 838 ap->a_xp = xp++; 839 } 840 ap->a_atype |= ASTAR; 841 sawmul = 0; 842 } 843 if (sawindex){ 844 ap->a_atype |= AINDX; 845 sawindex = 0; 846 } 847 ap->a_dispsize = sawsize == 0 ? d124 : sawsize; 848 if (val != CM) break; 849 shiftover(CM); 850 } /*processing all the arguments*/ 851 852 if (argcnt > 6){ 853 yyerror("More than 6 arguments"); 854 goto errorfix; 855 } 856 857 /* 858 * See if this is a case instruction, 859 * so we can set up tests on the following 860 * vector of branch displacements 861 */ 862 if (yyopcode.Op_eopcode == CORE){ 863 switch(yyopcode.Op_popcode){ 864 case 0x8f: /* caseb */ 865 case 0xaf: /* casew */ 866 case 0xcf: /* casel */ 867 incasetable++; 868 break; 869 default: 870 incasetable = 0; 871 break; 872 } 873 } 874 875 insout(yyopcode, arglist, 876 auxval == INSTn ? argcnt : - argcnt); 877 break; 878 879 case IQUAD: toconv = TYPQ; goto bignumlist; 880 case IOCTA: toconv = TYPO; goto bignumlist; 881 882 case IFFLOAT: toconv = TYPF; goto bignumlist; 883 case IDFLOAT: toconv = TYPD; goto bignumlist; 884 case IGFLOAT: toconv = TYPG; goto bignumlist; 885 case IHFLOAT: toconv = TYPH; goto bignumlist; 886 bignumlist: 887 /* 888 * eat a list of non 32 bit numbers. 889 * IQUAD and IOCTA can, possibly, return 890 * INT's, if the numbers are "small". 891 * 892 * The value of the numbers is coming back 893 * as an expression, NOT in yybignum. 894 */ 895 shift; /* over the opener */ 896 if ((val == BIGNUM) || (val == INT)){ 897 do{ 898 if ((val != BIGNUM) && (val != INT)){ 899 ERROR(ty_float[toconv] 900 ? "floating number expected" 901 : "integer number expected" ); 902 } 903 dotp->e_xvalue += ty_nbyte[toconv]; 904 if (passno == 2){ 905 bignumwrite( 906 ((struct exp *)yylval)->e_number, 907 toconv); 908 } 909 xp = explist; 910 shift; /* over this number */ 911 if (auxval = (val == CM)) 912 shift; /* over the comma */ 913 } while (auxval); /* as long as there are commas */ 914 } 915 break; 916 /* end of the case for initialized big numbers */ 917 } /*end of the switch for looking at each reserved word*/ 918 919 continue; 920 921 errorfix: 922 /* 923 * got here by either requesting to skip to the 924 * end of this statement, or by erroring out and 925 * wanting to apply panic mode recovery 926 */ 927 while ( (val != NL) 928 && (val != SEMI) 929 && (val != PARSEEOF) 930 ){ 931 shift; 932 } 933 if (val == NL) 934 lineno++; 935 shift; 936 937 } /*end of the loop to read the entire file, line by line*/ 938 939 } /*end of yyparse*/ 940 941 /* 942 * Process a register declaration of the form 943 * % <expr> 944 * 945 * Note: 946 * The scanner has already processed funny registers of the form 947 * %dd[+-]*, where dd is a decimal number in the range 00 to 15 (optional 948 * preceding zero digit). If there was any space between the % and 949 * the digit, the scanner wouldn't have recognized it, so we 950 * hack it out here. 951 */ 952 inttoktype funnyreg(val, regnoback) /*what the read head will sit on*/ 953 inttoktype val; /*what the read head is sitting on*/ 954 int *regnoback; /*call by return*/ 955 { 956 reg struct exp *locxp; 957 struct exp *loc1xp; 958 struct exp **ptrloc1xp = & loc1xp; 959 960 expr(locxp, val); /*and leave the current read head with value*/ 961 if ( (passno == 2) && 962 ( (locxp->e_xtype & XTYPE) != XABS 963 || (locxp->e_xvalue < 0) 964 || (locxp->e_xvalue >= 16) 965 ) 966 ){ 967 yyerror("Illegal register"); 968 return(0); 969 } 970 *regnoback = locxp->e_xvalue; 971 return(val); 972 } 973 /* 974 * Shift over error 975 */ 976 shiftoerror(token) 977 int token; 978 { 979 char *tok_to_name(); 980 yyerror("%s expected", tok_to_name(token)); 981 } 982 983 /*VARARGS1*/ 984 yyerror(s, a1, a2,a3,a4,a5) 985 char *s; 986 { 987 988 #define sink stdout 989 990 if (anyerrs == 0 && anywarnings == 0 && ! silent) 991 fprintf(sink, "Assembler:\n"); 992 anyerrs++; 993 if (silent) 994 return; 995 fprintf(sink, "\"%s\", line %d: ", dotsname, lineno); 996 fprintf(sink, s, a1, a2,a3,a4,a5); 997 fprintf(sink, "\n"); 998 #undef sink 999 } 1000 1001 /*VARARGS1*/ 1002 yywarning(s, a1, a2,a3,a4,a5) 1003 char *s; 1004 { 1005 #define sink stdout 1006 if (anyerrs == 0 && anywarnings == 0 && ! silent) 1007 fprintf(sink, "Assembler:\n"); 1008 anywarnings++; 1009 if (silent) 1010 return; 1011 fprintf(sink, "\"%s\", line %d: WARNING: ", dotsname, lineno); 1012 fprintf(sink, s, a1, a2,a3,a4,a5); 1013 fprintf(sink, "\n"); 1014 #undef sink 1015 } 1016