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