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