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