summaryrefslogtreecommitdiffstats
path: root/src/runtime/cgo/gcc_s390x.S
diff options
context:
space:
mode:
Diffstat (limited to 'src/runtime/cgo/gcc_s390x.S')
-rw-r--r--src/runtime/cgo/gcc_s390x.S56
1 files changed, 56 insertions, 0 deletions
diff --git a/src/runtime/cgo/gcc_s390x.S b/src/runtime/cgo/gcc_s390x.S
new file mode 100644
index 0000000..614de4b
--- /dev/null
+++ b/src/runtime/cgo/gcc_s390x.S
@@ -0,0 +1,56 @@
+// Copyright 2016 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.
+
+/*
+ * void crosscall_s390x(void (*fn)(void), void *g)
+ *
+ * Calling into the go tool chain, where all registers are caller save.
+ * Called from standard s390x C ABI, where r6-r13, r15, and f8-f15 are
+ * callee-save, so they must be saved explicitly.
+ */
+.globl crosscall_s390x
+crosscall_s390x:
+ /* save r6-r15 in the register save area of the calling function */
+ stmg %r6, %r15, 48(%r15)
+
+ /* allocate 64 bytes of stack space to save f8-f15 */
+ lay %r15, -64(%r15)
+
+ /* save callee-saved floating point registers */
+ std %f8, 0(%r15)
+ std %f9, 8(%r15)
+ std %f10, 16(%r15)
+ std %f11, 24(%r15)
+ std %f12, 32(%r15)
+ std %f13, 40(%r15)
+ std %f14, 48(%r15)
+ std %f15, 56(%r15)
+
+ /* restore g pointer */
+ lgr %r13, %r3
+
+ /* call fn */
+ basr %r14, %r2
+
+ /* restore floating point registers */
+ ld %f8, 0(%r15)
+ ld %f9, 8(%r15)
+ ld %f10, 16(%r15)
+ ld %f11, 24(%r15)
+ ld %f12, 32(%r15)
+ ld %f13, 40(%r15)
+ ld %f14, 48(%r15)
+ ld %f15, 56(%r15)
+
+ /* de-allocate stack frame */
+ la %r15, 64(%r15)
+
+ /* restore general purpose registers */
+ lmg %r6, %r15, 48(%r15)
+
+ br %r14 /* restored by lmg */
+
+#ifdef __ELF__
+.section .note.GNU-stack,"",%progbits
+#endif