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