mirror of
https://github.com/golang/go
synced 2024-11-23 03:50:03 -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 R1 up as temps */
|
||||||
/* compiler allocates register variables R3 up */
|
/* compiler allocates register variables R3 up */
|
||||||
#define REGEXT 10
|
#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 */
|
/* compiler allocates external registers R10 down */
|
||||||
#define REGTMP 11
|
#define REGTMP 11
|
||||||
#define REGSB 12
|
#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
|
enum
|
||||||
{
|
{
|
||||||
|
Sxxx,
|
||||||
|
|
||||||
STEXT = 1,
|
STEXT = 1,
|
||||||
SDATA,
|
SDATA,
|
||||||
SBSS,
|
SBSS,
|
||||||
@ -375,7 +377,7 @@ int Sconv(Fmt*);
|
|||||||
int aclass(Adr*);
|
int aclass(Adr*);
|
||||||
int thumbaclass(Adr*, Prog*);
|
int thumbaclass(Adr*, Prog*);
|
||||||
void addhist(int32, int);
|
void addhist(int32, int);
|
||||||
void append(Prog*, Prog*);
|
Prog* appendp(Prog*);
|
||||||
void asmb(void);
|
void asmb(void);
|
||||||
void asmdyn(void);
|
void asmdyn(void);
|
||||||
void asmlc(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);
|
vlong size, uint32 link, uint32 info, vlong align, vlong entsize);
|
||||||
int linuxstrtable(void);
|
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
|
#endif
|
||||||
|
@ -30,6 +30,12 @@
|
|||||||
|
|
||||||
#include "l.h"
|
#include "l.h"
|
||||||
|
|
||||||
|
// see ../../runtime/proc.c:/StackGuard
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
StackBig = 4096,
|
||||||
|
};
|
||||||
|
|
||||||
static Sym* sym_div;
|
static Sym* sym_div;
|
||||||
static Sym* sym_divu;
|
static Sym* sym_divu;
|
||||||
static Sym* sym_mod;
|
static Sym* sym_mod;
|
||||||
@ -105,6 +111,8 @@ noops(void)
|
|||||||
{
|
{
|
||||||
Prog *p, *q, *q1, *q2;
|
Prog *p, *q, *q1, *q2;
|
||||||
int o, curframe, curbecome, maxbecome, foreign;
|
int o, curframe, curbecome, maxbecome, foreign;
|
||||||
|
Prog *pmorestack;
|
||||||
|
Sym *symmorestack;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* find leaf subroutines
|
* find leaf subroutines
|
||||||
@ -119,6 +127,23 @@ noops(void)
|
|||||||
Bprint(&bso, "%5.2f noops\n", cputime());
|
Bprint(&bso, "%5.2f noops\n", cputime());
|
||||||
Bflush(&bso);
|
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;
|
curframe = 0;
|
||||||
curbecome = 0;
|
curbecome = 0;
|
||||||
maxbecome = 0;
|
maxbecome = 0;
|
||||||
@ -281,27 +306,13 @@ noops(void)
|
|||||||
if(curtext->mark & LEAF) {
|
if(curtext->mark & LEAF) {
|
||||||
if(curtext->from.sym)
|
if(curtext->from.sym)
|
||||||
curtext->from.sym->type = SLEAF;
|
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)
|
if(!autosize)
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(thumb){
|
if(thumb){
|
||||||
|
if(!(p->reg & NOSPLIT))
|
||||||
|
diag("stack splitting not supported in thumb");
|
||||||
if(!(curtext->mark & LEAF)){
|
if(!(curtext->mark & LEAF)){
|
||||||
q = movrr(nil, REGLINK, REGTMPT-1, p);
|
q = movrr(nil, REGLINK, REGTMPT-1, p);
|
||||||
p->link = q;
|
p->link = q;
|
||||||
@ -331,6 +342,8 @@ noops(void)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if(p->reg & NOSPLIT) {
|
||||||
|
if(1) {
|
||||||
q1 = prg();
|
q1 = prg();
|
||||||
q1->as = AMOVW;
|
q1->as = AMOVW;
|
||||||
q1->scond |= C_WBIT;
|
q1->scond |= C_WBIT;
|
||||||
@ -342,6 +355,62 @@ noops(void)
|
|||||||
q1->to.reg = REGSP;
|
q1->to.reg = REGSP;
|
||||||
q1->link = p->link;
|
q1->link = p->link;
|
||||||
p->link = q1;
|
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;
|
break;
|
||||||
|
|
||||||
case ARET:
|
case ARET:
|
||||||
@ -364,31 +433,6 @@ noops(void)
|
|||||||
p->to.reg = REGLINK;
|
p->to.reg = REGLINK;
|
||||||
break;
|
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(thumb){
|
||||||
if(curtext->mark & LEAF){
|
if(curtext->mark & LEAF){
|
||||||
@ -491,28 +535,6 @@ noops(void)
|
|||||||
p->from = zprg.from;
|
p->from = zprg.from;
|
||||||
break;
|
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 = prg();
|
||||||
q->scond = p->scond;
|
q->scond = p->scond;
|
||||||
|
@ -278,6 +278,11 @@ main(int argc, char *argv[])
|
|||||||
sprint(a, "%s/pkg/%s_%s/runtime.a", goroot, goos, goarch);
|
sprint(a, "%s/pkg/%s_%s/runtime.a", goroot, goos, goarch);
|
||||||
objfile(a);
|
objfile(a);
|
||||||
}
|
}
|
||||||
|
// TODO(kaib): add these go specific extensions
|
||||||
|
// definetypestrings();
|
||||||
|
// definetypesigs();
|
||||||
|
// deadcode();
|
||||||
|
|
||||||
firstp = firstp->link;
|
firstp = firstp->link;
|
||||||
if(firstp == P)
|
if(firstp == P)
|
||||||
goto out;
|
goto out;
|
||||||
@ -764,8 +769,10 @@ ldobj(Biobuf *f, int32 len, char *pn)
|
|||||||
uint32 sig;
|
uint32 sig;
|
||||||
static int files;
|
static int files;
|
||||||
static char **filen;
|
static char **filen;
|
||||||
char **nfilen,*name;
|
char **nfilen, *line, *name;
|
||||||
vlong eof;
|
int n, c1, c2, c3;
|
||||||
|
int32 eof;
|
||||||
|
int32 start, import0, import1;
|
||||||
|
|
||||||
eof = Boffset(f) + len;
|
eof = Boffset(f) + len;
|
||||||
|
|
||||||
@ -779,6 +786,48 @@ ldobj(Biobuf *f, int32 len, char *pn)
|
|||||||
|
|
||||||
di = S;
|
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:
|
newloop:
|
||||||
memset(h, 0, sizeof(h));
|
memset(h, 0, sizeof(h));
|
||||||
version++;
|
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);
|
// 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
|
void
|
||||||
undefsym(Sym *s)
|
undefsym(Sym *s)
|
||||||
{
|
{
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
Optab optab[] =
|
Optab optab[] =
|
||||||
{
|
{
|
||||||
/* Data layout:
|
/* 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_NONE, C_LCON, 0, 0, 0 },
|
||||||
{ ATEXT, C_LEXT, C_REG, 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 },
|
{ ATEXT, C_ADDR, C_NONE, C_LCON, 0, 0, 0 },
|
||||||
|
Loading…
Reference in New Issue
Block a user