diff options
author | Clément Chigot <clement.chigot@atos.net> | 2018-10-01 09:50:36 +0200 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2018-10-19 14:11:52 +0000 |
commit | ff99a61e5e892dedb88f9f80bce9cc102d2f50b2 (patch) | |
tree | a9ac4fde6eff29e0cc91de0a6c2494f93072618e /src/runtime/asm_ppc64x.s | |
parent | 38df4c177b06441b40ac707f1eede49488da2396 (diff) | |
download | go-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.s | 52 |
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 |