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