|
|
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: (void)sprintf (layoutpos, "%4ld ", lineno);
193: layoutpos += 6;
194: long_out (dotp->e_xvalue);
195: if (dotp->e_xvalue >= datbase)
196: (void)sprintf (layoutpos," * ");
197: else
198: (void)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: (void)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: (void)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: (void)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_LCSYM:
708: stpt->s_dest = (struct symtab *)exprisname;
709: stpt->s_type |= STABFLAG;
710: case N_GSYM:
711: case N_FNAME:
712: case N_RSYM:
713: case N_SSYM:
714: case N_LSYM:
715: case N_PSYM:
716: case N_BCOMM:
717: case N_ECOMM:
718: case N_LENG:
719: stpt->s_tag = STABFIXED;
720: break;
721: default:
722: stpt->s_tag = STABFLOATING;
723: break;
724: }
725: } else
726: stpt->s_tag = STABFIXED;
727: }
728: else { /*really have a name*/
729: stpt->s_dest = locxp->e_xname;
730: stpt->s_index = p->s_index;
731: stpt->s_type = p->s_type | STABFLAG;
732: /*
733: * We will assign a more accruate
734: * guess of locxp's location when
735: * we sort the symbol table
736: * The final value of value is
737: * given by stabfix()
738: */
739: /*
740: * For exprs of the form (name + value) one needs to remember locxp->e_xvalue
741: * for use in stabfix. The right place to keep this is in stpt->s_value
742: * however this gets corrupted at an unknown point.
743: * As a bandaid hack the value is preserved in s_desc and s_other (a
744: * short and a char). This destroys these two values and will
745: * be fixed. May 19 ,1983 Alastair Fyfe
746: */
747: if(locxp->e_xvalue) {
748: stpt->s_other = (locxp->e_xvalue >> 16);
749: stpt->s_desc = (locxp->e_xvalue & 0x0000ffff);
750: stpt->s_tag = STABFLOATING;
751: }
752: }
753: /*
754: * tokptr now points at one token beyond
755: * the current token stored in val and yylval,
756: * which are the next tokens after the end of
757: * this .stab directive. This next token must
758: * be either a SEMI or NL, so is of width just
759: * one. Therefore, to point to the next token
760: * after the end of this stab, just back up one..
761: */
762: buildskip(stabstart, (bytetoktype *)tokptr - sizeof(bytetoktype));
763: break; /*end of the .stab*/
764:
765: case ISTABDOT:
766: stabname = ".stabd";
767: stpt = (struct symtab *)yylval;
768: /*
769: * We clobber everything after the
770: * .stabd and its pointer... we MUST
771: * be able to get back to this .stabd
772: * so that we can resolve its final value
773: */
774: stabstart = tokptr;
775: shift; /*over the ISTABDOT*/
776: if (passno == 1){
777: expr(locxp, val);
778: if (! (locxp->e_xvalue & STABTYPS)){
779: yyerror("Invalid type in .stabd");
780: goto errorfix;
781: }
782: stpt->s_ptype = locxp->e_xvalue;
783: shiftover(CM);
784: expr(locxp, val);
785: stpt->s_other = locxp->e_xvalue;
786: shiftover(CM);
787: expr(locxp, val);
788: stpt->s_desc = locxp->e_xvalue;
789: /*
790: *
791: * Now, clobber everything but the
792: * .stabd pseudo and the pointer
793: * to its symbol table entry
794: * tokptr points to the next token,
795: * build the skip up to this
796: */
797: buildskip(stabstart, (bytetoktype *)tokptr - sizeof(bytetoktype));
798: }
799: /*
800: * pass 1: Assign a good guess for its position
801: * (ensures they are sorted into right place)/
802: * pass 2: Fix the actual value
803: */
804: stpt->s_value = dotp->e_xvalue;
805: stpt->s_index = dotp - usedot;
806: stpt->s_tag = STABFLOATING; /*although it has no effect in pass 2*/
807: break;
808:
809: case ISTABNONE: stabname = ".stabn"; goto shortstab;
810:
811: case ISTABSTR: stabname = ".stabs";
812: shortstab:
813: auxval = val;
814: if (passno == 2) goto errorfix;
815: stpt = (struct symtab *)yylval;
816: stabstart = tokptr;
817: (bytetoktype *)stabstart -= sizeof(struct symtab *);
818: (bytetoktype *)stabstart -= sizeof(bytetoktype);
819: shift;
820: if (auxval == ISTABSTR){
821: stringp = (struct strdesc *)yylval;
822: shiftover(STRING);
823: stpt->s_name = (char *)stringp;
824: /*
825: * We want the trailing null included in this string.
826: * We utilize the cheat the string scanner used,
827: * and merely increment the string length
828: */
829: stringp->sd_strlen += 1;
830: shiftover(CM);
831: } else {
832: stpt->s_name = (char *)savestr("\0", 0, STR_BOTH);
833: }
834: goto tailstab;
835: break;
836:
837: case ICOMM: /* .comm <name> , <expr> */
838: case ILCOMM: /* .lcomm <name> , <expr> */
839: auxval = val;
840: shift;
841: np = (struct symtab *)yylval;
842: shiftover(NAME);
843: shiftover(CM);
844: expr(locxp, val);
845:
846: if ( (locxp->e_xtype & XTYPE) != XABS) /* tekmdp */
847: yyerror("comm size not absolute");
848: if (passno == 1 && (np->s_type&XTYPE) != XUNDEF)
849: yyerror("Redefinition of %s", FETCHNAME(np));
850: if (passno==1) {
851: np->s_value = locxp->e_xvalue;
852: if (auxval == ICOMM)
853: np->s_type |= XXTRN;
854: else {
855: np->s_type &= ~XTYPE;
856: np->s_type |= XBSS;
857: }
858: }
859: break;
860:
861: case IALIGN: /* .align <expr> */
862: stpt = (struct symtab *)yylval;
863: shift;
864: expr(locxp, val);
865: if ((dotp->e_xtype & XTYPE) == XDATA)
866: djalign(locxp, stpt);
867: else
868: jalign(locxp, stpt);
869: break;
870:
871: case INST0: /* instructions w/o arguments*/
872: incasetable = 0;
873: insout(yyopcode, (struct arg *)0, 0);
874: shift;
875: break;
876:
877: case INSTn: /* instructions with arguments*/
878: case IJXXX: /* UNIX style jump instructions */
879: auxval = val;
880: /*
881: * Code to process an argument list
882: */
883: ap = arglist;
884: xp = explist;
885:
886: shift; /* bring in the first token for the arg list*/
887:
888: for (argcnt = 1; argcnt <= 6; argcnt++, ap++){
889: /*
890: * code to process an argument proper
891: */
892: sawindex = sawmul = sawsize = 0;
893: {
894: switch(val) {
895:
896: default:
897: disp:
898: if( !(INTOKSET(val,
899: EBEGOPS
900: +YUKKYEXPRBEG
901: +SAFEEXPRBEG)) ) {
902: ERROR("expression expected");
903: }
904: expr(ap->a_xp,val);
905: overdisp:
906: if ( val == LP || sawsize){
907: shiftover(LP);
908: findreg(regno);
909: shiftover(RP);
910: ap->a_atype = ADISP;
911: ap->a_areg1 = regno;
912: } else {
913: ap->a_atype = AEXP;
914: ap->a_areg1 = 0;
915: }
916: goto index;
917:
918: case SIZESPEC:
919: sizespec:
920: sawsize = yylval;
921: shift;
922: goto disp;
923:
924: case REG:
925: case REGOP:
926: findreg(regno);
927: ap->a_atype = AREG;
928: ap->a_areg1 = regno;
929: break;
930:
931: case MUL:
932: sawmul = 1;
933: shift;
934: if (val == LP) goto base;
935: if (val == LITOP) goto imm;
936: if (val == SIZESPEC) goto sizespec;
937: if (INTOKSET(val,
938: EBEGOPS
939: +YUKKYEXPRBEG
940: +SAFEEXPRBEG)) goto disp;
941: ERROR("expression, '(' or '$' expected");
942: break;
943:
944: case LP:
945: base:
946: shift; /*consume the LP*/
947: /*
948: * hack the ambiguity of
949: * movl (expr) (rn), ...
950: * note that (expr) could also
951: * be (rn) (by special hole in the
952: * grammar), which we ensure
953: * means register indirection, instead
954: * of an expression with value n
955: */
956: if (val != REG && val != REGOP){
957: droppedLP = 1;
958: val = exprparse(val, &(ap->a_xp));
959: droppedLP = 0;
960: goto overdisp;
961: }
962: findreg(regno);
963: shiftover(RP);
964: if (val == PLUS){
965: shift;
966: ap->a_atype = AINCR;
967: if (sawmul && regno != 0xE)
968: yyerror ("Autoincrement deferred register must be SP");
969: if (!(sawmul || regno == 0xE))
970: yyerror ("Autoincrement register must be SP");
971: } else
972: ap->a_atype = ABASE;
973: ap->a_areg1 = regno;
974: goto index;
975:
976: case LITOP:
977: imm:
978: shift;
979: expr(locxp, val);
980: ap->a_atype = AIMM;
981: ap->a_areg1 = 0;
982: ap->a_xp = locxp;
983: goto index;
984:
985: case MP:
986: shift; /* -(reg) */
987: findreg(regno);
988: if (regno != 0xE)
989: yyerror ("Autodecrement register must be SP");
990: shiftover(RP);
991: ap->a_atype = ADECR;
992: ap->a_areg1 = regno;
993: index: /*look for [reg] */
994: if (val == LB){
995: shift;
996: findreg(regno);
997: shiftover(RB);
998: sawindex = 1;
999: ap->a_areg2 = regno;
1000: }
1001: break;
1002:
1003: } /*end of the switch to process an arg*/
1004: } /*end of processing an argument*/
1005:
1006: if (sawmul){
1007: /*
1008: * Make a concession for *(%r)
1009: * meaning *0(%r)
1010: */
1011: if (ap->a_atype == ABASE) {
1012: ap->a_atype = ADISP;
1013: xp->e_xtype = XABS;
1014: xp->e_number = Znumber;
1015: xp->e_number.num_tag = TYPL;
1016: xp->e_xloc = 0;
1017: ap->a_xp = xp++;
1018: }
1019: ap->a_atype |= ASTAR;
1020: sawmul = 0;
1021: }
1022: if (sawindex){
1023: ap->a_atype |= AINDX;
1024: sawindex = 0;
1025: }
1026: ap->a_dispsize = sawsize == 0 ? d124 : sawsize;
1027: if (val != CM) break;
1028: shiftover(CM);
1029: } /*processing all the arguments*/
1030:
1031: if (argcnt > 6){
1032: yyerror("More than 6 arguments");
1033: goto errorfix;
1034: }
1035:
1036: /*
1037: * See if this is a case instruction,
1038: * so we can set up tests on the following
1039: * vector of branch displacements
1040: */
1041: if (yyopcode == 0xfc) /* 'casel' instruction */
1042: incasetable++;
1043: else
1044: incasetable = 0;
1045:
1046: insout(yyopcode, arglist,
1047: auxval == INSTn ? argcnt : - argcnt);
1048: break;
1049:
1050: case IQUAD: num_type = TYPQ; goto bignumlist;
1051: case IFFLOAT: num_type = TYPF; goto bignumlist;
1052: case IDFLOAT: num_type = TYPD;
1053: bignumlist:
1054: /*
1055: * eat a list of non 32 bit numbers.
1056: * IQUAD can, possibly, return
1057: * INT's, if the numbers are "small".
1058: *
1059: * The value of the numbers is coming back
1060: * as an expression, NOT in yybignum.
1061: */
1062: shift; /* over the opener */
1063: if ((val == BIGNUM) || (val == INT)){
1064: do{
1065: if ((val != BIGNUM) && (val != INT)){
1066: ERROR(ty_float[num_type]
1067: ? "floating number expected"
1068: : "integer number expected" );
1069: }
1070: dotp->e_xvalue += ty_nbyte[num_type];
1071: if (passno == 2){
1072: switch (num_type) {
1073: case TYPF:
1074: bwrite(&((struct exp *)yylval)->e_number.num_num.numFf_float.Ff_ulong,
1075: ty_nbyte[num_type], txtfil);
1076: if (liston)
1077: {
1078: long_out(((struct exp *)yylval)->e_number.num_num.numFf_float.Ff_ulong[0]);
1079: *layoutpos++ = ' ';
1080: }
1081: break;
1082: case TYPD:
1083: bwrite(&((struct exp *)yylval)->e_number.num_num.numFd_float.Fd_ulong[0],
1084: sizeof (long), txtfil);
1085: bwrite(&((struct exp *)yylval)->e_number.num_num.numFd_float.Fd_ulong[1],
1086: sizeof (long), txtfil);
1087: if (liston)
1088: {
1089: long_out(((struct exp *)yylval)->e_number.num_num.numIq_int.Iq_ulong[0]);
1090: long_out(((struct exp *)yylval)->e_number.num_num.numIq_int.Iq_ulong[1]);
1091: *layoutpos++ = ' ';
1092: }
1093: break;
1094: case TYPQ:
1095: bwrite(&((struct exp *)yylval)->e_number.num_num.numIq_int.Iq_ulong[1],
1096: sizeof (long), txtfil);
1097: bwrite(&((struct exp *)yylval)->e_number.num_num.numIq_int.Iq_ulong[0],
1098: sizeof (long), txtfil);
1099: if (liston)
1100: {
1101: long_out(((struct exp *)yylval)->e_number.num_num.numIq_int.Iq_ulong[1]);
1102: long_out(((struct exp *)yylval)->e_number.num_num.numIq_int.Iq_ulong[0]);
1103: *layoutpos++ = ' ';
1104: }
1105: break;
1106: }
1107: }
1108: xp = explist;
1109: shift; /* over this number */
1110: if (auxval = (val == CM))
1111: shift; /* over the comma */
1112: } while (auxval); /* as long as there are commas */
1113: }
1114: break;
1115: /* end of the case for initialized big numbers */
1116: } /*end of the switch for looking at each reserved word*/
1117:
1118: continue;
1119:
1120: errorfix:
1121: /*
1122: * got here by either requesting to skip to the
1123: * end of this statement, or by erroring out and
1124: * wanting to apply panic mode recovery
1125: */
1126: while ( (val != NL)
1127: && (val != SEMI)
1128: && (val != PARSEEOF)
1129: ){
1130: shift;
1131: }
1132: if (val == NL)
1133: lineno++;
1134: shift;
1135:
1136: } /*end of the loop to read the entire file, line by line*/
1137:
1138: } /*end of yyparse*/
1139:
1140: /*
1141: * Process a register declaration of the form
1142: * % <expr>
1143: *
1144: * Note:
1145: * The scanner has already processed funny registers of the form
1146: * %dd[+-]*, where dd is a decimal number in the range 00 to 15 (optional
1147: * preceding zero digit). If there was any space between the % and
1148: * the digit, the scanner wouldn't have recognized it, so we
1149: * hack it out here.
1150: */
1151: inttoktype funnyreg(val, regnoback) /*what the read head will sit on*/
1152: inttoktype val; /*what the read head is sitting on*/
1153: int *regnoback; /*call by return*/
1154: {
1155: reg struct exp *locxp;
1156: struct exp *loc1xp;
1157: struct exp **ptrloc1xp = & loc1xp;
1158:
1159: expr(locxp, val); /*and leave the current read head with value*/
1160: if ( (passno == 2) &&
1161: ( (locxp->e_xtype & XTYPE) != XABS
1162: || (locxp->e_xvalue < 0)
1163: || (locxp->e_xvalue >= 16)
1164: )
1165: ){
1166: yyerror("Illegal register");
1167: return(0);
1168: }
1169: *regnoback = locxp->e_xvalue;
1170: return(val);
1171: }
1172: /*
1173: * Shift over error
1174: */
1175: shiftoerror(token)
1176: int token;
1177: {
1178: char *tok_to_name();
1179: yyerror("%s expected", tok_to_name(token));
1180: }
1181:
1182: /*VARARGS1*/
1183: yyerror(s, a1, a2,a3,a4,a5)
1184: char *s;
1185: {
1186:
1187: #define sink stdout
1188:
1189: if (anyerrs == 0 && anywarnings == 0 && ! silent)
1190: fprintf(sink, "Assembler:\n");
1191: anyerrs++;
1192: if (silent)
1193: return;
1194: fprintf(sink, "\"%s\", line %d: ", dotsname, lineno);
1195: fprintf(sink, s, a1, a2,a3,a4,a5);
1196: fprintf(sink, "\n");
1197: #undef sink
1198: }
1199:
1200: /*VARARGS1*/
1201: yywarning(s, a1, a2,a3,a4,a5)
1202: char *s;
1203: {
1204: #define sink stdout
1205: if (anyerrs == 0 && anywarnings == 0 && ! silent)
1206: fprintf(sink, "Assembler:\n");
1207: anywarnings++;
1208: if (silent)
1209: return;
1210: fprintf(sink, "\"%s\", line %d: WARNING: ", dotsname, lineno);
1211: fprintf(sink, s, a1, a2,a3,a4,a5);
1212: fprintf(sink, "\n");
1213: #undef sink
1214: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.