129832Ssam /* 229832Ssam * Copyright (c) 1982 Regents of the University of California 329832Ssam */ 429832Ssam #ifndef lint 529832Ssam static char sccsid[] = "@(#)asparse.c 4.17 7/1/83"; 629832Ssam #endif not lint 729832Ssam 829832Ssam #include <stdio.h> 929832Ssam #include "as.h" 1029832Ssam #include "asscan.h" 1129832Ssam #include "assyms.h" 1229832Ssam #include "asexpr.h" 1329832Ssam 1429832Ssam int lgensym[10]; 1529832Ssam char genref[10]; 1629832Ssam 1729832Ssam long bitfield; 1829832Ssam int bitoff; 1929832Ssam int curlen; /* current length of literals */ 2029832Ssam int printblank; 2129832Ssam 2229832Ssam /* 2329832Ssam * The following three variables are communication between various 2429832Ssam * modules to special case a number of things. They are properly 2529832Ssam * categorized as hacks. 2629832Ssam */ 2729832Ssam extern struct symtab *lastnam;/*last name seen by the lexical analyzer*/ 2829832Ssam int exprisname; /*last factor in an expression was a name*/ 2929832Ssam int droppedLP; /*one is analyzing an expression beginning with*/ 3029832Ssam /*a left parenthesis, which has already been*/ 3129832Ssam /*shifted. (Used to parse (<expr>)(rn)*/ 3229832Ssam 3329832Ssam char yytext[NCPName+2]; /*the lexical image*/ 3429832Ssam int yylval; /*the lexical value; sloppy typing*/ 3529832Ssam u_char yyopcode; /* lexical value for an opcode */ 3629832Ssam Bignum yybignum; /* lexical value for a big number */ 3729832Ssam int num_type; /* type of bignums */ 3829832Ssam /* 3929832Ssam * Expression and argument managers 4029832Ssam */ 4129832Ssam struct exp *xp; /*next free expression slot, used by expr.c*/ 4229832Ssam struct exp explist[NEXP]; /*max of 20 expressions in one opcode*/ 4329832Ssam struct arg arglist[NARG]; /*building up operands in instructions*/ 4429832Ssam /* 4529832Ssam * Sets to accelerate token discrimination 4629832Ssam */ 4729832Ssam char tokensets[(LASTTOKEN) - (FIRSTTOKEN) + 1]; 4829832Ssam 4929832Ssam static char UDotsname[64]; /*name of the assembly source*/ 5029832Ssam 5129832Ssam yyparse() 5229832Ssam { 5329832Ssam reg struct exp *locxp; 5429832Ssam /* 5529832Ssam * loc1xp and ptrloc1xp are used in the 5629832Ssam * expression lookahead 5729832Ssam */ 5829832Ssam struct exp *loc1xp; /*must be non register*/ 5929832Ssam struct exp **ptrloc1xp = & loc1xp; 6029832Ssam struct exp *pval; /*hacking expr:expr*/ 6129832Ssam 6229832Ssam reg struct symtab *np; 6329832Ssam reg int argcnt; 6429832Ssam 6529832Ssam reg inttoktype val; /*what yylex gives*/ 6629832Ssam reg inttoktype auxval; /*saves val*/ 6729832Ssam 6829832Ssam reg struct arg *ap; /*first free argument*/ 6929832Ssam 7029832Ssam reg struct symtab *p; 7129832Ssam reg struct symtab *stpt; 7229832Ssam 7329832Ssam struct strdesc *stringp; /*handles string lists*/ 7429832Ssam 7529832Ssam int regno; /*handles arguments*/ 7629832Ssam int *ptrregno = ®no; 7729832Ssam int sawmul; /*saw * */ 7829832Ssam int sawindex; /*saw [rn]*/ 7929832Ssam int sawsize; 8029832Ssam int seg_type; /*the kind of segment: data or text*/ 8129832Ssam int seg_number; /*the segment number*/ 8229832Ssam int space_value; /*how much .space needs*/ 8329832Ssam int fill_rep; /*how many reps for .fill */ 8429832Ssam int rep_fill; /*the same - temprary */ 8529832Ssam int fill_size; /*how many bytes for .fill */ 8629832Ssam 8729832Ssam int field_width; /*how wide a field is to be*/ 8829832Ssam int field_value; /*the value to stuff in a field*/ 8929832Ssam char *stabname; /*name of stab dealing with*/ 9029832Ssam ptrall stabstart; /*where the stab starts in the buffer*/ 9129832Ssam int reloc_how; /* how to relocate expressions */ 9229832Ssam int incasetable; /* set if in a case table */ 9329832Ssam int j, k; 9429832Ssam char ch; 9529832Ssam int length; /* for printout */ 9629832Ssam union twolong 9729832Ssam { 9829832Ssam long lpart[2]; 9929832Ssam char strpart [8]; 10029832Ssam }fillval; 10129832Ssam 10229832Ssam 10329832Ssam incasetable = 0; 10429832Ssam xp = explist; 10529832Ssam ap = arglist; 10629832Ssam 10729832Ssam val = yylex(); 10829832Ssam 10929832Ssam while (val != PARSEEOF){ /* primary loop */ 11029832Ssam 11129832Ssam while (INTOKSET(val, LINSTBEGIN)){ 11229832Ssam if (val == INT) { 11329832Ssam int i = ((struct exp *)yylval)->e_xvalue; 11429832Ssam shift; 11529832Ssam if (val != COLON){ 11629832Ssam yyerror("Local label %d is not followed by a ':' for a label definition", 11729832Ssam i); 11829832Ssam goto errorfix; 11929832Ssam } 12029832Ssam if (i < 0 || i > 9) { 12129832Ssam yyerror("Local labels are 0-9"); 12229832Ssam goto errorfix; 12329832Ssam } 12429832Ssam (void)sprintf(yytext, "L%d\001%d", i, lgensym[i]); 12529832Ssam lgensym[i]++; 12629832Ssam genref[i] = 0; 12729832Ssam yylval = (int)*lookup(passno == 1); 12829832Ssam val = NAME; 12929832Ssam np = (struct symtab *)yylval; 13029832Ssam goto restlab; 13129832Ssam } 13229832Ssam if (val == NL){ 13329832Ssam lineno++; 13429832Ssam if (liston && (passno == 2) && (! endofsource)) 13529832Ssam { 13629832Ssam /* printing previous line & layout */ 13729832Ssam length = strlen (layout); 13829832Ssam fprintf (listfile, "%*.*s", LHEAD, LHEAD, layout); 13929832Ssam if (length <= LHEAD+LLEN) 14029832Ssam j = LLEN; 14129832Ssam else { /* break line at last blank */ 14229832Ssam j = LHEAD+LLEN; 14329832Ssam while(j>LHEAD && layout[j]!= ' ') 14429832Ssam j--; 14529832Ssam if(j == LHEAD) 14629832Ssam j = LLEN; 14729832Ssam else 14829832Ssam j -= LHEAD; 14929832Ssam } 15029832Ssam k = LHEAD+j; 15129832Ssam fprintf (listfile, "%-*.*s", LLEN, j, &layout[LHEAD]); 15229832Ssam fprintf (listfile, " "); 15329832Ssam do { 15429832Ssam ch = getc (source); 15529832Ssam putc (ch, listfile); 15629832Ssam } while (ch != '\n'); 15729832Ssam while (k < length) 15829832Ssam { 15929832Ssam fprintf (listfile, "%*s", LHEAD, ""); 16029832Ssam /* break line at last blank */ 16129832Ssam if(layout[k] == ' ') 16229832Ssam k++; 16329832Ssam if((j = k+LLEN) >= length) 16429832Ssam j = length; 16529832Ssam else 16629832Ssam while(j>k && layout[j]!= ' ') 16729832Ssam j--; 16829832Ssam if(j == k) 16929832Ssam j = LLEN; 17029832Ssam else 17129832Ssam j -= k; 17229832Ssam fprintf (listfile, "%-*.*s\n", j, j, &layout[k]); 17329832Ssam k += j; 17429832Ssam } 17529832Ssam k = 0; 17629832Ssam while (layout[k] != '\0') 17729832Ssam layout[k++] = '\0'; 17829832Ssam ch = getc (source); 17929832Ssam if (ch == EOF) 18029832Ssam { 18129832Ssam if (ind == ninfiles) 18229832Ssam endofsource = 1; 18329832Ssam else 18429832Ssam { 18529832Ssam source = fopen (innames[ind++], "r"); 18629832Ssam lineno = 1; 18729832Ssam } 18829832Ssam } 18929832Ssam else 19029832Ssam ungetc (ch, source); 19129832Ssam layoutpos = layout; 19232436Sbostic (void)sprintf (layoutpos, "%4ld ", lineno); 19329832Ssam layoutpos += 6; 19429832Ssam long_out (dotp->e_xvalue); 19529832Ssam if (dotp->e_xvalue >= datbase) 19632436Sbostic (void)sprintf (layoutpos," * "); 19729832Ssam else 19832436Sbostic (void)sprintf (layoutpos," "); 19929832Ssam layoutpos += 4; 20029832Ssam } 20129832Ssam shift; 20229832Ssam } else 20329832Ssam if (val == SEMI) 20429832Ssam shift; 20529832Ssam else { /*its a name, so we have a label or def */ 20629832Ssam if (val != NAME){ 20729832Ssam ERROR("Name expected for a label"); 20829832Ssam } 20929832Ssam np = (struct symtab *)yylval; 21029832Ssam shiftover(NAME); 21129832Ssam if (val != COLON) { 21229832Ssam yyerror("\"%s\" is not followed by a ':' for a label definition", 21329832Ssam FETCHNAME(np)); 21429832Ssam goto errorfix; 21529832Ssam } 21629832Ssam restlab: 21729832Ssam shift; 21829832Ssam flushfield(NBPW/4); 21929832Ssam if ((np->s_type&XTYPE)!=XUNDEF) { 22029832Ssam if( (np->s_type&XTYPE)!=dotp->e_xtype 22129832Ssam || np->s_value!=dotp->e_xvalue 22229832Ssam || ( (passno==1) 22329832Ssam &&(np->s_index != dotp->e_xloc) 22429832Ssam ) 22529832Ssam ){ 22629832Ssam #ifndef DEBUG 22729832Ssam if (FETCHNAME(np)[0] != 'L') 22829832Ssam #endif not DEBUG 22929832Ssam { 23029832Ssam if (passno == 1) 23129832Ssam yyerror("%s redefined", 23229832Ssam FETCHNAME(np)); 23329832Ssam else 23429832Ssam yyerror("%s redefined: PHASE ERROR, 1st: %d, 2nd: %d", 23529832Ssam FETCHNAME(np), 23629832Ssam np->s_value, 23729832Ssam dotp->e_xvalue); 23829832Ssam } 23929832Ssam } 24029832Ssam } 24129832Ssam np->s_type &= ~(XTYPE|XFORW); 24229832Ssam np->s_type |= dotp->e_xtype; 24329832Ssam np->s_value = dotp->e_xvalue; 24429832Ssam if (passno == 1){ 24529832Ssam np->s_index = dotp-usedot; 24629832Ssam if (FETCHNAME(np)[0] == 'L'){ 24729832Ssam nlabels++; 24829832Ssam } 24929832Ssam np->s_tag = LABELID; 25029832Ssam } 25129832Ssam } /*end of this being a label*/ 25229832Ssam } /*end of to consuming all labels, NLs and SEMIS */ 25329832Ssam 25429832Ssam xp = explist; 25529832Ssam ap = arglist; 25629832Ssam 25729832Ssam /* 25829832Ssam * process the INSTRUCTION body 25929832Ssam */ 26029832Ssam switch(val){ 26129832Ssam 26229832Ssam default: 26329832Ssam ERROR("Unrecognized instruction or directive"); 26429832Ssam 26529832Ssam case IABORT: 26629832Ssam shift; 26729832Ssam sawabort(); 26829832Ssam /*NOTREACHED*/ 26929832Ssam break; 27029832Ssam 27129832Ssam case PARSEEOF: 27229832Ssam tokptr -= sizeof(bytetoktype); 27329832Ssam *tokptr++ = VOID; 27429832Ssam tokptr[1] = VOID; 27529832Ssam tokptr[2] = PARSEEOF; 27629832Ssam break; 27729832Ssam 27829832Ssam case IFILE: 27929832Ssam shift; 28029832Ssam stringp = (struct strdesc *)yylval; 28129832Ssam shiftover(STRING); 28229832Ssam dotsname = &UDotsname[0]; 28329832Ssam movestr(dotsname, stringp->sd_string, 28429832Ssam min(stringp->sd_strlen, sizeof(UDotsname))); 28529832Ssam break; 28629832Ssam 28729832Ssam case ILINENO: 28829832Ssam shift; /*over the ILINENO*/ 28929832Ssam expr(locxp, val); 29029832Ssam lineno = locxp->e_xvalue; 29129832Ssam break; 29229832Ssam 29329832Ssam case ISET: /* .set <name> , <expr> */ 29429832Ssam shift; 29529832Ssam np = (struct symtab *)yylval; 29629832Ssam shiftover(NAME); 29729832Ssam shiftover(CM); 29829832Ssam expr(locxp, val); 29929832Ssam np->s_type &= (XXTRN|XFORW); 30029832Ssam np->s_type |= locxp->e_xtype&(XTYPE|XFORW); 30129832Ssam np->s_value = locxp->e_xvalue; 30229832Ssam if (passno==1) 30329832Ssam np->s_index = locxp->e_xloc; 30429832Ssam if ((locxp->e_xtype&XTYPE) == XUNDEF) 30529832Ssam yyerror("Illegal set?"); 30629832Ssam break; 30729832Ssam 30829832Ssam case ILSYM: /*.lsym name , expr */ 30929832Ssam shift; 31029832Ssam np = (struct symtab *)yylval; 31129832Ssam shiftover(NAME); 31229832Ssam shiftover(CM); 31329832Ssam expr(locxp, val); 31429832Ssam /* 31529832Ssam * Build the unique occurance of the 31629832Ssam * symbol. 31729832Ssam * The character scanner will have 31829832Ssam * already entered it into the symbol 31929832Ssam * table, but we should remove it 32029832Ssam */ 32129832Ssam if (passno == 1){ 32229832Ssam stpt = (struct symtab *)symalloc(); 32329832Ssam stpt->s_name = np->s_name; 32429832Ssam np->s_tag = OBSOLETE; /*invalidate original */ 32529832Ssam nforgotten++; 32629832Ssam np = stpt; 32729832Ssam if ( (locxp->e_xtype & XTYPE) != XABS) 32829832Ssam yyerror("Illegal second argument to lsym"); 32929832Ssam np->s_value = locxp->e_xvalue; 33029832Ssam np->s_type = XABS; 33129832Ssam np->s_tag = ILSYM; 33229832Ssam } 33329832Ssam break; 33429832Ssam 33529832Ssam case IGLOBAL: /*.globl <name> */ 33629832Ssam shift; 33729832Ssam np = (struct symtab *)yylval; 33829832Ssam shiftover(NAME); 33929832Ssam np->s_type |= XXTRN; 34029832Ssam break; 34129832Ssam 34229832Ssam case IDATA: /*.data [ <expr> ] */ 34329832Ssam case ITEXT: /*.text [ <expr> ] */ 34429832Ssam incasetable = 0; 34529832Ssam seg_type = -val; 34629832Ssam shift; 34729832Ssam if (INTOKSET(val, EBEGOPS+YUKKYEXPRBEG+SAFEEXPRBEG)){ 34829832Ssam expr(locxp, val); 34929832Ssam seg_type = -seg_type; /*now, it is positive*/ 35029832Ssam } 35129832Ssam 35229832Ssam if (seg_type < 0) { /*there wasn't an associated expr*/ 35329832Ssam seg_number = 0; 35429832Ssam seg_type = -seg_type; 35529832Ssam } else { 35629832Ssam if ( ((locxp->e_xtype & XTYPE) != XABS) /* tekmdp */ 35729832Ssam || (seg_number = locxp->e_xvalue) >= NLOC) { 35829832Ssam yyerror("illegal location counter"); 35929832Ssam seg_number = 0; 36029832Ssam } 36129832Ssam } 36229832Ssam if (seg_type == IDATA) 36329832Ssam seg_number += NLOC; 36429832Ssam flushfield(NBPW/4); 36529832Ssam dotp = &usedot[seg_number]; 36629832Ssam if (passno==2) { /* go salt away in pass 2*/ 36729832Ssam txtfil = usefile[seg_number]; 36829832Ssam relfil = rusefile[seg_number]; 36929832Ssam } 37029832Ssam break; 37129832Ssam 37229832Ssam /* 37329832Ssam * Storage filler directives: 37429832Ssam * 37529832Ssam * .byte [<exprlist>] 37629832Ssam * 37729832Ssam * exprlist: empty | exprlist outexpr 37829832Ssam * outexpr: <expr> | <expr> : <expr> 37929832Ssam */ 38029832Ssam case IBYTE: curlen = NBPW/4; goto elist; 38129832Ssam case IWORD: curlen = NBPW/2; goto elist; 38229832Ssam case IINT: curlen = NBPW; goto elist; 38329832Ssam case ILONG: curlen = NBPW; goto elist; 38429832Ssam 38529832Ssam elist: 38629832Ssam seg_type = val; 38729832Ssam shift; 38829832Ssam 38929832Ssam /* 39029832Ssam * Expression List processing 39129832Ssam */ 39229832Ssam if (INTOKSET(val, EBEGOPS+YUKKYEXPRBEG+SAFEEXPRBEG)){ 39329832Ssam do{ 39429832Ssam /* 39529832Ssam * expression list consists of a list of : 39629832Ssam * <expr> 39729832Ssam * <expr> : <expr> 39829832Ssam * (pack expr2 into expr1 bits 39929832Ssam */ 40029832Ssam expr(locxp, val); 40129832Ssam /* 40229832Ssam * now, pointing at the next token 40329832Ssam */ 40429832Ssam /* if (val == COLON){ */ 40529832Ssam /* shiftover(COLON); */ 40629832Ssam /* expr(pval, val); */ 40729832Ssam /* if ((locxp->e_xtype & XTYPE) != XABS) */ 40829832Ssam /* yyerror("Width not absolute"); */ 40929832Ssam /* field_width = locxp->e_xvalue; */ 41029832Ssam /* locxp = pval; */ 41129832Ssam /* if (bitoff + field_width > curlen) */ 41229832Ssam /* flushfield(curlen); */ 41329832Ssam /* if (field_width > curlen) */ 41429832Ssam /* yyerror("Expression crosses field boundary"); */ 41529832Ssam /* } else { */ 41629832Ssam field_width = curlen; 41729832Ssam if (bitoff == 0) printblank = 0; 41829832Ssam else printblank = 1; 41929832Ssam flushfield(curlen); 42029832Ssam if (liston && (passno == 2) && printblank) 42129832Ssam *layoutpos++ = ' '; 42229832Ssam /* } */ 42329832Ssam 42429832Ssam if ((locxp->e_xtype & XTYPE) != XABS) { 42529832Ssam if (bitoff) 42629832Ssam yyerror("Illegal relocation in field"); 42729832Ssam switch(curlen){ 42829832Ssam case NBPW/4: reloc_how = TYPB; break; 42929832Ssam case NBPW/2: reloc_how = TYPW; break; 43029832Ssam case NBPW: reloc_how = TYPL; break; 43129832Ssam } 43229832Ssam if (passno == 1){ 43329832Ssam dotp->e_xvalue += ty_nbyte[reloc_how]; 43429832Ssam } else { 43529832Ssam outrel(locxp, reloc_how); 43629832Ssam if (liston) 43729832Ssam *layoutpos++ = ' '; 43829832Ssam } 43929832Ssam } else { 44029832Ssam /* 44129832Ssam * 44229832Ssam * See if we are doing a case instruction. 44329832Ssam * If so, then see if the branch distance, 44429832Ssam * stored as a word, 44529832Ssam * is going to loose sig bits. 44629832Ssam */ 44729832Ssam if (passno == 2 && incasetable){ 44829832Ssam if ( !(ISWORD(locxp->e_xvalue))) 44929832Ssam yyerror("Case will branch too far"); 45029832Ssam } 45129832Ssam field_value = locxp->e_xvalue & ( (1L << field_width)-1); 45229832Ssam bitfield |= field_value << bitoff; 45329832Ssam bitoff += field_width; 45429832Ssam } 45529832Ssam xp = explist; 45629832Ssam if (auxval = (val == CM)) 45729832Ssam shift; 45829832Ssam } while (auxval); 45929832Ssam } /* there existed an expression at all */ 46029832Ssam 46129832Ssam flushfield(curlen); 46229832Ssam if ( ( curlen == NBPW/4) && bitoff) 46329832Ssam dotp->e_xvalue ++; 46429832Ssam break; 46529832Ssam /*end of case IBYTE, IWORD, ILONG, IINT*/ 46629832Ssam 46729832Ssam case ISPACE: /* .space <expr> */ 46829832Ssam shift; 46929832Ssam expr(locxp, val); 47029832Ssam if ((locxp->e_xtype & XTYPE) != XABS) /* tekmdp */ 47129832Ssam yyerror("Space size not absolute"); 47229832Ssam if (locxp->e_xvalue < 0) 47329832Ssam yyerror("Space size not positive"); 47429832Ssam space_value = locxp->e_xvalue; 47529832Ssam ospace: 47629832Ssam flushfield(NBPW/4); 47729832Ssam { 47829832Ssam static char spacebuf[128]; 47929832Ssam while (space_value > sizeof(spacebuf)){ 48029832Ssam outs(spacebuf, sizeof(spacebuf)); 48129832Ssam space_value -= sizeof(spacebuf); 48229832Ssam } 48329832Ssam outs(spacebuf, space_value); 48429832Ssam } 48529832Ssam if (liston && (passno == 2)) 48632436Sbostic (void)sprintf (layoutpos, "****"); 48729832Ssam break; 48829832Ssam 48929832Ssam /* 49029832Ssam * .fill rep, size, value 49129832Ssam * repeat rep times: fill size bytes with (truncated) value 49229832Ssam * size must be between 1 and 8 49329832Ssam */ 49429832Ssam case IFILL: 49529832Ssam shift; 49629832Ssam expr(locxp, val); 49729832Ssam if ( (locxp->e_xtype & XTYPE) != XABS) /* tekmdp */ 49829832Ssam yyerror("Fill repetition count not absolute"); 49929832Ssam rep_fill = fill_rep = locxp->e_xvalue; 50029832Ssam shiftover(CM); 50129832Ssam expr(locxp, val); 50229832Ssam if ( (locxp->e_xtype & XTYPE) != XABS) /* tekmdp */ 50329832Ssam yyerror("Fill size not absolute"); 50429832Ssam fill_size = locxp->e_xvalue; 50529832Ssam if (fill_size <= 0 || fill_size > 8) 50629832Ssam yyerror("Fill count not in in 1..8"); 50729832Ssam shiftover(CM); 50829832Ssam expr(locxp, val); 50929832Ssam if (passno == 2 && (locxp->e_xtype & XTYPE) != XABS) /* tekmdp */ 51029832Ssam yyerror("Fill value not absolute"); 51129832Ssam flushfield(NBPW/4); 51229832Ssam dotp->e_xvalue += fill_rep * fill_size; 51329832Ssam if (passno == 1) { 51429832Ssam locxp->e_xvalue += fill_rep * fill_size; 51529832Ssam } else { 51629832Ssam fillval.lpart[0] = locxp->e_yvalue; 51729832Ssam fillval.lpart[1] = locxp->e_xvalue; 51829832Ssam while (fill_rep-- > 0) 51929832Ssam bwrite(&(fillval.strpart[8-fill_size]),fill_size,txtfil); 52029832Ssam if (liston) { 52129832Ssam while (rep_fill-- > 0) 52229832Ssam { 52329832Ssam switch (fill_size) 52429832Ssam { 52529832Ssam case 1: 52629832Ssam byte_out (locxp->e_xvalue); 52729832Ssam *layoutpos++ = ' '; 52829832Ssam break; 52929832Ssam case 2: 53029832Ssam word_out (locxp->e_xvalue); 53129832Ssam *layoutpos++ = ' '; 53229832Ssam break; 53329832Ssam case 3: 53429832Ssam byte_out (locxp->e_xvalue >> 16); 53529832Ssam byte_out (locxp->e_xvalue >> 8); 53629832Ssam byte_out (locxp->e_xvalue); 53729832Ssam *layoutpos++ = ' '; 53829832Ssam break; 53929832Ssam case 4: 54029832Ssam long_out (locxp->e_xvalue); 54129832Ssam *layoutpos++ = ' '; 54229832Ssam break; 54329832Ssam case 5: 54429832Ssam byte_out (locxp->e_yvalue); 54529832Ssam long_out (locxp->e_xvalue); 54629832Ssam *layoutpos++ = ' '; 54729832Ssam break; 54829832Ssam case 6: 54929832Ssam word_out (locxp->e_yvalue); 55029832Ssam long_out (locxp->e_xvalue); 55129832Ssam *layoutpos++ = ' '; 55229832Ssam break; 55329832Ssam case 7: 55429832Ssam byte_out (locxp->e_yvalue >> 16); 55529832Ssam byte_out (locxp->e_yvalue >> 8); 55629832Ssam byte_out (locxp->e_yvalue); 55729832Ssam long_out (locxp->e_xvalue); 55829832Ssam *layoutpos++ = ' '; 55929832Ssam break; 56029832Ssam case 8: 56129832Ssam long_out (locxp->e_yvalue); 56229832Ssam long_out (locxp->e_xvalue); 56329832Ssam *layoutpos++ = ' '; 56429832Ssam break; 56529832Ssam } 56629832Ssam } 56729832Ssam } 56829832Ssam } 56929832Ssam break; 57029832Ssam 57129832Ssam case IASCII: /* .ascii [ <stringlist> ] */ 57229832Ssam case IASCIZ: /* .asciz [ <stringlist> ] */ 57329832Ssam auxval = val; 57429832Ssam shift; 57529832Ssam /* 57629832Ssam * Code to consume a string list 57729832Ssam * 57829832Ssam * stringlist: empty | STRING | stringlist STRING 57929832Ssam */ 58029832Ssam while (val == STRING){ 58129832Ssam int mystrlen; 58229832Ssam flushfield(NBPW/4); 58329832Ssam if (bitoff) 58429832Ssam dotp->e_xvalue++; 58529832Ssam stringp = (struct strdesc *)yylval; 58629832Ssam /* 58729832Ssam * utilize the string scanner cheat; 58829832Ssam * the scanner appended a null byte on the string, 58929832Ssam * but didn't charge it to sd_strlen 59029832Ssam */ 59129832Ssam mystrlen = stringp->sd_strlen; 59229832Ssam mystrlen += (auxval == IASCIZ) ? 1 : 0; 59329832Ssam if (passno == 2){ 59429832Ssam if (stringp->sd_place & STR_CORE){ 59529832Ssam outs(stringp->sd_string, mystrlen); 59629832Ssam if (liston) 59729832Ssam { 59829832Ssam int i; 59929832Ssam for (i = 0;i < mystrlen; i++) 60029832Ssam { 60132436Sbostic (void)sprintf (layoutpos, "%02x", 60229832Ssam stringp->sd_string[i]); 60329832Ssam layoutpos += 2; 60429832Ssam } 60529832Ssam } 60629832Ssam } else { 60729832Ssam int i, nread; 60829832Ssam fseek(strfile, stringp->sd_stroff, 0); 60929832Ssam for (i = 0; i < mystrlen;/*VOID*/){ 61029832Ssam nread = fread(yytext, 1, 61129832Ssam min(mystrlen - i, 61229832Ssam sizeof(yytext)), strfile); 61329832Ssam outs(yytext, nread); 61429832Ssam if (liston) 61529832Ssam { 61629832Ssam int k; 61729832Ssam for (k = 0;k < nread; k++) 61829832Ssam { 61932436Sbostic (void)sprintf (layoutpos, 62029832Ssam "%02x", yytext[k]); 62129832Ssam layoutpos += 2; 62229832Ssam } 62329832Ssam } 62429832Ssam i += nread; 62529832Ssam } 62629832Ssam } 62729832Ssam } else { 62829832Ssam dotp->e_xvalue += mystrlen; 62929832Ssam } 63029832Ssam shift; /*over the STRING*/ 63129832Ssam if (val == CM) /*could be a split string*/ 63229832Ssam shift; 63329832Ssam } 63429832Ssam break; 63529832Ssam 63629832Ssam case IORG: /* .org <expr> */ 63729832Ssam shift; 63829832Ssam expr(locxp, val); 63929832Ssam 64029832Ssam if ((locxp->e_xtype & XTYPE) == XABS) /* tekmdp */ 64129832Ssam orgwarn++; 64229832Ssam else if ((locxp->e_xtype & ~XXTRN) != dotp->e_xtype) 64329832Ssam yyerror("Illegal expression to set origin"); 64429832Ssam if ((unsigned)locxp->e_xvalue < (unsigned)dotp->e_xvalue) 64529832Ssam { 64629832Ssam ERROR("Backwards 'org'"); 64729832Ssam } 64829832Ssam space_value = locxp->e_xvalue - dotp->e_xvalue; 64929832Ssam goto ospace; 65029832Ssam break; 65129832Ssam 65229832Ssam /* 65329832Ssam * 65429832Ssam * Process stabs. Stabs are created only by the f77 65529832Ssam * and the C compiler with the -g flag set. 65629832Ssam * We only look at the stab ONCE, during pass 1, and 65729832Ssam * virtually remove the stab from the intermediate file 65829832Ssam * so it isn't seen during pass2. This makes for some 65929832Ssam * hairy processing to handle labels occuring in 66029832Ssam * stab entries, but since most expressions in the 66129832Ssam * stab are integral we save lots of time in the second 66229832Ssam * pass by not looking at the stabs. 66329832Ssam * A stab that is tagged floating will be bumped during 66429832Ssam * the jxxx resolution phase. A stab tagged fixed will 66529832Ssam * not be be bumped. 66629832Ssam * 66729832Ssam * .stab: Old fashioned stabs 66829832Ssam * .stabn: For stabs without names 66929832Ssam * .stabs: For stabs with string names 67029832Ssam * .stabd: For stabs for line numbers or bracketing, 67129832Ssam * without a string name, without 67229832Ssam * a final expression. The value of the 67329832Ssam * final expression is taken to be the current 67429832Ssam * location counter, and is patched by the 2nd pass 67529832Ssam * 67629832Ssam * .stab{<expr>,}*NCPName,<expr>, <expr>, <expr>, <expr> 67729832Ssam * .stabn <expr>, <expr>, <expr>, <expr> 67829832Ssam * .stabs STRING, <expr>, <expr>, <expr>, <expr> 67929832Ssam * .stabd <expr>, <expr>, <expr> # . 68029832Ssam */ 68129832Ssam case ISTAB: 68229832Ssam yyerror(".stab directive no longer supported"); 68329832Ssam goto errorfix; 68429832Ssam 68529832Ssam tailstab: 68629832Ssam expr(locxp, val); 68729832Ssam if (! (locxp->e_xvalue & STABTYPS)){ 68829832Ssam yyerror("Invalid type in %s", stabname); 68929832Ssam goto errorfix; 69029832Ssam } 69129832Ssam stpt->s_ptype = locxp->e_xvalue; 69229832Ssam shiftover(CM); 69329832Ssam expr(locxp, val); 69429832Ssam stpt->s_other = locxp->e_xvalue; 69529832Ssam shiftover(CM); 69629832Ssam expr(locxp, val); 69729832Ssam stpt->s_desc = locxp->e_xvalue; 69829832Ssam shiftover(CM); 69929832Ssam exprisname = 0; 70029832Ssam expr(locxp, val); 70129832Ssam p = locxp->e_xname; 70229832Ssam if (p == NULL) { /*absolute expr to begin with*/ 70329832Ssam stpt->s_value = locxp->e_xvalue; 70429832Ssam stpt->s_index = dotp - usedot; 70529832Ssam if (exprisname){ 706*34441Sdonn stpt->s_type = locxp->e_xtype; 70729832Ssam switch(stpt->s_ptype){ 70831350Ssam case N_LCSYM: 70931350Ssam stpt->s_dest = (struct symtab *)exprisname; 71031350Ssam stpt->s_type |= STABFLAG; 71129832Ssam case N_GSYM: 71229832Ssam case N_FNAME: 71329832Ssam case N_RSYM: 71429832Ssam case N_SSYM: 71529832Ssam case N_LSYM: 71629832Ssam case N_PSYM: 71729832Ssam case N_BCOMM: 71829832Ssam case N_ECOMM: 71929832Ssam case N_LENG: 72029832Ssam stpt->s_tag = STABFIXED; 72129832Ssam break; 72229832Ssam default: 72329832Ssam stpt->s_tag = STABFLOATING; 72429832Ssam break; 72529832Ssam } 72629832Ssam } else 72729832Ssam stpt->s_tag = STABFIXED; 72829832Ssam } 72929832Ssam else { /*really have a name*/ 73029832Ssam stpt->s_dest = locxp->e_xname; 73129832Ssam stpt->s_index = p->s_index; 73229832Ssam stpt->s_type = p->s_type | STABFLAG; 73329832Ssam /* 73429832Ssam * We will assign a more accruate 73529832Ssam * guess of locxp's location when 73629832Ssam * we sort the symbol table 73729832Ssam * The final value of value is 73829832Ssam * given by stabfix() 73929832Ssam */ 74029832Ssam /* 74129832Ssam * For exprs of the form (name + value) one needs to remember locxp->e_xvalue 74229832Ssam * for use in stabfix. The right place to keep this is in stpt->s_value 74329832Ssam * however this gets corrupted at an unknown point. 74429832Ssam * As a bandaid hack the value is preserved in s_desc and s_other (a 74529832Ssam * short and a char). This destroys these two values and will 74629832Ssam * be fixed. May 19 ,1983 Alastair Fyfe 74729832Ssam */ 74829832Ssam if(locxp->e_xvalue) { 74929832Ssam stpt->s_other = (locxp->e_xvalue >> 16); 75029832Ssam stpt->s_desc = (locxp->e_xvalue & 0x0000ffff); 75129832Ssam stpt->s_tag = STABFLOATING; 75229832Ssam } 75329832Ssam } 75429832Ssam /* 75529832Ssam * tokptr now points at one token beyond 75629832Ssam * the current token stored in val and yylval, 75729832Ssam * which are the next tokens after the end of 75829832Ssam * this .stab directive. This next token must 75929832Ssam * be either a SEMI or NL, so is of width just 76029832Ssam * one. Therefore, to point to the next token 76129832Ssam * after the end of this stab, just back up one.. 76229832Ssam */ 76329832Ssam buildskip(stabstart, (bytetoktype *)tokptr - sizeof(bytetoktype)); 76429832Ssam break; /*end of the .stab*/ 76529832Ssam 76629832Ssam case ISTABDOT: 76729832Ssam stabname = ".stabd"; 76829832Ssam stpt = (struct symtab *)yylval; 76929832Ssam /* 77029832Ssam * We clobber everything after the 77129832Ssam * .stabd and its pointer... we MUST 77229832Ssam * be able to get back to this .stabd 77329832Ssam * so that we can resolve its final value 77429832Ssam */ 77529832Ssam stabstart = tokptr; 77629832Ssam shift; /*over the ISTABDOT*/ 77729832Ssam if (passno == 1){ 77829832Ssam expr(locxp, val); 77929832Ssam if (! (locxp->e_xvalue & STABTYPS)){ 78029832Ssam yyerror("Invalid type in .stabd"); 78129832Ssam goto errorfix; 78229832Ssam } 78329832Ssam stpt->s_ptype = locxp->e_xvalue; 78429832Ssam shiftover(CM); 78529832Ssam expr(locxp, val); 78629832Ssam stpt->s_other = locxp->e_xvalue; 78729832Ssam shiftover(CM); 78829832Ssam expr(locxp, val); 78929832Ssam stpt->s_desc = locxp->e_xvalue; 79029832Ssam /* 79129832Ssam * 79229832Ssam * Now, clobber everything but the 79329832Ssam * .stabd pseudo and the pointer 79429832Ssam * to its symbol table entry 79529832Ssam * tokptr points to the next token, 79629832Ssam * build the skip up to this 79729832Ssam */ 79829832Ssam buildskip(stabstart, (bytetoktype *)tokptr - sizeof(bytetoktype)); 79929832Ssam } 80029832Ssam /* 80129832Ssam * pass 1: Assign a good guess for its position 80229832Ssam * (ensures they are sorted into right place)/ 80329832Ssam * pass 2: Fix the actual value 80429832Ssam */ 80529832Ssam stpt->s_value = dotp->e_xvalue; 80629832Ssam stpt->s_index = dotp - usedot; 80729832Ssam stpt->s_tag = STABFLOATING; /*although it has no effect in pass 2*/ 80829832Ssam break; 80929832Ssam 81029832Ssam case ISTABNONE: stabname = ".stabn"; goto shortstab; 81129832Ssam 81229832Ssam case ISTABSTR: stabname = ".stabs"; 81329832Ssam shortstab: 81429832Ssam auxval = val; 81529832Ssam if (passno == 2) goto errorfix; 81629832Ssam stpt = (struct symtab *)yylval; 81729832Ssam stabstart = tokptr; 81829832Ssam (bytetoktype *)stabstart -= sizeof(struct symtab *); 81929832Ssam (bytetoktype *)stabstart -= sizeof(bytetoktype); 82029832Ssam shift; 82129832Ssam if (auxval == ISTABSTR){ 82229832Ssam stringp = (struct strdesc *)yylval; 82329832Ssam shiftover(STRING); 82429832Ssam stpt->s_name = (char *)stringp; 82529832Ssam /* 82629832Ssam * We want the trailing null included in this string. 82729832Ssam * We utilize the cheat the string scanner used, 82829832Ssam * and merely increment the string length 82929832Ssam */ 83029832Ssam stringp->sd_strlen += 1; 83129832Ssam shiftover(CM); 83229832Ssam } else { 83329832Ssam stpt->s_name = (char *)savestr("\0", 0, STR_BOTH); 83429832Ssam } 83529832Ssam goto tailstab; 83629832Ssam break; 83729832Ssam 83829832Ssam case ICOMM: /* .comm <name> , <expr> */ 83929832Ssam case ILCOMM: /* .lcomm <name> , <expr> */ 84029832Ssam auxval = val; 84129832Ssam shift; 84229832Ssam np = (struct symtab *)yylval; 84329832Ssam shiftover(NAME); 84429832Ssam shiftover(CM); 84529832Ssam expr(locxp, val); 84629832Ssam 84729832Ssam if ( (locxp->e_xtype & XTYPE) != XABS) /* tekmdp */ 84829832Ssam yyerror("comm size not absolute"); 84929832Ssam if (passno == 1 && (np->s_type&XTYPE) != XUNDEF) 85029832Ssam yyerror("Redefinition of %s", FETCHNAME(np)); 85129832Ssam if (passno==1) { 85229832Ssam np->s_value = locxp->e_xvalue; 85329832Ssam if (auxval == ICOMM) 85429832Ssam np->s_type |= XXTRN; 85529832Ssam else { 85629832Ssam np->s_type &= ~XTYPE; 85729832Ssam np->s_type |= XBSS; 85829832Ssam } 85929832Ssam } 86029832Ssam break; 86129832Ssam 86229832Ssam case IALIGN: /* .align <expr> */ 86329832Ssam stpt = (struct symtab *)yylval; 86429832Ssam shift; 86529832Ssam expr(locxp, val); 86629832Ssam if ((dotp->e_xtype & XTYPE) == XDATA) 86729832Ssam djalign(locxp, stpt); 86829832Ssam else 86929832Ssam jalign(locxp, stpt); 87029832Ssam break; 87129832Ssam 87229832Ssam case INST0: /* instructions w/o arguments*/ 87329832Ssam incasetable = 0; 87429832Ssam insout(yyopcode, (struct arg *)0, 0); 87529832Ssam shift; 87629832Ssam break; 87729832Ssam 87829832Ssam case INSTn: /* instructions with arguments*/ 87929832Ssam case IJXXX: /* UNIX style jump instructions */ 88029832Ssam auxval = val; 88129832Ssam /* 88229832Ssam * Code to process an argument list 88329832Ssam */ 88429832Ssam ap = arglist; 88529832Ssam xp = explist; 88629832Ssam 88729832Ssam shift; /* bring in the first token for the arg list*/ 88829832Ssam 88929832Ssam for (argcnt = 1; argcnt <= 6; argcnt++, ap++){ 89029832Ssam /* 89129832Ssam * code to process an argument proper 89229832Ssam */ 89329832Ssam sawindex = sawmul = sawsize = 0; 89429832Ssam { 89529832Ssam switch(val) { 89629832Ssam 89729832Ssam default: 89829832Ssam disp: 89929832Ssam if( !(INTOKSET(val, 90029832Ssam EBEGOPS 90129832Ssam +YUKKYEXPRBEG 90229832Ssam +SAFEEXPRBEG)) ) { 90329832Ssam ERROR("expression expected"); 90429832Ssam } 90529832Ssam expr(ap->a_xp,val); 90629832Ssam overdisp: 90729832Ssam if ( val == LP || sawsize){ 90829832Ssam shiftover(LP); 90929832Ssam findreg(regno); 91029832Ssam shiftover(RP); 91129832Ssam ap->a_atype = ADISP; 91229832Ssam ap->a_areg1 = regno; 91329832Ssam } else { 91429832Ssam ap->a_atype = AEXP; 91529832Ssam ap->a_areg1 = 0; 91629832Ssam } 91729832Ssam goto index; 91829832Ssam 91929832Ssam case SIZESPEC: 92029832Ssam sizespec: 92129832Ssam sawsize = yylval; 92229832Ssam shift; 92329832Ssam goto disp; 92429832Ssam 92529832Ssam case REG: 92629832Ssam case REGOP: 92729832Ssam findreg(regno); 92829832Ssam ap->a_atype = AREG; 92929832Ssam ap->a_areg1 = regno; 93029832Ssam break; 93129832Ssam 93229832Ssam case MUL: 93329832Ssam sawmul = 1; 93429832Ssam shift; 93529832Ssam if (val == LP) goto base; 93629832Ssam if (val == LITOP) goto imm; 93729832Ssam if (val == SIZESPEC) goto sizespec; 93829832Ssam if (INTOKSET(val, 93929832Ssam EBEGOPS 94029832Ssam +YUKKYEXPRBEG 94129832Ssam +SAFEEXPRBEG)) goto disp; 94229832Ssam ERROR("expression, '(' or '$' expected"); 94329832Ssam break; 94429832Ssam 94529832Ssam case LP: 94629832Ssam base: 94729832Ssam shift; /*consume the LP*/ 94829832Ssam /* 94929832Ssam * hack the ambiguity of 95029832Ssam * movl (expr) (rn), ... 95129832Ssam * note that (expr) could also 95229832Ssam * be (rn) (by special hole in the 95329832Ssam * grammar), which we ensure 95429832Ssam * means register indirection, instead 95529832Ssam * of an expression with value n 95629832Ssam */ 95729832Ssam if (val != REG && val != REGOP){ 95829832Ssam droppedLP = 1; 95929832Ssam val = exprparse(val, &(ap->a_xp)); 96029832Ssam droppedLP = 0; 96129832Ssam goto overdisp; 96229832Ssam } 96329832Ssam findreg(regno); 96429832Ssam shiftover(RP); 96529832Ssam if (val == PLUS){ 96629832Ssam shift; 96729832Ssam ap->a_atype = AINCR; 96829832Ssam if (sawmul && regno != 0xE) 96929832Ssam yyerror ("Autoincrement deferred register must be SP"); 97029832Ssam if (!(sawmul || regno == 0xE)) 97129832Ssam yyerror ("Autoincrement register must be SP"); 97229832Ssam } else 97329832Ssam ap->a_atype = ABASE; 97429832Ssam ap->a_areg1 = regno; 97529832Ssam goto index; 97629832Ssam 97729832Ssam case LITOP: 97829832Ssam imm: 97929832Ssam shift; 98029832Ssam expr(locxp, val); 98129832Ssam ap->a_atype = AIMM; 98229832Ssam ap->a_areg1 = 0; 98329832Ssam ap->a_xp = locxp; 98429832Ssam goto index; 98529832Ssam 98629832Ssam case MP: 98729832Ssam shift; /* -(reg) */ 98829832Ssam findreg(regno); 98929832Ssam if (regno != 0xE) 99029832Ssam yyerror ("Autodecrement register must be SP"); 99129832Ssam shiftover(RP); 99229832Ssam ap->a_atype = ADECR; 99329832Ssam ap->a_areg1 = regno; 99429832Ssam index: /*look for [reg] */ 99529832Ssam if (val == LB){ 99629832Ssam shift; 99729832Ssam findreg(regno); 99829832Ssam shiftover(RB); 99929832Ssam sawindex = 1; 100029832Ssam ap->a_areg2 = regno; 100129832Ssam } 100229832Ssam break; 100329832Ssam 100429832Ssam } /*end of the switch to process an arg*/ 100529832Ssam } /*end of processing an argument*/ 100629832Ssam 100729832Ssam if (sawmul){ 100829832Ssam /* 100929832Ssam * Make a concession for *(%r) 101029832Ssam * meaning *0(%r) 101129832Ssam */ 101229832Ssam if (ap->a_atype == ABASE) { 101329832Ssam ap->a_atype = ADISP; 101429832Ssam xp->e_xtype = XABS; 101529832Ssam xp->e_number = Znumber; 101629832Ssam xp->e_number.num_tag = TYPL; 101729832Ssam xp->e_xloc = 0; 101829832Ssam ap->a_xp = xp++; 101929832Ssam } 102029832Ssam ap->a_atype |= ASTAR; 102129832Ssam sawmul = 0; 102229832Ssam } 102329832Ssam if (sawindex){ 102429832Ssam ap->a_atype |= AINDX; 102529832Ssam sawindex = 0; 102629832Ssam } 102729832Ssam ap->a_dispsize = sawsize == 0 ? d124 : sawsize; 102829832Ssam if (val != CM) break; 102929832Ssam shiftover(CM); 103029832Ssam } /*processing all the arguments*/ 103129832Ssam 103229832Ssam if (argcnt > 6){ 103329832Ssam yyerror("More than 6 arguments"); 103429832Ssam goto errorfix; 103529832Ssam } 103629832Ssam 103729832Ssam /* 103829832Ssam * See if this is a case instruction, 103929832Ssam * so we can set up tests on the following 104029832Ssam * vector of branch displacements 104129832Ssam */ 104229832Ssam if (yyopcode == 0xfc) /* 'casel' instruction */ 104329832Ssam incasetable++; 104429832Ssam else 104529832Ssam incasetable = 0; 104629832Ssam 104729832Ssam insout(yyopcode, arglist, 104829832Ssam auxval == INSTn ? argcnt : - argcnt); 104929832Ssam break; 105029832Ssam 105129832Ssam case IQUAD: num_type = TYPQ; goto bignumlist; 105229832Ssam case IFFLOAT: num_type = TYPF; goto bignumlist; 105329832Ssam case IDFLOAT: num_type = TYPD; 105429832Ssam bignumlist: 105529832Ssam /* 105629832Ssam * eat a list of non 32 bit numbers. 105729832Ssam * IQUAD can, possibly, return 105829832Ssam * INT's, if the numbers are "small". 105929832Ssam * 106029832Ssam * The value of the numbers is coming back 106129832Ssam * as an expression, NOT in yybignum. 106229832Ssam */ 106329832Ssam shift; /* over the opener */ 106429832Ssam if ((val == BIGNUM) || (val == INT)){ 106529832Ssam do{ 106629832Ssam if ((val != BIGNUM) && (val != INT)){ 106729832Ssam ERROR(ty_float[num_type] 106829832Ssam ? "floating number expected" 106929832Ssam : "integer number expected" ); 107029832Ssam } 107129832Ssam dotp->e_xvalue += ty_nbyte[num_type]; 107229832Ssam if (passno == 2){ 107329832Ssam switch (num_type) { 107429832Ssam case TYPF: 107529832Ssam bwrite(&((struct exp *)yylval)->e_number.num_num.numFf_float.Ff_ulong, 107629832Ssam ty_nbyte[num_type], txtfil); 107729832Ssam if (liston) 107829832Ssam { 107929832Ssam long_out(((struct exp *)yylval)->e_number.num_num.numFf_float.Ff_ulong[0]); 108029832Ssam *layoutpos++ = ' '; 108129832Ssam } 108229832Ssam break; 108329832Ssam case TYPD: 108429832Ssam bwrite(&((struct exp *)yylval)->e_number.num_num.numFd_float.Fd_ulong[0], 108529832Ssam sizeof (long), txtfil); 108629832Ssam bwrite(&((struct exp *)yylval)->e_number.num_num.numFd_float.Fd_ulong[1], 108729832Ssam sizeof (long), txtfil); 108829832Ssam if (liston) 108929832Ssam { 109029832Ssam long_out(((struct exp *)yylval)->e_number.num_num.numIq_int.Iq_ulong[0]); 109129832Ssam long_out(((struct exp *)yylval)->e_number.num_num.numIq_int.Iq_ulong[1]); 109229832Ssam *layoutpos++ = ' '; 109329832Ssam } 109429832Ssam break; 109529832Ssam case TYPQ: 109629832Ssam bwrite(&((struct exp *)yylval)->e_number.num_num.numIq_int.Iq_ulong[1], 109729832Ssam sizeof (long), txtfil); 109829832Ssam bwrite(&((struct exp *)yylval)->e_number.num_num.numIq_int.Iq_ulong[0], 109929832Ssam sizeof (long), txtfil); 110029832Ssam if (liston) 110129832Ssam { 110229832Ssam long_out(((struct exp *)yylval)->e_number.num_num.numIq_int.Iq_ulong[1]); 110329832Ssam long_out(((struct exp *)yylval)->e_number.num_num.numIq_int.Iq_ulong[0]); 110429832Ssam *layoutpos++ = ' '; 110529832Ssam } 110629832Ssam break; 110729832Ssam } 110829832Ssam } 110929832Ssam xp = explist; 111029832Ssam shift; /* over this number */ 111129832Ssam if (auxval = (val == CM)) 111229832Ssam shift; /* over the comma */ 111329832Ssam } while (auxval); /* as long as there are commas */ 111429832Ssam } 111529832Ssam break; 111629832Ssam /* end of the case for initialized big numbers */ 111729832Ssam } /*end of the switch for looking at each reserved word*/ 111829832Ssam 111929832Ssam continue; 112029832Ssam 112129832Ssam errorfix: 112229832Ssam /* 112329832Ssam * got here by either requesting to skip to the 112429832Ssam * end of this statement, or by erroring out and 112529832Ssam * wanting to apply panic mode recovery 112629832Ssam */ 112729832Ssam while ( (val != NL) 112829832Ssam && (val != SEMI) 112929832Ssam && (val != PARSEEOF) 113029832Ssam ){ 113129832Ssam shift; 113229832Ssam } 113329832Ssam if (val == NL) 113429832Ssam lineno++; 113529832Ssam shift; 113629832Ssam 113729832Ssam } /*end of the loop to read the entire file, line by line*/ 113829832Ssam 113929832Ssam } /*end of yyparse*/ 114029832Ssam 114129832Ssam /* 114229832Ssam * Process a register declaration of the form 114329832Ssam * % <expr> 114429832Ssam * 114529832Ssam * Note: 114629832Ssam * The scanner has already processed funny registers of the form 114729832Ssam * %dd[+-]*, where dd is a decimal number in the range 00 to 15 (optional 114829832Ssam * preceding zero digit). If there was any space between the % and 114929832Ssam * the digit, the scanner wouldn't have recognized it, so we 115029832Ssam * hack it out here. 115129832Ssam */ 115229832Ssam inttoktype funnyreg(val, regnoback) /*what the read head will sit on*/ 115329832Ssam inttoktype val; /*what the read head is sitting on*/ 115429832Ssam int *regnoback; /*call by return*/ 115529832Ssam { 115629832Ssam reg struct exp *locxp; 115729832Ssam struct exp *loc1xp; 115829832Ssam struct exp **ptrloc1xp = & loc1xp; 115929832Ssam 116029832Ssam expr(locxp, val); /*and leave the current read head with value*/ 116129832Ssam if ( (passno == 2) && 116229832Ssam ( (locxp->e_xtype & XTYPE) != XABS 116329832Ssam || (locxp->e_xvalue < 0) 116429832Ssam || (locxp->e_xvalue >= 16) 116529832Ssam ) 116629832Ssam ){ 116729832Ssam yyerror("Illegal register"); 116829832Ssam return(0); 116929832Ssam } 117029832Ssam *regnoback = locxp->e_xvalue; 117129832Ssam return(val); 117229832Ssam } 117329832Ssam /* 117429832Ssam * Shift over error 117529832Ssam */ 117629832Ssam shiftoerror(token) 117729832Ssam int token; 117829832Ssam { 117929832Ssam char *tok_to_name(); 118029832Ssam yyerror("%s expected", tok_to_name(token)); 118129832Ssam } 118229832Ssam 118329832Ssam /*VARARGS1*/ 118429832Ssam yyerror(s, a1, a2,a3,a4,a5) 118529832Ssam char *s; 118629832Ssam { 118729832Ssam 118829832Ssam #define sink stdout 118929832Ssam 119029832Ssam if (anyerrs == 0 && anywarnings == 0 && ! silent) 119129832Ssam fprintf(sink, "Assembler:\n"); 119229832Ssam anyerrs++; 119329832Ssam if (silent) 119429832Ssam return; 119529832Ssam fprintf(sink, "\"%s\", line %d: ", dotsname, lineno); 119629832Ssam fprintf(sink, s, a1, a2,a3,a4,a5); 119729832Ssam fprintf(sink, "\n"); 119829832Ssam #undef sink 119929832Ssam } 120029832Ssam 120129832Ssam /*VARARGS1*/ 120229832Ssam yywarning(s, a1, a2,a3,a4,a5) 120329832Ssam char *s; 120429832Ssam { 120529832Ssam #define sink stdout 120629832Ssam if (anyerrs == 0 && anywarnings == 0 && ! silent) 120729832Ssam fprintf(sink, "Assembler:\n"); 120829832Ssam anywarnings++; 120929832Ssam if (silent) 121029832Ssam return; 121129832Ssam fprintf(sink, "\"%s\", line %d: WARNING: ", dotsname, lineno); 121229832Ssam fprintf(sink, s, a1, a2,a3,a4,a5); 121329832Ssam fprintf(sink, "\n"); 121429832Ssam #undef sink 121529832Ssam } 1216