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