aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/sys_aix_ppc64.s
diff options
context:
space:
mode:
Diffstat (limited to 'src/runtime/sys_aix_ppc64.s')
-rw-r--r--src/runtime/sys_aix_ppc64.s201
1 files changed, 201 insertions, 0 deletions
diff --git a/src/runtime/sys_aix_ppc64.s b/src/runtime/sys_aix_ppc64.s
new file mode 100644
index 0000000000..38e60f99eb
--- /dev/null
+++ b/src/runtime/sys_aix_ppc64.s
@@ -0,0 +1,201 @@
+// Copyright 2018 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.
+
+// +build aix
+// +build ppc64 ppc64le
+
+//
+// System calls and other sys.stuff for ppc64, Aix
+//
+
+#include "go_asm.h"
+#include "go_tls.h"
+#include "textflag.h"
+#include "asm_ppc64x.h"
+
+// This function calls a C function with the function descriptor in R12
+TEXT runtime·callCfunction(SB), NOSPLIT|NOFRAME,$0
+ MOVD 0(R12), R12
+ MOVD R2, 40(R1)
+ MOVD 0(R12), R0
+ MOVD 8(R12), R2
+ MOVD R0, CTR
+ BR (CTR)
+
+
+// asmsyscall6 calls a library function with a function descriptor
+// stored in libcall_fn and store the results in libcall struture
+// Up to 6 arguments can be passed to this C function
+// Called by runtime.asmcgocall
+// It reserves a stack of 288 bytes for the C function.
+// NOT USING GO CALLING CONVENTION
+TEXT runtime·asmsyscall6(SB),NOSPLIT,$256
+ MOVD R3, 48(R1) // Save libcall for later
+ MOVD libcall_fn(R3), R12
+ MOVD libcall_args(R3), R9
+ MOVD 0(R9), R3
+ MOVD 8(R9), R4
+ MOVD 16(R9), R5
+ MOVD 24(R9), R6
+ MOVD 32(R9), R7
+ MOVD 40(R9), R8
+ BL runtime·callCfunction(SB)
+
+ // Restore R0 and TOC
+ XOR R0, R0
+ MOVD 40(R1), R2
+
+ // Store result in libcall
+ MOVD 48(R1), R5
+ MOVD R3, (libcall_r1)(R5)
+ MOVD $-1, R6
+ CMP R6, R3
+ BNE skiperrno
+
+ // Save errno in libcall
+ BL runtime·load_g(SB)
+ MOVD g_m(g), R4
+ MOVD (m_mOS + mOS_perrno)(R4), R9
+ MOVW 0(R9), R9
+ MOVD R9, (libcall_err)(R5)
+ RET
+skiperrno:
+ // Reset errno if no error has been returned
+ MOVD R0, (libcall_err)(R5)
+ RET
+
+
+TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
+ MOVW sig+8(FP), R3
+ MOVD info+16(FP), R4
+ MOVD ctx+24(FP), R5
+ MOVD fn+0(FP), R12
+ MOVD R12, CTR
+ BL (CTR)
+ RET
+
+
+// runtime.sigtramp is a function descriptor to the real sigtramp.
+DATA runtime·sigtramp+0(SB)/8, $runtime·_sigtramp(SB)
+DATA runtime·sigtramp+8(SB)/8, $TOC(SB)
+DATA runtime·sigtramp+16(SB)/8, $0
+GLOBL runtime·sigtramp(SB), NOPTR, $24
+
+// This funcion must not have any frame as we want to control how
+// every registers are used.
+TEXT runtime·_sigtramp(SB),NOSPLIT|NOFRAME,$0
+ MOVD LR, R0
+ MOVD R0, 16(R1)
+ // initialize essential registers (just in case)
+ BL runtime·reginit(SB)
+
+ // Note that we are executing on altsigstack here, so we have
+ // more stack available than NOSPLIT would have us believe.
+ // To defeat the linker, we make our own stack frame with
+ // more space.
+ SUB $128+FIXED_FRAME, R1
+
+ // Save registers
+ MOVD R31, 56(R1)
+ MOVD g, 64(R1)
+ MOVD R29, 72(R1)
+
+ BL runtime·load_g(SB)
+
+ // Save m->libcall. We need to do this because we
+ // might get interrupted by a signal in runtime·asmcgocall.
+
+ // save m->libcall
+ MOVD g_m(g), R6
+ MOVD (m_libcall+libcall_fn)(R6), R7
+ MOVD R7, 80(R1)
+ MOVD (m_libcall+libcall_args)(R6), R7
+ MOVD R7, 88(R1)
+ MOVD (m_libcall+libcall_n)(R6), R7
+ MOVD R7, 96(R1)
+ MOVD (m_libcall+libcall_r1)(R6), R7
+ MOVD R7, 104(R1)
+ MOVD (m_libcall+libcall_r2)(R6), R7
+ MOVD R7, 112(R1)
+
+ // save errno, it might be EINTR; stuff we do here might reset it.
+ MOVD (m_mOS+mOS_perrno)(R6), R8
+ MOVD 0(R8), R8
+ MOVD R8, 120(R1)
+
+ MOVW R3, FIXED_FRAME+0(R1)
+ MOVD R4, FIXED_FRAME+8(R1)
+ MOVD R5, FIXED_FRAME+16(R1)
+ MOVD $runtime·sigtrampgo(SB), R12
+ MOVD R12, CTR
+ BL (CTR)
+
+ MOVD g_m(g), R6
+ // restore libcall
+ MOVD 80(R1), R7
+ MOVD R7, (m_libcall+libcall_fn)(R6)
+ MOVD 88(R1), R7
+ MOVD R7, (m_libcall+libcall_args)(R6)
+ MOVD 96(R1), R7
+ MOVD R7, (m_libcall+libcall_n)(R6)
+ MOVD 104(R1), R7
+ MOVD R7, (m_libcall+libcall_r1)(R6)
+ MOVD 112(R1), R7
+ MOVD R7, (m_libcall+libcall_r2)(R6)
+
+ // restore errno
+ MOVD (m_mOS+mOS_perrno)(R6), R7
+ MOVD 120(R1), R8
+ MOVD R8, 0(R7)
+
+ // restore registers
+ MOVD 56(R1),R31
+ MOVD 64(R1),g
+ MOVD 72(R1),R29
+
+ // Don't use RET because we need to restore R31 !
+ ADD $128+FIXED_FRAME, R1
+ MOVD 16(R1), R0
+ MOVD R0, LR
+ BR (LR)
+
+// runtime.tstart is a function descriptor to the real tstart.
+DATA runtime·tstart+0(SB)/8, $runtime·_tstart(SB)
+DATA runtime·tstart+8(SB)/8, $TOC(SB)
+DATA runtime·tstart+16(SB)/8, $0
+GLOBL runtime·tstart(SB), NOPTR, $24
+
+TEXT runtime·_tstart(SB),NOSPLIT,$0
+ XOR R0, R0 // reset R0
+
+ // set g
+ MOVD m_g0(R3), g
+ BL runtime·save_g(SB)
+ MOVD R3, g_m(g)
+
+ // Layout new m scheduler stack on os stack.
+ MOVD R1, R3
+ MOVD R3, (g_stack+stack_hi)(g)
+ SUB $(const_threadStackSize), R3 // stack size
+ MOVD R3, (g_stack+stack_lo)(g)
+ ADD $const__StackGuard, R3
+ MOVD R3, g_stackguard0(g)
+ MOVD R3, g_stackguard1(g)
+
+ BL runtime·mstart(SB)
+
+ MOVD R0, R3
+ RET
+
+// Runs on OS stack, called from runtime·osyield.
+TEXT runtime·osyield1(SB),NOSPLIT,$0
+ MOVD $libc_sched_yield(SB), R12
+ MOVD 0(R12), R12
+ MOVD R2, 40(R1)
+ MOVD 0(R12), R0
+ MOVD 8(R12), R2
+ MOVD R0, CTR
+ BL (CTR)
+ MOVD 40(R1), R2
+ RET