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