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