summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2009-05-06 17:06:06 -0700
committerRuss Cox <rsc@golang.org>2009-05-06 17:06:06 -0700
commitdc9dfef6774c63d00608773d2cfd611e0124ea33 (patch)
tree9ec55dd6149bade69d6a49a1c5e25912da4d503f
parenta0f67319f0e580ecfa608b0eeb9a15ca871610f0 (diff)
downloadgolang-dc9dfef6774c63d00608773d2cfd611e0124ea33.tar.gz
6g: simplify trampoline by postponing load.
TEXT tramp MOVQ 8(SP), AX ADDQ $40, AX MOVQ AX, 8(SP) JMP oldfunc is now TEXT tramp ADDQ $40, 8(SP) JMP oldfunc and if s/40/0/, then it simplifies to TEXT tramp JMP oldfunc (the tramp is still needed to satisfy symbol references from other object files) R=ken OCL=28377 CL=28381
-rw-r--r--src/cmd/6g/obj.c59
1 files changed, 37 insertions, 22 deletions
diff --git a/src/cmd/6g/obj.c b/src/cmd/6g/obj.c
index bdbf5c767..1970d1fab 100644
--- a/src/cmd/6g/obj.c
+++ b/src/cmd/6g/obj.c
@@ -272,7 +272,7 @@ data(void)
{
gflag = debug['g'];
debug['g'] = 0;
-
+
if(estrdat == nil) {
strdat = mal(sizeof(*pc));
clearp(strdat);
@@ -324,7 +324,7 @@ datastring(char *s, int len, Addr *a)
Strlit lit;
char buf[100];
} tmp;
-
+
// string
memset(&ao, 0, sizeof(ao));
ao.type = D_STATIC;
@@ -421,7 +421,7 @@ datagostring(Strlit *sval, Addr *a)
wi = types[TUINT32]->width;
wp = types[tptr]->width;
-
+
if(ap.index == D_STATIC) {
// huge strings are made static to avoid long names
snprint(namebuf, sizeof(namebuf), ".gostring.%d", ++gen);
@@ -457,7 +457,7 @@ datagostring(Strlit *sval, Addr *a)
p->from.scale = wi;
p->to = ac;
p->to.offset = sval->len;
-
+
p = pc;
ggloblsym(ao.sym, types[TSTRING]->width, ao.type == D_EXTERN);
if(ao.type == D_STATIC)
@@ -553,7 +553,7 @@ void
genembedtramp(Type *t, Sig *b)
{
Sym *e;
- int c, d, o;
+ int c, d, o, loaded;
Prog *p;
Type *f;
@@ -566,9 +566,6 @@ genembedtramp(Type *t, Sig *b)
fatal("genembedtramp %T.%s", t, b->name);
out:
- if(d == 0)
- return;
-
// print("genembedtramp %d\n", d);
// print(" t = %lT\n", t);
// print(" name = %s\n", b->name);
@@ -587,20 +584,24 @@ out:
p->from.scale = 7;
//print("1. %P\n", p);
- //MOVQ 8(SP), AX
- p = pc;
- gins(AMOVQ, N, N);
- p->from.type = D_INDIR+D_SP;
- p->from.offset = 8;
- p->to.type = D_AX;
-//print("2. %P\n", p);
-
+ loaded = 0;
o = 0;
for(c=d-1; c>=0; c--) {
f = dotlist[c].field;
o += f->width;
if(!isptr[f->type->etype])
continue;
+ if(!loaded) {
+ loaded = 1;
+ //MOVQ 8(SP), AX
+ p = pc;
+ gins(AMOVQ, N, N);
+ p->from.type = D_INDIR+D_SP;
+ p->from.offset = 8;
+ p->to.type = D_AX;
+//print("2. %P\n", p);
+ }
+
//MOVQ o(AX), AX
p = pc;
gins(AMOVQ, N, N);
@@ -616,17 +617,31 @@ out:
gins(AADDQ, N, N);
p->from.type = D_CONST;
p->from.offset = o;
- p->to.type = D_AX;
+ if(loaded)
+ p->to.type = D_AX;
+ else {
+ p->to.type = D_INDIR+D_SP;
+ p->to.offset = 8;
+ }
//print("4. %P\n", p);
}
//MOVQ AX, 8(SP)
- p = pc;
- gins(AMOVQ, N, N);
- p->from.type = D_AX;
- p->to.type = D_INDIR+D_SP;
- p->to.offset = 8;
+ if(loaded) {
+ p = pc;
+ gins(AMOVQ, N, N);
+ p->from.type = D_AX;
+ p->to.type = D_INDIR+D_SP;
+ p->to.offset = 8;
//print("5. %P\n", p);
+ } else {
+ // TODO(rsc): obviously this is unnecessary,
+ // but 6l has a bug, and it can't handle
+ // JMP instructions too close to the top of
+ // a new function.
+ p = pc;
+ gins(ANOP, N, N);
+ }
f = dotlist[0].field;
//JMP mainĀ·*Sub_test2(SB)