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