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