summaryrefslogtreecommitdiff
path: root/sys/src/cmd/ka/lex.c
diff options
context:
space:
mode:
authorTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
committerTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
commite5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch)
treed8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/ka/lex.c
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/ka/lex.c')
-rwxr-xr-xsys/src/cmd/ka/lex.c723
1 files changed, 723 insertions, 0 deletions
diff --git a/sys/src/cmd/ka/lex.c b/sys/src/cmd/ka/lex.c
new file mode 100755
index 000000000..aa2a98c37
--- /dev/null
+++ b/sys/src/cmd/ka/lex.c
@@ -0,0 +1,723 @@
+#include <ctype.h>
+#define EXTERN
+#include "a.h"
+#include "y.tab.h"
+
+void
+main(int argc, char *argv[])
+{
+ char *p;
+ int nout, nproc, status, i, c;
+
+ 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)
+ Dlist[nDlist++] = p;
+ break;
+
+ case 'I':
+ p = ARGF();
+ setinclude(p);
+ break;
+ } ARGEND
+ if(*argv == 0) {
+ print("usage: %ca [-options] file.s\n", thechar);
+ errorexit();
+ }
+ if(argc > 1 && systemtype(Windows)){
+ print("can't assemble multiple files on windows\n");
+ errorexit();
+ }
+ if(argc > 1 && !systemtype(Windows)) {
+ nproc = 1;
+ if(p = getenv("NPROC"))
+ nproc = atol(p); /* */
+ c = 0;
+ nout = 0;
+ for(;;) {
+ while(nout < nproc && argc > 0) {
+ i = myfork();
+ if(i < 0) {
+ i = mywait(&status);
+ if(i < 0)
+ errorexit();
+ if(status)
+ c++;
+ nout--;
+ continue;
+ }
+ if(i == 0) {
+ print("%s:\n", *argv);
+ if(assemble(*argv))
+ errorexit();
+ exits(0);
+ }
+ nout++;
+ argc--;
+ argv++;
+ }
+ i = mywait(&status);
+ if(i < 0) {
+ if(c)
+ errorexit();
+ exits(0);
+ }
+ if(status)
+ c++;
+ nout--;
+ }
+ }
+ if(assemble(argv[0]))
+ errorexit();
+ exits(0);
+}
+
+int
+assemble(char *file)
+{
+ char ofile[100], incfile[20], *p;
+ int i, of;
+
+ strcpy(ofile, file);
+ p = utfrrune(ofile, pathchar());
+ if(p) {
+ include[0] = ofile;
+ *p++ = 0;
+ } else
+ p = ofile;
+ if(outfile == 0) {
+ outfile = p;
+ if(outfile){
+ p = utfrrune(outfile, '.');
+ if(p)
+ if(p[1] == 's' && p[2] == 0)
+ p[0] = 0;
+ p = utfrune(outfile, 0);
+ p[0] = '.';
+ p[1] = thechar;
+ p[2] = 0;
+ } else
+ outfile = "/dev/null";
+ }
+ p = getenv("INCLUDE");
+ if(p) {
+ setinclude(p);
+ } else {
+ if(systemtype(Plan9)) {
+ sprint(incfile,"/%s/include", thestring);
+ setinclude(strdup(incfile));
+ }
+ }
+
+ of = mycreat(outfile, 0664);
+ if(of < 0) {
+ yyerror("%ca: cannot create %s", thechar, outfile);
+ errorexit();
+ }
+ Binit(&obuf, of, OWRITE);
+
+ pass = 1;
+ pinit(file);
+ for(i=0; i<nDlist; i++)
+ dodefine(Dlist[i]);
+ yyparse();
+ if(nerrors) {
+ cclean();
+ return nerrors;
+ }
+
+ pass = 2;
+ outhist();
+ pinit(file);
+ for(i=0; i<nDlist; i++)
+ dodefine(Dlist[i]);
+ yyparse();
+ cclean();
+ return nerrors;
+}
+
+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,
+
+ "SCHED", LSCHED, 0,
+ "NOSCHED", LSCHED, 0x80,
+
+ 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; i<sizeof(nullgen.sval); i++)
+ nullgen.sval[i] = 0;
+
+ nerrors = 0;
+ iostack = I;
+ iofree = I;
+ peekc = IGN;
+ nhunk = 0;
+ for(i=0; i<NHASH; i++)
+ hash[i] = S;
+ for(i=0; itab[i].name; i++) {
+ s = slookup(itab[i].name);
+ s->type = itab[i].type;
+ s->value = itab[i].value;
+ }
+
+ pathname = allocn(pathname, 0, 100);
+ if(mygetwd(pathname, 99) == 0) {
+ pathname = allocn(pathname, 100, 900);
+ if(mygetwd(pathname, 999) == 0)
+ strcpy(pathname, "/???");
+ }
+}
+
+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; i<NSNAME; i++) {
+ Bputc(&obuf, *n);
+ n++;
+ }
+ break;
+
+ case D_FCONST:
+ ieeedtod(&e, a->dval);
+ 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|nosched);
+ 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 *p, *q, *op, c;
+ int n;
+
+ g = nullgen;
+ c = pathchar();
+ for(h = hist; h != H; h = h->link) {
+ p = h->name;
+ op = 0;
+ /* on windows skip drive specifier in pathname */
+ if(systemtype(Windows) && p && p[1] == ':'){
+ p += 2;
+ c = *p;
+ }
+ if(p && p[0] != c && h->offset == 0 && pathname){
+ /* on windows skip drive specifier in pathname */
+ if(systemtype(Windows) && pathname[1] == ':') {
+ op = p;
+ p = pathname+2;
+ c = *p;
+ } else if(pathname[0] == c){
+ op = p;
+ p = pathname;
+ }
+ }
+ while(p) {
+ q = strchr(p, c);
+ if(q) {
+ n = q-p;
+ if(n == 0){
+ n = 1; /* leading "/" */
+ *p = '/'; /* don't emit "\" on windows */
+ }
+ q++;
+ } else {
+ n = strlen(p);
+ q = 0;
+ }
+ if(n) {
+ Bputc(&obuf, ANAME);
+ Bputc(&obuf, D_FILE); /* type */
+ Bputc(&obuf, 1); /* sym */
+ Bputc(&obuf, '<');
+ Bwrite(&obuf, p, n);
+ Bputc(&obuf, 0);
+ }
+ p = q;
+ if(p == 0 && op) {
+ p = op;
+ op = 0;
+ }
+ }
+ 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"
+#include "../cc/compat"