summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKai Backman <kaib@golang.org>2009-06-08 20:20:35 -0700
committerKai Backman <kaib@golang.org>2009-06-08 20:20:35 -0700
commitf58bbb8edf21b7142fb8b7aebd0f3a130cb12cd0 (patch)
tree9ba7eaaca16fc8f81b9af01095e8a62feccd0b32
parentd4893db2ffe8dae867dd8e037a8597e8a123c021 (diff)
downloadgolang-f58bbb8edf21b7142fb8b7aebd0f3a130cb12cd0.tar.gz
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
-rw-r--r--src/cmd/5l/5.out.h3
-rw-r--r--src/cmd/5l/go.c12
-rw-r--r--src/cmd/5l/l.h13
-rw-r--r--src/cmd/5l/noop.c170
-rw-r--r--src/cmd/5l/obj.c65
-rw-r--r--src/cmd/5l/optab.c2
6 files changed, 187 insertions, 78 deletions
diff --git a/src/cmd/5l/5.out.h b/src/cmd/5l/5.out.h
index ac463b4cd..22c675b04 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 000000000..f1146c0c9
--- /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 b864744e1..c8c49998e 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 e3207ab46..333a3999a 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 30f60e07d..3295348c2 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 b041e3234..3d7015d14 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 },