|
|
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.2 (Berkeley) 6/19/85"; ! 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_GSYM: ! 544: case N_FNAME: ! 545: case N_RSYM: ! 546: case N_SSYM: ! 547: case N_LSYM: ! 548: case N_PSYM: ! 549: case N_BCOMM: ! 550: case N_ECOMM: ! 551: case N_LENG: ! 552: stpt->s_tag = STABFIXED; ! 553: break; ! 554: default: ! 555: stpt->s_tag = STABFLOATING; ! 556: break; ! 557: } ! 558: } else ! 559: stpt->s_tag = STABFIXED; ! 560: } ! 561: else { /*really have a name*/ ! 562: stpt->s_dest = locxp->e_xname; ! 563: stpt->s_index = p->s_index; ! 564: stpt->s_type = p->s_type | STABFLAG; ! 565: /* ! 566: * We will assign a more accruate ! 567: * guess of locxp's location when ! 568: * we sort the symbol table ! 569: * The final value of value is ! 570: * given by stabfix() ! 571: */ ! 572: /* ! 573: * For exprs of the form (name + value) one needs to remember locxp->e_xvalue ! 574: * for use in stabfix. The right place to keep this is in stpt->s_value ! 575: * however this gets corrupted at an unknown point. ! 576: * As a bandaid hack the value is preserved in s_desc and s_other (a ! 577: * short and a char). This destroys these two values and will ! 578: * be fixed. May 19 ,1983 Alastair Fyfe ! 579: */ ! 580: if(locxp->e_xvalue) { ! 581: stpt->s_other = (locxp->e_xvalue >> 16); ! 582: stpt->s_desc = (locxp->e_xvalue & 0x0000ffff); ! 583: stpt->s_tag = STABFLOATING; ! 584: } ! 585: } ! 586: /* ! 587: * tokptr now points at one token beyond ! 588: * the current token stored in val and yylval, ! 589: * which are the next tokens after the end of ! 590: * this .stab directive. This next token must ! 591: * be either a SEMI or NL, so is of width just ! 592: * one. Therefore, to point to the next token ! 593: * after the end of this stab, just back up one.. ! 594: */ ! 595: buildskip(stabstart, (bytetoktype *)tokptr - sizeof(bytetoktype)); ! 596: break; /*end of the .stab*/ ! 597: ! 598: case ISTABDOT: ! 599: stabname = ".stabd"; ! 600: stpt = (struct symtab *)yylval; ! 601: /* ! 602: * We clobber everything after the ! 603: * .stabd and its pointer... we MUST ! 604: * be able to get back to this .stabd ! 605: * so that we can resolve its final value ! 606: */ ! 607: stabstart = tokptr; ! 608: shift; /*over the ISTABDOT*/ ! 609: if (passno == 1){ ! 610: expr(locxp, val); ! 611: if (! (locxp->e_xvalue & STABTYPS)){ ! 612: yyerror("Invalid type in .stabd"); ! 613: goto errorfix; ! 614: } ! 615: stpt->s_ptype = locxp->e_xvalue; ! 616: shiftover(CM); ! 617: expr(locxp, val); ! 618: stpt->s_other = locxp->e_xvalue; ! 619: shiftover(CM); ! 620: expr(locxp, val); ! 621: stpt->s_desc = locxp->e_xvalue; ! 622: /* ! 623: * ! 624: * Now, clobber everything but the ! 625: * .stabd pseudo and the pointer ! 626: * to its symbol table entry ! 627: * tokptr points to the next token, ! 628: * build the skip up to this ! 629: */ ! 630: buildskip(stabstart, (bytetoktype *)tokptr - sizeof(bytetoktype)); ! 631: } ! 632: /* ! 633: * pass 1: Assign a good guess for its position ! 634: * (ensures they are sorted into right place)/ ! 635: * pass 2: Fix the actual value ! 636: */ ! 637: stpt->s_value = dotp->e_xvalue; ! 638: stpt->s_index = dotp - usedot; ! 639: stpt->s_tag = STABFLOATING; /*although it has no effect in pass 2*/ ! 640: break; ! 641: ! 642: case ISTABNONE: stabname = ".stabn"; goto shortstab; ! 643: ! 644: case ISTABSTR: stabname = ".stabs"; ! 645: shortstab: ! 646: auxval = val; ! 647: if (passno == 2) goto errorfix; ! 648: stpt = (struct symtab *)yylval; ! 649: stabstart = tokptr; ! 650: (bytetoktype *)stabstart -= sizeof(struct symtab *); ! 651: (bytetoktype *)stabstart -= sizeof(bytetoktype); ! 652: shift; ! 653: if (auxval == ISTABSTR){ ! 654: stringp = (struct strdesc *)yylval; ! 655: shiftover(STRING); ! 656: stpt->s_name = (char *)stringp; ! 657: /* ! 658: * We want the trailing null included in this string. ! 659: * We utilize the cheat the string scanner used, ! 660: * and merely increment the string length ! 661: */ ! 662: stringp->sd_strlen += 1; ! 663: shiftover(CM); ! 664: } else { ! 665: stpt->s_name = (char *)savestr("\0", 0, STR_BOTH); ! 666: } ! 667: goto tailstab; ! 668: break; ! 669: ! 670: case ICOMM: /* .comm <name> , <expr> */ ! 671: case ILCOMM: /* .lcomm <name> , <expr> */ ! 672: auxval = val; ! 673: shift; ! 674: np = (struct symtab *)yylval; ! 675: shiftover(NAME); ! 676: shiftover(CM); ! 677: expr(locxp, val); ! 678: ! 679: if ( (locxp->e_xtype & XTYPE) != XABS) /* tekmdp */ ! 680: yyerror("comm size not absolute"); ! 681: if (passno == 1 && (np->s_type&XTYPE) != XUNDEF) ! 682: yyerror("Redefinition of %s", FETCHNAME(np)); ! 683: if (passno==1) { ! 684: np->s_value = locxp->e_xvalue; ! 685: if (auxval == ICOMM) ! 686: np->s_type |= XXTRN; ! 687: else { ! 688: np->s_type &= ~XTYPE; ! 689: np->s_type |= XBSS; ! 690: } ! 691: } ! 692: break; ! 693: ! 694: case IALIGN: /* .align <expr> */ ! 695: stpt = (struct symtab *)yylval; ! 696: shift; ! 697: expr(locxp, val); ! 698: jalign(locxp, stpt); ! 699: break; ! 700: ! 701: case INST0: /* instructions w/o arguments*/ ! 702: incasetable = 0; ! 703: insout(yyopcode, (struct arg *)0, 0); ! 704: shift; ! 705: break; ! 706: ! 707: case INSTn: /* instructions with arguments*/ ! 708: case IJXXX: /* UNIX style jump instructions */ ! 709: auxval = val; ! 710: /* ! 711: * Code to process an argument list ! 712: */ ! 713: ap = arglist; ! 714: xp = explist; ! 715: ! 716: shift; /* bring in the first token for the arg list*/ ! 717: ! 718: for (argcnt = 1; argcnt <= 6; argcnt++, ap++){ ! 719: /* ! 720: * code to process an argument proper ! 721: */ ! 722: sawindex = sawmul = sawsize = 0; ! 723: { ! 724: switch(val) { ! 725: ! 726: default: ! 727: disp: ! 728: if( !(INTOKSET(val, ! 729: EBEGOPS ! 730: +YUKKYEXPRBEG ! 731: +SAFEEXPRBEG)) ) { ! 732: ERROR("expression expected"); ! 733: } ! 734: expr(ap->a_xp,val); ! 735: overdisp: ! 736: if ( val == LP || sawsize){ ! 737: shiftover(LP); ! 738: findreg(regno); ! 739: shiftover(RP); ! 740: ap->a_atype = ADISP; ! 741: ap->a_areg1 = regno; ! 742: } else { ! 743: ap->a_atype = AEXP; ! 744: ap->a_areg1 = 0; ! 745: } ! 746: goto index; ! 747: ! 748: case SIZESPEC: ! 749: sizespec: ! 750: sawsize = yylval; ! 751: shift; ! 752: goto disp; ! 753: ! 754: case REG: ! 755: case REGOP: ! 756: findreg(regno); ! 757: ap->a_atype = AREG; ! 758: ap->a_areg1 = regno; ! 759: break; ! 760: ! 761: case MUL: ! 762: sawmul = 1; ! 763: shift; ! 764: if (val == LP) goto base; ! 765: if (val == LITOP) goto imm; ! 766: if (val == SIZESPEC) goto sizespec; ! 767: if (INTOKSET(val, ! 768: EBEGOPS ! 769: +YUKKYEXPRBEG ! 770: +SAFEEXPRBEG)) goto disp; ! 771: ERROR("expression, '(' or '$' expected"); ! 772: break; ! 773: ! 774: case LP: ! 775: base: ! 776: shift; /*consume the LP*/ ! 777: /* ! 778: * hack the ambiguity of ! 779: * movl (expr) (rn), ... ! 780: * note that (expr) could also ! 781: * be (rn) (by special hole in the ! 782: * grammar), which we ensure ! 783: * means register indirection, instead ! 784: * of an expression with value n ! 785: */ ! 786: if (val != REG && val != REGOP){ ! 787: droppedLP = 1; ! 788: val = exprparse(val, &(ap->a_xp)); ! 789: droppedLP = 0; ! 790: goto overdisp; ! 791: } ! 792: findreg(regno); ! 793: shiftover(RP); ! 794: if (val == PLUS){ ! 795: shift; ! 796: ap->a_atype = AINCR; ! 797: } else ! 798: ap->a_atype = ABASE; ! 799: ap->a_areg1 = regno; ! 800: goto index; ! 801: ! 802: case LITOP: ! 803: imm: ! 804: shift; ! 805: expr(locxp, val); ! 806: ap->a_atype = AIMM; ! 807: ap->a_areg1 = 0; ! 808: ap->a_xp = locxp; ! 809: goto index; ! 810: ! 811: case MP: ! 812: shift; /* -(reg) */ ! 813: findreg(regno); ! 814: shiftover(RP); ! 815: ap->a_atype = ADECR; ! 816: ap->a_areg1 = regno; ! 817: index: /*look for [reg] */ ! 818: if (val == LB){ ! 819: shift; ! 820: findreg(regno); ! 821: shiftover(RB); ! 822: sawindex = 1; ! 823: ap->a_areg2 = regno; ! 824: } ! 825: break; ! 826: ! 827: } /*end of the switch to process an arg*/ ! 828: } /*end of processing an argument*/ ! 829: ! 830: if (sawmul){ ! 831: /* ! 832: * Make a concession for *(%r) ! 833: * meaning *0(%r) ! 834: */ ! 835: if (ap->a_atype == ABASE) { ! 836: ap->a_atype = ADISP; ! 837: xp->e_xtype = XABS; ! 838: xp->e_number = Znumber; ! 839: xp->e_number.num_tag = TYPL; ! 840: xp->e_xloc = 0; ! 841: ap->a_xp = xp++; ! 842: } ! 843: ap->a_atype |= ASTAR; ! 844: sawmul = 0; ! 845: } ! 846: if (sawindex){ ! 847: ap->a_atype |= AINDX; ! 848: sawindex = 0; ! 849: } ! 850: ap->a_dispsize = sawsize == 0 ? d124 : sawsize; ! 851: if (val != CM) break; ! 852: shiftover(CM); ! 853: } /*processing all the arguments*/ ! 854: ! 855: if (argcnt > 6){ ! 856: yyerror("More than 6 arguments"); ! 857: goto errorfix; ! 858: } ! 859: ! 860: /* ! 861: * See if this is a case instruction, ! 862: * so we can set up tests on the following ! 863: * vector of branch displacements ! 864: */ ! 865: if (yyopcode.Op_eopcode == CORE){ ! 866: switch(yyopcode.Op_popcode){ ! 867: case 0x8f: /* caseb */ ! 868: case 0xaf: /* casew */ ! 869: case 0xcf: /* casel */ ! 870: incasetable++; ! 871: break; ! 872: default: ! 873: incasetable = 0; ! 874: break; ! 875: } ! 876: } ! 877: ! 878: insout(yyopcode, arglist, ! 879: auxval == INSTn ? argcnt : - argcnt); ! 880: break; ! 881: ! 882: case IQUAD: toconv = TYPQ; goto bignumlist; ! 883: case IOCTA: toconv = TYPO; goto bignumlist; ! 884: ! 885: case IFFLOAT: toconv = TYPF; goto bignumlist; ! 886: case IDFLOAT: toconv = TYPD; goto bignumlist; ! 887: case IGFLOAT: toconv = TYPG; goto bignumlist; ! 888: case IHFLOAT: toconv = TYPH; goto bignumlist; ! 889: bignumlist: ! 890: /* ! 891: * eat a list of non 32 bit numbers. ! 892: * IQUAD and IOCTA can, possibly, return ! 893: * INT's, if the numbers are "small". ! 894: * ! 895: * The value of the numbers is coming back ! 896: * as an expression, NOT in yybignum. ! 897: */ ! 898: shift; /* over the opener */ ! 899: if ((val == BIGNUM) || (val == INT)){ ! 900: do{ ! 901: if ((val != BIGNUM) && (val != INT)){ ! 902: ERROR(ty_float[toconv] ! 903: ? "floating number expected" ! 904: : "integer number expected" ); ! 905: } ! 906: dotp->e_xvalue += ty_nbyte[toconv]; ! 907: if (passno == 2){ ! 908: bignumwrite( ! 909: ((struct exp *)yylval)->e_number, ! 910: toconv); ! 911: } ! 912: xp = explist; ! 913: shift; /* over this number */ ! 914: if (auxval = (val == CM)) ! 915: shift; /* over the comma */ ! 916: } while (auxval); /* as long as there are commas */ ! 917: } ! 918: break; ! 919: /* end of the case for initialized big numbers */ ! 920: } /*end of the switch for looking at each reserved word*/ ! 921: ! 922: continue; ! 923: ! 924: errorfix: ! 925: /* ! 926: * got here by either requesting to skip to the ! 927: * end of this statement, or by erroring out and ! 928: * wanting to apply panic mode recovery ! 929: */ ! 930: while ( (val != NL) ! 931: && (val != SEMI) ! 932: && (val != PARSEEOF) ! 933: ){ ! 934: shift; ! 935: } ! 936: if (val == NL) ! 937: lineno++; ! 938: shift; ! 939: ! 940: } /*end of the loop to read the entire file, line by line*/ ! 941: ! 942: } /*end of yyparse*/ ! 943: ! 944: /* ! 945: * Process a register declaration of the form ! 946: * % <expr> ! 947: * ! 948: * Note: ! 949: * The scanner has already processed funny registers of the form ! 950: * %dd[+-]*, where dd is a decimal number in the range 00 to 15 (optional ! 951: * preceding zero digit). If there was any space between the % and ! 952: * the digit, the scanner wouldn't have recognized it, so we ! 953: * hack it out here. ! 954: */ ! 955: inttoktype funnyreg(val, regnoback) /*what the read head will sit on*/ ! 956: inttoktype val; /*what the read head is sitting on*/ ! 957: int *regnoback; /*call by return*/ ! 958: { ! 959: reg struct exp *locxp; ! 960: struct exp *loc1xp; ! 961: struct exp **ptrloc1xp = & loc1xp; ! 962: ! 963: expr(locxp, val); /*and leave the current read head with value*/ ! 964: if ( (passno == 2) && ! 965: ( (locxp->e_xtype & XTYPE) != XABS ! 966: || (locxp->e_xvalue < 0) ! 967: || (locxp->e_xvalue >= 16) ! 968: ) ! 969: ){ ! 970: yyerror("Illegal register"); ! 971: return(0); ! 972: } ! 973: *regnoback = locxp->e_xvalue; ! 974: return(val); ! 975: } ! 976: /* ! 977: * Shift over error ! 978: */ ! 979: shiftoerror(token) ! 980: int token; ! 981: { ! 982: char *tok_to_name(); ! 983: yyerror("%s expected", tok_to_name(token)); ! 984: } ! 985: ! 986: /*VARARGS1*/ ! 987: yyerror(s, a1, a2,a3,a4,a5) ! 988: char *s; ! 989: { ! 990: ! 991: #define sink stdout ! 992: ! 993: if (anyerrs == 0 && anywarnings == 0 && ! silent) ! 994: fprintf(sink, "Assembler:\n"); ! 995: anyerrs++; ! 996: if (silent) ! 997: return; ! 998: fprintf(sink, "\"%s\", line %d: ", dotsname, lineno); ! 999: fprintf(sink, s, a1, a2,a3,a4,a5); ! 1000: fprintf(sink, "\n"); ! 1001: #undef sink ! 1002: } ! 1003: ! 1004: /*VARARGS1*/ ! 1005: yywarning(s, a1, a2,a3,a4,a5) ! 1006: char *s; ! 1007: { ! 1008: #define sink stdout ! 1009: if (anyerrs == 0 && anywarnings == 0 && ! silent) ! 1010: fprintf(sink, "Assembler:\n"); ! 1011: anywarnings++; ! 1012: if (silent) ! 1013: return; ! 1014: fprintf(sink, "\"%s\", line %d: WARNING: ", dotsname, lineno); ! 1015: fprintf(sink, s, a1, a2,a3,a4,a5); ! 1016: fprintf(sink, "\n"); ! 1017: #undef sink ! 1018: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.