|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1982 Regents of the University of California ! 3: */ ! 4: #ifndef lint ! 5: static char sccsid[] = "$W$ (Berkeley) 5/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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.