ref: f8467210359d5c4e576e8c4aa89177902517ec5b
dir: /sys/src/cmd/7a/lex.c/
#include <ctype.h> #define EXTERN #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 = '7'; /* of 9 */ thestring = "alpha"; 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(); 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: strecpy(ofile, ofile+sizeof 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(0) { 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); for(i=0; i<nDlist; i++) dodefine(Dlist[i]); yyparse(); if(nerrors) { cclean(); errorexit(); } pass = 2; outhist(); pinit(*argv); for(i=0; i<nDlist; i++) dodefine(Dlist[i]); 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, "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, "P", LP, 0, "I", LP, 32, "A", LP, 64, "IA", LP, 96, "T", LP, 128, "IT", LP, 32+128, "AT", LP, 64+128, "IAT", LP, 96+128, "T0", LPREG, 0+128, "T1", LPREG, 1+128, "T2", LPREG, 2+128, "T3", LPREG, 3+128, "T4", LPREG, 4+128, "T5", LPREG, 5+128, "T6", LPREG, 6+128, "T7", LPREG, 7+128, "T8", LPREG, 8+128, "T9", LPREG, 9+128, "T10", LPREG, 10+128, "T11", LPREG, 11+128, "T12", LPREG, 12+128, "T13", LPREG, 13+128, "T14", LPREG, 14+128, "T15", LPREG, 15+128, "T16", LPREG, 16+128, "T17", LPREG, 17+128, "T18", LPREG, 18+128, "T19", LPREG, 19+128, "T20", LPREG, 20+128, "T21", LPREG, 21+128, "T22", LPREG, 22+128, "T23", LPREG, 23+128, "T24", LPREG, 24+128, "T25", LPREG, 25+128, "T26", LPREG, 26+128, "T27", LPREG, 27+128, "T28", LPREG, 28+128, "T29", LPREG, 29+128, "T30", LPREG, 30+128, "T31", LPREG, 31+128, "F", LF, 0, "F0", LFREG, 0, "F1", LFREG, 1, "F2", LFREG, 2, "F3", LFREG, 3, "F4", LFREG, 4, "F5", LFREG, 5, "F6", LFREG, 6, "F7", LFREG, 7, "F8", LFREG, 8, "F9", LFREG, 9, "F10", LFREG, 10, "F11", LFREG, 11, "F12", LFREG, 12, "F13", LFREG, 13, "F14", LFREG, 14, "F15", LFREG, 15, "F16", LFREG, 16, "F17", LFREG, 17, "F18", LFREG, 18, "F19", LFREG, 19, "F20", LFREG, 20, "F21", LFREG, 21, "F22", LFREG, 22, "F23", LFREG, 23, "F24", LFREG, 24, "F25", LFREG, 25, "F26", LFREG, 26, "F27", LFREG, 27, "F28", LFREG, 28, "F29", LFREG, 29, "F30", LFREG, 30, "F31", LFREG, 31, "FPCR", LFPCR, 0, "PCC", LPCC, 0, /* 1: integer operates */ "ADDQ", LTYPE1, AADDQ, "ADDL", LTYPE1, AADDL, "SUBL", LTYPE1, ASUBL, "SUBQ", LTYPE1, ASUBQ, "CMPEQ", LTYPE1, ACMPEQ, "CMPGT", LTYPE1, ACMPGT, "CMPGE", LTYPE1, ACMPGE, "CMPUGT", LTYPE1, ACMPUGT, "CMPUGE", LTYPE1, ACMPUGE, "CMPBLE", LTYPE1, ACMPBLE, "AND", LTYPE1, AAND, "ANDNOT", LTYPE1, AANDNOT, "OR", LTYPE1, AOR, "ORNOT", LTYPE1, AORNOT, "XOR", LTYPE1, AXOR, "XORNOT", LTYPE1, AXORNOT, "CMOVEQ", LTYPE1, ACMOVEQ, "CMOVNE", LTYPE1, ACMOVNE, "CMOVLT", LTYPE1, ACMOVLT, "CMOVGE", LTYPE1, ACMOVGE, "CMOVLE", LTYPE1, ACMOVLE, "CMOVGT", LTYPE1, ACMOVGT, "CMOVLBS", LTYPE1, ACMOVLBS, "CMOVLBC", LTYPE1, ACMOVLBC, "MULL", LTYPE1, AMULL, "MULQ", LTYPE1, AMULQ, "UMULH", LTYPE1, AUMULH, "DIVQ", LTYPE1, ADIVQ, "MODQ", LTYPE1, AMODQ, "DIVQU", LTYPE1, ADIVQU, "MODQU", LTYPE1, AMODQU, "DIVL", LTYPE1, ADIVL, "MODL", LTYPE1, AMODL, "DIVLU", LTYPE1, ADIVLU, "MODLU", LTYPE1, AMODLU, "SLLQ", LTYPE1, ASLLQ, "SRLQ", LTYPE1, ASRLQ, "SRAQ", LTYPE1, ASRAQ, "SLLL", LTYPE1, ASLLL, "SRLL", LTYPE1, ASRLL, "SRAL", LTYPE1, ASRAL, "EXTBL", LTYPE1, AEXTBL, "EXTWL", LTYPE1, AEXTWL, "EXTLL", LTYPE1, AEXTLL, "EXTQL", LTYPE1, AEXTQL, "EXTWH", LTYPE1, AEXTWH, "EXTLH", LTYPE1, AEXTLH, "EXTQH", LTYPE1, AEXTQH, "INSBL", LTYPE1, AINSBL, "INSWL", LTYPE1, AINSWL, "INSLL", LTYPE1, AINSLL, "INSQL", LTYPE1, AINSQL, "INSWH", LTYPE1, AINSWH, "INSLH", LTYPE1, AINSLH, "INSQH", LTYPE1, AINSQH, "MSKBL", LTYPE1, AMSKBL, "MSKWL", LTYPE1, AMSKWL, "MSKLL", LTYPE1, AMSKLL, "MSKQL", LTYPE1, AMSKQL, "MSKWH", LTYPE1, AMSKWH, "MSKLH", LTYPE1, AMSKLH, "MSKQH", LTYPE1, AMSKQH, "ZAP", LTYPE1, AZAP, "ZAPNOT", LTYPE1, AZAPNOT, /* 2: floating operates with 2 operands */ "CVTQS", LTYPE2, ACVTQS, "CVTQT", LTYPE2, ACVTQT, "CVTTS", LTYPE2, ACVTTS, "CVTTQ", LTYPE2, ACVTTQ, "CVTLQ", LTYPE2, ACVTLQ, "CVTQL", LTYPE2, ACVTQL, /* 3: floating operates with 2 or 3 operands */ "CPYS", LTYPE3, ACPYS, "CPYSN", LTYPE3, ACPYSN, "CPYSE", LTYPE3, ACPYSE, "ADDS", LTYPE3, AADDS, "ADDT", LTYPE3, AADDT, "CMPTEQ", LTYPE3, ACMPTEQ, "CMPTGT", LTYPE3, ACMPTGT, "CMPTGE", LTYPE3, ACMPTGE, "CMPTUN", LTYPE3, ACMPTUN, "DIVS", LTYPE3, ADIVS, "DIVT", LTYPE3, ADIVT, "MULS", LTYPE3, AMULS, "MULT", LTYPE3, AMULT, "SUBS", LTYPE3, ASUBS, "SUBT", LTYPE3, ASUBT, "FCMOVEQ", LTYPE3, AFCMOVEQ, "FCMOVNE", LTYPE3, AFCMOVNE, "FCMOVLT", LTYPE3, AFCMOVLT, "FCMOVGE", LTYPE3, AFCMOVGE, "FCMOVLE", LTYPE3, AFCMOVLE, "FCMOVGT", LTYPE3, AFCMOVGT, /* 4: integer load/store and reg->reg (incl special regs) */ "MOVQ", LTYPE4, AMOVQ, /* 5: integer load/store and reg->reg */ "MOVL", LTYPE5, AMOVL, "MOVQU", LTYPE5, AMOVQU, "MOVB", LTYPE5, AMOVB, "MOVBU", LTYPE5, AMOVBU, "MOVW", LTYPE5, AMOVW, "MOVWU", LTYPE5, AMOVWU, "MOVLP", LTYPE5, AMOVLP, "MOVQP", LTYPE5, AMOVQP, /* 6: integer load/store (only) */ "MOVA", LTYPE6, AMOVA, "MOVAH", LTYPE6, AMOVAH, "MOVLL", LTYPE6, AMOVLL, "MOVQL", LTYPE6, AMOVQL, "MOVLC", LTYPEK, AMOVLC, "MOVQC", LTYPEK, AMOVQC, /* 7: floating load/store and reg->reg */ "MOVS", LTYPE7, AMOVS, "MOVT", LTYPE7, AMOVT, /* 8,9: jumps */ "JMP", LTYPE8, AJMP, "JSR", LTYPE8, AJSR, "RET", LTYPE9, ARET, /* A: integer conditional branches */ "BEQ", LTYPEA, ABEQ, "BNE", LTYPEA, ABNE, "BLT", LTYPEA, ABLT, "BGE", LTYPEA, ABGE, "BLE", LTYPEA, ABLE, "BGT", LTYPEA, ABGT, "BLBC", LTYPEA, ABLBC, "BLBS", LTYPEA, ABLBS, /* B: floating conditional branches */ "FBEQ", LTYPEB, AFBEQ, "FBNE", LTYPEB, AFBNE, "FBLT", LTYPEB, AFBLT, "FBGE", LTYPEB, AFBGE, "FBLE", LTYPEB, AFBLE, "FBGT", LTYPEB, AFBGT, /* C-J: miscellaneous */ "TRAPB", LTYPEC, ATRAPB, "MB", LTYPEC, AMB, "REI", LTYPEC, AREI, "END", LTYPEC, AEND, "FETCH", LTYPED, AFETCH, "FETCHM", LTYPED, AFETCHM, "CALL_PAL", LTYPEE, ACALL_PAL, "TEXT", LTYPEF, ATEXT, "GLOBL", LTYPEF, AGLOBL, "DATA", LTYPEG, ADATA, "WORD", LTYPEH, AWORD, "NOP", LTYPEI, ANOP, 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; 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; } ALLOCN(pathname, 0, 100); if(getwd(pathname, 99) == 0) { ALLOCN(pathname, 100, 900); if(getwd(pathname, 999) == 0) strcpy(pathname, "/???"); } } void syminit(Sym *s) { s->type = LNAME; s->value = 0; } int isreg(Gen *g) { USED(g); return 1; } 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) { vlong 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_PREG: case D_FCREG: case D_PCC: break; case D_OREG: case D_CONST: case D_BRANCH: l = a->offset; Bputc(&obuf, l); Bputc(&obuf, l>>8); Bputc(&obuf, l>>16); Bputc(&obuf, l>>24); Bputc(&obuf, l>>32); Bputc(&obuf, l>>40); Bputc(&obuf, l>>48); Bputc(&obuf, l>>56); 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; 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 *p, *q, *op; int n; g = nullgen; for(h = hist; h != H; h = h->link) { p = h->name; op = 0; if(p && p[0] != '/' && h->offset == 0 && pathname && pathname[0] == '/') { op = p; p = pathname; } 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) { 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"