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