diff options
Diffstat (limited to 'src/cmd/5a/lex.c')
-rw-r--r-- | src/cmd/5a/lex.c | 377 |
1 files changed, 87 insertions, 290 deletions
diff --git a/src/cmd/5a/lex.c b/src/cmd/5a/lex.c index c1b54e50b..571fdf7f2 100644 --- a/src/cmd/5a/lex.c +++ b/src/cmd/5a/lex.c @@ -51,60 +51,76 @@ systemtype(int sys) #endif } +int +Lconv(Fmt *fp) +{ + return linklinefmt(ctxt, fp); +} + +void +dodef(char *p) +{ + if(nDlist%8 == 0) + Dlist = allocn(Dlist, nDlist*sizeof(char *), + 8*sizeof(char *)); + Dlist[nDlist++] = p; +} + +void +usage(void) +{ + print("usage: %ca [options] file.c...\n", thechar); + flagprint(1); + errorexit(); +} + void main(int argc, char *argv[]) { char *p; - int c; thechar = '5'; thestring = "arm"; + ctxt = linknew(&linkarm); + ctxt->diag = yyerror; + ctxt->bso = &bstdout; + Binit(&bstdout, 1, OWRITE); + listinit5(); + fmtinstall('L', Lconv); + + // Allow GOARCH=thestring or GOARCH=thestringsuffix, + // but not other values. + p = getgoarch(); + if(strncmp(p, thestring, strlen(thestring)) != 0) + sysfatal("cannot use %cc with GOARCH=%s", thechar, p); + ensuresymb(NSYMB); memset(debug, 0, sizeof(debug)); cinit(); outfile = 0; setinclude("."); - 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) { - if (nDlist%8 == 0) - Dlist = allocn(Dlist, nDlist*sizeof(char *), - 8*sizeof(char *)); - Dlist[nDlist++] = p; - } - break; - - case 'I': - p = ARGF(); - setinclude(p); - break; - case 't': - thechar = 't'; - thestring = "thumb"; - break; - } ARGEND - if(*argv == 0) { - print("usage: %ca [-options] file.s\n", thechar); - errorexit(); - } + + flagfn1("D", "name[=value]: add #define", dodef); + flagfn1("I", "dir: add dir to include path", setinclude); + flagcount("S", "print assembly and machine code", &debug['S']); + flagcount("m", "debug preprocessor macros", &debug['m']); + flagstr("o", "file: set output file", &outfile); + flagstr("trimpath", "prefix: remove prefix from recorded source file paths", &ctxt->trimpath); + + flagparse(&argc, &argv, usage); + ctxt->debugasm = debug['S']; + + if(argc < 1) + usage(); if(argc > 1){ print("can't assemble multiple files\n"); errorexit(); } + if(assemble(argv[0])) errorexit(); + Bflush(&bstdout); exits(0); } @@ -143,30 +159,22 @@ assemble(char *file) errorexit(); } Binit(&obuf, of, OWRITE); - - pass = 1; - pinit(file); - - Bprint(&obuf, "go object %s %s %s\n", getgoos(), thestring, getgoversion()); - - for(i=0; i<nDlist; i++) - dodefine(Dlist[i]); - yyparse(); - if(nerrors) { + Bprint(&obuf, "go object %s %s %s\n", getgoos(), getgoarch(), getgoversion()); + Bprint(&obuf, "!\n"); + + for(pass = 1; pass <= 2; pass++) { + pinit(file); + for(i=0; i<nDlist; i++) + dodefine(Dlist[i]); + yyparse(); cclean(); - return nerrors; + if(nerrors) + return nerrors; } - Bprint(&obuf, "\n!\n"); - - pass = 2; - outhist(); - pinit(file); - for(i=0; i<nDlist; i++) - dodefine(Dlist[i]); - yyparse(); - cclean(); - return nerrors; + writeobj(ctxt, &obuf); + Bflush(&obuf); + return 0; } struct @@ -426,15 +434,9 @@ 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; @@ -448,13 +450,6 @@ cinit(void) s->type = itab[i].type; s->value = itab[i].value; } - - pathname = allocn(pathname, 0, 100); - if(getwd(pathname, 99) == 0) { - pathname = allocn(pathname, 100, 900); - if(getwd(pathname, 999) == 0) - strcpy(pathname, "/???"); - } } void @@ -466,7 +461,7 @@ syminit(Sym *s) } int -isreg(Gen *g) +isreg(Addr *g) { USED(g); @@ -476,81 +471,7 @@ isreg(Gen *g) void cclean(void) { - outcode(AEND, Always, &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) -{ - int32 l; - int i; - char *n; - Ieee e; - - BPUTC(&obuf, a->type); - BPUTC(&obuf, a->reg); - BPUTC(&obuf, s); - BPUTC(&obuf, a->name); - BPUTC(&obuf, 0); - switch(a->type) { - default: - print("unknown type %d\n", a->type); - exits("arg"); - - case D_NONE: - case D_REG: - case D_FREG: - case D_PSR: - case D_FPCR: - break; - - case D_REGREG: - case D_REGREG2: - BPUTC(&obuf, a->offset); - break; - - case D_CONST2: - l = a->offset2; - BPUTLE4(&obuf, l); - // fall through - case D_OREG: - case D_CONST: - case D_BRANCH: - case D_SHIFT: - l = a->offset; - BPUTLE4(&obuf, l); - 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); - BPUTLE4(&obuf, e.l); - BPUTLE4(&obuf, e.h); - break; - } } static int bcode[] = @@ -573,11 +494,13 @@ static int bcode[] = ANOP, }; +static Prog *lastpc; + void -outcode(int a, int scond, Gen *g1, int reg, Gen *g2) +outcode(int a, int scond, Addr *g1, int reg, Addr *g2) { - int sf, st, t; - Sym *s; + Prog *p; + Plist *pl; /* hack to make B.NE etc. work: turn it into the corresponding conditional */ if(a == AB){ @@ -587,154 +510,28 @@ outcode(int a, int scond, Gen *g1, int reg, Gen *g2) 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, scond); - BPUTC(&obuf, reg); - BPUTLE4(&obuf, stmtline); - zaddr(g1, sf); - zaddr(g2, st); + + p = malloc(sizeof *p); + memset(p, 0, sizeof *p); + p->as = a; + p->lineno = stmtline; + p->scond = scond; + p->from = *g1; + p->reg = reg; + p->to = *g2; + p->pc = pc; + + if(lastpc == nil) { + pl = linknewplist(ctxt); + pl->firstpc = p; + } else + lastpc->link = p; + lastpc = p; out: if(a != AGLOBL && a != ADATA) pc++; } -void -outhist(void) -{ - Gen g; - Hist *h; - char *p, *q, *op, c; - int n; - char *tofree; - static int first = 1; - static char *goroot, *goroot_final; - - if(first) { - // Decide whether we need to rewrite paths from $GOROOT to $GOROOT_FINAL. - first = 0; - goroot = getenv("GOROOT"); - goroot_final = getenv("GOROOT_FINAL"); - if(goroot == nil) - goroot = ""; - if(goroot_final == nil) - goroot_final = goroot; - if(strcmp(goroot, goroot_final) == 0) { - goroot = nil; - goroot_final = nil; - } - } - - tofree = nil; - g = nullgen; - c = '/'; - for(h = hist; h != H; h = h->link) { - p = h->name; - if(p != nil && goroot != nil) { - n = strlen(goroot); - if(strncmp(p, goroot, strlen(goroot)) == 0 && p[n] == '/') { - tofree = smprint("%s%s", goroot_final, p+n); - p = tofree; - } - } - op = 0; - if(systemtype(Windows) && p && p[1] == ':'){ - c = p[2]; - } else if(p && p[0] != c && h->offset == 0 && pathname){ - if(systemtype(Windows) && pathname[1] == ':') { - op = p; - p = pathname; - c = p[2]; - } 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, Always); - BPUTC(&obuf, 0); - BPUTLE4(&obuf, h->line); - zaddr(&nullgen, 0); - zaddr(&g, 0); - - if(tofree) { - free(tofree); - tofree = nil; - } - } -} - #include "../cc/lexbody" #include "../cc/macbody" |