From 83632c7359e12779f134c88594779f1808b90172 Mon Sep 17 00:00:00 2001 From: Kai Backman Date: Mon, 8 Jun 2009 20:20:35 -0700 Subject: [PATCH] initial morestack support for 5l. still disabled, doesn't work. R=rsc APPROVED=rsc DELTA=245 (167 added, 63 deleted, 15 changed) OCL=30039 CL=30081 --- src/cmd/5l/5.out.h | 3 + src/cmd/5l/go.c | 12 ++++ src/cmd/5l/l.h | 13 +++- src/cmd/5l/noop.c | 170 +++++++++++++++++++++++++-------------------- src/cmd/5l/obj.c | 65 ++++++++++++++++- src/cmd/5l/optab.c | 2 +- 6 files changed, 187 insertions(+), 78 deletions(-) create mode 100644 src/cmd/5l/go.c diff --git a/src/cmd/5l/5.out.h b/src/cmd/5l/5.out.h index ac463b4cdf8..22c675b04d4 100644 --- a/src/cmd/5l/5.out.h +++ b/src/cmd/5l/5.out.h @@ -42,6 +42,9 @@ /* compiler allocates R1 up as temps */ /* compiler allocates register variables R3 up */ #define REGEXT 10 +/* these two registers are declared in runtime.h */ +#define REGG (REGEXT-0) +#define REGM (REGEXT-1) /* compiler allocates external registers R10 down */ #define REGTMP 11 #define REGSB 12 diff --git a/src/cmd/5l/go.c b/src/cmd/5l/go.c new file mode 100644 index 00000000000..f1146c0c999 --- /dev/null +++ b/src/cmd/5l/go.c @@ -0,0 +1,12 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#include "l.h" +#include "compat.h" +enum +{ + PtrSize = 4 +}; +#define pcond cond +#include "../ld/go.c" diff --git a/src/cmd/5l/l.h b/src/cmd/5l/l.h index b864744e16d..c8c49998e53 100644 --- a/src/cmd/5l/l.h +++ b/src/cmd/5l/l.h @@ -161,6 +161,8 @@ struct Use enum { + Sxxx, + STEXT = 1, SDATA, SBSS, @@ -375,7 +377,7 @@ int Sconv(Fmt*); int aclass(Adr*); int thumbaclass(Adr*, Prog*); void addhist(int32, int); -void append(Prog*, Prog*); +Prog* appendp(Prog*); void asmb(void); void asmdyn(void); void asmlc(void); @@ -481,4 +483,13 @@ void linuxshdr(char *name, uint32 type, vlong flags, vlong addr, vlong off, vlong size, uint32 link, uint32 info, vlong align, vlong entsize); int linuxstrtable(void); +/* + * go.c + */ +void deadcode(void); +void definetypestrings(void); +void definetypesigs(void); +char* gotypefor(char *name); +void ldpkg(Biobuf *f, int64 len, char *filename); + #endif diff --git a/src/cmd/5l/noop.c b/src/cmd/5l/noop.c index e3207ab46a1..333a3999a3e 100644 --- a/src/cmd/5l/noop.c +++ b/src/cmd/5l/noop.c @@ -30,6 +30,12 @@ #include "l.h" +// see ../../runtime/proc.c:/StackGuard +enum +{ + StackBig = 4096, +}; + static Sym* sym_div; static Sym* sym_divu; static Sym* sym_mod; @@ -105,6 +111,8 @@ noops(void) { Prog *p, *q, *q1, *q2; int o, curframe, curbecome, maxbecome, foreign; + Prog *pmorestack; + Sym *symmorestack; /* * find leaf subroutines @@ -119,6 +127,23 @@ noops(void) Bprint(&bso, "%5.2f noops\n", cputime()); Bflush(&bso); + pmorestack = P; + symmorestack = lookup("sys·morestack", 0); + + if(symmorestack->type == STEXT) + for(p = firstp; p != P; p = p->link) { + if(p->as == ATEXT) { + if(p->from.sym == symmorestack) { + pmorestack = p; + p->reg |= NOSPLIT; + break; + } + } + } + // TODO(kaib): make lack of morestack an error +// if(pmorestack == P) +// diag("sys·morestack not defined"); + curframe = 0; curbecome = 0; maxbecome = 0; @@ -281,27 +306,13 @@ noops(void) if(curtext->mark & LEAF) { if(curtext->from.sym) curtext->from.sym->type = SLEAF; -#ifdef optimise_time - if(autosize) { - q = prg(); - q->as = ASUB; - q->line = p->line; - q->from.type = D_CONST; - q->from.offset = autosize; - q->to.type = D_REG; - q->to.reg = REGSP; - - q->link = p->link; - p->link = q; - } - break; -#else if(!autosize) break; -#endif } if(thumb){ + if(!(p->reg & NOSPLIT)) + diag("stack splitting not supported in thumb"); if(!(curtext->mark & LEAF)){ q = movrr(nil, REGLINK, REGTMPT-1, p); p->link = q; @@ -331,17 +342,75 @@ noops(void) break; } - q1 = prg(); - q1->as = AMOVW; - q1->scond |= C_WBIT; - q1->line = p->line; - q1->from.type = D_REG; - q1->from.reg = REGLINK; - q1->to.type = D_OREG; - q1->to.offset = -autosize; - q1->to.reg = REGSP; - q1->link = p->link; - p->link = q1; +// if(p->reg & NOSPLIT) { + if(1) { + q1 = prg(); + q1->as = AMOVW; + q1->scond |= C_WBIT; + q1->line = p->line; + q1->from.type = D_REG; + q1->from.reg = REGLINK; + q1->to.type = D_OREG; + q1->to.offset = -autosize; + q1->to.reg = REGSP; + q1->link = p->link; + p->link = q1; + } else { // !NOSPLIT + // split stack check + if(autosize < StackBig) { + p = appendp(p); // load G.stackguard into R1 + p->as = AMOVW; + p->from.type = D_OREG; + p->from.reg = REGG; + p->to.type = D_REG; + p->to.reg = 1; + + p = appendp(p); + p->as = ACMP; + p->from.type = D_REG; + p->from.reg = 1; + p->from.offset = -autosize; + p->reg = REGSP; + } + + // TODO(kaib): Optimize the heck out of this + p = appendp(p); // store autosize in M.morearg + p->as = AMOVW; + p->from.type = D_CONST; + if(autosize+160 > 4096) + p->from.offset = (autosize+160) & ~7LL; + p->to.type = D_REG; + p->to.reg = REGTMP; + + p = appendp(p); + p->as = AMOVW; + p->from.type = D_REG; + p->from.reg = REGTMP; + p->to.type = D_OREG; + p->to.reg = REGM; + p->to.offset = 4; + + p = appendp(p); + p->as = AMOVW; + p->from.type = D_CONST; +// p->from.offset = curtext->to.offset2; + p->to.type = D_REG; + p->to.reg = REGTMP; + + p = appendp(p); + p->as = AMOVW; + p->from.type = D_REG; + p->from.reg = REGTMP; + p->to.type = D_OREG; + p->to.reg = REGM; + p->to.offset = 8; + +// p = appendp(p); +// p->as = ABL; +// p->to.type = D_BRANCH; +// p->to.sym = symmorestack; +// p->cond = pmorestack; + } break; case ARET: @@ -364,31 +433,6 @@ noops(void) p->to.reg = REGLINK; break; } - -#ifdef optimise_time - p->as = AADD; - p->from.type = D_CONST; - p->from.offset = autosize; - p->to.type = D_REG; - p->to.reg = REGSP; - if(thumb){ - p->link = fnret(nil, REGLINK, foreign, p); - break; - } - q = prg(); -// if(foreign) print("ABXRET 2 %s\n", curtext->from.sym->name); - q->as = foreign ? ABXRET : AB; - q->scond = p->scond; - q->line = p->line; - q->to.type = D_OREG; - q->to.offset = 0; - q->to.reg = REGLINK; - - q->link = p->link; - p->link = q; - - break; -#endif } if(thumb){ if(curtext->mark & LEAF){ @@ -491,28 +535,6 @@ noops(void) p->from = zprg.from; break; } - -#ifdef optimise_time - q = prg(); - q->scond = p->scond; - q->line = p->line; - q->as = AB; - q->from = zprg.from; - q->to = p->to; - q->cond = p->cond; - q->link = p->link; - p->link = q; - - p->as = AADD; - p->from = zprg.from; - p->from.type = D_CONST; - p->from.offset = autosize; - p->to = zprg.to; - p->to.type = D_REG; - p->to.reg = REGSP; - - break; -#endif } q = prg(); q->scond = p->scond; diff --git a/src/cmd/5l/obj.c b/src/cmd/5l/obj.c index 30f60e07dd3..3295348c23c 100644 --- a/src/cmd/5l/obj.c +++ b/src/cmd/5l/obj.c @@ -278,6 +278,11 @@ main(int argc, char *argv[]) sprint(a, "%s/pkg/%s_%s/runtime.a", goroot, goos, goarch); objfile(a); } + // TODO(kaib): add these go specific extensions +// definetypestrings(); +// definetypesigs(); +// deadcode(); + firstp = firstp->link; if(firstp == P) goto out; @@ -764,8 +769,10 @@ ldobj(Biobuf *f, int32 len, char *pn) uint32 sig; static int files; static char **filen; - char **nfilen,*name; - vlong eof; + char **nfilen, *line, *name; + int n, c1, c2, c3; + int32 eof; + int32 start, import0, import1; eof = Boffset(f) + len; @@ -779,6 +786,48 @@ ldobj(Biobuf *f, int32 len, char *pn) di = S; + goto newloop; + + /* check the header */ + start = Boffset(f); + line = Brdline(f, '\n'); + if(line == nil) { + if(Blinelen(f) > 0) { + diag("%s: malformed object file", pn); + return; + } + goto eof; + } + n = Blinelen(f) - 1; + if(n != strlen(thestring) || strncmp(line, thestring, n) != 0) { + if(line) + line[n] = '\0'; + diag("file not %s [%s]\n", thestring, line); + // TODO(kaib): Make not finding the header an error again +// return; + Bseek(f, start, 0); + goto newloop; + } + + /* skip over exports and other info -- ends with \n!\n */ + import0 = Boffset(f); + c1 = '\n'; // the last line ended in \n + c2 = Bgetc(f); + c3 = Bgetc(f); + while(c1 != '\n' || c2 != '!' || c3 != '\n') { + c1 = c2; + c2 = c3; + c3 = Bgetc(f); + if(c3 == Beof) + goto eof; + } + import1 = Boffset(f); + + Bseek(f, import0, 0); + // TODO(kaib): add in this go specific extension +// ldpkg(f, import1 - import0 - 2, pn); // -2 for !\n + Bseek(f, import1, 0); + newloop: memset(h, 0, sizeof(h)); version++; @@ -1509,6 +1558,18 @@ puntfp(Prog *p) // print("%s: generating ARM code (contains floating point ops %d)\n", curtext->from.sym->name, p->line); } +Prog* +appendp(Prog *q) +{ + Prog *p; + + p = prg(); + p->link = q->link; + q->link = p; + p->line = q->line; + return p; +} + void undefsym(Sym *s) { diff --git a/src/cmd/5l/optab.c b/src/cmd/5l/optab.c index b041e323427..3d7015d14c7 100644 --- a/src/cmd/5l/optab.c +++ b/src/cmd/5l/optab.c @@ -33,7 +33,7 @@ Optab optab[] = { /* Data layout: - OPCODE, ARG0, ARG1, ARG2, magic numbers? */ + OPCODE, from, prog->reg, to, magic numbers? */ { ATEXT, C_LEXT, C_NONE, C_LCON, 0, 0, 0 }, { ATEXT, C_LEXT, C_REG, C_LCON, 0, 0, 0 }, { ATEXT, C_ADDR, C_NONE, C_LCON, 0, 0, 0 },