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 lineno++; 422 goto l0; 423 } 424 if(c == EOF) { 425 yyerror("eof in comment"); 426 errorexit(); 427 } 428 } 429 } 430 if(c1 == '*') { 431 for(;;) { 432 c = GETC(); 433 while(c == '*') { 434 c = GETC(); 435 if(c == '/') 436 goto l0; 437 } 438 if(c == EOF) { 439 yyerror("eof in comment"); 440 errorexit(); 441 } 442 if(c == '\n') 443 lineno++; 444 } 445 } 446 break; 447 448 default: 449 return c; 450 } 451 peekc = c1; 452 return c; 453} 454 455int 456getc(void) 457{ 458 int c; 459 460 c = peekc; 461 if(c != IGN) { 462 peekc = IGN; 463 return c; 464 } 465 c = GETC(); 466 if(c == '\n') 467 lineno++; 468 if(c == EOF) { 469 yyerror("End of file"); 470 errorexit(); 471 } 472 return c; 473} 474 475int 476getnsc(void) 477{ 478 int c; 479 480 for(;;) { 481 c = getc(); 482 if(!isspace(c) || c == '\n') 483 return c; 484 } 485} 486 487void 488unget(int c) 489{ 490 491 peekc = c; 492 if(c == '\n') 493 lineno--; 494} 495 496int 497escchar(int e) 498{ 499 int c, l; 500 501loop: 502 c = getc(); 503 if(c == '\n') { 504 yyerror("newline in string"); 505 return EOF; 506 } 507 if(c != '\\') { 508 if(c == e) 509 return EOF; 510 return c; 511 } 512 c = getc(); 513 if(c >= '0' && c <= '7') { 514 l = c - '0'; 515 c = getc(); 516 if(c >= '0' && c <= '7') { 517 l = l*8 + c-'0'; 518 c = getc(); 519 if(c >= '0' && c <= '7') { 520 l = l*8 + c-'0'; 521 return l; 522 } 523 } 524 peekc = c; 525 return l; 526 } 527 switch(c) 528 { 529 case '\n': goto loop; 530 case 'n': return '\n'; 531 case 't': return '\t'; 532 case 'b': return '\b'; 533 case 'r': return '\r'; 534 case 'f': return '\f'; 535 case 'a': return 0x07; 536 case 'v': return 0x0b; 537 case 'z': return 0x00; 538 } 539 return c; 540} 541 542void 543pinit(char *f) 544{ 545 int i; 546 Sym *s; 547 548 lineno = 1; 549 newio(); 550 newfile(f, -1); 551 pc = 0; 552 peekc = IGN; 553 sym = 1; 554 for(i=0; i<NSYM; i++) { 555 h[i].type = 0; 556 h[i].sym = S; 557 } 558 for(i=0; i<NHASH; i++) 559 for(s = hash[i]; s != S; s = s->link) 560 s->macro = 0; 561} 562 563int 564filbuf(void) 565{ 566 Io *i; 567 568loop: 569 i = iostack; 570 if(i == I) 571 return EOF; 572 if(i->f < 0) 573 goto pop; 574 fi.c = read(i->f, i->b, BUFSIZ) - 1; 575 if(fi.c < 0) { 576 close(i->f); 577 linehist(0, 0); 578 goto pop; 579 } 580 fi.p = i->b + 1; 581 return i->b[0]; 582 583pop: 584 iostack = i->link; 585 i->link = iofree; 586 iofree = i; 587 i = iostack; 588 if(i == I) 589 return EOF; 590 fi.p = i->p; 591 fi.c = i->c; 592 if(--fi.c < 0) 593 goto loop; 594 return *fi.p++; 595} 596 597void 598yyerror(char *a, ...) 599{ 600 char buf[200]; 601 va_list arg; 602 603 /* 604 * hack to intercept message from yaccpar 605 */ 606 if(strcmp(a, "syntax error") == 0) { 607 yyerror("syntax error, last name: %s", symb); 608 return; 609 } 610 prfile(lineno); 611 va_start(arg, a); 612 vseprint(buf, buf+sizeof(buf), a, arg); 613 va_end(arg); 614 print("%s\n", buf); 615 nerrors++; 616 if(nerrors > 10) { 617 print("too many errors\n"); 618 errorexit(); 619 } 620} 621 622void 623prfile(long l) 624{ 625 int i, n; 626 Hist a[HISTSZ], *h; 627 long d; 628 629 n = 0; 630 for(h = hist; h != H; h = h->link) { 631 if(l < h->line) 632 break; 633 if(h->name) { 634 if(h->offset == 0) { 635 if(n >= 0 && n < HISTSZ) 636 a[n] = *h; 637 n++; 638 continue; 639 } 640 if(n > 0 && n < HISTSZ) 641 if(a[n-1].offset == 0) { 642 a[n] = *h; 643 n++; 644 } else 645 a[n-1] = *h; 646 continue; 647 } 648 n--; 649 if(n >= 0 && n < HISTSZ) { 650 d = h->line - a[n].line; 651 for(i=0; i<n; i++) 652 a[i].line += d; 653 } 654 } 655 if(n > HISTSZ) 656 n = HISTSZ; 657 for(i=0; i<n; i++) 658 print("%s:%ld ", a[i].name, (long)(l-a[i].line+a[i].offset+1)); 659} 660 661void 662ieeedtod(Ieee *ieee, double native) 663{ 664 double fr, ho, f; 665 int exp; 666 667 if(native < 0) { 668 ieeedtod(ieee, -native); 669 ieee->h |= 0x80000000L; 670 return; 671 } 672 if(native == 0) { 673 ieee->l = 0; 674 ieee->h = 0; 675 return; 676 } 677 fr = frexp(native, &exp); 678 f = 2097152L; /* shouldnt use fp constants here */ 679 fr = modf(fr*f, &ho); 680 ieee->h = ho; 681 ieee->h &= 0xfffffL; 682 ieee->h |= (exp+1022L) << 20; 683 f = 65536L; 684 fr = modf(fr*f, &ho); 685 ieee->l = ho; 686 ieee->l <<= 16; 687 ieee->l |= (long)(fr*f); 688} 689