1 #define EXTERN 2 #include "a.h" 3 #include "y.tab.h" 4 #include <ctype.h> 5 6 void 7 main(int argc, char *argv[]) 8 { 9 char *p; 10 int nout, nproc, status, i, c; 11 12 thechar = 'k'; 13 thestring = "sparc"; 14 memset(debug, 0, sizeof(debug)); 15 cinit(); 16 outfile = 0; 17 include[ninclude++] = "."; 18 ARGBEGIN { 19 default: 20 c = ARGC(); 21 if(c >= 0 || c < sizeof(debug)) 22 debug[c] = 1; 23 break; 24 25 case 'o': 26 outfile = ARGF(); 27 break; 28 29 case 'D': 30 p = ARGF(); 31 if(p) 32 Dlist[nDlist++] = p; 33 break; 34 35 case 'I': 36 p = ARGF(); 37 setinclude(p); 38 break; 39 } ARGEND 40 if(*argv == 0) { 41 print("usage: %ca [-options] file.s\n", thechar); 42 errorexit(); 43 } 44 if(argc > 1 && systemtype(Windows)){ 45 print("can't assemble multiple files on windows\n"); 46 errorexit(); 47 } 48 if(argc > 1 && !systemtype(Windows)) { 49 nproc = 1; 50 if(p = getenv("NPROC")) 51 nproc = atol(p); /* */ 52 c = 0; 53 nout = 0; 54 for(;;) { 55 while(nout < nproc && argc > 0) { 56 i = myfork(); 57 if(i < 0) { 58 i = mywait(&status); 59 if(i < 0) 60 errorexit(); 61 if(status) 62 c++; 63 nout--; 64 continue; 65 } 66 if(i == 0) { 67 print("%s:\n", *argv); 68 if(assemble(*argv)) 69 errorexit(); 70 exits(0); 71 } 72 nout++; 73 argc--; 74 argv++; 75 } 76 i = mywait(&status); 77 if(i < 0) { 78 if(c) 79 errorexit(); 80 exits(0); 81 } 82 if(status) 83 c++; 84 nout--; 85 } 86 } 87 if(assemble(argv[0])) 88 errorexit(); 89 exits(0); 90 } 91 92 int 93 assemble(char *file) 94 { 95 char ofile[100], incfile[20], *p; 96 int i, of; 97 98 strcpy(ofile, file); 99 p = utfrrune(ofile, pathchar()); 100 if(p) { 101 include[0] = ofile; 102 *p++ = 0; 103 } else 104 p = ofile; 105 if(outfile == 0) { 106 outfile = p; 107 if(outfile){ 108 p = utfrrune(outfile, '.'); 109 if(p) 110 if(p[1] == 's' && p[2] == 0) 111 p[0] = 0; 112 p = utfrune(outfile, 0); 113 p[0] = '.'; 114 p[1] = thechar; 115 p[2] = 0; 116 } else 117 outfile = "/dev/null"; 118 } 119 p = getenv("INCLUDE"); 120 if(p) { 121 setinclude(p); 122 } else { 123 if(systemtype(Plan9)) { 124 sprint(incfile,"/%s/include", thestring); 125 setinclude(strdup(incfile)); 126 } 127 } 128 129 of = mycreat(outfile, 0664); 130 if(of < 0) { 131 yyerror("%ca: cannot create %s", thechar, outfile); 132 errorexit(); 133 } 134 Binit(&obuf, of, OWRITE); 135 136 pass = 1; 137 pinit(file); 138 for(i=0; i<nDlist; i++) 139 dodefine(Dlist[i]); 140 yyparse(); 141 if(nerrors) { 142 cclean(); 143 return nerrors; 144 } 145 146 pass = 2; 147 outhist(); 148 pinit(file); 149 for(i=0; i<nDlist; i++) 150 dodefine(Dlist[i]); 151 yyparse(); 152 cclean(); 153 return nerrors; 154 } 155 156 struct 157 { 158 char *name; 159 ushort type; 160 ushort value; 161 } itab[] = 162 { 163 "SP", LSP, D_AUTO, 164 "SB", LSB, D_EXTERN, 165 "FP", LFP, D_PARAM, 166 "PC", LPC, D_BRANCH, 167 168 "FSR", LFSR, D_FSR, 169 "CSR", LFSR, D_CSR, 170 171 "FQ", LFPQ, D_FPQ, 172 "CQ", LFPQ, D_CPQ, 173 174 "Y", LPSR, D_Y, 175 "PSR", LPSR, D_PSR, 176 "WIM", LPSR, D_WIM, 177 "TBR", LPSR, D_TBR, 178 179 "R", LR, 0, 180 "R0", LREG, 0, 181 "R1", LREG, 1, 182 "R2", LREG, 2, 183 "R3", LREG, 3, 184 "R4", LREG, 4, 185 "R5", LREG, 5, 186 "R6", LREG, 6, 187 "R7", LREG, 7, 188 "R8", LREG, 8, 189 "R9", LREG, 9, 190 "R10", LREG, 10, 191 "R11", LREG, 11, 192 "R12", LREG, 12, 193 "R13", LREG, 13, 194 "R14", LREG, 14, 195 "R15", LREG, 15, 196 "R16", LREG, 16, 197 "R17", LREG, 17, 198 "R18", LREG, 18, 199 "R19", LREG, 19, 200 "R20", LREG, 20, 201 "R21", LREG, 21, 202 "R22", LREG, 22, 203 "R23", LREG, 23, 204 "R24", LREG, 24, 205 "R25", LREG, 25, 206 "R26", LREG, 26, 207 "R27", LREG, 27, 208 "R28", LREG, 28, 209 "R29", LREG, 29, 210 "R30", LREG, 30, 211 "R31", LREG, 31, 212 213 "C", LC, 0, 214 "C0", LCREG, 0, 215 "C1", LCREG, 1, 216 "C2", LCREG, 2, 217 "C3", LCREG, 3, 218 "C4", LCREG, 4, 219 "C5", LCREG, 5, 220 "C6", LCREG, 6, 221 "C7", LCREG, 7, 222 "C8", LCREG, 8, 223 "C9", LCREG, 9, 224 "C10", LCREG, 10, 225 "C11", LCREG, 11, 226 "C12", LCREG, 12, 227 "C13", LCREG, 13, 228 "C14", LCREG, 14, 229 "C15", LCREG, 15, 230 "C16", LCREG, 16, 231 "C17", LCREG, 17, 232 "C18", LCREG, 18, 233 "C19", LCREG, 19, 234 "C20", LCREG, 20, 235 "C21", LCREG, 21, 236 "C22", LCREG, 22, 237 "C23", LCREG, 23, 238 "C24", LCREG, 24, 239 "C25", LCREG, 25, 240 "C26", LCREG, 26, 241 "C27", LCREG, 27, 242 "C28", LCREG, 28, 243 "C29", LCREG, 29, 244 "C30", LCREG, 30, 245 "C31", LCREG, 31, 246 247 "F", LF, 0, 248 "F0", LFREG, 0, 249 "F2", LFREG, 2, 250 "F4", LFREG, 4, 251 "F6", LFREG, 6, 252 "F8", LFREG, 8, 253 "F10", LFREG, 10, 254 "F12", LFREG, 12, 255 "F14", LFREG, 14, 256 "F16", LFREG, 16, 257 "F18", LFREG, 18, 258 "F20", LFREG, 20, 259 "F22", LFREG, 22, 260 "F24", LFREG, 24, 261 "F26", LFREG, 26, 262 "F28", LFREG, 28, 263 "F30", LFREG, 30, 264 "F1", LFREG, 1, 265 "F3", LFREG, 3, 266 "F5", LFREG, 5, 267 "F7", LFREG, 7, 268 "F9", LFREG, 9, 269 "F11", LFREG, 11, 270 "F13", LFREG, 13, 271 "F15", LFREG, 15, 272 "F17", LFREG, 17, 273 "F19", LFREG, 19, 274 "F21", LFREG, 21, 275 "F23", LFREG, 23, 276 "F25", LFREG, 25, 277 "F27", LFREG, 27, 278 "F29", LFREG, 29, 279 "F31", LFREG, 31, 280 281 "ADD", LADDW, AADD, 282 "ADDCC", LADDW, AADDCC, 283 "ADDX", LADDW, AADDX, 284 "ADDXCC", LADDW, AADDXCC, 285 "AND", LADDW, AAND, 286 "ANDCC", LADDW, AANDCC, 287 "ANDN", LADDW, AANDN, 288 "ANDNCC", LADDW, AANDNCC, 289 "BA", LBRA, ABA, 290 "BCC", LBRA, ABCC, 291 "BCS", LBRA, ABCS, 292 "BE", LBRA, ABE, 293 "BG", LBRA, ABG, 294 "BGE", LBRA, ABGE, 295 "BGU", LBRA, ABGU, 296 "BL", LBRA, ABL, 297 "BLE", LBRA, ABLE, 298 "BLEU", LBRA, ABLEU, 299 "BN", LBRA, ABN, 300 "BNE", LBRA, ABNE, 301 "BNEG", LBRA, ABNEG, 302 "BPOS", LBRA, ABPOS, 303 "BVC", LBRA, ABVC, 304 "BVS", LBRA, ABVS, 305 "CB0", LBRA, ACB0, 306 "CB01", LBRA, ACB01, 307 "CB012", LBRA, ACB012, 308 "CB013", LBRA, ACB013, 309 "CB02", LBRA, ACB02, 310 "CB023", LBRA, ACB023, 311 "CB03", LBRA, ACB03, 312 "CB1", LBRA, ACB1, 313 "CB12", LBRA, ACB12, 314 "CB123", LBRA, ACB123, 315 "CB13", LBRA, ACB13, 316 "CB2", LBRA, ACB2, 317 "CB23", LBRA, ACB23, 318 "CB3", LBRA, ACB3, 319 "CBA", LBRA, ACBA, 320 "CBN", LBRA, ACBN, 321 "CMP", LCMP, ACMP, 322 "CPOP1", LCPOP, ACPOP1, 323 "CPOP2", LCPOP, ACPOP2, 324 "DATA", LDATA, ADATA, 325 "DIV", LADDW, ADIV, 326 "DIVL", LADDW, ADIVL, 327 "END", LEND, AEND, 328 "FABSD", LFCONV, AFABSD, 329 "FABSF", LFCONV, AFABSF, 330 "FABSX", LFCONV, AFABSX, 331 "FADDD", LFADD, AFADDD, 332 "FADDF", LFADD, AFADDF, 333 "FADDX", LFADD, AFADDX, 334 "FBA", LBRA, AFBA, 335 "FBE", LBRA, AFBE, 336 "FBG", LBRA, AFBG, 337 "FBGE", LBRA, AFBGE, 338 "FBL", LBRA, AFBL, 339 "FBLE", LBRA, AFBLE, 340 "FBLG", LBRA, AFBLG, 341 "FBN", LBRA, AFBN, 342 "FBNE", LBRA, AFBNE, 343 "FBO", LBRA, AFBO, 344 "FBU", LBRA, AFBU, 345 "FBUE", LBRA, AFBUE, 346 "FBUG", LBRA, AFBUG, 347 "FBUGE", LBRA, AFBUGE, 348 "FBUL", LBRA, AFBUL, 349 "FBULE", LBRA, AFBULE, 350 "FCMPD", LFADD, AFCMPD, 351 "FCMPED", LFADD, AFCMPED, 352 "FCMPEF", LFADD, AFCMPEF, 353 "FCMPEX", LFADD, AFCMPEX, 354 "FCMPF", LFADD, AFCMPF, 355 "FCMPX", LFADD, AFCMPX, 356 "FDIVD", LFADD, AFDIVD, 357 "FDIVF", LFADD, AFDIVF, 358 "FDIVX", LFADD, AFDIVX, 359 "FMOVD", LFMOV, AFMOVD, 360 "FMOVDF", LFCONV, AFMOVDF, 361 "FMOVDW", LFCONV, AFMOVDW, 362 "FMOVDX", LFCONV, AFMOVDX, 363 "FMOVF", LFMOV, AFMOVF, 364 "FMOVFD", LFCONV, AFMOVFD, 365 "FMOVFW", LFCONV, AFMOVFW, 366 "FMOVFX", LFCONV, AFMOVFX, 367 "FMOVWD", LFCONV, AFMOVWD, 368 "FMOVWF", LFCONV, AFMOVWF, 369 "FMOVWX", LFCONV, AFMOVWX, 370 "FMOVX", LFCONV, AFMOVX, 371 "FMOVXD", LFCONV, AFMOVXD, 372 "FMOVXF", LFCONV, AFMOVXF, 373 "FMOVXW", LFCONV, AFMOVXW, 374 "FMULD", LFADD, AFMULD, 375 "FMULF", LFADD, AFMULF, 376 "FMULX", LFADD, AFMULX, 377 "FNEGD", LFCONV, AFNEGD, 378 "FNEGF", LFCONV, AFNEGF, 379 "FNEGX", LFCONV, AFNEGX, 380 "FSQRTD", LFCONV, AFSQRTD, 381 "FSQRTF", LFCONV, AFSQRTF, 382 "FSQRTX", LFCONV, AFSQRTX, 383 "FSUBD", LFADD, AFSUBD, 384 "FSUBF", LFADD, AFSUBF, 385 "FSUBX", LFADD, AFSUBX, 386 "GLOBL", LTEXT, AGLOBL, 387 "IFLUSH", LFLUSH, AIFLUSH, 388 "JMPL", LJMPL, AJMPL, 389 "JMP", LJMPL, AJMP, 390 "MOD", LADDW, AMOD, 391 "MODL", LADDW, AMODL, 392 "MOVB", LMOVB, AMOVB, 393 "MOVBU", LMOVB, AMOVBU, 394 "MOVD", LMOVD, AMOVD, 395 "MOVH", LMOVB, AMOVH, 396 "MOVHU", LMOVB, AMOVHU, 397 "MOVW", LMOVW, AMOVW, 398 "MUL", LADDW, AMUL, 399 "MULSCC", LADDW, AMULSCC, 400 "NOP", LNOP, ANOP, 401 "OR", LADDW, AOR, 402 "ORCC", LADDW, AORCC, 403 "ORN", LADDW, AORN, 404 "ORNCC", LADDW, AORNCC, 405 "RESTORE", LADDW, ARESTORE, 406 "RETT", LRETT, ARETT, 407 "RETURN", LRETRN, ARETURN, 408 "SAVE", LADDW, ASAVE, 409 "SLL", LADDW, ASLL, 410 "SRA", LADDW, ASRA, 411 "SRL", LADDW, ASRL, 412 "SUB", LADDW, ASUB, 413 "SUBCC", LADDW, ASUBCC, 414 "SUBX", LADDW, ASUBX, 415 "SUBXCC", LADDW, ASUBXCC, 416 "SWAP", LSWAP, ASWAP, 417 "TA", LTRAP, ATA, 418 "TADDCC", LADDW, ATADDCC, 419 "TADDCCTV", LADDW, ATADDCCTV, 420 "TAS", LSWAP, ATAS, 421 "TCC", LTRAP, ATCC, 422 "TCS", LTRAP, ATCS, 423 "TE", LTRAP, ATE, 424 "TEXT", LTEXT, ATEXT, 425 "TG", LTRAP, ATG, 426 "TGE", LTRAP, ATGE, 427 "TGU", LTRAP, ATGU, 428 "TL", LTRAP, ATL, 429 "TLE", LTRAP, ATLE, 430 "TLEU", LTRAP, ATLEU, 431 "TN", LTRAP, ATN, 432 "TNE", LTRAP, ATNE, 433 "TNEG", LTRAP, ATNEG, 434 "TPOS", LTRAP, ATPOS, 435 "TSUBCC", LADDW, ATSUBCC, 436 "TSUBCCTV", LADDW, ATSUBCCTV, 437 "TVC", LTRAP, ATVC, 438 "TVS", LTRAP, ATVS, 439 "UNIMP", LUNIMP, AUNIMP, 440 "WORD", LUNIMP, AWORD, 441 "XNOR", LADDW, AXNOR, 442 "XNORCC", LADDW, AXNORCC, 443 "XOR", LXORW, AXOR, 444 "XORCC", LADDW, AXORCC, 445 446 "SCHED", LSCHED, 0, 447 "NOSCHED", LSCHED, 0x80, 448 449 0 450 }; 451 452 void 453 cinit(void) 454 { 455 Sym *s; 456 int i; 457 458 nullgen.sym = S; 459 nullgen.offset = 0; 460 nullgen.type = D_NONE; 461 nullgen.name = D_NONE; 462 nullgen.reg = NREG; 463 nullgen.xreg = NREG; 464 if(FPCHIP) 465 nullgen.dval = 0; 466 for(i=0; i<sizeof(nullgen.sval); i++) 467 nullgen.sval[i] = 0; 468 469 nerrors = 0; 470 iostack = I; 471 iofree = I; 472 peekc = IGN; 473 nhunk = 0; 474 for(i=0; i<NHASH; i++) 475 hash[i] = S; 476 for(i=0; itab[i].name; i++) { 477 s = slookup(itab[i].name); 478 s->type = itab[i].type; 479 s->value = itab[i].value; 480 } 481 482 pathname = allocn(pathname, 0, 100); 483 if(mygetwd(pathname, 99) == 0) { 484 pathname = allocn(pathname, 100, 900); 485 if(mygetwd(pathname, 999) == 0) 486 strcpy(pathname, "/?"); 487 } 488 } 489 490 void 491 syminit(Sym *s) 492 { 493 494 s->type = LNAME; 495 s->value = 0; 496 } 497 498 void 499 cclean(void) 500 { 501 502 outcode(AEND, &nullgen, NREG, &nullgen); 503 Bflush(&obuf); 504 } 505 506 void 507 zname(char *n, int t, int s) 508 { 509 510 Bputc(&obuf, ANAME); 511 Bputc(&obuf, t); /* type */ 512 Bputc(&obuf, s); /* sym */ 513 while(*n) { 514 Bputc(&obuf, *n); 515 n++; 516 } 517 Bputc(&obuf, 0); 518 } 519 520 void 521 zaddr(Gen *a, int s) 522 { 523 long l; 524 int i; 525 char *n; 526 Ieee e; 527 528 Bputc(&obuf, a->type); 529 Bputc(&obuf, a->reg); 530 Bputc(&obuf, s); 531 Bputc(&obuf, a->name); 532 switch(a->type) { 533 default: 534 print("unknown type %d\n", a->type); 535 exits("arg"); 536 537 case D_NONE: 538 case D_REG: 539 case D_FREG: 540 case D_CREG: 541 case D_PREG: 542 break; 543 544 case D_OREG: 545 case D_ASI: 546 case D_CONST: 547 case D_BRANCH: 548 l = a->offset; 549 Bputc(&obuf, l); 550 Bputc(&obuf, l>>8); 551 Bputc(&obuf, l>>16); 552 Bputc(&obuf, l>>24); 553 break; 554 555 case D_SCONST: 556 n = a->sval; 557 for(i=0; i<NSNAME; i++) { 558 Bputc(&obuf, *n); 559 n++; 560 } 561 break; 562 563 case D_FCONST: 564 ieeedtod(&e, a->dval); 565 Bputc(&obuf, e.l); 566 Bputc(&obuf, e.l>>8); 567 Bputc(&obuf, e.l>>16); 568 Bputc(&obuf, e.l>>24); 569 Bputc(&obuf, e.h); 570 Bputc(&obuf, e.h>>8); 571 Bputc(&obuf, e.h>>16); 572 Bputc(&obuf, e.h>>24); 573 break; 574 } 575 } 576 577 void 578 outcode(int a, Gen *g1, int reg, Gen *g2) 579 { 580 int sf, st, t; 581 Sym *s; 582 583 if(pass == 1) 584 goto out; 585 if(g1->xreg != NREG) { 586 if(reg != NREG || g2->xreg != NREG) 587 yyerror("bad addressing modes"); 588 reg = g1->xreg; 589 } else 590 if(g2->xreg != NREG) { 591 if(reg != NREG) 592 yyerror("bad addressing modes"); 593 reg = g2->xreg; 594 } 595 jackpot: 596 sf = 0; 597 s = g1->sym; 598 while(s != S) { 599 sf = s->sym; 600 if(sf < 0 || sf >= NSYM) 601 sf = 0; 602 t = g1->name; 603 if(h[sf].type == t) 604 if(h[sf].sym == s) 605 break; 606 zname(s->name, t, sym); 607 s->sym = sym; 608 h[sym].sym = s; 609 h[sym].type = t; 610 sf = sym; 611 sym++; 612 if(sym >= NSYM) 613 sym = 1; 614 break; 615 } 616 st = 0; 617 s = g2->sym; 618 while(s != S) { 619 st = s->sym; 620 if(st < 0 || st >= NSYM) 621 st = 0; 622 t = g2->name; 623 if(h[st].type == t) 624 if(h[st].sym == s) 625 break; 626 zname(s->name, t, sym); 627 s->sym = sym; 628 h[sym].sym = s; 629 h[sym].type = t; 630 st = sym; 631 sym++; 632 if(sym >= NSYM) 633 sym = 1; 634 if(st == sf) 635 goto jackpot; 636 break; 637 } 638 Bputc(&obuf, a); 639 Bputc(&obuf, reg|nosched); 640 Bputc(&obuf, lineno); 641 Bputc(&obuf, lineno>>8); 642 Bputc(&obuf, lineno>>16); 643 Bputc(&obuf, lineno>>24); 644 zaddr(g1, sf); 645 zaddr(g2, st); 646 647 out: 648 if(a != AGLOBL && a != ADATA) 649 pc++; 650 } 651 652 void 653 outhist(void) 654 { 655 Gen g; 656 Hist *h; 657 char *p, *q, *op, c; 658 int n; 659 660 g = nullgen; 661 c = pathchar(); 662 for(h = hist; h != H; h = h->link) { 663 p = h->name; 664 op = 0; 665 /* on windows skip drive specifier in pathname */ 666 if(systemtype(Windows) && p && p[1] == ':'){ 667 p += 2; 668 c = *p; 669 } 670 if(p && p[0] != c && h->offset == 0 && pathname){ 671 /* on windows skip drive specifier in pathname */ 672 if(systemtype(Windows) && pathname[1] == ':') { 673 op = p; 674 p = pathname+2; 675 c = *p; 676 } else if(pathname[0] == c){ 677 op = p; 678 p = pathname; 679 } 680 } 681 while(p) { 682 q = strchr(p, c); 683 if(q) { 684 n = q-p; 685 if(n == 0){ 686 n = 1; /* leading "/" */ 687 *p = '/'; /* don't emit "\" on windows */ 688 } 689 q++; 690 } else { 691 n = strlen(p); 692 q = 0; 693 } 694 if(n) { 695 Bputc(&obuf, ANAME); 696 Bputc(&obuf, D_FILE); /* type */ 697 Bputc(&obuf, 1); /* sym */ 698 Bputc(&obuf, '<'); 699 Bwrite(&obuf, p, n); 700 Bputc(&obuf, 0); 701 } 702 p = q; 703 if(p == 0 && op) { 704 p = op; 705 op = 0; 706 } 707 } 708 g.offset = h->offset; 709 710 Bputc(&obuf, AHISTORY); 711 Bputc(&obuf, 0); 712 Bputc(&obuf, h->line); 713 Bputc(&obuf, h->line>>8); 714 Bputc(&obuf, h->line>>16); 715 Bputc(&obuf, h->line>>24); 716 zaddr(&nullgen, 0); 717 zaddr(&g, 0); 718 } 719 } 720 721 #include "../cc/lexbody" 722 #include "../cc/macbody" 723