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; 192*32436Sbostic (void)sprintf (layoutpos, "%4ld ", lineno); 19329832Ssam layoutpos += 6; 19429832Ssam long_out (dotp->e_xvalue); 19529832Ssam if (dotp->e_xvalue >= datbase) 196*32436Sbostic (void)sprintf (layoutpos," * "); 19729832Ssam else 198*32436Sbostic (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)) 486*32436Sbostic (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 { 601*32436Sbostic (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 { 619*32436Sbostic (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){ 70629832Ssam switch(stpt->s_ptype){ 70731350Ssam case N_LCSYM: 70831350Ssam stpt->s_dest = (struct symtab *)exprisname; 70931350Ssam stpt->s_type |= STABFLAG; 71029832Ssam case N_GSYM: 71129832Ssam case N_FNAME: 71229832Ssam case N_RSYM: 71329832Ssam case N_SSYM: 71429832Ssam case N_LSYM: 71529832Ssam case N_PSYM: 71629832Ssam case N_BCOMM: 71729832Ssam case N_ECOMM: 71829832Ssam case N_LENG: 71929832Ssam stpt->s_tag = STABFIXED; 72029832Ssam break; 72129832Ssam default: 72229832Ssam stpt->s_tag = STABFLOATING; 72329832Ssam break; 72429832Ssam } 72529832Ssam } else 72629832Ssam stpt->s_tag = STABFIXED; 72729832Ssam } 72829832Ssam else { /*really have a name*/ 72929832Ssam stpt->s_dest = locxp->e_xname; 73029832Ssam stpt->s_index = p->s_index; 73129832Ssam stpt->s_type = p->s_type | STABFLAG; 73229832Ssam /* 73329832Ssam * We will assign a more accruate 73429832Ssam * guess of locxp's location when 73529832Ssam * we sort the symbol table 73629832Ssam * The final value of value is 73729832Ssam * given by stabfix() 73829832Ssam */ 73929832Ssam /* 74029832Ssam * For exprs of the form (name + value) one needs to remember locxp->e_xvalue 74129832Ssam * for use in stabfix. The right place to keep this is in stpt->s_value 74229832Ssam * however this gets corrupted at an unknown point. 74329832Ssam * As a bandaid hack the value is preserved in s_desc and s_other (a 74429832Ssam * short and a char). This destroys these two values and will 74529832Ssam * be fixed. May 19 ,1983 Alastair Fyfe 74629832Ssam */ 74729832Ssam if(locxp->e_xvalue) { 74829832Ssam stpt->s_other = (locxp->e_xvalue >> 16); 74929832Ssam stpt->s_desc = (locxp->e_xvalue & 0x0000ffff); 75029832Ssam stpt->s_tag = STABFLOATING; 75129832Ssam } 75229832Ssam } 75329832Ssam /* 75429832Ssam * tokptr now points at one token beyond 75529832Ssam * the current token stored in val and yylval, 75629832Ssam * which are the next tokens after the end of 75729832Ssam * this .stab directive. This next token must 75829832Ssam * be either a SEMI or NL, so is of width just 75929832Ssam * one. Therefore, to point to the next token 76029832Ssam * after the end of this stab, just back up one.. 76129832Ssam */ 76229832Ssam buildskip(stabstart, (bytetoktype *)tokptr - sizeof(bytetoktype)); 76329832Ssam break; /*end of the .stab*/ 76429832Ssam 76529832Ssam case ISTABDOT: 76629832Ssam stabname = ".stabd"; 76729832Ssam stpt = (struct symtab *)yylval; 76829832Ssam /* 76929832Ssam * We clobber everything after the 77029832Ssam * .stabd and its pointer... we MUST 77129832Ssam * be able to get back to this .stabd 77229832Ssam * so that we can resolve its final value 77329832Ssam */ 77429832Ssam stabstart = tokptr; 77529832Ssam shift; /*over the ISTABDOT*/ 77629832Ssam if (passno == 1){ 77729832Ssam expr(locxp, val); 77829832Ssam if (! (locxp->e_xvalue & STABTYPS)){ 77929832Ssam yyerror("Invalid type in .stabd"); 78029832Ssam goto errorfix; 78129832Ssam } 78229832Ssam stpt->s_ptype = locxp->e_xvalue; 78329832Ssam shiftover(CM); 78429832Ssam expr(locxp, val); 78529832Ssam stpt->s_other = locxp->e_xvalue; 78629832Ssam shiftover(CM); 78729832Ssam expr(locxp, val); 78829832Ssam stpt->s_desc = locxp->e_xvalue; 78929832Ssam /* 79029832Ssam * 79129832Ssam * Now, clobber everything but the 79229832Ssam * .stabd pseudo and the pointer 79329832Ssam * to its symbol table entry 79429832Ssam * tokptr points to the next token, 79529832Ssam * build the skip up to this 79629832Ssam */ 79729832Ssam buildskip(stabstart, (bytetoktype *)tokptr - sizeof(bytetoktype)); 79829832Ssam } 79929832Ssam /* 80029832Ssam * pass 1: Assign a good guess for its position 80129832Ssam * (ensures they are sorted into right place)/ 80229832Ssam * pass 2: Fix the actual value 80329832Ssam */ 80429832Ssam stpt->s_value = dotp->e_xvalue; 80529832Ssam stpt->s_index = dotp - usedot; 80629832Ssam stpt->s_tag = STABFLOATING; /*although it has no effect in pass 2*/ 80729832Ssam break; 80829832Ssam 80929832Ssam case ISTABNONE: stabname = ".stabn"; goto shortstab; 81029832Ssam 81129832Ssam case ISTABSTR: stabname = ".stabs"; 81229832Ssam shortstab: 81329832Ssam auxval = val; 81429832Ssam if (passno == 2) goto errorfix; 81529832Ssam stpt = (struct symtab *)yylval; 81629832Ssam stabstart = tokptr; 81729832Ssam (bytetoktype *)stabstart -= sizeof(struct symtab *); 81829832Ssam (bytetoktype *)stabstart -= sizeof(bytetoktype); 81929832Ssam shift; 82029832Ssam if (auxval == ISTABSTR){ 82129832Ssam stringp = (struct strdesc *)yylval; 82229832Ssam shiftover(STRING); 82329832Ssam stpt->s_name = (char *)stringp; 82429832Ssam /* 82529832Ssam * We want the trailing null included in this string. 82629832Ssam * We utilize the cheat the string scanner used, 82729832Ssam * and merely increment the string length 82829832Ssam */ 82929832Ssam stringp->sd_strlen += 1; 83029832Ssam shiftover(CM); 83129832Ssam } else { 83229832Ssam stpt->s_name = (char *)savestr("\0", 0, STR_BOTH); 83329832Ssam } 83429832Ssam goto tailstab; 83529832Ssam break; 83629832Ssam 83729832Ssam case ICOMM: /* .comm <name> , <expr> */ 83829832Ssam case ILCOMM: /* .lcomm <name> , <expr> */ 83929832Ssam auxval = val; 84029832Ssam shift; 84129832Ssam np = (struct symtab *)yylval; 84229832Ssam shiftover(NAME); 84329832Ssam shiftover(CM); 84429832Ssam expr(locxp, val); 84529832Ssam 84629832Ssam if ( (locxp->e_xtype & XTYPE) != XABS) /* tekmdp */ 84729832Ssam yyerror("comm size not absolute"); 84829832Ssam if (passno == 1 && (np->s_type&XTYPE) != XUNDEF) 84929832Ssam yyerror("Redefinition of %s", FETCHNAME(np)); 85029832Ssam if (passno==1) { 85129832Ssam np->s_value = locxp->e_xvalue; 85229832Ssam if (auxval == ICOMM) 85329832Ssam np->s_type |= XXTRN; 85429832Ssam else { 85529832Ssam np->s_type &= ~XTYPE; 85629832Ssam np->s_type |= XBSS; 85729832Ssam } 85829832Ssam } 85929832Ssam break; 86029832Ssam 86129832Ssam case IALIGN: /* .align <expr> */ 86229832Ssam stpt = (struct symtab *)yylval; 86329832Ssam shift; 86429832Ssam expr(locxp, val); 86529832Ssam if ((dotp->e_xtype & XTYPE) == XDATA) 86629832Ssam djalign(locxp, stpt); 86729832Ssam else 86829832Ssam jalign(locxp, stpt); 86929832Ssam break; 87029832Ssam 87129832Ssam case INST0: /* instructions w/o arguments*/ 87229832Ssam incasetable = 0; 87329832Ssam insout(yyopcode, (struct arg *)0, 0); 87429832Ssam shift; 87529832Ssam break; 87629832Ssam 87729832Ssam case INSTn: /* instructions with arguments*/ 87829832Ssam case IJXXX: /* UNIX style jump instructions */ 87929832Ssam auxval = val; 88029832Ssam /* 88129832Ssam * Code to process an argument list 88229832Ssam */ 88329832Ssam ap = arglist; 88429832Ssam xp = explist; 88529832Ssam 88629832Ssam shift; /* bring in the first token for the arg list*/ 88729832Ssam 88829832Ssam for (argcnt = 1; argcnt <= 6; argcnt++, ap++){ 88929832Ssam /* 89029832Ssam * code to process an argument proper 89129832Ssam */ 89229832Ssam sawindex = sawmul = sawsize = 0; 89329832Ssam { 89429832Ssam switch(val) { 89529832Ssam 89629832Ssam default: 89729832Ssam disp: 89829832Ssam if( !(INTOKSET(val, 89929832Ssam EBEGOPS 90029832Ssam +YUKKYEXPRBEG 90129832Ssam +SAFEEXPRBEG)) ) { 90229832Ssam ERROR("expression expected"); 90329832Ssam } 90429832Ssam expr(ap->a_xp,val); 90529832Ssam overdisp: 90629832Ssam if ( val == LP || sawsize){ 90729832Ssam shiftover(LP); 90829832Ssam findreg(regno); 90929832Ssam shiftover(RP); 91029832Ssam ap->a_atype = ADISP; 91129832Ssam ap->a_areg1 = regno; 91229832Ssam } else { 91329832Ssam ap->a_atype = AEXP; 91429832Ssam ap->a_areg1 = 0; 91529832Ssam } 91629832Ssam goto index; 91729832Ssam 91829832Ssam case SIZESPEC: 91929832Ssam sizespec: 92029832Ssam sawsize = yylval; 92129832Ssam shift; 92229832Ssam goto disp; 92329832Ssam 92429832Ssam case REG: 92529832Ssam case REGOP: 92629832Ssam findreg(regno); 92729832Ssam ap->a_atype = AREG; 92829832Ssam ap->a_areg1 = regno; 92929832Ssam break; 93029832Ssam 93129832Ssam case MUL: 93229832Ssam sawmul = 1; 93329832Ssam shift; 93429832Ssam if (val == LP) goto base; 93529832Ssam if (val == LITOP) goto imm; 93629832Ssam if (val == SIZESPEC) goto sizespec; 93729832Ssam if (INTOKSET(val, 93829832Ssam EBEGOPS 93929832Ssam +YUKKYEXPRBEG 94029832Ssam +SAFEEXPRBEG)) goto disp; 94129832Ssam ERROR("expression, '(' or '$' expected"); 94229832Ssam break; 94329832Ssam 94429832Ssam case LP: 94529832Ssam base: 94629832Ssam shift; /*consume the LP*/ 94729832Ssam /* 94829832Ssam * hack the ambiguity of 94929832Ssam * movl (expr) (rn), ... 95029832Ssam * note that (expr) could also 95129832Ssam * be (rn) (by special hole in the 95229832Ssam * grammar), which we ensure 95329832Ssam * means register indirection, instead 95429832Ssam * of an expression with value n 95529832Ssam */ 95629832Ssam if (val != REG && val != REGOP){ 95729832Ssam droppedLP = 1; 95829832Ssam val = exprparse(val, &(ap->a_xp)); 95929832Ssam droppedLP = 0; 96029832Ssam goto overdisp; 96129832Ssam } 96229832Ssam findreg(regno); 96329832Ssam shiftover(RP); 96429832Ssam if (val == PLUS){ 96529832Ssam shift; 96629832Ssam ap->a_atype = AINCR; 96729832Ssam if (sawmul && regno != 0xE) 96829832Ssam yyerror ("Autoincrement deferred register must be SP"); 96929832Ssam if (!(sawmul || regno == 0xE)) 97029832Ssam yyerror ("Autoincrement register must be SP"); 97129832Ssam } else 97229832Ssam ap->a_atype = ABASE; 97329832Ssam ap->a_areg1 = regno; 97429832Ssam goto index; 97529832Ssam 97629832Ssam case LITOP: 97729832Ssam imm: 97829832Ssam shift; 97929832Ssam expr(locxp, val); 98029832Ssam ap->a_atype = AIMM; 98129832Ssam ap->a_areg1 = 0; 98229832Ssam ap->a_xp = locxp; 98329832Ssam goto index; 98429832Ssam 98529832Ssam case MP: 98629832Ssam shift; /* -(reg) */ 98729832Ssam findreg(regno); 98829832Ssam if (regno != 0xE) 98929832Ssam yyerror ("Autodecrement register must be SP"); 99029832Ssam shiftover(RP); 99129832Ssam ap->a_atype = ADECR; 99229832Ssam ap->a_areg1 = regno; 99329832Ssam index: /*look for [reg] */ 99429832Ssam if (val == LB){ 99529832Ssam shift; 99629832Ssam findreg(regno); 99729832Ssam shiftover(RB); 99829832Ssam sawindex = 1; 99929832Ssam ap->a_areg2 = regno; 100029832Ssam } 100129832Ssam break; 100229832Ssam 100329832Ssam } /*end of the switch to process an arg*/ 100429832Ssam } /*end of processing an argument*/ 100529832Ssam 100629832Ssam if (sawmul){ 100729832Ssam /* 100829832Ssam * Make a concession for *(%r) 100929832Ssam * meaning *0(%r) 101029832Ssam */ 101129832Ssam if (ap->a_atype == ABASE) { 101229832Ssam ap->a_atype = ADISP; 101329832Ssam xp->e_xtype = XABS; 101429832Ssam xp->e_number = Znumber; 101529832Ssam xp->e_number.num_tag = TYPL; 101629832Ssam xp->e_xloc = 0; 101729832Ssam ap->a_xp = xp++; 101829832Ssam } 101929832Ssam ap->a_atype |= ASTAR; 102029832Ssam sawmul = 0; 102129832Ssam } 102229832Ssam if (sawindex){ 102329832Ssam ap->a_atype |= AINDX; 102429832Ssam sawindex = 0; 102529832Ssam } 102629832Ssam ap->a_dispsize = sawsize == 0 ? d124 : sawsize; 102729832Ssam if (val != CM) break; 102829832Ssam shiftover(CM); 102929832Ssam } /*processing all the arguments*/ 103029832Ssam 103129832Ssam if (argcnt > 6){ 103229832Ssam yyerror("More than 6 arguments"); 103329832Ssam goto errorfix; 103429832Ssam } 103529832Ssam 103629832Ssam /* 103729832Ssam * See if this is a case instruction, 103829832Ssam * so we can set up tests on the following 103929832Ssam * vector of branch displacements 104029832Ssam */ 104129832Ssam if (yyopcode == 0xfc) /* 'casel' instruction */ 104229832Ssam incasetable++; 104329832Ssam else 104429832Ssam incasetable = 0; 104529832Ssam 104629832Ssam insout(yyopcode, arglist, 104729832Ssam auxval == INSTn ? argcnt : - argcnt); 104829832Ssam break; 104929832Ssam 105029832Ssam case IQUAD: num_type = TYPQ; goto bignumlist; 105129832Ssam case IFFLOAT: num_type = TYPF; goto bignumlist; 105229832Ssam case IDFLOAT: num_type = TYPD; 105329832Ssam bignumlist: 105429832Ssam /* 105529832Ssam * eat a list of non 32 bit numbers. 105629832Ssam * IQUAD can, possibly, return 105729832Ssam * INT's, if the numbers are "small". 105829832Ssam * 105929832Ssam * The value of the numbers is coming back 106029832Ssam * as an expression, NOT in yybignum. 106129832Ssam */ 106229832Ssam shift; /* over the opener */ 106329832Ssam if ((val == BIGNUM) || (val == INT)){ 106429832Ssam do{ 106529832Ssam if ((val != BIGNUM) && (val != INT)){ 106629832Ssam ERROR(ty_float[num_type] 106729832Ssam ? "floating number expected" 106829832Ssam : "integer number expected" ); 106929832Ssam } 107029832Ssam dotp->e_xvalue += ty_nbyte[num_type]; 107129832Ssam if (passno == 2){ 107229832Ssam switch (num_type) { 107329832Ssam case TYPF: 107429832Ssam bwrite(&((struct exp *)yylval)->e_number.num_num.numFf_float.Ff_ulong, 107529832Ssam ty_nbyte[num_type], txtfil); 107629832Ssam if (liston) 107729832Ssam { 107829832Ssam long_out(((struct exp *)yylval)->e_number.num_num.numFf_float.Ff_ulong[0]); 107929832Ssam *layoutpos++ = ' '; 108029832Ssam } 108129832Ssam break; 108229832Ssam case TYPD: 108329832Ssam bwrite(&((struct exp *)yylval)->e_number.num_num.numFd_float.Fd_ulong[0], 108429832Ssam sizeof (long), txtfil); 108529832Ssam bwrite(&((struct exp *)yylval)->e_number.num_num.numFd_float.Fd_ulong[1], 108629832Ssam sizeof (long), txtfil); 108729832Ssam if (liston) 108829832Ssam { 108929832Ssam long_out(((struct exp *)yylval)->e_number.num_num.numIq_int.Iq_ulong[0]); 109029832Ssam long_out(((struct exp *)yylval)->e_number.num_num.numIq_int.Iq_ulong[1]); 109129832Ssam *layoutpos++ = ' '; 109229832Ssam } 109329832Ssam break; 109429832Ssam case TYPQ: 109529832Ssam bwrite(&((struct exp *)yylval)->e_number.num_num.numIq_int.Iq_ulong[1], 109629832Ssam sizeof (long), txtfil); 109729832Ssam bwrite(&((struct exp *)yylval)->e_number.num_num.numIq_int.Iq_ulong[0], 109829832Ssam sizeof (long), txtfil); 109929832Ssam if (liston) 110029832Ssam { 110129832Ssam long_out(((struct exp *)yylval)->e_number.num_num.numIq_int.Iq_ulong[1]); 110229832Ssam long_out(((struct exp *)yylval)->e_number.num_num.numIq_int.Iq_ulong[0]); 110329832Ssam *layoutpos++ = ' '; 110429832Ssam } 110529832Ssam break; 110629832Ssam } 110729832Ssam } 110829832Ssam xp = explist; 110929832Ssam shift; /* over this number */ 111029832Ssam if (auxval = (val == CM)) 111129832Ssam shift; /* over the comma */ 111229832Ssam } while (auxval); /* as long as there are commas */ 111329832Ssam } 111429832Ssam break; 111529832Ssam /* end of the case for initialized big numbers */ 111629832Ssam } /*end of the switch for looking at each reserved word*/ 111729832Ssam 111829832Ssam continue; 111929832Ssam 112029832Ssam errorfix: 112129832Ssam /* 112229832Ssam * got here by either requesting to skip to the 112329832Ssam * end of this statement, or by erroring out and 112429832Ssam * wanting to apply panic mode recovery 112529832Ssam */ 112629832Ssam while ( (val != NL) 112729832Ssam && (val != SEMI) 112829832Ssam && (val != PARSEEOF) 112929832Ssam ){ 113029832Ssam shift; 113129832Ssam } 113229832Ssam if (val == NL) 113329832Ssam lineno++; 113429832Ssam shift; 113529832Ssam 113629832Ssam } /*end of the loop to read the entire file, line by line*/ 113729832Ssam 113829832Ssam } /*end of yyparse*/ 113929832Ssam 114029832Ssam /* 114129832Ssam * Process a register declaration of the form 114229832Ssam * % <expr> 114329832Ssam * 114429832Ssam * Note: 114529832Ssam * The scanner has already processed funny registers of the form 114629832Ssam * %dd[+-]*, where dd is a decimal number in the range 00 to 15 (optional 114729832Ssam * preceding zero digit). If there was any space between the % and 114829832Ssam * the digit, the scanner wouldn't have recognized it, so we 114929832Ssam * hack it out here. 115029832Ssam */ 115129832Ssam inttoktype funnyreg(val, regnoback) /*what the read head will sit on*/ 115229832Ssam inttoktype val; /*what the read head is sitting on*/ 115329832Ssam int *regnoback; /*call by return*/ 115429832Ssam { 115529832Ssam reg struct exp *locxp; 115629832Ssam struct exp *loc1xp; 115729832Ssam struct exp **ptrloc1xp = & loc1xp; 115829832Ssam 115929832Ssam expr(locxp, val); /*and leave the current read head with value*/ 116029832Ssam if ( (passno == 2) && 116129832Ssam ( (locxp->e_xtype & XTYPE) != XABS 116229832Ssam || (locxp->e_xvalue < 0) 116329832Ssam || (locxp->e_xvalue >= 16) 116429832Ssam ) 116529832Ssam ){ 116629832Ssam yyerror("Illegal register"); 116729832Ssam return(0); 116829832Ssam } 116929832Ssam *regnoback = locxp->e_xvalue; 117029832Ssam return(val); 117129832Ssam } 117229832Ssam /* 117329832Ssam * Shift over error 117429832Ssam */ 117529832Ssam shiftoerror(token) 117629832Ssam int token; 117729832Ssam { 117829832Ssam char *tok_to_name(); 117929832Ssam yyerror("%s expected", tok_to_name(token)); 118029832Ssam } 118129832Ssam 118229832Ssam /*VARARGS1*/ 118329832Ssam yyerror(s, a1, a2,a3,a4,a5) 118429832Ssam char *s; 118529832Ssam { 118629832Ssam 118729832Ssam #define sink stdout 118829832Ssam 118929832Ssam if (anyerrs == 0 && anywarnings == 0 && ! silent) 119029832Ssam fprintf(sink, "Assembler:\n"); 119129832Ssam anyerrs++; 119229832Ssam if (silent) 119329832Ssam return; 119429832Ssam fprintf(sink, "\"%s\", line %d: ", dotsname, lineno); 119529832Ssam fprintf(sink, s, a1, a2,a3,a4,a5); 119629832Ssam fprintf(sink, "\n"); 119729832Ssam #undef sink 119829832Ssam } 119929832Ssam 120029832Ssam /*VARARGS1*/ 120129832Ssam yywarning(s, a1, a2,a3,a4,a5) 120229832Ssam char *s; 120329832Ssam { 120429832Ssam #define sink stdout 120529832Ssam if (anyerrs == 0 && anywarnings == 0 && ! silent) 120629832Ssam fprintf(sink, "Assembler:\n"); 120729832Ssam anywarnings++; 120829832Ssam if (silent) 120929832Ssam return; 121029832Ssam fprintf(sink, "\"%s\", line %d: WARNING: ", dotsname, lineno); 121129832Ssam fprintf(sink, s, a1, a2,a3,a4,a5); 121229832Ssam fprintf(sink, "\n"); 121329832Ssam #undef sink 121429832Ssam } 1215