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