1 /* 2 * Copyright (c) 1982 Regents of the University of California 3 */ 4 #ifndef lint 5 static char sccsid[] = "@(#)asparse.c 4.10 06/09/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 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 /* 641 * For exprs of the form (name + value) one needs to remember locxp->e_xvalue 642 * for use in stabfix. The right place to keep this is in stpt->s_value 643 * however this gets corrupted at an unknown point. 644 * As a bandaid hack the value is preserved in s_desc and s_other (a 645 * short and a char). This destroys these two values and will 646 * be fixed. May 19 ,1983 Alastair Fyfe 647 */ 648 if(locxp->e_xvalue) { 649 stpt->s_other = (locxp->e_xvalue >> 16); 650 stpt->s_desc = (locxp->e_xvalue & 0x0000ffff); 651 stpt->s_tag = STABFLOATING; 652 } 653 } 654 /* 655 * tokptr now points at one token beyond 656 * the current token stored in val and yylval, 657 * which are the next tokens after the end of 658 * this .stab directive. This next token must 659 * be either a SEMI or NL, so is of width just 660 * one. Therefore, to point to the next token 661 * after the end of this stab, just back up one.. 662 */ 663 buildskip(stabstart, (bytetoktype *)tokptr - sizeof(bytetoktype)); 664 break; /*end of the .stab*/ 665 666 case ISTABDOT: 667 stabname = ".stabd"; 668 stpt = (struct symtab *)yylval; 669 /* 670 * We clobber everything after the 671 * .stabd and its pointer... we MUST 672 * be able to get back to this .stabd 673 * so that we can resolve its final value 674 */ 675 stabstart = tokptr; 676 shift; /*over the ISTABDOT*/ 677 if (passno == 1){ 678 expr(locxp, val); 679 if (! (locxp->e_xvalue & STABTYPS)){ 680 yyerror("Invalid type in .stabd"); 681 goto errorfix; 682 } 683 stpt->s_ptype = locxp->e_xvalue; 684 shiftover(CM); 685 expr(locxp, val); 686 stpt->s_other = locxp->e_xvalue; 687 shiftover(CM); 688 expr(locxp, val); 689 stpt->s_desc = locxp->e_xvalue; 690 /* 691 * 692 * Now, clobber everything but the 693 * .stabd pseudo and the pointer 694 * to its symbol table entry 695 * tokptr points to the next token, 696 * build the skip up to this 697 */ 698 buildskip(stabstart, (bytetoktype *)tokptr - sizeof(bytetoktype)); 699 } 700 /* 701 * pass 1: Assign a good guess for its position 702 * (ensures they are sorted into right place)/ 703 * pass 2: Fix the actual value 704 */ 705 stpt->s_value = dotp->e_xvalue; 706 stpt->s_index = dotp - usedot; 707 stpt->s_tag = STABFLOATING; /*although it has no effect in pass 2*/ 708 break; 709 710 case ISTABNONE: stabname = ".stabn"; goto shortstab; 711 712 case ISTABSTR: stabname = ".stabs"; 713 shortstab: 714 auxval = val; 715 if (passno == 2) goto errorfix; 716 stpt = (struct symtab *)yylval; 717 stabstart = tokptr; 718 (bytetoktype *)stabstart -= sizeof(struct symtab *); 719 (bytetoktype *)stabstart -= sizeof(bytetoktype); 720 shift; 721 if (auxval == ISTABSTR){ 722 stringp = (struct strdesc *)yylval; 723 shiftover(STRING); 724 #ifndef FLEXNAMES 725 auxval = stringp->str_lg > NCPS ? NCPS : stringp->str_lg; 726 #else 727 stringp->str[stringp->str_lg] = 0; 728 #endif 729 shiftover(CM); 730 } else { 731 stringp = &(strbuf[2]); 732 #ifndef FLEXNAMES 733 auxval = NCPS; 734 #endif 735 } 736 #ifndef FLEXNAMES 737 movestr(stpt->s_name, stringp->str, auxval); 738 #else 739 stpt->s_name = savestr(stringp->str); 740 #endif 741 goto tailstab; 742 break; 743 744 case ICOMM: /* .comm <name> , <expr> */ 745 case ILCOMM: /* .lcomm <name> , <expr> */ 746 auxval = val; 747 shift; 748 np = (struct symtab *)yylval; 749 shiftover(NAME); 750 shiftover(CM); 751 expr(locxp, val); 752 753 if ( (locxp->e_xtype & XTYPE) != XABS) /* tekmdp */ 754 yyerror("comm size not absolute"); 755 if (passno == 1 && (np->s_type&XTYPE) != XUNDEF) 756 #ifdef FLEXNAMES 757 yyerror("Redefinition of %s", 758 #else not FLEXNAMES 759 yyerror("Redefinition of %.*s", 760 NCPS, 761 #endif not FLEXNAMES 762 np->s_name); 763 if (passno==1) { 764 np->s_value = locxp->e_xvalue; 765 if (auxval == ICOMM) 766 np->s_type |= XXTRN; 767 else { 768 np->s_type &= ~XTYPE; 769 np->s_type |= XBSS; 770 } 771 } 772 break; 773 774 case IALIGN: /* .align <expr> */ 775 stpt = (struct symtab *)yylval; 776 shift; 777 expr(locxp, val); 778 jalign(locxp, stpt); 779 break; 780 781 case INST0: /* instructions w/o arguments*/ 782 insout(yyopcode, (struct arg *)0, 0); 783 shift; 784 break; 785 786 case INSTn: /* instructions with arguments*/ 787 case IJXXX: /* UNIX style jump instructions */ 788 auxval = val; 789 /* 790 * Code to process an argument list 791 */ 792 ap = arglist; 793 xp = explist; 794 795 shift; /* bring in the first token for the arg list*/ 796 797 for (argcnt = 1; argcnt <= 6; argcnt++, ap++){ 798 /* 799 * code to process an argument proper 800 */ 801 sawindex = sawmul = sawsize = 0; 802 { 803 switch(val) { 804 805 default: 806 disp: 807 if( !(INTOKSET(val, 808 EBEGOPS 809 +YUKKYEXPRBEG 810 +SAFEEXPRBEG)) ) { 811 ERROR("expression expected"); 812 } 813 expr(ap->a_xp,val); 814 overdisp: 815 if ( val == LP || sawsize){ 816 shiftover(LP); 817 findreg(regno); 818 shiftover(RP); 819 ap->a_atype = ADISP; 820 ap->a_areg1 = regno; 821 } else { 822 ap->a_atype = AEXP; 823 ap->a_areg1 = 0; 824 } 825 goto index; 826 827 case SIZESPEC: 828 sizespec: 829 sawsize = yylval; 830 shift; 831 goto disp; 832 833 case REG: 834 case REGOP: 835 findreg(regno); 836 ap->a_atype = AREG; 837 ap->a_areg1 = regno; 838 break; 839 840 case MUL: 841 sawmul = 1; 842 shift; 843 if (val == LP) goto base; 844 if (val == LITOP) goto imm; 845 if (val == SIZESPEC) goto sizespec; 846 if (INTOKSET(val, 847 EBEGOPS 848 +YUKKYEXPRBEG 849 +SAFEEXPRBEG)) goto disp; 850 ERROR("expression, '(' or '$' expected"); 851 break; 852 853 case LP: 854 base: 855 shift; /*consume the LP*/ 856 /* 857 * hack the ambiguity of 858 * movl (expr) (rn), ... 859 * note that (expr) could also 860 * be (rn) (by special hole in the 861 * grammar), which we ensure 862 * means register indirection, instead 863 * of an expression with value n 864 */ 865 if (val != REG && val != REGOP){ 866 droppedLP = 1; 867 val = exprparse(val, &(ap->a_xp)); 868 droppedLP = 0; 869 goto overdisp; 870 } 871 findreg(regno); 872 shiftover(RP); 873 if (val == PLUS){ 874 shift; 875 ap->a_atype = AINCR; 876 } else 877 ap->a_atype = ABASE; 878 ap->a_areg1 = regno; 879 goto index; 880 881 case LITOP: 882 imm: 883 shift; 884 expr(locxp, val); 885 ap->a_atype = AIMM; 886 ap->a_areg1 = 0; 887 ap->a_xp = locxp; 888 goto index; 889 890 case MP: 891 shift; /* -(reg) */ 892 findreg(regno); 893 shiftover(RP); 894 ap->a_atype = ADECR; 895 ap->a_areg1 = regno; 896 index: /*look for [reg] */ 897 if (val == LB){ 898 shift; 899 findreg(regno); 900 shiftover(RB); 901 sawindex = 1; 902 ap->a_areg2 = regno; 903 } 904 break; 905 906 } /*end of the switch to process an arg*/ 907 } /*end of processing an argument*/ 908 909 if (sawmul){ 910 /* 911 * Make a concession for *(%r) 912 * meaning *0(%r) 913 */ 914 if (ap->a_atype == ABASE) { 915 ap->a_atype = ADISP; 916 xp->e_xtype = XABS; 917 xp->e_number = Znumber; 918 xp->e_number.num_tag = TYPL; 919 xp->e_xloc = 0; 920 ap->a_xp = xp++; 921 } 922 ap->a_atype |= ASTAR; 923 sawmul = 0; 924 } 925 if (sawindex){ 926 ap->a_atype |= AINDX; 927 sawindex = 0; 928 } 929 ap->a_dispsize = sawsize == 0 ? d124 : sawsize; 930 if (val != CM) break; 931 shiftover(CM); 932 } /*processing all the arguments*/ 933 934 if (argcnt > 6){ 935 yyerror("More than 6 arguments"); 936 goto errorfix; 937 } 938 939 insout(yyopcode, arglist, 940 auxval == INSTn ? argcnt : - argcnt); 941 break; 942 943 case IQUAD: toconv = TYPQ; goto bignumlist; 944 case IOCTA: toconv = TYPO; goto bignumlist; 945 946 case IFFLOAT: toconv = TYPF; goto bignumlist; 947 case IDFLOAT: toconv = TYPD; goto bignumlist; 948 case IGFLOAT: toconv = TYPG; goto bignumlist; 949 case IHFLOAT: toconv = TYPH; goto bignumlist; 950 bignumlist: 951 /* 952 * eat a list of non 32 bit numbers. 953 * IQUAD and IOCTA can, possibly, return 954 * INT's, if the numbers are "small". 955 * 956 * The value of the numbers is coming back 957 * as an expression, NOT in yybignum. 958 */ 959 shift; /* over the opener */ 960 if ((val == BIGNUM) || (val == INT)){ 961 do{ 962 if ((val != BIGNUM) && (val != INT)){ 963 ERROR(ty_float[toconv] 964 ? "floating number expected" 965 : "integer number expected" ); 966 } 967 dotp->e_xvalue += ty_nbyte[toconv]; 968 if (passno == 2){ 969 bignumwrite( 970 ((struct exp *)yylval)->e_number, 971 toconv); 972 } 973 xp = explist; 974 shift; /* over this number */ 975 if (auxval = (val == CM)) 976 shift; /* over the comma */ 977 } while (auxval); /* as long as there are commas */ 978 } 979 break; 980 /* end of the case for initialized big numbers */ 981 } /*end of the switch for looking at each reserved word*/ 982 983 continue; 984 985 errorfix: 986 /* 987 * got here by either requesting to skip to the 988 * end of this statement, or by erroring out and 989 * wanting to apply panic mode recovery 990 */ 991 while ( (val != NL) 992 && (val != SEMI) 993 && (val != PARSEEOF) 994 ){ 995 shift; 996 } 997 if (val == NL) 998 lineno++; 999 shift; 1000 1001 } /*end of the loop to read the entire file, line by line*/ 1002 1003 } /*end of yyparse*/ 1004 1005 /* 1006 * Process a register declaration of the form 1007 * % <expr> 1008 * 1009 * Note: 1010 * The scanner has already processed funny registers of the form 1011 * %dd[+-]*, where dd is a decimal number in the range 00 to 15 (optional 1012 * preceding zero digit). If there was any space between the % and 1013 * the digit, the scanner wouldn't have recognized it, so we 1014 * hack it out here. 1015 */ 1016 inttoktype funnyreg(val, regnoback) /*what the read head will sit on*/ 1017 inttoktype val; /*what the read head is sitting on*/ 1018 int *regnoback; /*call by return*/ 1019 { 1020 reg struct exp *locxp; 1021 struct exp *loc1xp; 1022 struct exp **ptrloc1xp = & loc1xp; 1023 1024 expr(locxp, val); /*and leave the current read head with value*/ 1025 if ( (passno == 2) && 1026 ( (locxp->e_xtype & XTYPE) != XABS 1027 || (locxp->e_xvalue < 0) 1028 || (locxp->e_xvalue >= 16) 1029 ) 1030 ){ 1031 yyerror("Illegal register"); 1032 return(0); 1033 } 1034 *regnoback = locxp->e_xvalue; 1035 return(val); 1036 } 1037 /* 1038 * Shift over error 1039 */ 1040 shiftoerror(token) 1041 int token; 1042 { 1043 char *tok_to_name(); 1044 yyerror("%s expected", tok_to_name(token)); 1045 } 1046 1047 /*VARARGS1*/ 1048 yyerror(s, a1, a2,a3,a4,a5) 1049 char *s; 1050 { 1051 1052 #define sink stdout 1053 1054 if (anyerrs == 0 && anywarnings == 0 && ! silent) 1055 fprintf(sink, "Assembler:\n"); 1056 anyerrs++; 1057 if (silent) 1058 return; 1059 fprintf(sink, "\"%s\", line %d: ", dotsname, lineno); 1060 fprintf(sink, s, a1, a2,a3,a4,a5); 1061 fprintf(sink, "\n"); 1062 #undef sink 1063 } 1064 1065 /*VARARGS1*/ 1066 yywarning(s, a1, a2,a3,a4,a5) 1067 char *s; 1068 { 1069 #define sink stdout 1070 if (anyerrs == 0 && anywarnings == 0 && ! silent) 1071 fprintf(sink, "Assembler:\n"); 1072 anywarnings++; 1073 if (silent) 1074 return; 1075 fprintf(sink, "\"%s\", line %d: WARNING: ", dotsname, lineno); 1076 fprintf(sink, s, a1, a2,a3,a4,a5); 1077 fprintf(sink, "\n"); 1078 #undef sink 1079 } 1080