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