|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1982 Regents of the University of California ! 3: */ ! 4: #ifndef lint ! 5: static char sccsid[] = "@(#)asparse.c 4.17 7/1/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: 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: sprintf (layoutpos, "%4ld ", lineno); ! 193: layoutpos += 6; ! 194: long_out (dotp->e_xvalue); ! 195: if (dotp->e_xvalue >= datbase) ! 196: sprintf (layoutpos," * "); ! 197: else ! 198: 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: 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: 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: 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: switch(stpt->s_ptype){ ! 707: case N_GSYM: ! 708: case N_FNAME: ! 709: case N_RSYM: ! 710: case N_SSYM: ! 711: case N_LSYM: ! 712: case N_PSYM: ! 713: case N_BCOMM: ! 714: case N_ECOMM: ! 715: case N_LENG: ! 716: stpt->s_tag = STABFIXED; ! 717: break; ! 718: default: ! 719: stpt->s_tag = STABFLOATING; ! 720: break; ! 721: } ! 722: } else ! 723: stpt->s_tag = STABFIXED; ! 724: } ! 725: else { /*really have a name*/ ! 726: stpt->s_dest = locxp->e_xname; ! 727: stpt->s_index = p->s_index; ! 728: stpt->s_type = p->s_type | STABFLAG; ! 729: /* ! 730: * We will assign a more accruate ! 731: * guess of locxp's location when ! 732: * we sort the symbol table ! 733: * The final value of value is ! 734: * given by stabfix() ! 735: */ ! 736: /* ! 737: * For exprs of the form (name + value) one needs to remember locxp->e_xvalue ! 738: * for use in stabfix. The right place to keep this is in stpt->s_value ! 739: * however this gets corrupted at an unknown point. ! 740: * As a bandaid hack the value is preserved in s_desc and s_other (a ! 741: * short and a char). This destroys these two values and will ! 742: * be fixed. May 19 ,1983 Alastair Fyfe ! 743: */ ! 744: if(locxp->e_xvalue) { ! 745: stpt->s_other = (locxp->e_xvalue >> 16); ! 746: stpt->s_desc = (locxp->e_xvalue & 0x0000ffff); ! 747: stpt->s_tag = STABFLOATING; ! 748: } ! 749: } ! 750: /* ! 751: * tokptr now points at one token beyond ! 752: * the current token stored in val and yylval, ! 753: * which are the next tokens after the end of ! 754: * this .stab directive. This next token must ! 755: * be either a SEMI or NL, so is of width just ! 756: * one. Therefore, to point to the next token ! 757: * after the end of this stab, just back up one.. ! 758: */ ! 759: buildskip(stabstart, (bytetoktype *)tokptr - sizeof(bytetoktype)); ! 760: break; /*end of the .stab*/ ! 761: ! 762: case ISTABDOT: ! 763: stabname = ".stabd"; ! 764: stpt = (struct symtab *)yylval; ! 765: /* ! 766: * We clobber everything after the ! 767: * .stabd and its pointer... we MUST ! 768: * be able to get back to this .stabd ! 769: * so that we can resolve its final value ! 770: */ ! 771: stabstart = tokptr; ! 772: shift; /*over the ISTABDOT*/ ! 773: if (passno == 1){ ! 774: expr(locxp, val); ! 775: if (! (locxp->e_xvalue & STABTYPS)){ ! 776: yyerror("Invalid type in .stabd"); ! 777: goto errorfix; ! 778: } ! 779: stpt->s_ptype = locxp->e_xvalue; ! 780: shiftover(CM); ! 781: expr(locxp, val); ! 782: stpt->s_other = locxp->e_xvalue; ! 783: shiftover(CM); ! 784: expr(locxp, val); ! 785: stpt->s_desc = locxp->e_xvalue; ! 786: /* ! 787: * ! 788: * Now, clobber everything but the ! 789: * .stabd pseudo and the pointer ! 790: * to its symbol table entry ! 791: * tokptr points to the next token, ! 792: * build the skip up to this ! 793: */ ! 794: buildskip(stabstart, (bytetoktype *)tokptr - sizeof(bytetoktype)); ! 795: } ! 796: /* ! 797: * pass 1: Assign a good guess for its position ! 798: * (ensures they are sorted into right place)/ ! 799: * pass 2: Fix the actual value ! 800: */ ! 801: stpt->s_value = dotp->e_xvalue; ! 802: stpt->s_index = dotp - usedot; ! 803: stpt->s_tag = STABFLOATING; /*although it has no effect in pass 2*/ ! 804: break; ! 805: ! 806: case ISTABNONE: stabname = ".stabn"; goto shortstab; ! 807: ! 808: case ISTABSTR: stabname = ".stabs"; ! 809: shortstab: ! 810: auxval = val; ! 811: if (passno == 2) goto errorfix; ! 812: stpt = (struct symtab *)yylval; ! 813: stabstart = tokptr; ! 814: (bytetoktype *)stabstart -= sizeof(struct symtab *); ! 815: (bytetoktype *)stabstart -= sizeof(bytetoktype); ! 816: shift; ! 817: if (auxval == ISTABSTR){ ! 818: stringp = (struct strdesc *)yylval; ! 819: shiftover(STRING); ! 820: stpt->s_name = (char *)stringp; ! 821: /* ! 822: * We want the trailing null included in this string. ! 823: * We utilize the cheat the string scanner used, ! 824: * and merely increment the string length ! 825: */ ! 826: stringp->sd_strlen += 1; ! 827: shiftover(CM); ! 828: } else { ! 829: stpt->s_name = (char *)savestr("\0", 0, STR_BOTH); ! 830: } ! 831: goto tailstab; ! 832: break; ! 833: ! 834: case ICOMM: /* .comm <name> , <expr> */ ! 835: case ILCOMM: /* .lcomm <name> , <expr> */ ! 836: auxval = val; ! 837: shift; ! 838: np = (struct symtab *)yylval; ! 839: shiftover(NAME); ! 840: shiftover(CM); ! 841: expr(locxp, val); ! 842: ! 843: if ( (locxp->e_xtype & XTYPE) != XABS) /* tekmdp */ ! 844: yyerror("comm size not absolute"); ! 845: if (passno == 1 && (np->s_type&XTYPE) != XUNDEF) ! 846: yyerror("Redefinition of %s", FETCHNAME(np)); ! 847: if (passno==1) { ! 848: np->s_value = locxp->e_xvalue; ! 849: if (auxval == ICOMM) ! 850: np->s_type |= XXTRN; ! 851: else { ! 852: np->s_type &= ~XTYPE; ! 853: np->s_type |= XBSS; ! 854: } ! 855: } ! 856: break; ! 857: ! 858: case IALIGN: /* .align <expr> */ ! 859: stpt = (struct symtab *)yylval; ! 860: shift; ! 861: expr(locxp, val); ! 862: jalign(locxp, stpt); ! 863: break; ! 864: ! 865: case INST0: /* instructions w/o arguments*/ ! 866: incasetable = 0; ! 867: insout(yyopcode, (struct arg *)0, 0); ! 868: shift; ! 869: break; ! 870: ! 871: case INSTn: /* instructions with arguments*/ ! 872: case IJXXX: /* UNIX style jump instructions */ ! 873: auxval = val; ! 874: /* ! 875: * Code to process an argument list ! 876: */ ! 877: ap = arglist; ! 878: xp = explist; ! 879: ! 880: shift; /* bring in the first token for the arg list*/ ! 881: ! 882: for (argcnt = 1; argcnt <= 6; argcnt++, ap++){ ! 883: /* ! 884: * code to process an argument proper ! 885: */ ! 886: sawindex = sawmul = sawsize = 0; ! 887: { ! 888: switch(val) { ! 889: ! 890: default: ! 891: disp: ! 892: if( !(INTOKSET(val, ! 893: EBEGOPS ! 894: +YUKKYEXPRBEG ! 895: +SAFEEXPRBEG)) ) { ! 896: ERROR("expression expected"); ! 897: } ! 898: expr(ap->a_xp,val); ! 899: overdisp: ! 900: if ( val == LP || sawsize){ ! 901: shiftover(LP); ! 902: findreg(regno); ! 903: shiftover(RP); ! 904: ap->a_atype = ADISP; ! 905: ap->a_areg1 = regno; ! 906: } else { ! 907: ap->a_atype = AEXP; ! 908: ap->a_areg1 = 0; ! 909: } ! 910: goto index; ! 911: ! 912: case SIZESPEC: ! 913: sizespec: ! 914: sawsize = yylval; ! 915: shift; ! 916: goto disp; ! 917: ! 918: case REG: ! 919: case REGOP: ! 920: findreg(regno); ! 921: ap->a_atype = AREG; ! 922: ap->a_areg1 = regno; ! 923: break; ! 924: ! 925: case MUL: ! 926: sawmul = 1; ! 927: shift; ! 928: if (val == LP) goto base; ! 929: if (val == LITOP) goto imm; ! 930: if (val == SIZESPEC) goto sizespec; ! 931: if (INTOKSET(val, ! 932: EBEGOPS ! 933: +YUKKYEXPRBEG ! 934: +SAFEEXPRBEG)) goto disp; ! 935: ERROR("expression, '(' or '$' expected"); ! 936: break; ! 937: ! 938: case LP: ! 939: base: ! 940: shift; /*consume the LP*/ ! 941: /* ! 942: * hack the ambiguity of ! 943: * movl (expr) (rn), ... ! 944: * note that (expr) could also ! 945: * be (rn) (by special hole in the ! 946: * grammar), which we ensure ! 947: * means register indirection, instead ! 948: * of an expression with value n ! 949: */ ! 950: if (val != REG && val != REGOP){ ! 951: droppedLP = 1; ! 952: val = exprparse(val, &(ap->a_xp)); ! 953: droppedLP = 0; ! 954: goto overdisp; ! 955: } ! 956: findreg(regno); ! 957: shiftover(RP); ! 958: if (val == PLUS){ ! 959: shift; ! 960: ap->a_atype = AINCR; ! 961: if (sawmul && regno != 0xE) ! 962: yyerror ("Autoincrement deferred register must be SP"); ! 963: if (!(sawmul || regno == 0xE)) ! 964: yyerror ("Autoincrement register must be SP"); ! 965: } else ! 966: ap->a_atype = ABASE; ! 967: ap->a_areg1 = regno; ! 968: goto index; ! 969: ! 970: case LITOP: ! 971: imm: ! 972: shift; ! 973: expr(locxp, val); ! 974: ap->a_atype = AIMM; ! 975: ap->a_areg1 = 0; ! 976: ap->a_xp = locxp; ! 977: goto index; ! 978: ! 979: case MP: ! 980: shift; /* -(reg) */ ! 981: findreg(regno); ! 982: if (regno != 0xE) ! 983: yyerror ("Autodecrement register must be SP"); ! 984: shiftover(RP); ! 985: ap->a_atype = ADECR; ! 986: ap->a_areg1 = regno; ! 987: index: /*look for [reg] */ ! 988: if (val == LB){ ! 989: shift; ! 990: findreg(regno); ! 991: shiftover(RB); ! 992: sawindex = 1; ! 993: ap->a_areg2 = regno; ! 994: } ! 995: break; ! 996: ! 997: } /*end of the switch to process an arg*/ ! 998: } /*end of processing an argument*/ ! 999: ! 1000: if (sawmul){ ! 1001: /* ! 1002: * Make a concession for *(%r) ! 1003: * meaning *0(%r) ! 1004: */ ! 1005: if (ap->a_atype == ABASE) { ! 1006: ap->a_atype = ADISP; ! 1007: xp->e_xtype = XABS; ! 1008: xp->e_number = Znumber; ! 1009: xp->e_number.num_tag = TYPL; ! 1010: xp->e_xloc = 0; ! 1011: ap->a_xp = xp++; ! 1012: } ! 1013: ap->a_atype |= ASTAR; ! 1014: sawmul = 0; ! 1015: } ! 1016: if (sawindex){ ! 1017: ap->a_atype |= AINDX; ! 1018: sawindex = 0; ! 1019: } ! 1020: ap->a_dispsize = sawsize == 0 ? d124 : sawsize; ! 1021: if (val != CM) break; ! 1022: shiftover(CM); ! 1023: } /*processing all the arguments*/ ! 1024: ! 1025: if (argcnt > 6){ ! 1026: yyerror("More than 6 arguments"); ! 1027: goto errorfix; ! 1028: } ! 1029: ! 1030: /* ! 1031: * See if this is a case instruction, ! 1032: * so we can set up tests on the following ! 1033: * vector of branch displacements ! 1034: */ ! 1035: if (yyopcode == 0xfc) /* 'casel' instruction */ ! 1036: incasetable++; ! 1037: else ! 1038: incasetable = 0; ! 1039: ! 1040: insout(yyopcode, arglist, ! 1041: auxval == INSTn ? argcnt : - argcnt); ! 1042: break; ! 1043: ! 1044: case IQUAD: num_type = TYPQ; goto bignumlist; ! 1045: case IFFLOAT: num_type = TYPF; goto bignumlist; ! 1046: case IDFLOAT: num_type = TYPD; ! 1047: bignumlist: ! 1048: /* ! 1049: * eat a list of non 32 bit numbers. ! 1050: * IQUAD can, possibly, return ! 1051: * INT's, if the numbers are "small". ! 1052: * ! 1053: * The value of the numbers is coming back ! 1054: * as an expression, NOT in yybignum. ! 1055: */ ! 1056: shift; /* over the opener */ ! 1057: if ((val == BIGNUM) || (val == INT)){ ! 1058: do{ ! 1059: if ((val != BIGNUM) && (val != INT)){ ! 1060: ERROR(ty_float[num_type] ! 1061: ? "floating number expected" ! 1062: : "integer number expected" ); ! 1063: } ! 1064: dotp->e_xvalue += ty_nbyte[num_type]; ! 1065: if (passno == 2){ ! 1066: switch (num_type) { ! 1067: case TYPF: ! 1068: bwrite(&((struct exp *)yylval)->e_number.num_num.numFf_float.Ff_ulong, ! 1069: ty_nbyte[num_type], txtfil); ! 1070: if (liston) ! 1071: { ! 1072: long_out(((struct exp *)yylval)->e_number.num_num.numFf_float.Ff_ulong[0]); ! 1073: *layoutpos++ = ' '; ! 1074: } ! 1075: break; ! 1076: case TYPD: ! 1077: bwrite(&((struct exp *)yylval)->e_number.num_num.numFd_float.Fd_ulong[0], ! 1078: sizeof (long), txtfil); ! 1079: bwrite(&((struct exp *)yylval)->e_number.num_num.numFd_float.Fd_ulong[1], ! 1080: sizeof (long), txtfil); ! 1081: if (liston) ! 1082: { ! 1083: long_out(((struct exp *)yylval)->e_number.num_num.numIq_int.Iq_ulong[0]); ! 1084: long_out(((struct exp *)yylval)->e_number.num_num.numIq_int.Iq_ulong[1]); ! 1085: *layoutpos++ = ' '; ! 1086: } ! 1087: break; ! 1088: case TYPQ: ! 1089: bwrite(&((struct exp *)yylval)->e_number.num_num.numIq_int.Iq_ulong[1], ! 1090: sizeof (long), txtfil); ! 1091: bwrite(&((struct exp *)yylval)->e_number.num_num.numIq_int.Iq_ulong[0], ! 1092: sizeof (long), txtfil); ! 1093: if (liston) ! 1094: { ! 1095: long_out(((struct exp *)yylval)->e_number.num_num.numIq_int.Iq_ulong[1]); ! 1096: long_out(((struct exp *)yylval)->e_number.num_num.numIq_int.Iq_ulong[0]); ! 1097: *layoutpos++ = ' '; ! 1098: } ! 1099: break; ! 1100: } ! 1101: } ! 1102: xp = explist; ! 1103: shift; /* over this number */ ! 1104: if (auxval = (val == CM)) ! 1105: shift; /* over the comma */ ! 1106: } while (auxval); /* as long as there are commas */ ! 1107: } ! 1108: break; ! 1109: /* end of the case for initialized big numbers */ ! 1110: } /*end of the switch for looking at each reserved word*/ ! 1111: ! 1112: continue; ! 1113: ! 1114: errorfix: ! 1115: /* ! 1116: * got here by either requesting to skip to the ! 1117: * end of this statement, or by erroring out and ! 1118: * wanting to apply panic mode recovery ! 1119: */ ! 1120: while ( (val != NL) ! 1121: && (val != SEMI) ! 1122: && (val != PARSEEOF) ! 1123: ){ ! 1124: shift; ! 1125: } ! 1126: if (val == NL) ! 1127: lineno++; ! 1128: shift; ! 1129: ! 1130: } /*end of the loop to read the entire file, line by line*/ ! 1131: ! 1132: } /*end of yyparse*/ ! 1133: ! 1134: /* ! 1135: * Process a register declaration of the form ! 1136: * % <expr> ! 1137: * ! 1138: * Note: ! 1139: * The scanner has already processed funny registers of the form ! 1140: * %dd[+-]*, where dd is a decimal number in the range 00 to 15 (optional ! 1141: * preceding zero digit). If there was any space between the % and ! 1142: * the digit, the scanner wouldn't have recognized it, so we ! 1143: * hack it out here. ! 1144: */ ! 1145: inttoktype funnyreg(val, regnoback) /*what the read head will sit on*/ ! 1146: inttoktype val; /*what the read head is sitting on*/ ! 1147: int *regnoback; /*call by return*/ ! 1148: { ! 1149: reg struct exp *locxp; ! 1150: struct exp *loc1xp; ! 1151: struct exp **ptrloc1xp = & loc1xp; ! 1152: ! 1153: expr(locxp, val); /*and leave the current read head with value*/ ! 1154: if ( (passno == 2) && ! 1155: ( (locxp->e_xtype & XTYPE) != XABS ! 1156: || (locxp->e_xvalue < 0) ! 1157: || (locxp->e_xvalue >= 16) ! 1158: ) ! 1159: ){ ! 1160: yyerror("Illegal register"); ! 1161: return(0); ! 1162: } ! 1163: *regnoback = locxp->e_xvalue; ! 1164: return(val); ! 1165: } ! 1166: /* ! 1167: * Shift over error ! 1168: */ ! 1169: shiftoerror(token) ! 1170: int token; ! 1171: { ! 1172: char *tok_to_name(); ! 1173: yyerror("%s expected", tok_to_name(token)); ! 1174: } ! 1175: ! 1176: /*VARARGS1*/ ! 1177: yyerror(s, a1, a2,a3,a4,a5) ! 1178: char *s; ! 1179: { ! 1180: ! 1181: #define sink stdout ! 1182: ! 1183: if (anyerrs == 0 && anywarnings == 0 && ! silent) ! 1184: fprintf(sink, "Assembler:\n"); ! 1185: anyerrs++; ! 1186: if (silent) ! 1187: return; ! 1188: fprintf(sink, "\"%s\", line %d: ", dotsname, lineno); ! 1189: fprintf(sink, s, a1, a2,a3,a4,a5); ! 1190: fprintf(sink, "\n"); ! 1191: #undef sink ! 1192: } ! 1193: ! 1194: /*VARARGS1*/ ! 1195: yywarning(s, a1, a2,a3,a4,a5) ! 1196: char *s; ! 1197: { ! 1198: #define sink stdout ! 1199: if (anyerrs == 0 && anywarnings == 0 && ! silent) ! 1200: fprintf(sink, "Assembler:\n"); ! 1201: anywarnings++; ! 1202: if (silent) ! 1203: return; ! 1204: fprintf(sink, "\"%s\", line %d: WARNING: ", dotsname, lineno); ! 1205: fprintf(sink, s, a1, a2,a3,a4,a5); ! 1206: fprintf(sink, "\n"); ! 1207: #undef sink ! 1208: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.