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