cmd/6g, cmd/8g: switch to DX for indirect call block
runtime: add context argument to gogocall
Too many other things use AX, and at least one
(stack zeroing) cannot be moved onto a different
register. Use the less special DX instead.
Preparation for step 2 of http://golang.org/s/go11func.
Nothing interesting here, just split out so that we can
see it's correct before moving on.
R=ken2
CC=golang-dev
https://golang.org/cl/7395050
diff --git a/src/cmd/6g/ggen.c b/src/cmd/6g/ggen.c
index c9a60c2..2f93acd 100644
--- a/src/cmd/6g/ggen.c
+++ b/src/cmd/6g/ggen.c
@@ -77,7 +77,7 @@
gins(AUNDEF, N, N);
break;
}
- nodreg(®, types[tptr], D_AX);
+ nodreg(®, types[tptr], D_DX);
nodreg(&r1, types[tptr], D_BX);
gmove(f, ®);
reg.op = OINDREG;
diff --git a/src/cmd/8g/ggen.c b/src/cmd/8g/ggen.c
index 1738c88..b0a1624 100644
--- a/src/cmd/8g/ggen.c
+++ b/src/cmd/8g/ggen.c
@@ -120,7 +120,7 @@
gins(AUNDEF, N, N);
break;
}
- nodreg(®, types[tptr], D_AX);
+ nodreg(®, types[tptr], D_DX);
nodreg(&r1, types[tptr], D_BX);
gmove(f, ®);
reg.op = OINDREG;
diff --git a/src/cmd/8l/pass.c b/src/cmd/8l/pass.c
index 03292a5..14dd3e0 100644
--- a/src/cmd/8l/pass.c
+++ b/src/cmd/8l/pass.c
@@ -539,9 +539,9 @@
q = p;
}
- p = appendp(p); // save frame size in DX
+ p = appendp(p); // save frame size in DI
p->as = AMOVL;
- p->to.type = D_DX;
+ p->to.type = D_DI;
p->from.type = D_CONST;
// If we ask for more stack, we'll get a minimum of StackMin bytes.
diff --git a/src/pkg/runtime/asm_386.s b/src/pkg/runtime/asm_386.s
index 4d8cb1a..1e47274 100644
--- a/src/pkg/runtime/asm_386.s
+++ b/src/pkg/runtime/asm_386.s
@@ -134,16 +134,17 @@
MOVL gobuf_pc(BX), BX
JMP BX
-// void gogocall(Gobuf*, void (*fn)(void))
+// void gogocall(Gobuf*, void (*fn)(void), uintptr r0)
// restore state from Gobuf but then call fn.
// (call fn, returning to state in Gobuf)
TEXT runtime·gogocall(SB), 7, $0
+ MOVL 12(SP), DX // context
MOVL 8(SP), AX // fn
MOVL 4(SP), BX // gobuf
- MOVL gobuf_g(BX), DX
+ MOVL gobuf_g(BX), DI
get_tls(CX)
- MOVL DX, g(CX)
- MOVL 0(DX), CX // make sure g != nil
+ MOVL DI, g(CX)
+ MOVL 0(DI), CX // make sure g != nil
MOVL gobuf_sp(BX), SP // restore SP
MOVL gobuf_pc(BX), BX
PUSHL BX
@@ -154,16 +155,16 @@
// restore state from Gobuf but then call fn.
// (call fn, returning to state in Gobuf)
TEXT runtime·gogocallfn(SB), 7, $0
- MOVL 8(SP), AX // fn
+ MOVL 8(SP), DX // fn
MOVL 4(SP), BX // gobuf
- MOVL gobuf_g(BX), DX
+ MOVL gobuf_g(BX), DI
get_tls(CX)
- MOVL DX, g(CX)
- MOVL 0(DX), CX // make sure g != nil
+ MOVL DI, g(CX)
+ MOVL 0(DI), CX // make sure g != nil
MOVL gobuf_sp(BX), SP // restore SP
MOVL gobuf_pc(BX), BX
PUSHL BX
- MOVL 0(AX), BX
+ MOVL 0(DX), BX
JMP BX
POPL BX // not reached
@@ -209,11 +210,13 @@
CMPL g(CX), SI
JNE 2(PC)
INT $3
+
+ MOVL DX, m_cret(BX)
- // frame size in DX
+ // frame size in DI
// arg size in AX
// Save in m.
- MOVL DX, m_moreframesize(BX)
+ MOVL DI, m_moreframesize(BX)
MOVL AX, m_moreargsize(BX)
// Called from f.
@@ -441,11 +444,11 @@
// 2. sub 5 bytes from the callers return
// 3. jmp to the argument
TEXT runtime·jmpdefer(SB), 7, $0
- MOVL 4(SP), AX // fn
+ MOVL 4(SP), DX // fn
MOVL 8(SP), BX // caller sp
LEAL -4(BX), SP // caller sp after CALL
SUBL $5, (SP) // return to CALL again
- MOVL 0(AX), BX
+ MOVL 0(DX), BX
JMP BX // but first run the deferred function
// Dummy function to use in saved gobuf.PC,
diff --git a/src/pkg/runtime/asm_amd64.s b/src/pkg/runtime/asm_amd64.s
index ea944e1..ae84707 100644
--- a/src/pkg/runtime/asm_amd64.s
+++ b/src/pkg/runtime/asm_amd64.s
@@ -121,16 +121,17 @@
MOVQ gobuf_pc(BX), BX
JMP BX
-// void gogocall(Gobuf*, void (*fn)(void))
+// void gogocall(Gobuf*, void (*fn)(void), uintptr r0)
// restore state from Gobuf but then call fn.
// (call fn, returning to state in Gobuf)
TEXT runtime·gogocall(SB), 7, $0
+ MOVQ 24(SP), DX // context
MOVQ 16(SP), AX // fn
MOVQ 8(SP), BX // gobuf
- MOVQ gobuf_g(BX), DX
+ MOVQ gobuf_g(BX), DI
get_tls(CX)
- MOVQ DX, g(CX)
- MOVQ 0(DX), CX // make sure g != nil
+ MOVQ DI, g(CX)
+ MOVQ 0(DI), CX // make sure g != nil
MOVQ gobuf_sp(BX), SP // restore SP
MOVQ gobuf_pc(BX), BX
PUSHQ BX
@@ -141,16 +142,16 @@
// restore state from Gobuf but then call fn.
// (call fn, returning to state in Gobuf)
TEXT runtime·gogocallfn(SB), 7, $0
- MOVQ 16(SP), AX // fn
+ MOVQ 16(SP), DX // fn
MOVQ 8(SP), BX // gobuf
- MOVQ gobuf_g(BX), DX
+ MOVQ gobuf_g(BX), AX
get_tls(CX)
- MOVQ DX, g(CX)
- MOVQ 0(DX), CX // make sure g != nil
+ MOVQ AX, g(CX)
+ MOVQ 0(AX), CX // make sure g != nil
MOVQ gobuf_sp(BX), SP // restore SP
MOVQ gobuf_pc(BX), BX
PUSHQ BX
- MOVQ 0(AX), BX
+ MOVQ 0(DX), BX
JMP BX
POPQ BX // not reached
@@ -195,6 +196,8 @@
CMPQ g(CX), SI
JNE 2(PC)
INT $3
+
+ MOVQ DX, m_cret(BX)
// Called from f.
// Set m->morebuf to f's caller.
@@ -471,11 +474,11 @@
// 2. sub 5 bytes from the callers return
// 3. jmp to the argument
TEXT runtime·jmpdefer(SB), 7, $0
- MOVQ 8(SP), AX // fn
+ MOVQ 8(SP), DX // fn
MOVQ 16(SP), BX // caller sp
LEAQ -8(BX), SP // caller sp after CALL
SUBQ $5, (SP) // return to CALL again
- MOVQ 0(AX), BX
+ MOVQ 0(DX), BX
JMP BX // but first run the deferred function
// Dummy function to use in saved gobuf.PC,
diff --git a/src/pkg/runtime/asm_arm.s b/src/pkg/runtime/asm_arm.s
index 0f6026c..dc2438c 100644
--- a/src/pkg/runtime/asm_arm.s
+++ b/src/pkg/runtime/asm_arm.s
@@ -112,19 +112,19 @@
MOVW gobuf_sp(R1), SP // restore SP
MOVW gobuf_pc(R1), PC
-// void gogocall(Gobuf*, void (*fn)(void))
+// void gogocall(Gobuf*, void (*fn)(void), uintptr r0)
// restore state from Gobuf but then call fn.
// (call fn, returning to state in Gobuf)
// using frame size $-4 means do not save LR on stack.
TEXT runtime·gogocall(SB), 7, $-4
MOVW 0(FP), R3 // gobuf
MOVW 4(FP), R1 // fn
- MOVW 8(FP), R2 // fp offset
MOVW gobuf_g(R3), g
MOVW 0(g), R0 // make sure g != nil
MOVW cgo_save_gm(SB), R0
CMP $0, R0 // if in Cgo, we have to save g and m
BL.NE (R0) // this call will clobber R0
+ MOVW 8(FP), R0 // context
MOVW gobuf_sp(R3), SP // restore SP
MOVW gobuf_pc(R3), LR
MOVW R1, PC
@@ -136,7 +136,6 @@
TEXT runtime·gogocallfn(SB), 7, $-4
MOVW 0(FP), R3 // gobuf
MOVW 4(FP), R1 // fn
- MOVW 8(FP), R2 // fp offset
MOVW gobuf_g(R3), g
MOVW 0(g), R0 // make sure g != nil
MOVW cgo_save_gm(SB), R0
@@ -189,6 +188,7 @@
BL.EQ runtime·abort(SB)
// Save in m.
+ MOVW R0, m_cret(m) // function context
MOVW R1, m_moreframesize(m)
MOVW R2, m_moreargsize(m)
diff --git a/src/pkg/runtime/runtime.h b/src/pkg/runtime/runtime.h
index e98f13b..2459199 100644
--- a/src/pkg/runtime/runtime.h
+++ b/src/pkg/runtime/runtime.h
@@ -615,7 +615,7 @@
#define FLUSH(x) USED(x)
void runtime·gogo(Gobuf*, uintptr);
-void runtime·gogocall(Gobuf*, void(*)(void));
+void runtime·gogocall(Gobuf*, void(*)(void), uintptr);
void runtime·gogocallfn(Gobuf*, FuncVal*);
void runtime·gosave(Gobuf*);
void runtime·lessstack(void);
diff --git a/src/pkg/runtime/stack.c b/src/pkg/runtime/stack.c
index d1d5c8f..d5cc3a7 100644
--- a/src/pkg/runtime/stack.c
+++ b/src/pkg/runtime/stack.c
@@ -276,7 +276,7 @@
if(reflectcall)
runtime·gogocallfn(&label, (FuncVal*)m->morepc);
else
- runtime·gogocall(&label, m->morepc);
+ runtime·gogocall(&label, m->morepc, m->cret);
*(int32*)345 = 123; // never return
}