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.3 (Berkeley) 11/17/86"; 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(NBWD/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(NBWD/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 = NBWD/4; goto elist; 298 case IWORD: curlen = NBWD/2; goto elist; 299 case IINT: curlen = NBWD; goto elist; 300 case ILONG: curlen = NBWD; 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 NBWD/4: reloc_how = TYPB; break; 342 case NBWD/2: reloc_how = TYPW; break; 343 case NBWD: 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 == NBWD/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(NBWD/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(NBWD/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(NBWD/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_LCSYM: 544 stpt->s_dest = (struct symtab *)exprisname; 545 stpt->s_type |= STABFLAG; 546 case N_GSYM: 547 case N_FNAME: 548 case N_RSYM: 549 case N_SSYM: 550 case N_LSYM: 551 case N_PSYM: 552 case N_BCOMM: 553 case N_ECOMM: 554 case N_LENG: 555 stpt->s_tag = STABFIXED; 556 break; 557 default: 558 stpt->s_tag = STABFLOATING; 559 break; 560 } 561 } else 562 stpt->s_tag = STABFIXED; 563 } 564 else { /*really have a name*/ 565 stpt->s_dest = locxp->e_xname; 566 stpt->s_index = p->s_index; 567 stpt->s_type = p->s_type | STABFLAG; 568 /* 569 * We will assign a more accruate 570 * guess of locxp's location when 571 * we sort the symbol table 572 * The final value of value is 573 * given by stabfix() 574 */ 575 /* 576 * For exprs of the form (name + value) one needs to remember locxp->e_xvalue 577 * for use in stabfix. The right place to keep this is in stpt->s_value 578 * however this gets corrupted at an unknown point. 579 * As a bandaid hack the value is preserved in s_desc and s_other (a 580 * short and a char). This destroys these two values and will 581 * be fixed. May 19 ,1983 Alastair Fyfe 582 */ 583 if(locxp->e_xvalue) { 584 stpt->s_other = (locxp->e_xvalue >> 16); 585 stpt->s_desc = (locxp->e_xvalue & 0x0000ffff); 586 stpt->s_tag = STABFLOATING; 587 } 588 } 589 /* 590 * tokptr now points at one token beyond 591 * the current token stored in val and yylval, 592 * which are the next tokens after the end of 593 * this .stab directive. This next token must 594 * be either a SEMI or NL, so is of width just 595 * one. Therefore, to point to the next token 596 * after the end of this stab, just back up one.. 597 */ 598 buildskip(stabstart, (bytetoktype *)tokptr - sizeof(bytetoktype)); 599 break; /*end of the .stab*/ 600 601 case ISTABDOT: 602 stabname = ".stabd"; 603 stpt = (struct symtab *)yylval; 604 /* 605 * We clobber everything after the 606 * .stabd and its pointer... we MUST 607 * be able to get back to this .stabd 608 * so that we can resolve its final value 609 */ 610 stabstart = tokptr; 611 shift; /*over the ISTABDOT*/ 612 if (passno == 1){ 613 expr(locxp, val); 614 if (! (locxp->e_xvalue & STABTYPS)){ 615 yyerror("Invalid type in .stabd"); 616 goto errorfix; 617 } 618 stpt->s_ptype = locxp->e_xvalue; 619 shiftover(CM); 620 expr(locxp, val); 621 stpt->s_other = locxp->e_xvalue; 622 shiftover(CM); 623 expr(locxp, val); 624 stpt->s_desc = locxp->e_xvalue; 625 /* 626 * 627 * Now, clobber everything but the 628 * .stabd pseudo and the pointer 629 * to its symbol table entry 630 * tokptr points to the next token, 631 * build the skip up to this 632 */ 633 buildskip(stabstart, (bytetoktype *)tokptr - sizeof(bytetoktype)); 634 } 635 /* 636 * pass 1: Assign a good guess for its position 637 * (ensures they are sorted into right place)/ 638 * pass 2: Fix the actual value 639 */ 640 stpt->s_value = dotp->e_xvalue; 641 stpt->s_index = dotp - usedot; 642 stpt->s_tag = STABFLOATING; /*although it has no effect in pass 2*/ 643 break; 644 645 case ISTABNONE: stabname = ".stabn"; goto shortstab; 646 647 case ISTABSTR: stabname = ".stabs"; 648 shortstab: 649 auxval = val; 650 if (passno == 2) goto errorfix; 651 stpt = (struct symtab *)yylval; 652 stabstart = tokptr; 653 (bytetoktype *)stabstart -= sizeof(struct symtab *); 654 (bytetoktype *)stabstart -= sizeof(bytetoktype); 655 shift; 656 if (auxval == ISTABSTR){ 657 stringp = (struct strdesc *)yylval; 658 shiftover(STRING); 659 stpt->s_name = (char *)stringp; 660 /* 661 * We want the trailing null included in this string. 662 * We utilize the cheat the string scanner used, 663 * and merely increment the string length 664 */ 665 stringp->sd_strlen += 1; 666 shiftover(CM); 667 } else { 668 stpt->s_name = (char *)savestr("\0", 0, STR_BOTH); 669 } 670 goto tailstab; 671 break; 672 673 case ICOMM: /* .comm <name> , <expr> */ 674 case ILCOMM: /* .lcomm <name> , <expr> */ 675 auxval = val; 676 shift; 677 np = (struct symtab *)yylval; 678 shiftover(NAME); 679 shiftover(CM); 680 expr(locxp, val); 681 682 if ( (locxp->e_xtype & XTYPE) != XABS) /* tekmdp */ 683 yyerror("comm size not absolute"); 684 if (passno == 1 && (np->s_type&XTYPE) != XUNDEF) 685 yyerror("Redefinition of %s", FETCHNAME(np)); 686 if (passno==1) { 687 np->s_value = locxp->e_xvalue; 688 if (auxval == ICOMM) 689 np->s_type |= XXTRN; 690 else { 691 np->s_type &= ~XTYPE; 692 np->s_type |= XBSS; 693 } 694 } 695 break; 696 697 case IALIGN: /* .align <expr> */ 698 stpt = (struct symtab *)yylval; 699 shift; 700 expr(locxp, val); 701 jalign(locxp, stpt); 702 break; 703 704 case INST0: /* instructions w/o arguments*/ 705 incasetable = 0; 706 insout(yyopcode, (struct arg *)0, 0); 707 shift; 708 break; 709 710 case INSTn: /* instructions with arguments*/ 711 case IJXXX: /* UNIX style jump instructions */ 712 auxval = val; 713 /* 714 * Code to process an argument list 715 */ 716 ap = arglist; 717 xp = explist; 718 719 shift; /* bring in the first token for the arg list*/ 720 721 for (argcnt = 1; argcnt <= 6; argcnt++, ap++){ 722 /* 723 * code to process an argument proper 724 */ 725 sawindex = sawmul = sawsize = 0; 726 { 727 switch(val) { 728 729 default: 730 disp: 731 if( !(INTOKSET(val, 732 EBEGOPS 733 +YUKKYEXPRBEG 734 +SAFEEXPRBEG)) ) { 735 ERROR("expression expected"); 736 } 737 expr(ap->a_xp,val); 738 overdisp: 739 if ( val == LP || sawsize){ 740 shiftover(LP); 741 findreg(regno); 742 shiftover(RP); 743 ap->a_atype = ADISP; 744 ap->a_areg1 = regno; 745 } else { 746 ap->a_atype = AEXP; 747 ap->a_areg1 = 0; 748 } 749 goto index; 750 751 case SIZESPEC: 752 sizespec: 753 sawsize = yylval; 754 shift; 755 goto disp; 756 757 case REG: 758 case REGOP: 759 findreg(regno); 760 ap->a_atype = AREG; 761 ap->a_areg1 = regno; 762 break; 763 764 case MUL: 765 sawmul = 1; 766 shift; 767 if (val == LP) goto base; 768 if (val == LITOP) goto imm; 769 if (val == SIZESPEC) goto sizespec; 770 if (INTOKSET(val, 771 EBEGOPS 772 +YUKKYEXPRBEG 773 +SAFEEXPRBEG)) goto disp; 774 ERROR("expression, '(' or '$' expected"); 775 break; 776 777 case LP: 778 base: 779 shift; /*consume the LP*/ 780 /* 781 * hack the ambiguity of 782 * movl (expr) (rn), ... 783 * note that (expr) could also 784 * be (rn) (by special hole in the 785 * grammar), which we ensure 786 * means register indirection, instead 787 * of an expression with value n 788 */ 789 if (val != REG && val != REGOP){ 790 droppedLP = 1; 791 val = exprparse(val, &(ap->a_xp)); 792 droppedLP = 0; 793 goto overdisp; 794 } 795 findreg(regno); 796 shiftover(RP); 797 if (val == PLUS){ 798 shift; 799 ap->a_atype = AINCR; 800 } else 801 ap->a_atype = ABASE; 802 ap->a_areg1 = regno; 803 goto index; 804 805 case LITOP: 806 imm: 807 shift; 808 expr(locxp, val); 809 ap->a_atype = AIMM; 810 ap->a_areg1 = 0; 811 ap->a_xp = locxp; 812 goto index; 813 814 case MP: 815 shift; /* -(reg) */ 816 findreg(regno); 817 shiftover(RP); 818 ap->a_atype = ADECR; 819 ap->a_areg1 = regno; 820 index: /*look for [reg] */ 821 if (val == LB){ 822 shift; 823 findreg(regno); 824 shiftover(RB); 825 sawindex = 1; 826 ap->a_areg2 = regno; 827 } 828 break; 829 830 } /*end of the switch to process an arg*/ 831 } /*end of processing an argument*/ 832 833 if (sawmul){ 834 /* 835 * Make a concession for *(%r) 836 * meaning *0(%r) 837 */ 838 if (ap->a_atype == ABASE) { 839 ap->a_atype = ADISP; 840 xp->e_xtype = XABS; 841 xp->e_number = Znumber; 842 xp->e_number.num_tag = TYPL; 843 xp->e_xloc = 0; 844 ap->a_xp = xp++; 845 } 846 ap->a_atype |= ASTAR; 847 sawmul = 0; 848 } 849 if (sawindex){ 850 ap->a_atype |= AINDX; 851 sawindex = 0; 852 } 853 ap->a_dispsize = sawsize == 0 ? d124 : sawsize; 854 if (val != CM) break; 855 shiftover(CM); 856 } /*processing all the arguments*/ 857 858 if (argcnt > 6){ 859 yyerror("More than 6 arguments"); 860 goto errorfix; 861 } 862 863 /* 864 * See if this is a case instruction, 865 * so we can set up tests on the following 866 * vector of branch displacements 867 */ 868 if (yyopcode.Op_eopcode == CORE){ 869 switch(yyopcode.Op_popcode){ 870 case 0x8f: /* caseb */ 871 case 0xaf: /* casew */ 872 case 0xcf: /* casel */ 873 incasetable++; 874 break; 875 default: 876 incasetable = 0; 877 break; 878 } 879 } 880 881 insout(yyopcode, arglist, 882 auxval == INSTn ? argcnt : - argcnt); 883 break; 884 885 case IQUAD: toconv = TYPQ; goto bignumlist; 886 case IOCTA: toconv = TYPO; goto bignumlist; 887 888 case IFFLOAT: toconv = TYPF; goto bignumlist; 889 case IDFLOAT: toconv = TYPD; goto bignumlist; 890 case IGFLOAT: toconv = TYPG; goto bignumlist; 891 case IHFLOAT: toconv = TYPH; goto bignumlist; 892 bignumlist: 893 /* 894 * eat a list of non 32 bit numbers. 895 * IQUAD and IOCTA can, possibly, return 896 * INT's, if the numbers are "small". 897 * 898 * The value of the numbers is coming back 899 * as an expression, NOT in yybignum. 900 */ 901 shift; /* over the opener */ 902 if ((val == BIGNUM) || (val == INT)){ 903 do{ 904 if ((val != BIGNUM) && (val != INT)){ 905 ERROR(ty_float[toconv] 906 ? "floating number expected" 907 : "integer number expected" ); 908 } 909 dotp->e_xvalue += ty_nbyte[toconv]; 910 if (passno == 2){ 911 bignumwrite( 912 ((struct exp *)yylval)->e_number, 913 toconv); 914 } 915 xp = explist; 916 shift; /* over this number */ 917 if (auxval = (val == CM)) 918 shift; /* over the comma */ 919 } while (auxval); /* as long as there are commas */ 920 } 921 break; 922 /* end of the case for initialized big numbers */ 923 } /*end of the switch for looking at each reserved word*/ 924 925 continue; 926 927 errorfix: 928 /* 929 * got here by either requesting to skip to the 930 * end of this statement, or by erroring out and 931 * wanting to apply panic mode recovery 932 */ 933 while ( (val != NL) 934 && (val != SEMI) 935 && (val != PARSEEOF) 936 ){ 937 shift; 938 } 939 if (val == NL) 940 lineno++; 941 shift; 942 943 } /*end of the loop to read the entire file, line by line*/ 944 945 } /*end of yyparse*/ 946 947 /* 948 * Process a register declaration of the form 949 * % <expr> 950 * 951 * Note: 952 * The scanner has already processed funny registers of the form 953 * %dd[+-]*, where dd is a decimal number in the range 00 to 15 (optional 954 * preceding zero digit). If there was any space between the % and 955 * the digit, the scanner wouldn't have recognized it, so we 956 * hack it out here. 957 */ 958 inttoktype funnyreg(val, regnoback) /*what the read head will sit on*/ 959 inttoktype val; /*what the read head is sitting on*/ 960 int *regnoback; /*call by return*/ 961 { 962 reg struct exp *locxp; 963 struct exp *loc1xp; 964 struct exp **ptrloc1xp = & loc1xp; 965 966 expr(locxp, val); /*and leave the current read head with value*/ 967 if ( (passno == 2) && 968 ( (locxp->e_xtype & XTYPE) != XABS 969 || (locxp->e_xvalue < 0) 970 || (locxp->e_xvalue >= 16) 971 ) 972 ){ 973 yyerror("Illegal register"); 974 return(0); 975 } 976 *regnoback = locxp->e_xvalue; 977 return(val); 978 } 979 /* 980 * Shift over error 981 */ 982 shiftoerror(token) 983 int token; 984 { 985 char *tok_to_name(); 986 yyerror("%s expected", tok_to_name(token)); 987 } 988 989 /*VARARGS1*/ 990 yyerror(s, a1, a2,a3,a4,a5) 991 char *s; 992 { 993 994 #define sink stdout 995 996 if (anyerrs == 0 && anywarnings == 0 && ! silent) 997 fprintf(sink, "Assembler:\n"); 998 anyerrs++; 999 if (silent) 1000 return; 1001 fprintf(sink, "\"%s\", line %d: ", dotsname, lineno); 1002 fprintf(sink, s, a1, a2,a3,a4,a5); 1003 fprintf(sink, "\n"); 1004 #undef sink 1005 } 1006 1007 /*VARARGS1*/ 1008 yywarning(s, a1, a2,a3,a4,a5) 1009 char *s; 1010 { 1011 #define sink stdout 1012 if (anyerrs == 0 && anywarnings == 0 && ! silent) 1013 fprintf(sink, "Assembler:\n"); 1014 anywarnings++; 1015 if (silent) 1016 return; 1017 fprintf(sink, "\"%s\", line %d: WARNING: ", dotsname, lineno); 1018 fprintf(sink, s, a1, a2,a3,a4,a5); 1019 fprintf(sink, "\n"); 1020 #undef sink 1021 } 1022