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: }