aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/asm_ppc64x.s
diff options
context:
space:
mode:
authorClément Chigot <clement.chigot@atos.net>2018-10-01 09:50:36 +0200
committerIan Lance Taylor <iant@golang.org>2018-10-19 14:11:52 +0000
commitff99a61e5e892dedb88f9f80bce9cc102d2f50b2 (patch)
treea9ac4fde6eff29e0cc91de0a6c2494f93072618e /src/runtime/asm_ppc64x.s
parent38df4c177b06441b40ac707f1eede49488da2396 (diff)
downloadgo-ff99a61e5e892dedb88f9f80bce9cc102d2f50b2.tar.gz
go-ff99a61e5e892dedb88f9f80bce9cc102d2f50b2.zip
runtime: port assembly files for aix/ppc64
This commit adds the change on asm_ppc64.s and tls_ppc64.s files for AIX operating system. R2 does not need to be set for aix/ppc64 since it should remain valid througout Go execution, except after a call to a C function. Moreover, g must always be saved on the tls as syscalls are made with C functions. Some modifications on asm_ppc64.s are due to AIX stack layout. It also removes a useless part in asmcgocall which was done twice. Change-Id: Ie037ab73da00562bb978f2d0f17fcdabd4a40aa2 Reviewed-on: https://go-review.googlesource.com/c/138735 Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Carlos Eduardo Seo <cseo@linux.vnet.ibm.com> Reviewed-by: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/runtime/asm_ppc64x.s')
-rw-r--r--src/runtime/asm_ppc64x.s52
1 files changed, 45 insertions, 7 deletions
diff --git a/src/runtime/asm_ppc64x.s b/src/runtime/asm_ppc64x.s
index b180cb06ab..e77c717935 100644
--- a/src/runtime/asm_ppc64x.s
+++ b/src/runtime/asm_ppc64x.s
@@ -140,7 +140,9 @@ TEXT runtime·gogo(SB), NOSPLIT, $16-8
MOVD 0(g), R4
MOVD gobuf_sp(R5), R1
MOVD gobuf_lr(R5), R31
+#ifndef GOOS_aix
MOVD 24(R1), R2 // restore R2
+#endif
MOVD R31, LR
MOVD gobuf_ret(R5), R3
MOVD gobuf_ctxt(R5), R11
@@ -257,7 +259,9 @@ switch:
MOVD g_m(g), R3
MOVD m_curg(R3), g
MOVD (g_sched+gobuf_sp)(g), R3
+#ifndef GOOS_aix
MOVD 24(R3), R2
+#endif
// switch back to g
MOVD g_m(g), R3
MOVD m_curg(R3), g
@@ -274,7 +278,9 @@ noswitch:
MOVD 0(R11), R12 // code pointer
MOVD R12, CTR
BL (CTR)
+#ifndef GOOS_aix
MOVD 24(R1), R2
+#endif
RET
/*
@@ -422,11 +428,20 @@ tail: \
callfn: \
/* call function */ \
MOVD f+8(FP), R11; \
+#ifdef GOOS_aix \
+ /* AIX won't trigger a SIGSEGV if R11 = nil */ \
+ /* So it manually triggers it */ \
+ CMP R0, R11 \
+ BNE 2(PC) \
+ MOVD R0, 0(R0) \
+#endif \
MOVD (R11), R12; \
MOVD R12, CTR; \
PCDATA $PCDATA_StackMapIndex, $0; \
BL (CTR); \
+#ifndef GOOS_aix \
MOVD 24(R1), R2; \
+#endif \
/* copy return values back */ \
MOVD argtype+0(FP), R7; \
MOVD arg+16(FP), R3; \
@@ -504,12 +519,22 @@ again:
// the BL deferreturn and jmpdefer rewinds to that.
TEXT runtime·jmpdefer(SB), NOSPLIT|NOFRAME, $0-16
MOVD 0(R1), R31
+#ifdef GOOS_aix
+ MOVD 16(R31), R31 // caller LR is on the previous stack frame on AIX
+#endif
SUB $8, R31
MOVD R31, LR
MOVD fv+0(FP), R11
MOVD argp+8(FP), R1
SUB $FIXED_FRAME, R1
+#ifdef GOOS_aix
+ // AIX won't trigger a SIGSEGV if R11 = nil
+ // So it manually triggers it
+ CMP R0, R11
+ BNE 2(PC)
+ MOVD R0, 0(R0)
+#endif
MOVD 0(R11), R12
MOVD R12, CTR
BR (CTR)
@@ -542,8 +567,13 @@ TEXT ·asmcgocall(SB),NOSPLIT,$0-20
// Figure out if we need to switch to m->g0 stack.
// We get called to create new OS threads too, and those
// come in on the m->g0 stack already.
- MOVD g_m(g), R6
- MOVD m_g0(R6), R6
+ // Moreover, if it's called inside the signal handler, it must not switch
+ // to g0 as it can be in use by another syscall.
+ MOVD g_m(g), R8
+ MOVD m_gsignal(R8), R6
+ CMP R6, g
+ BEQ g0
+ MOVD m_g0(R8), R6
CMP R6, g
BEQ g0
BL gosave<>(SB)
@@ -555,13 +585,22 @@ TEXT ·asmcgocall(SB),NOSPLIT,$0-20
g0:
// Save room for two of our pointers, plus 32 bytes of callee
// save area that lives on the caller stack.
+#ifdef GOOS_aix
+ // Create a fake LR to improve backtrace.
+ MOVD $runtime·asmcgocall(SB), R6
+ MOVD R6, 16(R1)
+#endif
SUB $48, R1
RLDCR $0, R1, $~15, R1 // 16-byte alignment for gcc ABI
MOVD R5, 40(R1) // save old g on stack
MOVD (g_stack+stack_hi)(R5), R5
SUB R7, R5
MOVD R5, 32(R1) // save depth in old g stack (can't just save SP, as stack might be copied during a callback)
+#ifdef GOOS_aix
+ MOVD R7, 0(R1) // Save frame pointer to allow manual backtrace with gdb
+#else
MOVD R0, 0(R1) // clear back chain pointer (TODO can we give it real back trace information?)
+#endif
// This is a "global call", so put the global entry point in r12
MOVD R3, R12
MOVD R12, CTR
@@ -574,15 +613,14 @@ g0:
// Restore g, stack pointer, toc pointer.
// R3 is errno, so don't touch it
MOVD 40(R1), g
- MOVD (g_stack+stack_hi)(g), R5
- MOVD 32(R1), R6
- SUB R6, R5
- MOVD 24(R5), R2
- BL runtime·save_g(SB)
MOVD (g_stack+stack_hi)(g), R5
MOVD 32(R1), R6
SUB R6, R5
+#ifndef GOOS_aix
+ MOVD 24(R5), R2
+#endif
MOVD R5, R1
+ BL runtime·save_g(SB)
MOVW R3, ret+16(FP)
RET