aboutsummaryrefslogtreecommitdiff
path: root/libgo/runtime/go-context.S
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/runtime/go-context.S')
-rw-r--r--libgo/runtime/go-context.S69
1 files changed, 69 insertions, 0 deletions
diff --git a/libgo/runtime/go-context.S b/libgo/runtime/go-context.S
new file mode 100644
index 0000000..0cd2242
--- /dev/null
+++ b/libgo/runtime/go-context.S
@@ -0,0 +1,69 @@
+// Copyright 2019 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.
+
+// This provides a simplified version of getcontext and
+// setcontext. They are like the corresponding functions
+// in libc, but we only save/restore the callee-save
+// registers and PC, SP. Unlike the libc functions, we
+// don't save/restore the signal masks and floating point
+// environment.
+
+#if defined(__x86_64__) && defined(__linux__) && !defined(__CET__)
+
+#define RBP_OFF (0*8)
+#define RBX_OFF (1*8)
+#define R12_OFF (2*8)
+#define R13_OFF (3*8)
+#define R14_OFF (4*8)
+#define R15_OFF (5*8)
+#define SP_OFF (6*8)
+#define PC_OFF (7*8)
+
+.globl __go_getcontext
+.text
+__go_getcontext:
+ movq %rbx, RBX_OFF(%rdi)
+ movq %rbp, RBP_OFF(%rdi)
+ movq %r12, R12_OFF(%rdi)
+ movq %r13, R13_OFF(%rdi)
+ movq %r14, R14_OFF(%rdi)
+ movq %r15, R15_OFF(%rdi)
+
+ movq (%rsp), %rax // return PC
+ movq %rax, PC_OFF(%rdi)
+ leaq 8(%rsp), %rax // the SP before pushing return PC
+ movq %rax, SP_OFF(%rdi)
+
+ ret
+
+.globl __go_setcontext
+.text
+__go_setcontext:
+ movq RBX_OFF(%rdi), %rbx
+ movq RBP_OFF(%rdi), %rbp
+ movq R12_OFF(%rdi), %r12
+ movq R13_OFF(%rdi), %r13
+ movq R14_OFF(%rdi), %r14
+ movq R15_OFF(%rdi), %r15
+ movq SP_OFF(%rdi), %rsp
+ movq PC_OFF(%rdi), %rdx
+
+ jmp *%rdx
+
+.globl __go_makecontext
+.text
+__go_makecontext:
+ addq %rcx, %rdx
+
+ // Align the SP, and push a dummy return address.
+ andq $~0xfULL, %rdx
+ subq $8, %rdx
+ movq $0, (%rdx)
+
+ movq %rdx, SP_OFF(%rdi)
+ movq %rsi, PC_OFF(%rdi)
+
+ ret
+
+#endif