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