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