1/* 2 * common code for all the assemblers 3 */ 4 5void 6pragpack(void) 7{ 8 while(getnsc() != '\n') 9 ; 10} 11 12void 13pragvararg(void) 14{ 15 while(getnsc() != '\n') 16 ; 17} 18 19void 20pragfpround(void) 21{ 22 while(getnsc() != '\n') 23 ; 24} 25 26void 27pragprofile(void) 28{ 29 while(getnsc() != '\n') 30 ; 31} 32 33void 34pragincomplete(void) 35{ 36 while(getnsc() != '\n') 37 ; 38} 39 40/* 41 * real allocs 42 */ 43void* 44alloc(long n) 45{ 46 void *p; 47 48 while((uintptr)hunk & MAXALIGN) { 49 hunk++; 50 nhunk--; 51 } 52 while(nhunk < n) 53 gethunk(); 54 p = hunk; 55 nhunk -= n; 56 hunk += n; 57 return p; 58} 59 60void* 61allocn(void *p, long on, long n) 62{ 63 void *q; 64 65 q = (uchar*)p + on; 66 if(q != hunk || nhunk < n) { 67 while(nhunk < on+n) 68 gethunk(); 69 memmove(hunk, p, on); 70 p = hunk; 71 hunk += on; 72 nhunk -= on; 73 } 74 hunk += n; 75 nhunk -= n; 76 return p; 77} 78 79void 80setinclude(char *p) 81{ 82 int i; 83 84 if(p == 0) 85 return; 86 for(i=1; i < ninclude; i++) 87 if(strcmp(p, include[i]) == 0) 88 return; 89 90 if(ninclude >= nelem(include)) { 91 yyerror("ninclude too small %d", nelem(include)); 92 exits("ninclude"); 93 } 94 include[ninclude++] = p; 95} 96 97void 98errorexit(void) 99{ 100 101 if(outfile) 102 remove(outfile); 103 exits("error"); 104} 105 106void 107pushio(void) 108{ 109 Io *i; 110 111 i = iostack; 112 if(i == I) { 113 yyerror("botch in pushio"); 114 errorexit(); 115 } 116 i->p = fi.p; 117 i->c = fi.c; 118} 119 120void 121newio(void) 122{ 123 Io *i; 124 static int pushdepth = 0; 125 126 i = iofree; 127 if(i == I) { 128 pushdepth++; 129 if(pushdepth > 1000) { 130 yyerror("macro/io expansion too deep"); 131 errorexit(); 132 } 133 i = alloc(sizeof(*i)); 134 } else 135 iofree = i->link; 136 i->c = 0; 137 i->f = -1; 138 ionext = i; 139} 140 141void 142newfile(char *s, int f) 143{ 144 Io *i; 145 146 i = ionext; 147 i->link = iostack; 148 iostack = i; 149 i->f = f; 150 if(f < 0) 151 i->f = open(s, 0); 152 if(i->f < 0) { 153 yyerror("%ca: %r: %s", thechar, s); 154 errorexit(); 155 } 156 fi.c = 0; 157 linehist(s, 0); 158} 159 160Sym* 161slookup(char *s) 162{ 163 164 strcpy(symb, s); 165 return lookup(); 166} 167 168Sym* 169lookup(void) 170{ 171 Sym *s; 172 long h; 173 char *p; 174 int c, l; 175 176 h = 0; 177 for(p=symb; c = *p; p++) 178 h = h+h+h + c; 179 l = (p - symb) + 1; 180 if(h < 0) 181 h = ~h; 182 h %= NHASH; 183 c = symb[0]; 184 for(s = hash[h]; s != S; s = s->link) { 185 if(s->name[0] != c) 186 continue; 187 if(memcmp(s->name, symb, l) == 0) 188 return s; 189 } 190 s = alloc(sizeof(*s)); 191 s->name = alloc(l); 192 memmove(s->name, symb, l); 193 194 s->link = hash[h]; 195 hash[h] = s; 196 syminit(s); 197 return s; 198} 199 200long 201yylex(void) 202{ 203 int c, c1; 204 char *cp; 205 Sym *s; 206 207 c = peekc; 208 if(c != IGN) { 209 peekc = IGN; 210 goto l1; 211 } 212l0: 213 c = GETC(); 214 215l1: 216 if(c == EOF) { 217 peekc = EOF; 218 return -1; 219 } 220 if(isspace(c)) { 221 if(c == '\n') { 222 lineno++; 223 return ';'; 224 } 225 goto l0; 226 } 227 if(isalpha(c)) 228 goto talph; 229 if(isdigit(c)) 230 goto tnum; 231 switch(c) 232 { 233 case '\n': 234 lineno++; 235 return ';'; 236 237 case '#': 238 domacro(); 239 goto l0; 240 241 case '.': 242 c = GETC(); 243 if(isalpha(c)) { 244 cp = symb; 245 *cp++ = '.'; 246 goto aloop; 247 } 248 if(isdigit(c)) { 249 cp = symb; 250 *cp++ = '.'; 251 goto casedot; 252 } 253 peekc = c; 254 return '.'; 255 256 talph: 257 case '_': 258 case '@': 259 cp = symb; 260 261 aloop: 262 *cp++ = c; 263 c = GETC(); 264 if(isalpha(c) || isdigit(c) || c == '_' || c == '$') 265 goto aloop; 266 *cp = 0; 267 peekc = c; 268 s = lookup(); 269 if(s->macro) { 270 newio(); 271 cp = ionext->b; 272 macexpand(s, cp); 273 pushio(); 274 ionext->link = iostack; 275 iostack = ionext; 276 fi.p = cp; 277 fi.c = strlen(cp); 278 if(peekc != IGN) { 279 cp[fi.c++] = peekc; 280 cp[fi.c] = 0; 281 peekc = IGN; 282 } 283 goto l0; 284 } 285 if(s->type == 0) 286 s->type = LNAME; 287 if(s->type == LNAME || 288 s->type == LVAR || 289 s->type == LLAB) { 290 yylval.sym = s; 291 return s->type; 292 } 293 yylval.lval = s->value; 294 return s->type; 295 296 tnum: 297 cp = symb; 298 if(c != '0') 299 goto dc; 300 *cp++ = c; 301 c = GETC(); 302 c1 = 3; 303 if(c == 'x' || c == 'X') { 304 c1 = 4; 305 c = GETC(); 306 } else 307 if(c < '0' || c > '7') 308 goto dc; 309 yylval.lval = 0; 310 for(;;) { 311 if(c >= '0' && c <= '9') { 312 if(c > '7' && c1 == 3) 313 break; 314 yylval.lval <<= c1; 315 yylval.lval += c - '0'; 316 c = GETC(); 317 continue; 318 } 319 if(c1 == 3) 320 break; 321 if(c >= 'A' && c <= 'F') 322 c += 'a' - 'A'; 323 if(c >= 'a' && c <= 'f') { 324 yylval.lval <<= c1; 325 yylval.lval += c - 'a' + 10; 326 c = GETC(); 327 continue; 328 } 329 break; 330 } 331 goto ncu; 332 333 dc: 334 for(;;) { 335 if(!isdigit(c)) 336 break; 337 *cp++ = c; 338 c = GETC(); 339 } 340 if(c == '.') 341 goto casedot; 342 if(c == 'e' || c == 'E') 343 goto casee; 344 *cp = 0; 345 if(sizeof(yylval.lval) == sizeof(vlong)) 346 yylval.lval = strtoll(symb, nil, 10); 347 else 348 yylval.lval = strtol(symb, nil, 10); 349 350 ncu: 351 while(c == 'U' || c == 'u' || c == 'l' || c == 'L') 352 c = GETC(); 353 peekc = c; 354 return LCONST; 355 356 casedot: 357 for(;;) { 358 *cp++ = c; 359 c = GETC(); 360 if(!isdigit(c)) 361 break; 362 } 363 if(c == 'e' || c == 'E') 364 goto casee; 365 goto caseout; 366 367 casee: 368 *cp++ = 'e'; 369 c = GETC(); 370 if(c == '+' || c == '-') { 371 *cp++ = c; 372 c = GETC(); 373 } 374 while(isdigit(c)) { 375 *cp++ = c; 376 c = GETC(); 377 } 378 379 caseout: 380 *cp = 0; 381 peekc = c; 382 if(FPCHIP) { 383 yylval.dval = atof(symb); 384 return LFCONST; 385 } 386 yyerror("assembler cannot interpret fp constants"); 387 yylval.lval = 1L; 388 return LCONST; 389 390 case '"': 391 memcpy(yylval.sval, nullgen.sval, sizeof(yylval.sval)); 392 cp = yylval.sval; 393 c1 = 0; 394 for(;;) { 395 c = escchar('"'); 396 if(c == EOF) 397 break; 398 if(c1 < sizeof(yylval.sval)) 399 *cp++ = c; 400 c1++; 401 } 402 if(c1 > sizeof(yylval.sval)) 403 yyerror("string constant too long"); 404 return LSCONST; 405 406 case '\'': 407 c = escchar('\''); 408 if(c == EOF) 409 c = '\''; 410 if(escchar('\'') != EOF) 411 yyerror("missing '"); 412 yylval.lval = c; 413 return LCONST; 414 415 case '/': 416 c1 = GETC(); 417 if(c1 == '/') { 418 for(;;) { 419 c = GETC(); 420 if(c == '\n') 421 goto l1; 422 if(c == EOF) { 423 yyerror("eof in comment"); 424 errorexit(); 425 } 426 } 427 } 428 if(c1 == '*') { 429 for(;;) { 430 c = GETC(); 431 while(c == '*') { 432 c = GETC(); 433 if(c == '/') 434 goto l0; 435 } 436 if(c == EOF) { 437 yyerror("eof in comment"); 438 errorexit(); 439 } 440 if(c == '\n') 441 lineno++; 442 } 443 } 444 break; 445 446 default: 447 return c; 448 } 449 peekc = c1; 450 return c; 451} 452 453int 454getc(void) 455{ 456 int c; 457 458 c = peekc; 459 if(c != IGN) { 460 peekc = IGN; 461 return c; 462 } 463 c = GETC(); 464 if(c == '\n') 465 lineno++; 466 if(c == EOF) { 467 yyerror("End of file"); 468 errorexit(); 469 } 470 return c; 471} 472 473int 474getnsc(void) 475{ 476 int c; 477 478 for(;;) { 479 c = getc(); 480 if(!isspace(c) || c == '\n') 481 return c; 482 } 483} 484 485void 486unget(int c) 487{ 488 489 peekc = c; 490 if(c == '\n') 491 lineno--; 492} 493 494int 495escchar(int e) 496{ 497 int c, l; 498 499loop: 500 c = getc(); 501 if(c == '\n') { 502 yyerror("newline in string"); 503 return EOF; 504 } 505 if(c != '\\') { 506 if(c == e) 507 return EOF; 508 return c; 509 } 510 c = getc(); 511 if(c >= '0' && c <= '7') { 512 l = c - '0'; 513 c = getc(); 514 if(c >= '0' && c <= '7') { 515 l = l*8 + c-'0'; 516 c = getc(); 517 if(c >= '0' && c <= '7') { 518 l = l*8 + c-'0'; 519 return l; 520 } 521 } 522 peekc = c; 523 return l; 524 } 525 switch(c) 526 { 527 case '\n': goto loop; 528 case 'n': return '\n'; 529 case 't': return '\t'; 530 case 'b': return '\b'; 531 case 'r': return '\r'; 532 case 'f': return '\f'; 533 case 'a': return 0x07; 534 case 'v': return 0x0b; 535 case 'z': return 0x00; 536 } 537 return c; 538} 539 540void 541pinit(char *f) 542{ 543 int i; 544 Sym *s; 545 546 lineno = 1; 547 newio(); 548 newfile(f, -1); 549 pc = 0; 550 peekc = IGN; 551 sym = 1; 552 for(i=0; i<NSYM; i++) { 553 h[i].type = 0; 554 h[i].sym = S; 555 } 556 for(i=0; i<NHASH; i++) 557 for(s = hash[i]; s != S; s = s->link) 558 s->macro = 0; 559} 560 561int 562filbuf(void) 563{ 564 Io *i; 565 566loop: 567 i = iostack; 568 if(i == I) 569 return EOF; 570 if(i->f < 0) 571 goto pop; 572 fi.c = read(i->f, i->b, BUFSIZ) - 1; 573 if(fi.c < 0) { 574 close(i->f); 575 linehist(0, 0); 576 goto pop; 577 } 578 fi.p = i->b + 1; 579 return i->b[0]; 580 581pop: 582 iostack = i->link; 583 i->link = iofree; 584 iofree = i; 585 i = iostack; 586 if(i == I) 587 return EOF; 588 fi.p = i->p; 589 fi.c = i->c; 590 if(--fi.c < 0) 591 goto loop; 592 return *fi.p++; 593} 594 595void 596yyerror(char *a, ...) 597{ 598 char buf[200]; 599 va_list arg; 600 601 /* 602 * hack to intercept message from yaccpar 603 */ 604 if(strcmp(a, "syntax error") == 0) { 605 yyerror("syntax error, last name: %s", symb); 606 return; 607 } 608 prfile(lineno); 609 va_start(arg, a); 610 vseprint(buf, buf+sizeof(buf), a, arg); 611 va_end(arg); 612 print("%s\n", buf); 613 nerrors++; 614 if(nerrors > 10) { 615 print("too many errors\n"); 616 errorexit(); 617 } 618} 619 620void 621prfile(long l) 622{ 623 int i, n; 624 Hist a[HISTSZ], *h; 625 long d; 626 627 n = 0; 628 for(h = hist; h != H; h = h->link) { 629 if(l < h->line) 630 break; 631 if(h->name) { 632 if(h->offset == 0) { 633 if(n >= 0 && n < HISTSZ) 634 a[n] = *h; 635 n++; 636 continue; 637 } 638 if(n > 0 && n < HISTSZ) 639 if(a[n-1].offset == 0) { 640 a[n] = *h; 641 n++; 642 } else 643 a[n-1] = *h; 644 continue; 645 } 646 n--; 647 if(n >= 0 && n < HISTSZ) { 648 d = h->line - a[n].line; 649 for(i=0; i<n; i++) 650 a[i].line += d; 651 } 652 } 653 if(n > HISTSZ) 654 n = HISTSZ; 655 for(i=0; i<n; i++) 656 print("%s:%ld ", a[i].name, (long)(l-a[i].line+a[i].offset+1)); 657} 658 659void 660ieeedtod(Ieee *ieee, double native) 661{ 662 double fr, ho, f; 663 int exp; 664 665 if(native < 0) { 666 ieeedtod(ieee, -native); 667 ieee->h |= 0x80000000L; 668 return; 669 } 670 if(native == 0) { 671 ieee->l = 0; 672 ieee->h = 0; 673 return; 674 } 675 fr = frexp(native, &exp); 676 f = 2097152L; /* shouldnt use fp constants here */ 677 fr = modf(fr*f, &ho); 678 ieee->h = ho; 679 ieee->h &= 0xfffffL; 680 ieee->h |= (exp+1022L) << 20; 681 f = 65536L; 682 fr = modf(fr*f, &ho); 683 ieee->l = ho; 684 ieee->l <<= 16; 685 ieee->l |= (long)(fr*f); 686} 687