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