mirror of
https://github.com/golang/go
synced 2024-09-30 14:18:32 -06:00
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
This commit is contained in:
parent
e508c55760
commit
5a67ea3883
@ -553,7 +553,7 @@ void
|
|||||||
genembedtramp(Type *t, Sig *b)
|
genembedtramp(Type *t, Sig *b)
|
||||||
{
|
{
|
||||||
Sym *e;
|
Sym *e;
|
||||||
int c, d, o;
|
int c, d, o, loaded;
|
||||||
Prog *p;
|
Prog *p;
|
||||||
Type *f;
|
Type *f;
|
||||||
|
|
||||||
@ -566,9 +566,6 @@ genembedtramp(Type *t, Sig *b)
|
|||||||
fatal("genembedtramp %T.%s", t, b->name);
|
fatal("genembedtramp %T.%s", t, b->name);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if(d == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// print("genembedtramp %d\n", d);
|
// print("genembedtramp %d\n", d);
|
||||||
// print(" t = %lT\n", t);
|
// print(" t = %lT\n", t);
|
||||||
// print(" name = %s\n", b->name);
|
// print(" name = %s\n", b->name);
|
||||||
@ -587,20 +584,24 @@ out:
|
|||||||
p->from.scale = 7;
|
p->from.scale = 7;
|
||||||
//print("1. %P\n", p);
|
//print("1. %P\n", p);
|
||||||
|
|
||||||
//MOVQ 8(SP), AX
|
loaded = 0;
|
||||||
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);
|
|
||||||
|
|
||||||
o = 0;
|
o = 0;
|
||||||
for(c=d-1; c>=0; c--) {
|
for(c=d-1; c>=0; c--) {
|
||||||
f = dotlist[c].field;
|
f = dotlist[c].field;
|
||||||
o += f->width;
|
o += f->width;
|
||||||
if(!isptr[f->type->etype])
|
if(!isptr[f->type->etype])
|
||||||
continue;
|
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
|
//MOVQ o(AX), AX
|
||||||
p = pc;
|
p = pc;
|
||||||
gins(AMOVQ, N, N);
|
gins(AMOVQ, N, N);
|
||||||
@ -616,17 +617,31 @@ out:
|
|||||||
gins(AADDQ, N, N);
|
gins(AADDQ, N, N);
|
||||||
p->from.type = D_CONST;
|
p->from.type = D_CONST;
|
||||||
p->from.offset = o;
|
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);
|
//print("4. %P\n", p);
|
||||||
}
|
}
|
||||||
|
|
||||||
//MOVQ AX, 8(SP)
|
//MOVQ AX, 8(SP)
|
||||||
p = pc;
|
if(loaded) {
|
||||||
gins(AMOVQ, N, N);
|
p = pc;
|
||||||
p->from.type = D_AX;
|
gins(AMOVQ, N, N);
|
||||||
p->to.type = D_INDIR+D_SP;
|
p->from.type = D_AX;
|
||||||
p->to.offset = 8;
|
p->to.type = D_INDIR+D_SP;
|
||||||
|
p->to.offset = 8;
|
||||||
//print("5. %P\n", p);
|
//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;
|
f = dotlist[0].field;
|
||||||
//JMP main·*Sub_test2(SB)
|
//JMP main·*Sub_test2(SB)
|
||||||
|
Loading…
Reference in New Issue
Block a user