mirror of https://go.googlesource.com/go
319 lines
7.4 KiB
ArmAsm
319 lines
7.4 KiB
ArmAsm
// 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.
|
|
|
|
//
|
|
// 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 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 structure
|
|
// 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. It must
|
|
// follow AIX convention, thus the first local variable must
|
|
// be stored at the offset 112, after the linker area (48 bytes)
|
|
// and the argument area (64).
|
|
// The AIX convention is described here:
|
|
// https://www.ibm.com/docs/en/aix/7.2?topic=overview-runtime-process-stack
|
|
// NOT USING GO CALLING CONVENTION
|
|
// runtime.asmsyscall6 is a function descriptor to the real asmsyscall6.
|
|
DATA runtime·asmsyscall6+0(SB)/8, $asmsyscall6<>(SB)
|
|
DATA runtime·asmsyscall6+8(SB)/8, $TOC(SB)
|
|
DATA runtime·asmsyscall6+16(SB)/8, $0
|
|
GLOBL runtime·asmsyscall6(SB), NOPTR, $24
|
|
|
|
TEXT asmsyscall6<>(SB),NOSPLIT,$256
|
|
// Save libcall for later
|
|
MOVD R3, 112(R1)
|
|
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 callCfunction<>(SB)
|
|
|
|
// Restore R0 and TOC
|
|
XOR R0, R0
|
|
MOVD 40(R1), R2
|
|
|
|
// Store result in libcall
|
|
MOVD 112(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
|
|
// fn is a function descriptor
|
|
// R2 must be saved on restore
|
|
MOVD 0(R12), R0
|
|
MOVD R2, 40(R1)
|
|
MOVD 8(R12), R2
|
|
MOVD R0, CTR
|
|
BL (CTR)
|
|
MOVD 40(R1), R2
|
|
BL runtime·reginit(SB)
|
|
RET
|
|
|
|
|
|
// runtime.sigtramp is a function descriptor to the real sigtramp.
|
|
DATA runtime·sigtramp+0(SB)/8, $sigtramp<>(SB)
|
|
DATA runtime·sigtramp+8(SB)/8, $TOC(SB)
|
|
DATA runtime·sigtramp+16(SB)/8, $0
|
|
GLOBL runtime·sigtramp(SB), NOPTR, $24
|
|
|
|
// This function must not have any frame as we want to control how
|
|
// every registers are used.
|
|
// TODO(aix): Implement SetCgoTraceback handler.
|
|
TEXT sigtramp<>(SB),NOSPLIT|NOFRAME|TOPFRAME,$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 $144+FIXED_FRAME, R1
|
|
|
|
// Save registers
|
|
MOVD R31, 56(R1)
|
|
MOVD g, 64(R1)
|
|
MOVD R29, 72(R1)
|
|
MOVD R14, 80(R1)
|
|
MOVD R15, 88(R1)
|
|
|
|
BL runtime·load_g(SB)
|
|
|
|
CMP $0, g
|
|
BEQ sigtramp // g == nil
|
|
MOVD g_m(g), R6
|
|
CMP $0, R6
|
|
BEQ sigtramp // g.m == nil
|
|
|
|
// Save m->libcall. We need to do this because we
|
|
// might get interrupted by a signal in runtime·asmcgocall.
|
|
MOVD (m_libcall+libcall_fn)(R6), R7
|
|
MOVD R7, 96(R1)
|
|
MOVD (m_libcall+libcall_args)(R6), R7
|
|
MOVD R7, 104(R1)
|
|
MOVD (m_libcall+libcall_n)(R6), R7
|
|
MOVD R7, 112(R1)
|
|
MOVD (m_libcall+libcall_r1)(R6), R7
|
|
MOVD R7, 120(R1)
|
|
MOVD (m_libcall+libcall_r2)(R6), R7
|
|
MOVD R7, 128(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, 136(R1)
|
|
|
|
sigtramp:
|
|
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)
|
|
|
|
CMP $0, g
|
|
BEQ exit // g == nil
|
|
MOVD g_m(g), R6
|
|
CMP $0, R6
|
|
BEQ exit // g.m == nil
|
|
|
|
// restore libcall
|
|
MOVD 96(R1), R7
|
|
MOVD R7, (m_libcall+libcall_fn)(R6)
|
|
MOVD 104(R1), R7
|
|
MOVD R7, (m_libcall+libcall_args)(R6)
|
|
MOVD 112(R1), R7
|
|
MOVD R7, (m_libcall+libcall_n)(R6)
|
|
MOVD 120(R1), R7
|
|
MOVD R7, (m_libcall+libcall_r1)(R6)
|
|
MOVD 128(R1), R7
|
|
MOVD R7, (m_libcall+libcall_r2)(R6)
|
|
|
|
// restore errno
|
|
MOVD (m_mOS+mOS_perrno)(R6), R7
|
|
MOVD 136(R1), R8
|
|
MOVD R8, 0(R7)
|
|
|
|
exit:
|
|
// restore registers
|
|
MOVD 56(R1),R31
|
|
MOVD 64(R1),g
|
|
MOVD 72(R1),R29
|
|
MOVD 80(R1), R14
|
|
MOVD 88(R1), R15
|
|
|
|
// Don't use RET because we need to restore R31 !
|
|
ADD $144+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, $tstart<>(SB)
|
|
DATA runtime·tstart+8(SB)/8, $TOC(SB)
|
|
DATA runtime·tstart+16(SB)/8, $0
|
|
GLOBL runtime·tstart(SB), NOPTR, $24
|
|
|
|
TEXT 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
|
|
|
|
|
|
#define CSYSCALL() \
|
|
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 \
|
|
BL runtime·reginit(SB)
|
|
|
|
|
|
// Runs on OS stack, called from runtime·osyield.
|
|
TEXT runtime·osyield1(SB),NOSPLIT,$0
|
|
MOVD $libc_sched_yield(SB), R12
|
|
CSYSCALL()
|
|
RET
|
|
|
|
|
|
// Runs on OS stack, called from runtime·sigprocmask.
|
|
TEXT runtime·sigprocmask1(SB),NOSPLIT,$0-24
|
|
MOVD how+0(FP), R3
|
|
MOVD new+8(FP), R4
|
|
MOVD old+16(FP), R5
|
|
MOVD $libpthread_sigthreadmask(SB), R12
|
|
CSYSCALL()
|
|
RET
|
|
|
|
// Runs on OS stack, called from runtime·usleep.
|
|
TEXT runtime·usleep1(SB),NOSPLIT,$0-4
|
|
MOVW us+0(FP), R3
|
|
MOVD $libc_usleep(SB), R12
|
|
CSYSCALL()
|
|
RET
|
|
|
|
// Runs on OS stack, called from runtime·exit.
|
|
TEXT runtime·exit1(SB),NOSPLIT,$0-4
|
|
MOVW code+0(FP), R3
|
|
MOVD $libc_exit(SB), R12
|
|
CSYSCALL()
|
|
RET
|
|
|
|
// Runs on OS stack, called from runtime·write1.
|
|
TEXT runtime·write2(SB),NOSPLIT,$0-28
|
|
MOVD fd+0(FP), R3
|
|
MOVD p+8(FP), R4
|
|
MOVW n+16(FP), R5
|
|
MOVD $libc_write(SB), R12
|
|
CSYSCALL()
|
|
MOVW R3, ret+24(FP)
|
|
RET
|
|
|
|
// Runs on OS stack, called from runtime·pthread_attr_init.
|
|
TEXT runtime·pthread_attr_init1(SB),NOSPLIT,$0-12
|
|
MOVD attr+0(FP), R3
|
|
MOVD $libpthread_attr_init(SB), R12
|
|
CSYSCALL()
|
|
MOVW R3, ret+8(FP)
|
|
RET
|
|
|
|
// Runs on OS stack, called from runtime·pthread_attr_setstacksize.
|
|
TEXT runtime·pthread_attr_setstacksize1(SB),NOSPLIT,$0-20
|
|
MOVD attr+0(FP), R3
|
|
MOVD size+8(FP), R4
|
|
MOVD $libpthread_attr_setstacksize(SB), R12
|
|
CSYSCALL()
|
|
MOVW R3, ret+16(FP)
|
|
RET
|
|
|
|
// Runs on OS stack, called from runtime·pthread_setdetachstate.
|
|
TEXT runtime·pthread_attr_setdetachstate1(SB),NOSPLIT,$0-20
|
|
MOVD attr+0(FP), R3
|
|
MOVW state+8(FP), R4
|
|
MOVD $libpthread_attr_setdetachstate(SB), R12
|
|
CSYSCALL()
|
|
MOVW R3, ret+16(FP)
|
|
RET
|
|
|
|
// Runs on OS stack, called from runtime·pthread_create.
|
|
TEXT runtime·pthread_create1(SB),NOSPLIT,$0-36
|
|
MOVD tid+0(FP), R3
|
|
MOVD attr+8(FP), R4
|
|
MOVD fn+16(FP), R5
|
|
MOVD arg+24(FP), R6
|
|
MOVD $libpthread_create(SB), R12
|
|
CSYSCALL()
|
|
MOVW R3, ret+32(FP)
|
|
RET
|
|
|
|
// Runs on OS stack, called from runtime·sigaction.
|
|
TEXT runtime·sigaction1(SB),NOSPLIT,$0-24
|
|
MOVD sig+0(FP), R3
|
|
MOVD new+8(FP), R4
|
|
MOVD old+16(FP), R5
|
|
MOVD $libc_sigaction(SB), R12
|
|
CSYSCALL()
|
|
RET
|