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