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