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