aboutsummaryrefslogtreecommitdiff
path: root/src/pkg/runtime/amd64
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2010-04-09 13:30:11 -0700
committerIan Lance Taylor <iant@golang.org>2010-04-09 13:30:11 -0700
commit2d0ff3f1a638b1a90bc89619f23dd932ce5dd2b1 (patch)
tree49636e7dfe80e5d2edd9e3e75493c724fb90c5e0 /src/pkg/runtime/amd64
parentbc2d977d677c433910ea705508acd7ed644ddee8 (diff)
downloadgo-2d0ff3f1a638b1a90bc89619f23dd932ce5dd2b1.tar.xz
Support cgo export on amd64.
R=rsc CC=golang-dev https://golang.org/cl/857045
Diffstat (limited to 'src/pkg/runtime/amd64')
-rw-r--r--src/pkg/runtime/amd64/asm.s48
1 files changed, 42 insertions, 6 deletions
diff --git a/src/pkg/runtime/amd64/asm.s b/src/pkg/runtime/amd64/asm.s
index 8fbc9802c2..627af66320 100644
--- a/src/pkg/runtime/amd64/asm.s
+++ b/src/pkg/runtime/amd64/asm.s
@@ -276,14 +276,13 @@ TEXT jmpdefer(SB), 7, $0
// Save g and m across the call,
// since the foreign code might reuse them.
TEXT runcgo(SB),7,$32
- // Save old registers.
- MOVQ fn+0(FP),AX
- MOVQ arg+8(FP),DI // DI = first argument in AMD64 ABI
+ MOVQ fn+0(FP), R12
+ MOVQ arg+8(FP), R13
MOVQ SP, CX
// Figure out if we need to switch to m->g0 stack.
- MOVQ m_g0(m), R8
- CMPQ R8, g
+ MOVQ m_g0(m), SI
+ CMPQ SI, g
JEQ 2(PC)
MOVQ (m_sched+gobuf_sp)(m), SP
@@ -293,7 +292,17 @@ TEXT runcgo(SB),7,$32
MOVQ g, 24(SP) // save old g, m, SP
MOVQ m, 16(SP)
MOVQ CX, 8(SP)
- CALL AX
+
+ // Save g and m values for a potential callback. The callback
+ // will start running with on the g0 stack and as such should
+ // have g set to m->g0.
+ MOVQ m, DI // DI = first argument in AMD64 ABI
+ // SI, second argument, set above
+ MOVQ libcgo_set_scheduler(SB), BX
+ CALL BX
+
+ MOVQ R13, DI // DI = first argument in AMD64 ABI
+ CALL R12
// Restore registers, stack pointer.
MOVQ 16(SP), m
@@ -301,6 +310,32 @@ TEXT runcgo(SB),7,$32
MOVQ 8(SP), SP
RET
+// runcgocallback(G *g1, void* sp, void (*fn)(void))
+// Switch to g1 and sp, call fn, switch back. fn's arguments are on
+// the new stack.
+TEXT runcgocallback(SB),7,$48
+ MOVQ g1+0(FP), DX
+ MOVQ sp+8(FP), AX
+ MOVQ fp+16(FP), BX
+
+ MOVQ DX, g
+
+ // We are running on m's scheduler stack. Save current SP
+ // into m->sched.sp so that a recursive call to runcgo doesn't
+ // clobber our stack, and also so that we can restore
+ // the SP when the call finishes. Reusing m->sched.sp
+ // for this purpose depends on the fact that there is only
+ // one possible gosave of m->sched.
+ MOVQ SP, (m_sched+gobuf_sp)(m)
+
+ // Set new SP, call fn
+ MOVQ AX, SP
+ CALL BX
+
+ // Restore old SP, return
+ MOVQ (m_sched+gobuf_sp)(m), SP
+ RET
+
// check that SP is in range [g->stackbase, g->stackguard)
TEXT stackcheck(SB), 7, $0
CMPQ g_stackbase(g), SP
@@ -337,3 +372,4 @@ TEXT getcallersp(SB),7,$0
MOVQ sp+0(FP), AX
RET
+GLOBL libcgo_set_scheduler(SB), $8