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