|
|
1.1 ! root 1: /* Copyright (c) 1979 Regents of the University of California */ ! 2: #include <stdio.h> ! 3: #include <a.out.h> ! 4: #include "as.h" ! 5: #include "asexpr.h" ! 6: #include "asscan.h" ! 7: #include "assyms.h" ! 8: ! 9: extern struct exp usedot[];/*information on the dot for each seg*/ ! 10: struct exp *dotp = &usedot[0]; /*current dot*/ ! 11: int anyerrs; ! 12: ! 13: int passno = 1; ! 14: ! 15: FILE *tmpfil; ! 16: FILE *relfil; /*relocation info sent here*/ ! 17: FILE *txtfil; /*text (for any text #) sent here*/ ! 18: ! 19: int hshused; /*hash slots consumed */ ! 20: long tsize; ! 21: long dsize; ! 22: ! 23: long bitfield; ! 24: int bitoff; ! 25: ! 26: /* ! 27: * The following three variables are communication between various ! 28: * modules to special case a number of things. They are properly ! 29: * categorized as hacks. ! 30: */ ! 31: struct symtab *lastnam; /*last name seen by the lexical analyzer*/ ! 32: int exprisname; /*last factor in an expression was a name*/ ! 33: int droppedLP; /*one is analyzing an expression beginning with*/ ! 34: /*a left parenthesis, which has already been*/ ! 35: /*shifted. (Used to parse (<expr>)(rn)*/ ! 36: ! 37: char yytext[NCPS+2]; ! 38: static char Dotsname[32]; ! 39: ! 40: struct exp *xp; /*next free expression slot, used by expr.c*/ ! 41: ! 42: int yylval; /*the lexical value; sloppy typing*/ ! 43: ! 44: extern ptrall tokptr; /*points to current token being eaten*/ ! 45: extern int d124; ! 46: ! 47: int yyparse() ! 48: { ! 49: register struct exp *locxp; ! 50: /* ! 51: * loc1xp and ptrloc1xp are used in the ! 52: * expression lookahead ! 53: */ ! 54: struct exp *loc1xp; /*must be non register*/ ! 55: struct exp **ptrloc1xp = & loc1xp; ! 56: struct exp *pval; /*hacking expr:expr*/ ! 57: ! 58: register struct symtab *np; ! 59: register int argcnt; ! 60: ! 61: register int val; /*what yylex gives*/ ! 62: register int auxval; /*saves val*/ ! 63: ! 64: register struct arg *ap; /*first free argument*/ ! 65: ! 66: struct symtab *p; ! 67: register struct symtab *stpt; ! 68: ! 69: struct strdesc *stringp; /*handles string lists*/ ! 70: ! 71: int regno; /*handles arguments*/ ! 72: int *ptrregno = ®no; ! 73: int sawmul; /*saw * */ ! 74: int sawindex; /*saw [rn]*/ ! 75: int sawsize; ! 76: int seg_type; /*the kind of segment: data or text*/ ! 77: int seg_number; /*the segment number*/ ! 78: long space_value; /*how much .space needs*/ ! 79: ! 80: int field_width; /*how wide a field is to be*/ ! 81: int field_value; /*the value to stuff in a field*/ ! 82: char *stabname; /*name of stab dealing with*/ ! 83: ptrall stabstart; /*where the stab starts in the buffer*/ ! 84: ! 85: xp = explist; ! 86: ap = arglist; ! 87: ! 88: val = yylex(); ! 89: while (val != PARSEEOF){ ! 90: while (INTOKSET(val, LINSTBEGIN)){ ! 91: if (val == NL){ ! 92: lineno++; ! 93: shift; ! 94: } else ! 95: if (val == SEMI) ! 96: shift; ! 97: else { /*its a name, so we have a label (hopefully*/ ! 98: if (val != NAME){ ! 99: ERROR("Name expected for a label"); ! 100: } ! 101: np = (struct symtab *)yylval; ! 102: shiftover(NAME); ! 103: shiftover(COLON); ! 104: flushfield(NBPW/4); ! 105: if ((np->type&XTYPE)!=XUNDEF) { ! 106: if( (np->type&XTYPE)!=dotp->xtype ! 107: || np->value!=dotp->xvalue ! 108: || ( (passno==1) ! 109: &&(np->index != dotp->xloc) ! 110: ) ! 111: ){ ! 112: #ifndef DEBUG ! 113: if (np->name[0] != 'L') ! 114: #endif ! 115: { ! 116: yyerror("%.8s redefined", np->name); ! 117: #ifdef DEBUG ! 118: printf("name.value=%d, dotp->xvalue=%d\n", ! 119: np->value, dotp->xvalue); ! 120: #endif ! 121: } ! 122: } ! 123: } ! 124: np->type &= ~(XTYPE|XFORW); ! 125: np->type |= dotp->xtype; ! 126: np->value = dotp->xvalue; ! 127: if (passno == 1){ ! 128: np->index = dotp-usedot; ! 129: if (np->name[0] == 'L'){ ! 130: nlabels++; ! 131: } ! 132: np->tag = LABELID; ! 133: } ! 134: } /*end of this being a label*/ ! 135: } /*end of to consuming all labels, NLs and SEMIS */ ! 136: ! 137: xp = explist; ! 138: ap = arglist; ! 139: ! 140: /* ! 141: * process the INSTRUCTION body ! 142: */ ! 143: switch(val){ ! 144: default: ! 145: ERROR("Unrecognized instruction or directive"); ! 146: ! 147: case IABORT: ! 148: shift; ! 149: sawabort(); ! 150: /*NOTREACHED*/ ! 151: break; ! 152: ! 153: case PARSEEOF: ! 154: tokptr -= sizeof(toktype); ! 155: *tokptr++ = VOID; ! 156: tokptr[1] = VOID; ! 157: tokptr[2] = PARSEEOF; ! 158: break; ! 159: ! 160: case IFILE: ! 161: shift; ! 162: stringp = (struct strdesc *)yylval; ! 163: shiftover(STRING); ! 164: dotsname = &Dotsname[0]; ! 165: movestr(dotsname, stringp->str, ! 166: stringp->str_lg >= 32? 32 :stringp->str_lg); ! 167: dotsname[stringp->str_lg] = '\0'; ! 168: #ifdef DEBUG ! 169: if (debug) ! 170: printf("(from parser) Now considered to be in file %s\n", ! 171: dotsname); ! 172: #endif ! 173: break; ! 174: ! 175: case ILINENO: ! 176: shift; /*over the ILINENO*/ ! 177: expr(locxp, val); ! 178: lineno = locxp->xvalue; ! 179: #ifdef DEBUG ! 180: if (debug) ! 181: printf("Now considered to be on line number %d\n", ! 182: lineno); ! 183: #endif ! 184: break; ! 185: ! 186: case ISET: { /* .set <name> , <expr> */ ! 187: shift; ! 188: np = (struct symtab *)yylval; ! 189: shiftover(NAME); ! 190: shiftover(CM); ! 191: expr(locxp, val); ! 192: np->type &= (XXTRN|XFORW); ! 193: np->type |= locxp->xtype&(XTYPE|XFORW); ! 194: np->value = locxp->xvalue; ! 195: if (passno==1) ! 196: np->index = locxp->xloc; ! 197: if ((locxp->xtype&XTYPE) == XUNDEF) ! 198: yyerror("Illegal set?"); ! 199: break; ! 200: } /*end of case ISET*/ ! 201: ! 202: case ILSYM: { /*.lsym name , expr */ ! 203: shift; ! 204: np = (struct symtab *)yylval; ! 205: shiftover(NAME); ! 206: shiftover(CM); ! 207: expr(locxp, val); ! 208: /* ! 209: * Build the unique occurance of the ! 210: * symbol. ! 211: * The character scanner will have ! 212: * already entered it into the symbol ! 213: * table, but we should remove it ! 214: */ ! 215: if (passno == 1){ ! 216: stpt = (struct symtab *)symalloc(); ! 217: movestr(stpt->name, np->name, NCPS); ! 218: np->tag = OBSOLETE; /*invalidate original */ ! 219: nforgotten++; ! 220: np = stpt; ! 221: if (locxp->xtype != XABS) ! 222: ("Illegal lsym"); ! 223: np->value=locxp->xvalue; ! 224: np->type=XABS; ! 225: np->tag = ILSYM; ! 226: } ! 227: break; ! 228: } /*end of case ILSYM*/ ! 229: ! 230: case IGLOBAL: { /*.globl <name> */ ! 231: shift; ! 232: np = (struct symtab *)yylval; ! 233: shiftover(NAME); ! 234: np->type |= XXTRN; ! 235: break; ! 236: } /*end of case IGLOBAL*/ ! 237: ! 238: case IDATA: /*.data [ <expr> ] */ ! 239: case ITEXT: { /*.text [ <expr> ] */ ! 240: seg_type = -val; ! 241: shift; ! 242: if (INTOKSET(val, EBEGOPS+YUKKYEXPRBEG+SAFEEXPRBEG)){ ! 243: expr(locxp, val); ! 244: seg_type = -seg_type; /*now, it is positive*/ ! 245: } ! 246: ! 247: if (seg_type < 0) { /*there wasn't an associated expr*/ ! 248: seg_number = 0; ! 249: seg_type = -seg_type; ! 250: } else { ! 251: if (locxp->xtype != XABS || (seg_number=locxp->xvalue) >= NLOC) { ! 252: yyerror("illegal location counter"); ! 253: seg_number = 0; ! 254: } ! 255: } ! 256: if (seg_type == IDATA) ! 257: seg_number += NLOC; ! 258: flushfield(NBPW/4); ! 259: dotp = &usedot[seg_number]; ! 260: if (passno==2) { /* go salt away in pass 2*/ ! 261: if (usefile[seg_number] == NULL) { ! 262: tmpn2[TMPC] = 'a'+seg_number; ! 263: if ((usefile[seg_number] = ! 264: fopen(tmpn2, "w"))==NULL) { ! 265: yyerror("cannot create temp %s", tmpn2); ! 266: delexit(); ! 267: } ! 268: ! 269: tmpn3[TMPC] = 'a'+seg_number; ! 270: if ((rusefile[seg_number] = ! 271: fopen(tmpn3, "w"))==NULL) { ! 272: ! 273: yyerror("cannot create temp %s", ! 274: tmpn3); ! 275: } ! 276: } ! 277: txtfil = usefile[seg_number]; ! 278: relfil = rusefile[seg_number]; ! 279: } ! 280: ! 281: break; ! 282: } /*end of case .TEXT and .DATA*/ ! 283: ! 284: /* ! 285: * Storage filler directives: ! 286: * ! 287: * .byte [<exprlist>] ! 288: * ! 289: * exprlist: empty | exprlist outexpr ! 290: * outexpr: <expr> | <expr> : <expr> ! 291: */ ! 292: case IBYTE: curlen = NBPW/4; goto elist; ! 293: ! 294: case IINT: ! 295: case ILONG: curlen = NBPW; goto elist; ! 296: ! 297: case IWORD: { ! 298: curlen = NBPW/2; ! 299: elist: ! 300: seg_type = val; ! 301: shift; ! 302: ! 303: /* ! 304: * This processes an expression list ! 305: */ ! 306: if (INTOKSET(val, EBEGOPS+YUKKYEXPRBEG+SAFEEXPRBEG)){ ! 307: do{ ! 308: /* ! 309: * expression list consists of a list of : ! 310: * <expr> ! 311: * <expr> : <expr> ! 312: * (pack expr2 into expr1 bits ! 313: */ ! 314: expr(locxp, val); ! 315: /* ! 316: * now, pointing at the next token ! 317: */ ! 318: if (val == COLON){ ! 319: shiftover(COLON); ! 320: expr(pval, val); ! 321: if (locxp->xtype != XABS) ! 322: yyerror("Width not absolute"); ! 323: field_width = locxp->xvalue; ! 324: locxp = pval; ! 325: if (bitoff + field_width > ! 326: curlen) ! 327: flushfield(curlen); ! 328: if (field_width > curlen) ! 329: yyerror("Expression crosses field boundary"); ! 330: } /*value being colon*/ ! 331: else { ! 332: field_width = curlen; ! 333: flushfield(curlen); ! 334: } ! 335: ! 336: if ((locxp->xtype&XTYPE)!=XABS) { ! 337: if (bitoff) ! 338: yyerror("Illegal relocation in field"); ! 339: field_width=LEN1+!PCREL; ! 340: if (curlen==NBPW) ! 341: field_width = LEN4 + !PCREL; ! 342: if (curlen==NBPW/2) ! 343: field_width = LEN2 + !PCREL; ! 344: /* ! 345: * Save relocation information for this non absolute ! 346: * symbol: ! 347: * pass 1: saves enough space for the value, and ! 348: * fixes dotp. ! 349: * pass 2: writes the address info in ld compatable ! 350: * format onto one of the relfiles ! 351: */ ! 352: outrel(&locxp->xvalue, ! 353: field_width, ! 354: locxp->xtype, ! 355: locxp->xname); ! 356: } else { ! 357: field_value = locxp->xvalue & ( (1L << field_width)-1); ! 358: bitfield |= field_value << bitoff; ! 359: bitoff += field_width; ! 360: } ! 361: if ( auxval = (val == CM)) shift; ! 362: } while (auxval); ! 363: } /*existed an expression at all*/ ! 364: ! 365: flushfield(curlen); ! 366: if ( ( curlen == NBPW/4) && bitoff) ! 367: dotp->xvalue ++; ! 368: break; ! 369: } /*end of case IBYTE, IWORD, ILONG, IINT*/ ! 370: ! 371: case ISPACE: { /* .space <expr> */ ! 372: shift; ! 373: expr(locxp, val); ! 374: if (locxp->xtype != XABS) ! 375: yyerror("Space size not absolute"); ! 376: space_value = locxp->xvalue; ! 377: ospace: ! 378: flushfield(NBPW/4); ! 379: while (space_value > 96){ ! 380: outs(strbuf[2].str, 96); ! 381: space_value -= 96; ! 382: } ! 383: outs(strbuf[2].str, space_value); ! 384: break; ! 385: } /*end of case ISPACE*/ ! 386: ! 387: case IASCII: /* .ascii [ <stringlist> ] */ ! 388: case IASCIZ: { /* .asciz [ <stringlist> ] */ ! 389: auxval = val; ! 390: shift; ! 391: ! 392: /* ! 393: * Code to consume a string list ! 394: * ! 395: * stringlist: empty | STRING | stringlist STRING ! 396: */ ! 397: while (val == STRING){ ! 398: flushfield(NBPW/4); ! 399: if (bitoff) ! 400: dotp->xvalue++; ! 401: stringp = (struct strdesc *)yylval; ! 402: outs(stringp->str, stringp->str_lg); ! 403: shift; /*over the STRING*/ ! 404: if (val == CM) /*could be a split string*/ ! 405: shift; ! 406: } ! 407: ! 408: if (auxval == IASCIZ){ ! 409: flushfield(NBPW/4); ! 410: outb(0); ! 411: } ! 412: break; ! 413: } /*end of case IASCII and IASIZ*/ ! 414: ! 415: case IORG: { /* .org <expr> */ ! 416: shift; ! 417: expr(locxp, val); ! 418: ! 419: if (locxp->xtype==XABS) ! 420: orgwarn++; ! 421: else if (locxp->xtype!=dotp->xtype) ! 422: yyerror("Illegal expression to set origin"); ! 423: space_value = locxp->xvalue - dotp->xvalue; ! 424: if (space_value < 0) ! 425: yyerror("Backwards 'org'"); ! 426: goto ospace; ! 427: break; ! 428: } /*end of case IORG*/ ! 429: ! 430: /* ! 431: * ! 432: * Process stabs. Stabs are created only by the f77 ! 433: * and the C compiler with the -g flag set. ! 434: * We only look at the stab ONCE, during pass 1, and ! 435: * virtually remove the stab from the intermediate file ! 436: * so it isn't seen during pass2. This makes for some ! 437: * hairy processing to handle labels occuring in ! 438: * stab entries, but since most expressions in the ! 439: * stab are integral we save lots of time in the second ! 440: * pass by not looking at the stabs. ! 441: * A stab that is tagged floating will be bumped during ! 442: * the jxxx resolution phase. A stab tagged fixed will ! 443: * not be be bumped. ! 444: * ! 445: * .stab: Old fashioned stabs ! 446: * .stabn: For stabs without names ! 447: * .stabs: For stabs with string names ! 448: * .stabd: For stabs for line numbers or bracketing, ! 449: * without a string name, without ! 450: * a final expression. The value of the ! 451: * final expression is taken to be the current ! 452: * location counter, and is patched by the 2nd pass ! 453: * ! 454: * .stab{<expr>,}*8,<expr>, <expr>, <expr>, <expr> ! 455: * .stabn <expr>, <expr>, <expr>, <expr> ! 456: * .stabs STRING, <expr>, <expr>, <expr>, <expr> ! 457: * .stabd <expr>, <expr>, <expr> # . ! 458: */ ! 459: case ISTAB: { ! 460: stabname = ".stab"; ! 461: if (passno == 2) goto errorfix; ! 462: stpt = (struct symtab *)yylval; ! 463: /* ! 464: * Make a pointer to the .stab slot. ! 465: * There is a pointer in the way (stpt), and ! 466: * tokptr points to the next token. ! 467: */ ! 468: stabstart = tokptr; ! 469: (char *)stabstart -= sizeof(struct symtab *); ! 470: (char *)stabstart -= sizeof(toktype); ! 471: shift; ! 472: for (argcnt = 0; argcnt < 8; argcnt++){ ! 473: expr(locxp, val); ! 474: stpt->name[argcnt] = locxp->xvalue; ! 475: shiftover(CM); ! 476: } ! 477: tailstab: ! 478: expr(locxp, val); ! 479: if (! (locxp->xvalue & STABTYPS)){ ! 480: yyerror("Invalid type in %s",stabname); ! 481: goto errorfix; ! 482: } ! 483: stpt->ptype = locxp->xvalue; ! 484: shiftover(CM); ! 485: expr(locxp, val); ! 486: stpt->other = locxp->xvalue; ! 487: shiftover(CM); ! 488: expr(locxp, val); ! 489: stpt->desc = locxp->xvalue; ! 490: shiftover(CM); ! 491: exprisname = 0; ! 492: expr(locxp, val); ! 493: p = locxp->xname; ! 494: if (p == NULL) { /*absolute expr to begin with*/ ! 495: stpt->value = locxp->xvalue; ! 496: stpt->index = dotp - usedot; ! 497: if (exprisname){ ! 498: switch(stpt->ptype){ ! 499: case N_GSYM: ! 500: case N_FNAME: ! 501: case N_RSYM: ! 502: case N_SSYM: ! 503: case N_LSYM: ! 504: case N_PSYM: ! 505: case N_BCOMM: ! 506: case N_ECOMM: ! 507: case N_LENG: ! 508: stpt->tag = STABFIXED; ! 509: break; ! 510: default: ! 511: stpt->tag = STABFLOATING; ! 512: break; ! 513: } ! 514: } else ! 515: stpt->tag = STABFIXED; ! 516: } ! 517: else { /*really have a name*/ ! 518: stpt->dest = locxp->xname; ! 519: stpt->index = p->index; ! 520: stpt->type = p->type | STABFLAG; ! 521: /* ! 522: * We will assign a more accruate ! 523: * guess of locxp's location when ! 524: * we sort the symbol table ! 525: * The final value of value is ! 526: * given by stabfix() ! 527: */ ! 528: stpt->tag = STABFLOAT; ! 529: #ifdef DSTAB ! 530: printf("FORWARD REF FOR %s...\n", stabname); ! 531: printf("value (xname) = %x value(value(xname) = %x\n", ! 532: stpt->dest,stpt->dest->value); ! 533: printf("name: %.8s\n\n", ! 534: (stpt->dest)->name); ! 535: #endif ! 536: } ! 537: /* ! 538: * tokptr now points at one token beyond ! 539: * the current token stored in val and yylval, ! 540: * which are the next tokens after the end of ! 541: * this .stab directive. This next token must ! 542: * be either a SEMI or NL, so is of width just ! 543: * one. Therefore, to point to the next token ! 544: * after the end of this stab, just back up one.. ! 545: */ ! 546: buildskip(stabstart, (char *)tokptr - sizeof(toktype)); ! 547: break; /*end of the .stab*/ ! 548: } /*end of ISTAB*/ ! 549: ! 550: case ISTABDOT: { ! 551: stabname = ".stabd"; ! 552: stpt = (struct symtab *)yylval; ! 553: /* ! 554: * We clobber everything after the ! 555: * .stabd and its pointer... we MUST ! 556: * be able to get back to this .stabd ! 557: * so that we can resolve its final value ! 558: */ ! 559: stabstart = tokptr; ! 560: shift; /*over the ISTABDOT*/ ! 561: if (passno == 1){ ! 562: expr(locxp, val); ! 563: if (! (locxp->xvalue & STABTYPS)){ ! 564: yyerror("Invalid type in .stabd"); ! 565: goto errorfix; ! 566: } ! 567: stpt->ptype = locxp->xvalue; ! 568: shiftover(CM); ! 569: expr(locxp, val); ! 570: stpt->other = locxp->xvalue; ! 571: shiftover(CM); ! 572: expr(locxp, val); ! 573: stpt->desc = locxp->xvalue; ! 574: /* ! 575: * ! 576: * Now, clobber everything but the ! 577: * .stabd pseudo and the pointer ! 578: * to its symbol table entry ! 579: * tokptr points to the next token, ! 580: * build the skip up to this ! 581: */ ! 582: buildskip(stabstart, (toktype *)tokptr - sizeof(toktype)); ! 583: } ! 584: /* ! 585: * pass 1: Assign a good guess for its position ! 586: * (ensures they are sorted into right place)/ ! 587: * pass 2: Fix the actual value ! 588: */ ! 589: stpt->value = dotp->xvalue; ! 590: stpt->index = dotp - usedot; ! 591: stpt->tag = STABFLOAT; /*although it has no effect in pass 2*/ ! 592: break; ! 593: } /*end of case ISTABDOT*/ ! 594: ! 595: case ISTABNONE: stabname = ".stabn"; goto shortstab; ! 596: ! 597: case ISTABSTR: { stabname = ".stabs"; ! 598: shortstab: ! 599: auxval = val; ! 600: if (passno == 2) goto errorfix; ! 601: stpt = (struct symtab *)yylval; ! 602: stabstart = tokptr; ! 603: (char *)stabstart -= sizeof(struct symtab *); ! 604: (char *)stabstart -= sizeof(toktype); ! 605: shift; ! 606: if (auxval == ISTABSTR){ ! 607: stringp = (struct strdesc *)yylval; ! 608: shiftover(STRING); ! 609: auxval = stringp->str_lg > NCPS ? NCPS : stringp->str_lg; ! 610: shiftover(CM); ! 611: } else { ! 612: stringp = &(strbuf[2]); ! 613: auxval = NCPS; ! 614: } ! 615: movestr(stpt->name, stringp->str, auxval); ! 616: goto tailstab; ! 617: break; ! 618: } /*end of case ISTABSTR and ISTABN*/ ! 619: ! 620: case ICOMM: /* .comm <name> , <expr> */ ! 621: case ILCOMM: { /* .lcomm <name> , <expr> */ ! 622: auxval = val; ! 623: shift; ! 624: np = (struct symtab *)yylval; ! 625: shiftover(NAME); ! 626: shiftover(CM); ! 627: expr(locxp, val); ! 628: ! 629: if (locxp->xtype != XABS) ! 630: yyerror("comm size not absolute"); ! 631: if (passno==1 && (np->type&XTYPE)!=XUNDEF) ! 632: yyerror("Redefinition of %.8s", np->name); ! 633: if (passno==1) { ! 634: np->value = locxp->xvalue; ! 635: if (auxval == ICOMM) ! 636: np->type |= XXTRN; ! 637: else { ! 638: np->type &= ~XTYPE; ! 639: np->type |= XBSS; ! 640: } ! 641: } ! 642: break; ! 643: } /*end of case ICOMM and ILCOMM*/ ! 644: ! 645: case IALIGN: { /* .align <expr> */ ! 646: stpt = (struct symtab *)yylval; ! 647: shift; ! 648: expr(locxp, val); ! 649: jalign(locxp, stpt); ! 650: break; ! 651: } /*end of case IALIGN*/ ! 652: ! 653: case INST0: { /* instructions w/o arguments*/ ! 654: insout(yylval, 0, 0); ! 655: shift; ! 656: break; ! 657: } /*end of case INST0*/ ! 658: ! 659: case INSTn: /* instructions with arguments*/ ! 660: case IJXXX: { /* UNIX style jump instructions */ ! 661: auxval = val; ! 662: seg_type = yylval; ! 663: /* ! 664: * Code to process an argument list ! 665: */ ! 666: ap = arglist; ! 667: xp = explist; /*must be set before bring in the first token*/ ! 668: ! 669: shift; /*and bring in the first token for the arg list*/ ! 670: ! 671: for (argcnt = 1; argcnt <= 6; argcnt++, ap++){ ! 672: /* ! 673: * code to process an argument proper ! 674: */ ! 675: sawindex = sawmul = sawsize = 0; ! 676: { ! 677: switch(val) { ! 678: ! 679: default: { ! 680: disp: ! 681: if( !(INTOKSET(val, ! 682: EBEGOPS ! 683: +YUKKYEXPRBEG ! 684: +SAFEEXPRBEG)) ) { ! 685: ERROR("expression expected"); ! 686: } ! 687: expr(ap->xp,val); ! 688: overdisp: ! 689: if ( val == LP || sawsize){ ! 690: shiftover(LP); ! 691: findreg(regno); ! 692: shiftover(RP); ! 693: ap->atype = ADISP; ! 694: ap->areg1 = regno; ! 695: } else { ! 696: ap->atype = AEXP; ! 697: ap->areg1 = 0; ! 698: } ! 699: goto index; ! 700: } /*end of the default action*/ ! 701: ! 702: case SIZESPEC: { ! 703: sizespec: ! 704: sawsize = yylval; ! 705: shift; ! 706: goto disp; ! 707: } ! 708: ! 709: case REG: ! 710: case REGOP: { ! 711: findreg(regno); ! 712: ap->atype = AREG; ! 713: ap->areg1 = regno; ! 714: break; ! 715: } /*end of case REG*/ ! 716: ! 717: case MUL: { ! 718: sawmul = 1; ! 719: shift; ! 720: if (val == LP) goto base; ! 721: if (val == LITOP) goto imm; ! 722: if (val == SIZESPEC) goto sizespec; ! 723: if (INTOKSET(val, ! 724: EBEGOPS ! 725: +YUKKYEXPRBEG ! 726: +SAFEEXPRBEG)) goto disp; ! 727: ERROR("expression, '(' or '$' expected"); ! 728: break; ! 729: } /*end of case MUL*/ ! 730: ! 731: case LP: { ! 732: base: ! 733: shift; /*consume the LP*/ ! 734: /* ! 735: * hack the ambiguity of ! 736: * movl (expr) (rn), ... ! 737: * note that (expr) could also ! 738: * be (rn) (by special hole in the ! 739: * grammar), which we ensure ! 740: * means register indirection, instead ! 741: * of an expression with value n ! 742: */ ! 743: if (val != REG && val != REGOP){ ! 744: droppedLP = 1; ! 745: val = exprparse(val, &(ap->xp)); ! 746: droppedLP = 0; ! 747: goto overdisp; ! 748: } ! 749: findreg(regno); ! 750: shiftover(RP); ! 751: if (val == PLUS){ ! 752: shift; ! 753: ap->atype = AINCR; ! 754: } else ! 755: ap->atype = ABASE; ! 756: ap->areg1 = regno; ! 757: goto index; ! 758: } /*end of case LP*/ ! 759: ! 760: case LITOP: { ! 761: imm: ! 762: shift; ! 763: expr(locxp, val); ! 764: ap->atype = AIMM; ! 765: ap->areg1 = 0; ! 766: ap->xp = locxp; ! 767: goto index; ! 768: } /*end of case LITOP*/ ! 769: ! 770: case MP: { ! 771: shift; /* -(reg) */ ! 772: findreg(regno); ! 773: shiftover(RP); ! 774: ap->atype = ADECR; ! 775: ap->areg1 = regno; ! 776: index: /*look for [reg] */ ! 777: if (val == LB){ ! 778: shift; ! 779: findreg(regno); ! 780: shiftover(RB); ! 781: sawindex = 1; ! 782: ap->areg2 = regno; ! 783: } ! 784: break; ! 785: } /*end of case MP*/ ! 786: ! 787: } /*end of the switch to process an arg*/ ! 788: } /*end of processing an argument*/ ! 789: ! 790: if (sawmul){ ! 791: /* ! 792: * Make a concession for *(%r) ! 793: * meaning *0(%r) ! 794: */ ! 795: if (ap->atype == ABASE) { ! 796: ap->atype = ADISP; ! 797: xp->xtype = XABS; ! 798: xp->xvalue = 0; ! 799: xp->xloc = 0; ! 800: ap->xp = xp++; ! 801: } ! 802: ap->atype |= ASTAR; ! 803: sawmul = 0; ! 804: } ! 805: if (sawindex){ ! 806: ap->atype |= AINDX; ! 807: sawindex = 0; ! 808: } ! 809: ap->dispsize = sawsize == 0 ? d124 : sawsize; ! 810: if (val != CM) break; ! 811: shiftover(CM); ! 812: } /*processing all the arguments*/ ! 813: ! 814: if (argcnt > 6){ ! 815: yyerror("More than 6 arguments"); ! 816: goto errorfix; ! 817: } ! 818: ! 819: insout(seg_type, arglist, ! 820: auxval == INSTn ? argcnt : - argcnt); ! 821: break; ! 822: } /*end of case INSTn and IJXXX*/ ! 823: ! 824: case IFLOAT: curlen = 4; goto floatlist; ! 825: ! 826: case IDOUBLE: { ! 827: curlen = 8; ! 828: floatlist: ! 829: /* ! 830: * eat a list of floating point numbers ! 831: */ ! 832: shift; ! 833: if (val == FLTNUM){ ! 834: do{ ! 835: if (val == CM) shift; ! 836: if (val != FLTNUM) { ! 837: ERROR("floating number expected"); ! 838: } ! 839: dotp->xvalue += curlen; ! 840: if (passno == 2) ! 841: fwrite( ! 842: &(((struct exp *)yylval)->doubval.dvalue), ! 843: 1, curlen, txtfil); ! 844: shift; ! 845: } while (val == CM); ! 846: } ! 847: break; ! 848: } /*end of case IFLOAT and IDOUBLE*/ ! 849: ! 850: } /*end of the switch for looking at each reserved word*/ ! 851: ! 852: /* ! 853: * If got here, then one has no syntax errors! ! 854: */ ! 855: continue; ! 856: ! 857: /* ! 858: * got here by either requesting to skip to the ! 859: * end of this statement, or by erroring out and ! 860: * wanting to apply panic mode recovery ! 861: */ ! 862: errorfix: { ! 863: #ifdef DEBUG ! 864: if (debug) ! 865: printf("Discarding tokens from here:\n"); ! 866: #endif ! 867: while ( (val != NL) ! 868: && (val != SEMI) ! 869: && (val != PARSEEOF) ! 870: ){ ! 871: #ifdef DEBUG ! 872: if (debug) ! 873: printf("****>>>>\t"); ! 874: #endif ! 875: shift; ! 876: } ! 877: if (val == NL) ! 878: lineno++; ! 879: #ifdef DEBUG ! 880: if (debug) ! 881: printf("To here.\n"); ! 882: #endif ! 883: shift; ! 884: } ! 885: ! 886: } /*end of the loop to read the entire file, line by line*/ ! 887: ! 888: ! 889: } /*end of yyparse*/ ! 890: ! 891: /* ! 892: * Process a register declaration of the form ! 893: * % <expr> ! 894: * ! 895: * Note: ! 896: * The scanner has already processed funny registers of the form ! 897: * %dd[+-]*, where dd is a decimal number in the range 00 to 15 (optional ! 898: * preceding zero digit). If there was any space between the % and ! 899: * the digit, the scanner wouldn't have recognized it, so we ! 900: * hack it out here. ! 901: */ ! 902: int funnyreg(val, regnoback) /*what the read head will sit on*/ ! 903: int val; /*what the read head is sitting on*/ ! 904: int *regnoback; /*call by return*/ ! 905: { ! 906: register struct exp *locxp; ! 907: struct exp *loc1xp; ! 908: struct exp **ptrloc1xp = & loc1xp; ! 909: ! 910: expr(locxp, val); /*and leave the current read head with value*/ ! 911: if ( (passno == 2) && ! 912: ( locxp->xtype & XTYPE != XABS ! 913: || locxp->xvalue < 0 ! 914: || locxp->xvalue >= 16 ! 915: ) ! 916: ){ ! 917: yyerror("Illegal register"); ! 918: return(0); ! 919: } ! 920: *regnoback = locxp->xvalue; ! 921: return(val); ! 922: } ! 923: ! 924: /* VARARGS 1*/ ! 925: yyerror(s, a1, a2) ! 926: char *s; ! 927: { ! 928: FILE *sink; ! 929: ! 930: #ifdef DEBUG ! 931: sink = stdout; ! 932: #else ! 933: sink = stderr; ! 934: #endif ! 935: ! 936: if (anyerrs == 0 && ! silent) ! 937: fprintf(sink, "Assembler:\n"); ! 938: anyerrs++; ! 939: if (silent) return; ! 940: ! 941: fprintf(sink, "\"%s\", line %d: ", dotsname, lineno); ! 942: fprintf(sink, s, a1, a2); ! 943: fprintf(sink, "\n"); ! 944: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.