// 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