#include #include #include #include #include "../kc/k.out.h" #include "a.h" #include "y.tab.h" void main(int argc, char *argv[]) { char ofile[100], incfile[20], *p; int nout, nproc, status, i, c, of; thechar = 'k'; thestring = "sparc"; memset(debug, 0, sizeof(debug)); cinit(); outfile = 0; include[ninclude++] = "."; ARGBEGIN { default: c = ARGC(); if(c >= 0 || c < sizeof(debug)) debug[c] = 1; break; case 'o': outfile = ARGF(); break; case 'D': p = ARGF(); if(p) dodefine(p); break; case 'I': p = ARGF(); if(p) include[ninclude++] = p; break; } ARGEND if(*argv == 0) { print("usage: %ca [-options] file.s\n", thechar); errorexit(); } nproc = 3; if(p = getenv("NPROC")) nproc = atol(p); if(argc > 1) { c = 0; nout = 0; for(;;) { while(nout < nproc && argc > 0) { i = fork(); if(i < 0) { i = mywait(&status); if(i < 0) errorexit(); if(status) c++; nout--; continue; } if(i == 0) { print("%s:\n", *argv); goto child; } nout++; argc--; argv++; } i = mywait(&status); if(i < 0) { if(c) errorexit(); exits(0); } if(status) c++; nout--; } } child: strcpy(ofile, *argv); if(p = strrchr(ofile, '/')) { include[0] = ofile; *p++ = 0; } else p = ofile; if(outfile == 0) { outfile = p; if(p = strrchr(outfile, '.')) if(p[1] == 's' && p[2] == 0) p[0] = 0; p = strrchr(outfile, 0); p[0] = '.'; p[1] = thechar; p[2] = 0; } if(unix()) { strcpy(incfile, "/usr/%include"); p = strrchr(incfile, '%'); if(p) *p = thechar; } else { strcpy(incfile, "/"); strcat(incfile, thestring); strcat(incfile, "/include"); } include[ninclude++] = incfile; if(p = getenv("INCLUDE")) include[ninclude-1] = p; /* */ of = mycreat(outfile, 0664); if(of < 0) { yyerror("%ca: cannot create %s", thechar, outfile); errorexit(); } Binit(&obuf, of, OWRITE); pass = 1; pinit(*argv); yyparse(); if(nerrors) { cclean(); errorexit(); } pass = 2; outhist(); pinit(*argv); yyparse(); cclean(); if(nerrors) errorexit(); exits(0); } struct { char *name; ushort type; ushort value; } itab[] = { "SP", LSP, D_AUTO, "SB", LSB, D_EXTERN, "FP", LFP, D_PARAM, "PC", LPC, D_BRANCH, "FSR", LFSR, D_FSR, "CSR", LFSR, D_CSR, "FQ", LFPQ, D_FPQ, "CQ", LFPQ, D_CPQ, "Y", LPSR, D_Y, "PSR", LPSR, D_PSR, "WIM", LPSR, D_WIM, "TBR", LPSR, D_TBR, "R", LR, 0, "R0", LREG, 0, "R1", LREG, 1, "R2", LREG, 2, "R3", LREG, 3, "R4", LREG, 4, "R5", LREG, 5, "R6", LREG, 6, "R7", LREG, 7, "R8", LREG, 8, "R9", LREG, 9, "R10", LREG, 10, "R11", LREG, 11, "R12", LREG, 12, "R13", LREG, 13, "R14", LREG, 14, "R15", LREG, 15, "R16", LREG, 16, "R17", LREG, 17, "R18", LREG, 18, "R19", LREG, 19, "R20", LREG, 20, "R21", LREG, 21, "R22", LREG, 22, "R23", LREG, 23, "R24", LREG, 24, "R25", LREG, 25, "R26", LREG, 26, "R27", LREG, 27, "R28", LREG, 28, "R29", LREG, 29, "R30", LREG, 30, "R31", LREG, 31, "C", LC, 0, "C0", LCREG, 0, "C1", LCREG, 1, "C2", LCREG, 2, "C3", LCREG, 3, "C4", LCREG, 4, "C5", LCREG, 5, "C6", LCREG, 6, "C7", LCREG, 7, "C8", LCREG, 8, "C9", LCREG, 9, "C10", LCREG, 10, "C11", LCREG, 11, "C12", LCREG, 12, "C13", LCREG, 13, "C14", LCREG, 14, "C15", LCREG, 15, "C16", LCREG, 16, "C17", LCREG, 17, "C18", LCREG, 18, "C19", LCREG, 19, "C20", LCREG, 20, "C21", LCREG, 21, "C22", LCREG, 22, "C23", LCREG, 23, "C24", LCREG, 24, "C25", LCREG, 25, "C26", LCREG, 26, "C27", LCREG, 27, "C28", LCREG, 28, "C29", LCREG, 29, "C30", LCREG, 30, "C31", LCREG, 31, "F", LF, 0, "F0", LFREG, 0, "F2", LFREG, 2, "F4", LFREG, 4, "F6", LFREG, 6, "F8", LFREG, 8, "F10", LFREG, 10, "F12", LFREG, 12, "F14", LFREG, 14, "F16", LFREG, 16, "F18", LFREG, 18, "F20", LFREG, 20, "F22", LFREG, 22, "F24", LFREG, 24, "F26", LFREG, 26, "F28", LFREG, 28, "F30", LFREG, 30, "F1", LFREG, 1, "F3", LFREG, 3, "F5", LFREG, 5, "F7", LFREG, 7, "F9", LFREG, 9, "F11", LFREG, 11, "F13", LFREG, 13, "F15", LFREG, 15, "F17", LFREG, 17, "F19", LFREG, 19, "F21", LFREG, 21, "F23", LFREG, 23, "F25", LFREG, 25, "F27", LFREG, 27, "F29", LFREG, 29, "F31", LFREG, 31, "ADD", LADDW, AADD, "ADDCC", LADDW, AADDCC, "ADDX", LADDW, AADDX, "ADDXCC", LADDW, AADDXCC, "AND", LADDW, AAND, "ANDCC", LADDW, AANDCC, "ANDN", LADDW, AANDN, "ANDNCC", LADDW, AANDNCC, "BA", LBRA, ABA, "BCC", LBRA, ABCC, "BCS", LBRA, ABCS, "BE", LBRA, ABE, "BG", LBRA, ABG, "BGE", LBRA, ABGE, "BGU", LBRA, ABGU, "BL", LBRA, ABL, "BLE", LBRA, ABLE, "BLEU", LBRA, ABLEU, "BN", LBRA, ABN, "BNE", LBRA, ABNE, "BNEG", LBRA, ABNEG, "BPOS", LBRA, ABPOS, "BVC", LBRA, ABVC, "BVS", LBRA, ABVS, "CB0", LBRA, ACB0, "CB01", LBRA, ACB01, "CB012", LBRA, ACB012, "CB013", LBRA, ACB013, "CB02", LBRA, ACB02, "CB023", LBRA, ACB023, "CB03", LBRA, ACB03, "CB1", LBRA, ACB1, "CB12", LBRA, ACB12, "CB123", LBRA, ACB123, "CB13", LBRA, ACB13, "CB2", LBRA, ACB2, "CB23", LBRA, ACB23, "CB3", LBRA, ACB3, "CBA", LBRA, ACBA, "CBN", LBRA, ACBN, "CMP", LCMP, ACMP, "CPOP1", LCPOP, ACPOP1, "CPOP2", LCPOP, ACPOP2, "DATA", LDATA, ADATA, "DIV", LADDW, ADIV, "DIVL", LADDW, ADIVL, "END", LEND, AEND, "FABSD", LFCONV, AFABSD, "FABSF", LFCONV, AFABSF, "FABSX", LFCONV, AFABSX, "FADDD", LFADD, AFADDD, "FADDF", LFADD, AFADDF, "FADDX", LFADD, AFADDX, "FBA", LBRA, AFBA, "FBE", LBRA, AFBE, "FBG", LBRA, AFBG, "FBGE", LBRA, AFBGE, "FBL", LBRA, AFBL, "FBLE", LBRA, AFBLE, "FBLG", LBRA, AFBLG, "FBN", LBRA, AFBN, "FBNE", LBRA, AFBNE, "FBO", LBRA, AFBO, "FBU", LBRA, AFBU, "FBUE", LBRA, AFBUE, "FBUG", LBRA, AFBUG, "FBUGE", LBRA, AFBUGE, "FBUL", LBRA, AFBUL, "FBULE", LBRA, AFBULE, "FCMPD", LFADD, AFCMPD, "FCMPED", LFADD, AFCMPED, "FCMPEF", LFADD, AFCMPEF, "FCMPEX", LFADD, AFCMPEX, "FCMPF", LFADD, AFCMPF, "FCMPX", LFADD, AFCMPX, "FDIVD", LFADD, AFDIVD, "FDIVF", LFADD, AFDIVF, "FDIVX", LFADD, AFDIVX, "FMOVD", LFMOV, AFMOVD, "FMOVDF", LFCONV, AFMOVDF, "FMOVDW", LFCONV, AFMOVDW, "FMOVDX", LFCONV, AFMOVDX, "FMOVF", LFMOV, AFMOVF, "FMOVFD", LFCONV, AFMOVFD, "FMOVFW", LFCONV, AFMOVFW, "FMOVFX", LFCONV, AFMOVFX, "FMOVWD", LFCONV, AFMOVWD, "FMOVWF", LFCONV, AFMOVWF, "FMOVWX", LFCONV, AFMOVWX, "FMOVX", LFCONV, AFMOVX, "FMOVXD", LFCONV, AFMOVXD, "FMOVXF", LFCONV, AFMOVXF, "FMOVXW", LFCONV, AFMOVXW, "FMULD", LFADD, AFMULD, "FMULF", LFADD, AFMULF, "FMULX", LFADD, AFMULX, "FNEGD", LFCONV, AFNEGD, "FNEGF", LFCONV, AFNEGF, "FNEGX", LFCONV, AFNEGX, "FSQRTD", LFCONV, AFSQRTD, "FSQRTF", LFCONV, AFSQRTF, "FSQRTX", LFCONV, AFSQRTX, "FSUBD", LFADD, AFSUBD, "FSUBF", LFADD, AFSUBF, "FSUBX", LFADD, AFSUBX, "GLOBL", LTEXT, AGLOBL, "IFLUSH", LFLUSH, AIFLUSH, "JMPL", LJMPL, AJMPL, "JMP", LJMPL, AJMP, "MOD", LADDW, AMOD, "MODL", LADDW, AMODL, "MOVB", LMOVB, AMOVB, "MOVBU", LMOVB, AMOVBU, "MOVD", LMOVD, AMOVD, "MOVH", LMOVB, AMOVH, "MOVHU", LMOVB, AMOVHU, "MOVW", LMOVW, AMOVW, "MUL", LADDW, AMUL, "MULSCC", LADDW, AMULSCC, "NOP", LNOP, ANOP, "OR", LADDW, AOR, "ORCC", LADDW, AORCC, "ORN", LADDW, AORN, "ORNCC", LADDW, AORNCC, "RESTORE", LADDW, ARESTORE, "RETT", LRETT, ARETT, "RETURN", LRETRN, ARETURN, "SAVE", LADDW, ASAVE, "SLL", LADDW, ASLL, "SRA", LADDW, ASRA, "SRL", LADDW, ASRL, "SUB", LADDW, ASUB, "SUBCC", LADDW, ASUBCC, "SUBX", LADDW, ASUBX, "SUBXCC", LADDW, ASUBXCC, "SWAP", LSWAP, ASWAP, "TA", LTRAP, ATA, "TADDCC", LADDW, ATADDCC, "TADDCCTV", LADDW, ATADDCCTV, "TAS", LSWAP, ATAS, "TCC", LTRAP, ATCC, "TCS", LTRAP, ATCS, "TE", LTRAP, ATE, "TEXT", LTEXT, ATEXT, "TG", LTRAP, ATG, "TGE", LTRAP, ATGE, "TGU", LTRAP, ATGU, "TL", LTRAP, ATL, "TLE", LTRAP, ATLE, "TLEU", LTRAP, ATLEU, "TN", LTRAP, ATN, "TNE", LTRAP, ATNE, "TNEG", LTRAP, ATNEG, "TPOS", LTRAP, ATPOS, "TSUBCC", LADDW, ATSUBCC, "TSUBCCTV", LADDW, ATSUBCCTV, "TVC", LTRAP, ATVC, "TVS", LTRAP, ATVS, "UNIMP", LUNIMP, AUNIMP, "WORD", LUNIMP, AWORD, "XNOR", LADDW, AXNOR, "XNORCC", LADDW, AXNORCC, "XOR", LXORW, AXOR, "XORCC", LADDW, AXORCC, 0 }; void cinit(void) { Sym *s; int i; nullgen.sym = S; nullgen.offset = 0; nullgen.type = D_NONE; nullgen.name = D_NONE; nullgen.reg = NREG; nullgen.xreg = NREG; if(FPCHIP) nullgen.dval = 0; for(i=0; itype = itab[i].type; s->value = itab[i].value; } } void syminit(Sym *s) { s->type = LNAME; s->value = 0; } void cclean(void) { outcode(AEND, &nullgen, NREG, &nullgen); Bflush(&obuf); } void zname(char *n, int t, int s) { Bputc(&obuf, ANAME); Bputc(&obuf, t); /* type */ Bputc(&obuf, s); /* sym */ while(*n) { Bputc(&obuf, *n); n++; } Bputc(&obuf, 0); } void zaddr(Gen *a, int s) { long l; int i; char *n; Ieee e; Bputc(&obuf, a->type); Bputc(&obuf, a->reg); Bputc(&obuf, s); Bputc(&obuf, a->name); switch(a->type) { default: print("unknown type %d\n", a->type); exits("arg"); case D_NONE: case D_REG: case D_FREG: case D_CREG: case D_PREG: break; case D_OREG: case D_ASI: case D_CONST: case D_BRANCH: l = a->offset; Bputc(&obuf, l); Bputc(&obuf, l>>8); Bputc(&obuf, l>>16); Bputc(&obuf, l>>24); break; case D_SCONST: n = a->sval; for(i=0; idval); Bputc(&obuf, e.l); Bputc(&obuf, e.l>>8); Bputc(&obuf, e.l>>16); Bputc(&obuf, e.l>>24); Bputc(&obuf, e.h); Bputc(&obuf, e.h>>8); Bputc(&obuf, e.h>>16); Bputc(&obuf, e.h>>24); break; } } void outcode(int a, Gen *g1, int reg, Gen *g2) { int sf, st, t; Sym *s; if(pass == 1) goto out; if(g1->xreg != NREG) { if(reg != NREG || g2->xreg != NREG) yyerror("bad addressing modes"); reg = g1->xreg; } else if(g2->xreg != NREG) { if(reg != NREG) yyerror("bad addressing modes"); reg = g2->xreg; } jackpot: sf = 0; s = g1->sym; while(s != S) { sf = s->sym; if(sf < 0 || sf >= NSYM) sf = 0; t = g1->name; if(h[sf].type == t) if(h[sf].sym == s) break; zname(s->name, t, sym); s->sym = sym; h[sym].sym = s; h[sym].type = t; sf = sym; sym++; if(sym >= NSYM) sym = 1; break; } st = 0; s = g2->sym; while(s != S) { st = s->sym; if(st < 0 || st >= NSYM) st = 0; t = g2->name; if(h[st].type == t) if(h[st].sym == s) break; zname(s->name, t, sym); s->sym = sym; h[sym].sym = s; h[sym].type = t; st = sym; sym++; if(sym >= NSYM) sym = 1; if(st == sf) goto jackpot; break; } Bputc(&obuf, a); Bputc(&obuf, reg); Bputc(&obuf, lineno); Bputc(&obuf, lineno>>8); Bputc(&obuf, lineno>>16); Bputc(&obuf, lineno>>24); zaddr(g1, sf); zaddr(g2, st); out: if(a != AGLOBL && a != ADATA) pc++; } void outhist(void) { Gen g; Hist *h; char name[NNAME], *p, *q; int n; g = nullgen; name[0] = '<'; for(h = hist; h != H; h = h->link) { p = h->name; while(p) { q = strchr(p, '/'); if(q) { n = q-p; if(n == 0) n = 1; /* leading "/" */ q++; } else { n = strlen(p); q = 0; } if(n >= NNAME-1) n = NNAME-2; if(n) { memmove(name+1, p, n); name[n+1] = 0; zname(name, D_FILE, 1); } p = q; } g.offset = h->offset; Bputc(&obuf, AHISTORY); Bputc(&obuf, 0); Bputc(&obuf, h->line); Bputc(&obuf, h->line>>8); Bputc(&obuf, h->line>>16); Bputc(&obuf, h->line>>24); zaddr(&nullgen, 0); zaddr(&g, 0); } } #include "../cc/lexbody" #include "../cc/macbody"