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