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