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