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