1
0
mirror of https://github.com/golang/go synced 2024-11-26 17:56:55 -07:00

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
This commit is contained in:
Kai Backman 2009-06-08 20:20:35 -07:00
parent 9b480bb78a
commit 83632c7359
6 changed files with 187 additions and 78 deletions

View File

@ -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

12
src/cmd/5l/go.c Normal file
View File

@ -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"

View File

@ -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

View File

@ -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,6 +342,8 @@ noops(void)
break;
}
// if(p->reg & NOSPLIT) {
if(1) {
q1 = prg();
q1->as = AMOVW;
q1->scond |= C_WBIT;
@ -342,6 +355,62 @@ noops(void)
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;

View File

@ -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)
{

View File

@ -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 },