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