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:
parent
9b480bb78a
commit
83632c7359
@ -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
12
src/cmd/5l/go.c
Normal 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"
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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 },
|
||||
|
Loading…
Reference in New Issue
Block a user