1 /* 2 * Copyright (c) 1982 Regents of the University of California 3 */ 4 #ifndef lint 5 static char sccsid[] = "$W$ (Berkeley) 05/31/88"; 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 int printblank; 21 22 /* 23 * The following three variables are communication between various 24 * modules to special case a number of things. They are properly 25 * categorized as hacks. 26 */ 27 extern struct symtab *lastnam;/*last name seen by the lexical analyzer*/ 28 int exprisname; /*last factor in an expression was a name*/ 29 int droppedLP; /*one is analyzing an expression beginning with*/ 30 /*a left parenthesis, which has already been*/ 31 /*shifted. (Used to parse (<expr>)(rn)*/ 32 33 char yytext[NCPName+2]; /*the lexical image*/ 34 int yylval; /*the lexical value; sloppy typing*/ 35 u_char yyopcode; /* lexical value for an opcode */ 36 Bignum yybignum; /* lexical value for a big number */ 37 int num_type; /* type of bignums */ 38 /* 39 * Expression and argument managers 40 */ 41 struct exp *xp; /*next free expression slot, used by expr.c*/ 42 struct exp explist[NEXP]; /*max of 20 expressions in one opcode*/ 43 struct arg arglist[NARG]; /*building up operands in instructions*/ 44 /* 45 * Sets to accelerate token discrimination 46 */ 47 char tokensets[(LASTTOKEN) - (FIRSTTOKEN) + 1]; 48 49 static char UDotsname[64]; /*name of the assembly source*/ 50 51 yyparse() 52 { 53 reg struct exp *locxp; 54 /* 55 * loc1xp and ptrloc1xp are used in the 56 * expression lookahead 57 */ 58 struct exp *loc1xp; /*must be non register*/ 59 struct exp **ptrloc1xp = & loc1xp; 60 struct exp *pval; /*hacking expr:expr*/ 61 62 reg struct symtab *np; 63 reg int argcnt; 64 65 reg inttoktype val; /*what yylex gives*/ 66 reg inttoktype auxval; /*saves val*/ 67 68 reg struct arg *ap; /*first free argument*/ 69 70 reg struct symtab *p; 71 reg struct symtab *stpt; 72 73 struct strdesc *stringp; /*handles string lists*/ 74 75 int regno; /*handles arguments*/ 76 int *ptrregno = ®no; 77 int sawmul; /*saw * */ 78 int sawindex; /*saw [rn]*/ 79 int sawsize; 80 int seg_type; /*the kind of segment: data or text*/ 81 int seg_number; /*the segment number*/ 82 int space_value; /*how much .space needs*/ 83 int fill_rep; /*how many reps for .fill */ 84 int rep_fill; /*the same - temprary */ 85 int fill_size; /*how many bytes for .fill */ 86 87 int field_width; /*how wide a field is to be*/ 88 int field_value; /*the value to stuff in a field*/ 89 char *stabname; /*name of stab dealing with*/ 90 ptrall stabstart; /*where the stab starts in the buffer*/ 91 int reloc_how; /* how to relocate expressions */ 92 int incasetable; /* set if in a case table */ 93 int j, k; 94 char ch; 95 int length; /* for printout */ 96 union twolong 97 { 98 long lpart[2]; 99 char strpart [8]; 100 }fillval; 101 102 103 incasetable = 0; 104 xp = explist; 105 ap = arglist; 106 107 val = yylex(); 108 109 while (val != PARSEEOF){ /* primary loop */ 110 111 while (INTOKSET(val, LINSTBEGIN)){ 112 if (val == INT) { 113 int i = ((struct exp *)yylval)->e_xvalue; 114 shift; 115 if (val != COLON){ 116 yyerror("Local label %d is not followed by a ':' for a label definition", 117 i); 118 goto errorfix; 119 } 120 if (i < 0 || i > 9) { 121 yyerror("Local labels are 0-9"); 122 goto errorfix; 123 } 124 (void)sprintf(yytext, "L%d\001%d", i, lgensym[i]); 125 lgensym[i]++; 126 genref[i] = 0; 127 yylval = (int)*lookup(passno == 1); 128 val = NAME; 129 np = (struct symtab *)yylval; 130 goto restlab; 131 } 132 if (val == NL){ 133 lineno++; 134 if (liston && (passno == 2) && (! endofsource)) 135 { 136 /* printing previous line & layout */ 137 length = strlen (layout); 138 fprintf (listfile, "%*.*s", LHEAD, LHEAD, layout); 139 if (length <= LHEAD+LLEN) 140 j = LLEN; 141 else { /* break line at last blank */ 142 j = LHEAD+LLEN; 143 while(j>LHEAD && layout[j]!= ' ') 144 j--; 145 if(j == LHEAD) 146 j = LLEN; 147 else 148 j -= LHEAD; 149 } 150 k = LHEAD+j; 151 fprintf (listfile, "%-*.*s", LLEN, j, &layout[LHEAD]); 152 fprintf (listfile, " "); 153 do { 154 ch = getc (source); 155 putc (ch, listfile); 156 } while (ch != '\n'); 157 while (k < length) 158 { 159 fprintf (listfile, "%*s", LHEAD, ""); 160 /* break line at last blank */ 161 if(layout[k] == ' ') 162 k++; 163 if((j = k+LLEN) >= length) 164 j = length; 165 else 166 while(j>k && layout[j]!= ' ') 167 j--; 168 if(j == k) 169 j = LLEN; 170 else 171 j -= k; 172 fprintf (listfile, "%-*.*s\n", j, j, &layout[k]); 173 k += j; 174 } 175 k = 0; 176 while (layout[k] != '\0') 177 layout[k++] = '\0'; 178 ch = getc (source); 179 if (ch == EOF) 180 { 181 if (ind == ninfiles) 182 endofsource = 1; 183 else 184 { 185 source = fopen (innames[ind++], "r"); 186 lineno = 1; 187 } 188 } 189 else 190 ungetc (ch, source); 191 layoutpos = layout; 192 (void)sprintf (layoutpos, "%4ld ", lineno); 193 layoutpos += 6; 194 long_out (dotp->e_xvalue); 195 if (dotp->e_xvalue >= datbase) 196 (void)sprintf (layoutpos," * "); 197 else 198 (void)sprintf (layoutpos," "); 199 layoutpos += 4; 200 } 201 shift; 202 } else 203 if (val == SEMI) 204 shift; 205 else { /*its a name, so we have a label or def */ 206 if (val != NAME){ 207 ERROR("Name expected for a label"); 208 } 209 np = (struct symtab *)yylval; 210 shiftover(NAME); 211 if (val != COLON) { 212 yyerror("\"%s\" is not followed by a ':' for a label definition", 213 FETCHNAME(np)); 214 goto errorfix; 215 } 216 restlab: 217 shift; 218 flushfield(NBPW/4); 219 if ((np->s_type&XTYPE)!=XUNDEF) { 220 if( (np->s_type&XTYPE)!=dotp->e_xtype 221 || np->s_value!=dotp->e_xvalue 222 || ( (passno==1) 223 &&(np->s_index != dotp->e_xloc) 224 ) 225 ){ 226 #ifndef DEBUG 227 if (FETCHNAME(np)[0] != 'L') 228 #endif not DEBUG 229 { 230 if (passno == 1) 231 yyerror("%s redefined", 232 FETCHNAME(np)); 233 else 234 yyerror("%s redefined: PHASE ERROR, 1st: %d, 2nd: %d", 235 FETCHNAME(np), 236 np->s_value, 237 dotp->e_xvalue); 238 } 239 } 240 } 241 np->s_type &= ~(XTYPE|XFORW); 242 np->s_type |= dotp->e_xtype; 243 np->s_value = dotp->e_xvalue; 244 if (passno == 1){ 245 np->s_index = dotp-usedot; 246 if (FETCHNAME(np)[0] == 'L'){ 247 nlabels++; 248 } 249 np->s_tag = LABELID; 250 } 251 } /*end of this being a label*/ 252 } /*end of to consuming all labels, NLs and SEMIS */ 253 254 xp = explist; 255 ap = arglist; 256 257 /* 258 * process the INSTRUCTION body 259 */ 260 switch(val){ 261 262 default: 263 ERROR("Unrecognized instruction or directive"); 264 265 case IABORT: 266 shift; 267 sawabort(); 268 /*NOTREACHED*/ 269 break; 270 271 case PARSEEOF: 272 tokptr -= sizeof(bytetoktype); 273 *tokptr++ = VOID; 274 tokptr[1] = VOID; 275 tokptr[2] = PARSEEOF; 276 break; 277 278 case IFILE: 279 shift; 280 stringp = (struct strdesc *)yylval; 281 shiftover(STRING); 282 dotsname = &UDotsname[0]; 283 movestr(dotsname, stringp->sd_string, 284 min(stringp->sd_strlen, sizeof(UDotsname))); 285 break; 286 287 case ILINENO: 288 shift; /*over the ILINENO*/ 289 expr(locxp, val); 290 lineno = locxp->e_xvalue; 291 break; 292 293 case ISET: /* .set <name> , <expr> */ 294 shift; 295 np = (struct symtab *)yylval; 296 shiftover(NAME); 297 shiftover(CM); 298 expr(locxp, val); 299 np->s_type &= (XXTRN|XFORW); 300 np->s_type |= locxp->e_xtype&(XTYPE|XFORW); 301 np->s_value = locxp->e_xvalue; 302 if (passno==1) 303 np->s_index = locxp->e_xloc; 304 if ((locxp->e_xtype&XTYPE) == XUNDEF) 305 yyerror("Illegal set?"); 306 break; 307 308 case ILSYM: /*.lsym name , expr */ 309 shift; 310 np = (struct symtab *)yylval; 311 shiftover(NAME); 312 shiftover(CM); 313 expr(locxp, val); 314 /* 315 * Build the unique occurance of the 316 * symbol. 317 * The character scanner will have 318 * already entered it into the symbol 319 * table, but we should remove it 320 */ 321 if (passno == 1){ 322 stpt = (struct symtab *)symalloc(); 323 stpt->s_name = np->s_name; 324 np->s_tag = OBSOLETE; /*invalidate original */ 325 nforgotten++; 326 np = stpt; 327 if ( (locxp->e_xtype & XTYPE) != XABS) 328 yyerror("Illegal second argument to lsym"); 329 np->s_value = locxp->e_xvalue; 330 np->s_type = XABS; 331 np->s_tag = ILSYM; 332 } 333 break; 334 335 case IGLOBAL: /*.globl <name> */ 336 shift; 337 np = (struct symtab *)yylval; 338 shiftover(NAME); 339 np->s_type |= XXTRN; 340 break; 341 342 case IDATA: /*.data [ <expr> ] */ 343 case ITEXT: /*.text [ <expr> ] */ 344 incasetable = 0; 345 seg_type = -val; 346 shift; 347 if (INTOKSET(val, EBEGOPS+YUKKYEXPRBEG+SAFEEXPRBEG)){ 348 expr(locxp, val); 349 seg_type = -seg_type; /*now, it is positive*/ 350 } 351 352 if (seg_type < 0) { /*there wasn't an associated expr*/ 353 seg_number = 0; 354 seg_type = -seg_type; 355 } else { 356 if ( ((locxp->e_xtype & XTYPE) != XABS) /* tekmdp */ 357 || (seg_number = locxp->e_xvalue) >= NLOC) { 358 yyerror("illegal location counter"); 359 seg_number = 0; 360 } 361 } 362 if (seg_type == IDATA) 363 seg_number += NLOC; 364 flushfield(NBPW/4); 365 dotp = &usedot[seg_number]; 366 if (passno==2) { /* go salt away in pass 2*/ 367 txtfil = usefile[seg_number]; 368 relfil = rusefile[seg_number]; 369 } 370 break; 371 372 /* 373 * Storage filler directives: 374 * 375 * .byte [<exprlist>] 376 * 377 * exprlist: empty | exprlist outexpr 378 * outexpr: <expr> | <expr> : <expr> 379 */ 380 case IBYTE: curlen = NBPW/4; goto elist; 381 case IWORD: curlen = NBPW/2; goto elist; 382 case IINT: curlen = NBPW; goto elist; 383 case ILONG: curlen = NBPW; goto elist; 384 385 elist: 386 seg_type = val; 387 shift; 388 389 /* 390 * Expression List processing 391 */ 392 if (INTOKSET(val, EBEGOPS+YUKKYEXPRBEG+SAFEEXPRBEG)){ 393 do{ 394 /* 395 * expression list consists of a list of : 396 * <expr> 397 * <expr> : <expr> 398 * (pack expr2 into expr1 bits 399 */ 400 expr(locxp, val); 401 /* 402 * now, pointing at the next token 403 */ 404 /* if (val == COLON){ */ 405 /* shiftover(COLON); */ 406 /* expr(pval, val); */ 407 /* if ((locxp->e_xtype & XTYPE) != XABS) */ 408 /* yyerror("Width not absolute"); */ 409 /* field_width = locxp->e_xvalue; */ 410 /* locxp = pval; */ 411 /* if (bitoff + field_width > curlen) */ 412 /* flushfield(curlen); */ 413 /* if (field_width > curlen) */ 414 /* yyerror("Expression crosses field boundary"); */ 415 /* } else { */ 416 field_width = curlen; 417 if (bitoff == 0) printblank = 0; 418 else printblank = 1; 419 flushfield(curlen); 420 if (liston && (passno == 2) && printblank) 421 *layoutpos++ = ' '; 422 /* } */ 423 424 if ((locxp->e_xtype & XTYPE) != XABS) { 425 if (bitoff) 426 yyerror("Illegal relocation in field"); 427 switch(curlen){ 428 case NBPW/4: reloc_how = TYPB; break; 429 case NBPW/2: reloc_how = TYPW; break; 430 case NBPW: reloc_how = TYPL; break; 431 } 432 if (passno == 1){ 433 dotp->e_xvalue += ty_nbyte[reloc_how]; 434 } else { 435 outrel(locxp, reloc_how); 436 if (liston) 437 *layoutpos++ = ' '; 438 } 439 } else { 440 /* 441 * 442 * See if we are doing a case instruction. 443 * If so, then see if the branch distance, 444 * stored as a word, 445 * is going to loose sig bits. 446 */ 447 if (passno == 2 && incasetable){ 448 if ( !(ISWORD(locxp->e_xvalue))) 449 yyerror("Case will branch too far"); 450 } 451 field_value = locxp->e_xvalue & ( (1L << field_width)-1); 452 bitfield |= field_value << bitoff; 453 bitoff += field_width; 454 } 455 xp = explist; 456 if (auxval = (val == CM)) 457 shift; 458 } while (auxval); 459 } /* there existed an expression at all */ 460 461 flushfield(curlen); 462 if ( ( curlen == NBPW/4) && bitoff) 463 dotp->e_xvalue ++; 464 break; 465 /*end of case IBYTE, IWORD, ILONG, IINT*/ 466 467 case ISPACE: /* .space <expr> */ 468 shift; 469 expr(locxp, val); 470 if ((locxp->e_xtype & XTYPE) != XABS) /* tekmdp */ 471 yyerror("Space size not absolute"); 472 if (locxp->e_xvalue < 0) 473 yyerror("Space size not positive"); 474 space_value = locxp->e_xvalue; 475 ospace: 476 flushfield(NBPW/4); 477 { 478 static char spacebuf[128]; 479 while (space_value > sizeof(spacebuf)){ 480 outs(spacebuf, sizeof(spacebuf)); 481 space_value -= sizeof(spacebuf); 482 } 483 outs(spacebuf, space_value); 484 } 485 if (liston && (passno == 2)) 486 (void)sprintf (layoutpos, "****"); 487 break; 488 489 /* 490 * .fill rep, size, value 491 * repeat rep times: fill size bytes with (truncated) value 492 * size must be between 1 and 8 493 */ 494 case IFILL: 495 shift; 496 expr(locxp, val); 497 if ( (locxp->e_xtype & XTYPE) != XABS) /* tekmdp */ 498 yyerror("Fill repetition count not absolute"); 499 rep_fill = fill_rep = locxp->e_xvalue; 500 shiftover(CM); 501 expr(locxp, val); 502 if ( (locxp->e_xtype & XTYPE) != XABS) /* tekmdp */ 503 yyerror("Fill size not absolute"); 504 fill_size = locxp->e_xvalue; 505 if (fill_size <= 0 || fill_size > 8) 506 yyerror("Fill count not in in 1..8"); 507 shiftover(CM); 508 expr(locxp, val); 509 if (passno == 2 && (locxp->e_xtype & XTYPE) != XABS) /* tekmdp */ 510 yyerror("Fill value not absolute"); 511 flushfield(NBPW/4); 512 dotp->e_xvalue += fill_rep * fill_size; 513 if (passno == 1) { 514 locxp->e_xvalue += fill_rep * fill_size; 515 } else { 516 fillval.lpart[0] = locxp->e_yvalue; 517 fillval.lpart[1] = locxp->e_xvalue; 518 while (fill_rep-- > 0) 519 bwrite(&(fillval.strpart[8-fill_size]),fill_size,txtfil); 520 if (liston) { 521 while (rep_fill-- > 0) 522 { 523 switch (fill_size) 524 { 525 case 1: 526 byte_out (locxp->e_xvalue); 527 *layoutpos++ = ' '; 528 break; 529 case 2: 530 word_out (locxp->e_xvalue); 531 *layoutpos++ = ' '; 532 break; 533 case 3: 534 byte_out (locxp->e_xvalue >> 16); 535 byte_out (locxp->e_xvalue >> 8); 536 byte_out (locxp->e_xvalue); 537 *layoutpos++ = ' '; 538 break; 539 case 4: 540 long_out (locxp->e_xvalue); 541 *layoutpos++ = ' '; 542 break; 543 case 5: 544 byte_out (locxp->e_yvalue); 545 long_out (locxp->e_xvalue); 546 *layoutpos++ = ' '; 547 break; 548 case 6: 549 word_out (locxp->e_yvalue); 550 long_out (locxp->e_xvalue); 551 *layoutpos++ = ' '; 552 break; 553 case 7: 554 byte_out (locxp->e_yvalue >> 16); 555 byte_out (locxp->e_yvalue >> 8); 556 byte_out (locxp->e_yvalue); 557 long_out (locxp->e_xvalue); 558 *layoutpos++ = ' '; 559 break; 560 case 8: 561 long_out (locxp->e_yvalue); 562 long_out (locxp->e_xvalue); 563 *layoutpos++ = ' '; 564 break; 565 } 566 } 567 } 568 } 569 break; 570 571 case IASCII: /* .ascii [ <stringlist> ] */ 572 case IASCIZ: /* .asciz [ <stringlist> ] */ 573 auxval = val; 574 shift; 575 /* 576 * Code to consume a string list 577 * 578 * stringlist: empty | STRING | stringlist STRING 579 */ 580 while (val == STRING){ 581 int mystrlen; 582 flushfield(NBPW/4); 583 if (bitoff) 584 dotp->e_xvalue++; 585 stringp = (struct strdesc *)yylval; 586 /* 587 * utilize the string scanner cheat; 588 * the scanner appended a null byte on the string, 589 * but didn't charge it to sd_strlen 590 */ 591 mystrlen = stringp->sd_strlen; 592 mystrlen += (auxval == IASCIZ) ? 1 : 0; 593 if (passno == 2){ 594 if (stringp->sd_place & STR_CORE){ 595 outs(stringp->sd_string, mystrlen); 596 if (liston) 597 { 598 int i; 599 for (i = 0;i < mystrlen; i++) 600 { 601 (void)sprintf (layoutpos, "%02x", 602 stringp->sd_string[i]); 603 layoutpos += 2; 604 } 605 } 606 } else { 607 int i, nread; 608 fseek(strfile, stringp->sd_stroff, 0); 609 for (i = 0; i < mystrlen;/*VOID*/){ 610 nread = fread(yytext, 1, 611 min(mystrlen - i, 612 sizeof(yytext)), strfile); 613 outs(yytext, nread); 614 if (liston) 615 { 616 int k; 617 for (k = 0;k < nread; k++) 618 { 619 (void)sprintf (layoutpos, 620 "%02x", yytext[k]); 621 layoutpos += 2; 622 } 623 } 624 i += nread; 625 } 626 } 627 } else { 628 dotp->e_xvalue += mystrlen; 629 } 630 shift; /*over the STRING*/ 631 if (val == CM) /*could be a split string*/ 632 shift; 633 } 634 break; 635 636 case IORG: /* .org <expr> */ 637 shift; 638 expr(locxp, val); 639 640 if ((locxp->e_xtype & XTYPE) == XABS) /* tekmdp */ 641 orgwarn++; 642 else if ((locxp->e_xtype & ~XXTRN) != dotp->e_xtype) 643 yyerror("Illegal expression to set origin"); 644 if ((unsigned)locxp->e_xvalue < (unsigned)dotp->e_xvalue) 645 { 646 ERROR("Backwards 'org'"); 647 } 648 space_value = locxp->e_xvalue - dotp->e_xvalue; 649 goto ospace; 650 break; 651 652 /* 653 * 654 * Process stabs. Stabs are created only by the f77 655 * and the C compiler with the -g flag set. 656 * We only look at the stab ONCE, during pass 1, and 657 * virtually remove the stab from the intermediate file 658 * so it isn't seen during pass2. This makes for some 659 * hairy processing to handle labels occuring in 660 * stab entries, but since most expressions in the 661 * stab are integral we save lots of time in the second 662 * pass by not looking at the stabs. 663 * A stab that is tagged floating will be bumped during 664 * the jxxx resolution phase. A stab tagged fixed will 665 * not be be bumped. 666 * 667 * .stab: Old fashioned stabs 668 * .stabn: For stabs without names 669 * .stabs: For stabs with string names 670 * .stabd: For stabs for line numbers or bracketing, 671 * without a string name, without 672 * a final expression. The value of the 673 * final expression is taken to be the current 674 * location counter, and is patched by the 2nd pass 675 * 676 * .stab{<expr>,}*NCPName,<expr>, <expr>, <expr>, <expr> 677 * .stabn <expr>, <expr>, <expr>, <expr> 678 * .stabs STRING, <expr>, <expr>, <expr>, <expr> 679 * .stabd <expr>, <expr>, <expr> # . 680 */ 681 case ISTAB: 682 yyerror(".stab directive no longer supported"); 683 goto errorfix; 684 685 tailstab: 686 expr(locxp, val); 687 if (! (locxp->e_xvalue & STABTYPS)){ 688 yyerror("Invalid type in %s", stabname); 689 goto errorfix; 690 } 691 stpt->s_ptype = locxp->e_xvalue; 692 shiftover(CM); 693 expr(locxp, val); 694 stpt->s_other = locxp->e_xvalue; 695 shiftover(CM); 696 expr(locxp, val); 697 stpt->s_desc = locxp->e_xvalue; 698 shiftover(CM); 699 exprisname = 0; 700 expr(locxp, val); 701 p = locxp->e_xname; 702 if (p == NULL) { /*absolute expr to begin with*/ 703 stpt->s_value = locxp->e_xvalue; 704 stpt->s_index = dotp - usedot; 705 if (exprisname){ 706 stpt->s_type = locxp->e_xtype; 707 switch(stpt->s_ptype){ 708 case N_LCSYM: 709 stpt->s_dest = (struct symtab *)exprisname; 710 stpt->s_type |= STABFLAG; 711 case N_GSYM: 712 case N_FNAME: 713 case N_RSYM: 714 case N_SSYM: 715 case N_LSYM: 716 case N_PSYM: 717 case N_BCOMM: 718 case N_ECOMM: 719 case N_LENG: 720 stpt->s_tag = STABFIXED; 721 break; 722 default: 723 stpt->s_tag = STABFLOATING; 724 break; 725 } 726 } else 727 stpt->s_tag = STABFIXED; 728 } 729 else { /*really have a name*/ 730 stpt->s_dest = locxp->e_xname; 731 stpt->s_index = p->s_index; 732 stpt->s_type = p->s_type | STABFLAG; 733 /* 734 * We will assign a more accruate 735 * guess of locxp's location when 736 * we sort the symbol table 737 * The final value of value is 738 * given by stabfix() 739 */ 740 /* 741 * For exprs of the form (name + value) one needs to remember locxp->e_xvalue 742 * for use in stabfix. The right place to keep this is in stpt->s_value 743 * however this gets corrupted at an unknown point. 744 * As a bandaid hack the value is preserved in s_desc and s_other (a 745 * short and a char). This destroys these two values and will 746 * be fixed. May 19 ,1983 Alastair Fyfe 747 */ 748 if(locxp->e_xvalue) { 749 stpt->s_other = (locxp->e_xvalue >> 16); 750 stpt->s_desc = (locxp->e_xvalue & 0x0000ffff); 751 stpt->s_tag = STABFLOATING; 752 } 753 } 754 /* 755 * tokptr now points at one token beyond 756 * the current token stored in val and yylval, 757 * which are the next tokens after the end of 758 * this .stab directive. This next token must 759 * be either a SEMI or NL, so is of width just 760 * one. Therefore, to point to the next token 761 * after the end of this stab, just back up one.. 762 */ 763 buildskip(stabstart, (bytetoktype *)tokptr - sizeof(bytetoktype)); 764 break; /*end of the .stab*/ 765 766 case ISTABDOT: 767 stabname = ".stabd"; 768 stpt = (struct symtab *)yylval; 769 /* 770 * We clobber everything after the 771 * .stabd and its pointer... we MUST 772 * be able to get back to this .stabd 773 * so that we can resolve its final value 774 */ 775 stabstart = tokptr; 776 shift; /*over the ISTABDOT*/ 777 if (passno == 1){ 778 expr(locxp, val); 779 if (! (locxp->e_xvalue & STABTYPS)){ 780 yyerror("Invalid type in .stabd"); 781 goto errorfix; 782 } 783 stpt->s_ptype = locxp->e_xvalue; 784 shiftover(CM); 785 expr(locxp, val); 786 stpt->s_other = locxp->e_xvalue; 787 shiftover(CM); 788 expr(locxp, val); 789 stpt->s_desc = locxp->e_xvalue; 790 /* 791 * 792 * Now, clobber everything but the 793 * .stabd pseudo and the pointer 794 * to its symbol table entry 795 * tokptr points to the next token, 796 * build the skip up to this 797 */ 798 buildskip(stabstart, (bytetoktype *)tokptr - sizeof(bytetoktype)); 799 } 800 /* 801 * pass 1: Assign a good guess for its position 802 * (ensures they are sorted into right place)/ 803 * pass 2: Fix the actual value 804 */ 805 stpt->s_value = dotp->e_xvalue; 806 stpt->s_index = dotp - usedot; 807 stpt->s_tag = STABFLOATING; /*although it has no effect in pass 2*/ 808 break; 809 810 case ISTABNONE: stabname = ".stabn"; goto shortstab; 811 812 case ISTABSTR: stabname = ".stabs"; 813 shortstab: 814 auxval = val; 815 if (passno == 2) goto errorfix; 816 stpt = (struct symtab *)yylval; 817 stabstart = tokptr; 818 (bytetoktype *)stabstart -= sizeof(struct symtab *); 819 (bytetoktype *)stabstart -= sizeof(bytetoktype); 820 shift; 821 if (auxval == ISTABSTR){ 822 stringp = (struct strdesc *)yylval; 823 shiftover(STRING); 824 stpt->s_name = (char *)stringp; 825 /* 826 * We want the trailing null included in this string. 827 * We utilize the cheat the string scanner used, 828 * and merely increment the string length 829 */ 830 stringp->sd_strlen += 1; 831 shiftover(CM); 832 } else { 833 stpt->s_name = (char *)savestr("\0", 0, STR_BOTH); 834 } 835 goto tailstab; 836 break; 837 838 case ICOMM: /* .comm <name> , <expr> */ 839 case ILCOMM: /* .lcomm <name> , <expr> */ 840 auxval = val; 841 shift; 842 np = (struct symtab *)yylval; 843 shiftover(NAME); 844 shiftover(CM); 845 expr(locxp, val); 846 847 if ( (locxp->e_xtype & XTYPE) != XABS) /* tekmdp */ 848 yyerror("comm size not absolute"); 849 if (passno == 1 && (np->s_type&XTYPE) != XUNDEF) 850 yyerror("Redefinition of %s", FETCHNAME(np)); 851 if (passno==1) { 852 np->s_value = locxp->e_xvalue; 853 if (auxval == ICOMM) 854 np->s_type |= XXTRN; 855 else { 856 np->s_type &= ~XTYPE; 857 np->s_type |= XBSS; 858 } 859 } 860 break; 861 862 case IALIGN: /* .align <expr> */ 863 stpt = (struct symtab *)yylval; 864 shift; 865 expr(locxp, val); 866 if ((dotp->e_xtype & XTYPE) == XDATA) 867 djalign(locxp, stpt); 868 else 869 jalign(locxp, stpt); 870 break; 871 872 case INST0: /* instructions w/o arguments*/ 873 incasetable = 0; 874 insout(yyopcode, (struct arg *)0, 0); 875 shift; 876 break; 877 878 case INSTn: /* instructions with arguments*/ 879 case IJXXX: /* UNIX style jump instructions */ 880 auxval = val; 881 /* 882 * Code to process an argument list 883 */ 884 ap = arglist; 885 xp = explist; 886 887 shift; /* bring in the first token for the arg list*/ 888 889 for (argcnt = 1; argcnt <= 6; argcnt++, ap++){ 890 /* 891 * code to process an argument proper 892 */ 893 sawindex = sawmul = sawsize = 0; 894 { 895 switch(val) { 896 897 default: 898 disp: 899 if( !(INTOKSET(val, 900 EBEGOPS 901 +YUKKYEXPRBEG 902 +SAFEEXPRBEG)) ) { 903 ERROR("expression expected"); 904 } 905 expr(ap->a_xp,val); 906 overdisp: 907 if ( val == LP || sawsize){ 908 shiftover(LP); 909 findreg(regno); 910 shiftover(RP); 911 ap->a_atype = ADISP; 912 ap->a_areg1 = regno; 913 } else { 914 ap->a_atype = AEXP; 915 ap->a_areg1 = 0; 916 } 917 goto index; 918 919 case SIZESPEC: 920 sizespec: 921 sawsize = yylval; 922 shift; 923 goto disp; 924 925 case REG: 926 case REGOP: 927 findreg(regno); 928 ap->a_atype = AREG; 929 ap->a_areg1 = regno; 930 break; 931 932 case MUL: 933 sawmul = 1; 934 shift; 935 if (val == LP) goto base; 936 if (val == LITOP) goto imm; 937 if (val == SIZESPEC) goto sizespec; 938 if (INTOKSET(val, 939 EBEGOPS 940 +YUKKYEXPRBEG 941 +SAFEEXPRBEG)) goto disp; 942 ERROR("expression, '(' or '$' expected"); 943 break; 944 945 case LP: 946 base: 947 shift; /*consume the LP*/ 948 /* 949 * hack the ambiguity of 950 * movl (expr) (rn), ... 951 * note that (expr) could also 952 * be (rn) (by special hole in the 953 * grammar), which we ensure 954 * means register indirection, instead 955 * of an expression with value n 956 */ 957 if (val != REG && val != REGOP){ 958 droppedLP = 1; 959 val = exprparse(val, &(ap->a_xp)); 960 droppedLP = 0; 961 goto overdisp; 962 } 963 findreg(regno); 964 shiftover(RP); 965 if (val == PLUS){ 966 shift; 967 ap->a_atype = AINCR; 968 if (sawmul && regno != 0xE) 969 yyerror ("Autoincrement deferred register must be SP"); 970 if (!(sawmul || regno == 0xE)) 971 yyerror ("Autoincrement register must be SP"); 972 } else 973 ap->a_atype = ABASE; 974 ap->a_areg1 = regno; 975 goto index; 976 977 case LITOP: 978 imm: 979 shift; 980 expr(locxp, val); 981 ap->a_atype = AIMM; 982 ap->a_areg1 = 0; 983 ap->a_xp = locxp; 984 goto index; 985 986 case MP: 987 shift; /* -(reg) */ 988 findreg(regno); 989 if (regno != 0xE) 990 yyerror ("Autodecrement register must be SP"); 991 shiftover(RP); 992 ap->a_atype = ADECR; 993 ap->a_areg1 = regno; 994 index: /*look for [reg] */ 995 if (val == LB){ 996 shift; 997 findreg(regno); 998 shiftover(RB); 999 sawindex = 1; 1000 ap->a_areg2 = regno; 1001 } 1002 break; 1003 1004 } /*end of the switch to process an arg*/ 1005 } /*end of processing an argument*/ 1006 1007 if (sawmul){ 1008 /* 1009 * Make a concession for *(%r) 1010 * meaning *0(%r) 1011 */ 1012 if (ap->a_atype == ABASE) { 1013 ap->a_atype = ADISP; 1014 xp->e_xtype = XABS; 1015 xp->e_number = Znumber; 1016 xp->e_number.num_tag = TYPL; 1017 xp->e_xloc = 0; 1018 ap->a_xp = xp++; 1019 } 1020 ap->a_atype |= ASTAR; 1021 sawmul = 0; 1022 } 1023 if (sawindex){ 1024 ap->a_atype |= AINDX; 1025 sawindex = 0; 1026 } 1027 ap->a_dispsize = sawsize == 0 ? d124 : sawsize; 1028 if (val != CM) break; 1029 shiftover(CM); 1030 } /*processing all the arguments*/ 1031 1032 if (argcnt > 6){ 1033 yyerror("More than 6 arguments"); 1034 goto errorfix; 1035 } 1036 1037 /* 1038 * See if this is a case instruction, 1039 * so we can set up tests on the following 1040 * vector of branch displacements 1041 */ 1042 if (yyopcode == 0xfc) /* 'casel' instruction */ 1043 incasetable++; 1044 else 1045 incasetable = 0; 1046 1047 insout(yyopcode, arglist, 1048 auxval == INSTn ? argcnt : - argcnt); 1049 break; 1050 1051 case IQUAD: num_type = TYPQ; goto bignumlist; 1052 case IFFLOAT: num_type = TYPF; goto bignumlist; 1053 case IDFLOAT: num_type = TYPD; 1054 bignumlist: 1055 /* 1056 * eat a list of non 32 bit numbers. 1057 * IQUAD can, possibly, return 1058 * INT's, if the numbers are "small". 1059 * 1060 * The value of the numbers is coming back 1061 * as an expression, NOT in yybignum. 1062 */ 1063 shift; /* over the opener */ 1064 if ((val == BIGNUM) || (val == INT)){ 1065 do{ 1066 if ((val != BIGNUM) && (val != INT)){ 1067 ERROR(ty_float[num_type] 1068 ? "floating number expected" 1069 : "integer number expected" ); 1070 } 1071 dotp->e_xvalue += ty_nbyte[num_type]; 1072 if (passno == 2){ 1073 switch (num_type) { 1074 case TYPF: 1075 bwrite(((struct exp *)yylval)->e_number.num_num.numFf_float.Ff_ulong, 1076 ty_nbyte[num_type], txtfil); 1077 if (liston) 1078 { 1079 long_out(((struct exp *)yylval)->e_number.num_num.numFf_float.Ff_ulong[0]); 1080 *layoutpos++ = ' '; 1081 } 1082 break; 1083 case TYPD: 1084 bwrite(&((struct exp *)yylval)->e_number.num_num.numFd_float.Fd_ulong[0], 1085 sizeof (long), txtfil); 1086 bwrite(&((struct exp *)yylval)->e_number.num_num.numFd_float.Fd_ulong[1], 1087 sizeof (long), txtfil); 1088 if (liston) 1089 { 1090 long_out(((struct exp *)yylval)->e_number.num_num.numIq_int.Iq_ulong[0]); 1091 long_out(((struct exp *)yylval)->e_number.num_num.numIq_int.Iq_ulong[1]); 1092 *layoutpos++ = ' '; 1093 } 1094 break; 1095 case TYPQ: 1096 bwrite(&((struct exp *)yylval)->e_number.num_num.numIq_int.Iq_ulong[1], 1097 sizeof (long), txtfil); 1098 bwrite(&((struct exp *)yylval)->e_number.num_num.numIq_int.Iq_ulong[0], 1099 sizeof (long), txtfil); 1100 if (liston) 1101 { 1102 long_out(((struct exp *)yylval)->e_number.num_num.numIq_int.Iq_ulong[1]); 1103 long_out(((struct exp *)yylval)->e_number.num_num.numIq_int.Iq_ulong[0]); 1104 *layoutpos++ = ' '; 1105 } 1106 break; 1107 } 1108 } 1109 xp = explist; 1110 shift; /* over this number */ 1111 if (auxval = (val == CM)) 1112 shift; /* over the comma */ 1113 } while (auxval); /* as long as there are commas */ 1114 } 1115 break; 1116 /* end of the case for initialized big numbers */ 1117 } /*end of the switch for looking at each reserved word*/ 1118 1119 continue; 1120 1121 errorfix: 1122 /* 1123 * got here by either requesting to skip to the 1124 * end of this statement, or by erroring out and 1125 * wanting to apply panic mode recovery 1126 */ 1127 while ( (val != NL) 1128 && (val != SEMI) 1129 && (val != PARSEEOF) 1130 ){ 1131 shift; 1132 } 1133 if (val == NL) 1134 lineno++; 1135 shift; 1136 1137 } /*end of the loop to read the entire file, line by line*/ 1138 1139 } /*end of yyparse*/ 1140 1141 /* 1142 * Process a register declaration of the form 1143 * % <expr> 1144 * 1145 * Note: 1146 * The scanner has already processed funny registers of the form 1147 * %dd[+-]*, where dd is a decimal number in the range 00 to 15 (optional 1148 * preceding zero digit). If there was any space between the % and 1149 * the digit, the scanner wouldn't have recognized it, so we 1150 * hack it out here. 1151 */ 1152 inttoktype funnyreg(val, regnoback) /*what the read head will sit on*/ 1153 inttoktype val; /*what the read head is sitting on*/ 1154 int *regnoback; /*call by return*/ 1155 { 1156 reg struct exp *locxp; 1157 struct exp *loc1xp; 1158 struct exp **ptrloc1xp = & loc1xp; 1159 1160 expr(locxp, val); /*and leave the current read head with value*/ 1161 if ( (passno == 2) && 1162 ( (locxp->e_xtype & XTYPE) != XABS 1163 || (locxp->e_xvalue < 0) 1164 || (locxp->e_xvalue >= 16) 1165 ) 1166 ){ 1167 yyerror("Illegal register"); 1168 return(0); 1169 } 1170 *regnoback = locxp->e_xvalue; 1171 return(val); 1172 } 1173 /* 1174 * Shift over error 1175 */ 1176 shiftoerror(token) 1177 int token; 1178 { 1179 char *tok_to_name(); 1180 yyerror("%s expected", tok_to_name(token)); 1181 } 1182 1183 /*VARARGS1*/ 1184 yyerror(s, a1, a2,a3,a4,a5) 1185 char *s; 1186 { 1187 1188 #define sink stdout 1189 1190 if (anyerrs == 0 && anywarnings == 0 && ! silent) 1191 fprintf(sink, "Assembler:\n"); 1192 anyerrs++; 1193 if (silent) 1194 return; 1195 fprintf(sink, "\"%s\", line %d: ", dotsname, lineno); 1196 fprintf(sink, s, a1, a2,a3,a4,a5); 1197 fprintf(sink, "\n"); 1198 #undef sink 1199 } 1200 1201 /*VARARGS1*/ 1202 yywarning(s, a1, a2,a3,a4,a5) 1203 char *s; 1204 { 1205 #define sink stdout 1206 if (anyerrs == 0 && anywarnings == 0 && ! silent) 1207 fprintf(sink, "Assembler:\n"); 1208 anywarnings++; 1209 if (silent) 1210 return; 1211 fprintf(sink, "\"%s\", line %d: WARNING: ", dotsname, lineno); 1212 fprintf(sink, s, a1, a2,a3,a4,a5); 1213 fprintf(sink, "\n"); 1214 #undef sink 1215 } 1216