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