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