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