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

Defined functions

funnyreg defined in line 955; used 2 times
shiftoerror defined in line 979; used 1 times
yyparse defined in line 52; used 3 times

Defined variables

UDotsname defined in line 50; used 2 times
arglist defined in line 44; used 8 times
bitfield defined in line 20; used 5 times
bitoff defined in line 21; used 16 times
curlen defined in line 22; used 24 times
droppedLP defined in line 31; used 2 times
explist defined in line 43; used 12 times
exprisname defined in line 30; used 2 times
genref defined in line 18; used 6 times
lgensym defined in line 17; used 8 times
sccsid defined in line 8; never used
tokensets defined in line 48; used 1 times
xp defined in line 42; used 85 times
yybignum defined in line 38; never used
yylval defined in line 36; used 16 times
yyopcode defined in line 37; used 4 times
yytext defined in line 35; used 16 times

Defined macros

sink defined in line 1008; used 10 times
Last modified: 1985-06-20
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2430
Valid CSS Valid XHTML 1.0 Strict