diff options
Diffstat (limited to 'src/runtime')
-rw-r--r-- | src/runtime/asm_arm64.s | 47 | ||||
-rw-r--r-- | src/runtime/signal_unix.go | 2 | ||||
-rw-r--r-- | src/runtime/sys_linux_ppc64x.s | 86 |
3 files changed, 96 insertions, 39 deletions
diff --git a/src/runtime/asm_arm64.s b/src/runtime/asm_arm64.s index 6b3d1e779e..141ed76624 100644 --- a/src/runtime/asm_arm64.s +++ b/src/runtime/asm_arm64.s @@ -1161,10 +1161,10 @@ TEXT ·checkASM(SB),NOSPLIT,$0-1 // It does not clobber any general-purpose registers, // but may clobber others (e.g., floating point registers) // The act of CALLing gcWriteBarrier will clobber R30 (LR). -TEXT runtime·gcWriteBarrier(SB),NOSPLIT,$216 +TEXT runtime·gcWriteBarrier(SB),NOSPLIT,$200 // Save the registers clobbered by the fast path. - MOVD R0, 200(RSP) - MOVD R1, 208(RSP) + MOVD R0, 184(RSP) + MOVD R1, 192(RSP) MOVD g_m(g), R0 MOVD m_p(R0), R0 MOVD (p_wbBuf+wbBuf_next)(R0), R1 @@ -1180,8 +1180,8 @@ TEXT runtime·gcWriteBarrier(SB),NOSPLIT,$216 // Is the buffer full? (flags set in CMP above) BEQ flush ret: - MOVD 200(RSP), R0 - MOVD 208(RSP), R1 + MOVD 184(RSP), R0 + MOVD 192(RSP), R1 // Do the write. MOVD R3, (R2) RET @@ -1205,17 +1205,16 @@ flush: MOVD R13, 96(RSP) MOVD R14, 104(RSP) MOVD R15, 112(RSP) - MOVD R16, 120(RSP) - MOVD R17, 128(RSP) + // R16, R17 may be clobbered by linker trampoline // R18 is unused. - MOVD R19, 136(RSP) - MOVD R20, 144(RSP) - MOVD R21, 152(RSP) - MOVD R22, 160(RSP) - MOVD R23, 168(RSP) - MOVD R24, 176(RSP) - MOVD R25, 184(RSP) - MOVD R26, 192(RSP) + MOVD R19, 120(RSP) + MOVD R20, 128(RSP) + MOVD R21, 136(RSP) + MOVD R22, 144(RSP) + MOVD R23, 152(RSP) + MOVD R24, 160(RSP) + MOVD R25, 168(RSP) + MOVD R26, 176(RSP) // R27 is temp register. // R28 is g. // R29 is frame pointer (unused). @@ -1239,16 +1238,14 @@ flush: MOVD 96(RSP), R13 MOVD 104(RSP), R14 MOVD 112(RSP), R15 - MOVD 120(RSP), R16 - MOVD 128(RSP), R17 - MOVD 136(RSP), R19 - MOVD 144(RSP), R20 - MOVD 152(RSP), R21 - MOVD 160(RSP), R22 - MOVD 168(RSP), R23 - MOVD 176(RSP), R24 - MOVD 184(RSP), R25 - MOVD 192(RSP), R26 + MOVD 120(RSP), R19 + MOVD 128(RSP), R20 + MOVD 136(RSP), R21 + MOVD 144(RSP), R22 + MOVD 152(RSP), R23 + MOVD 160(RSP), R24 + MOVD 168(RSP), R25 + MOVD 176(RSP), R26 JMP ret // Note: these functions use a special calling convention to save generated code space. diff --git a/src/runtime/signal_unix.go b/src/runtime/signal_unix.go index 003c7b0bc8..8e1eb9e186 100644 --- a/src/runtime/signal_unix.go +++ b/src/runtime/signal_unix.go @@ -393,7 +393,7 @@ func preemptM(mp *m) { //go:nosplit func sigFetchG(c *sigctxt) *g { switch GOARCH { - case "arm", "arm64": + case "arm", "arm64", "ppc64", "ppc64le": if !iscgo && inVDSOPage(c.sigpc()) { // When using cgo, we save the g on TLS and load it from there // in sigtramp. Just use that. diff --git a/src/runtime/sys_linux_ppc64x.s b/src/runtime/sys_linux_ppc64x.s index fd69ee70a5..7be8c4c724 100644 --- a/src/runtime/sys_linux_ppc64x.s +++ b/src/runtime/sys_linux_ppc64x.s @@ -215,15 +215,45 @@ TEXT runtime·walltime1(SB),NOSPLIT,$16-12 MOVD (g_sched+gobuf_sp)(R7), R1 // Set SP to g0 stack noswitch: - SUB $16, R1 // Space for results - RLDICR $0, R1, $59, R1 // Align for C code + SUB $16, R1 // Space for results + RLDICR $0, R1, $59, R1 // Align for C code MOVD R12, CTR MOVD R1, R4 - BL (CTR) // Call from VDSO - MOVD $0, R0 // Restore R0 - MOVD 0(R1), R3 // sec - MOVD 8(R1), R5 // nsec - MOVD R15, R1 // Restore SP + + // Store g on gsignal's stack, so if we receive a signal + // during VDSO code we can find the g. + // If we don't have a signal stack, we won't receive signal, + // so don't bother saving g. + // When using cgo, we already saved g on TLS, also don't save + // g here. + // Also don't save g if we are already on the signal stack. + // We won't get a nested signal. + MOVBZ runtime·iscgo(SB), R22 + CMP R22, $0 + BNE nosaveg + MOVD m_gsignal(R21), R22 // g.m.gsignal + CMP R22, $0 + BEQ nosaveg + + CMP g, R22 + BEQ nosaveg + MOVD (g_stack+stack_lo)(R22), R22 // g.m.gsignal.stack.lo + MOVD g, (R22) + + BL (CTR) // Call from VDSO + + MOVD $0, (R22) // clear g slot, R22 is unchanged by C code + + JMP finish + +nosaveg: + BL (CTR) // Call from VDSO + +finish: + MOVD $0, R0 // Restore R0 + MOVD 0(R1), R3 // sec + MOVD 8(R1), R5 // nsec + MOVD R15, R1 // Restore SP // Restore vdsoPC, vdsoSP // We don't worry about being signaled between the two stores. @@ -235,7 +265,7 @@ noswitch: MOVD 32(R1), R6 MOVD R6, m_vdsoPC(R21) -finish: +return: MOVD R3, sec+0(FP) MOVW R5, nsec+8(FP) RET @@ -246,7 +276,7 @@ fallback: SYSCALL $SYS_clock_gettime MOVD 32(R1), R3 MOVD 40(R1), R5 - JMP finish + JMP return TEXT runtime·nanotime1(SB),NOSPLIT,$16-8 MOVD $1, R3 // CLOCK_MONOTONIC @@ -282,7 +312,37 @@ noswitch: RLDICR $0, R1, $59, R1 // Align for C code MOVD R12, CTR MOVD R1, R4 - BL (CTR) // Call from VDSO + + // Store g on gsignal's stack, so if we receive a signal + // during VDSO code we can find the g. + // If we don't have a signal stack, we won't receive signal, + // so don't bother saving g. + // When using cgo, we already saved g on TLS, also don't save + // g here. + // Also don't save g if we are already on the signal stack. + // We won't get a nested signal. + MOVBZ runtime·iscgo(SB), R22 + CMP R22, $0 + BNE nosaveg + MOVD m_gsignal(R21), R22 // g.m.gsignal + CMP R22, $0 + BEQ nosaveg + + CMP g, R22 + BEQ nosaveg + MOVD (g_stack+stack_lo)(R22), R22 // g.m.gsignal.stack.lo + MOVD g, (R22) + + BL (CTR) // Call from VDSO + + MOVD $0, (R22) // clear g slot, R22 is unchanged by C code + + JMP finish + +nosaveg: + BL (CTR) // Call from VDSO + +finish: MOVD $0, R0 // Restore R0 MOVD 0(R1), R3 // sec MOVD 8(R1), R5 // nsec @@ -298,7 +358,7 @@ noswitch: MOVD 32(R1), R6 MOVD R6, m_vdsoPC(R21) -finish: +return: // sec is in R3, nsec in R5 // return nsec in R3 MOVD $1000000000, R4 @@ -313,7 +373,7 @@ fallback: SYSCALL $SYS_clock_gettime MOVD 32(R1), R3 MOVD 40(R1), R5 - JMP finish + JMP return TEXT runtime·rtsigprocmask(SB),NOSPLIT|NOFRAME,$0-28 MOVW how+0(FP), R3 @@ -366,7 +426,7 @@ TEXT sigtramp<>(SB),NOSPLIT,$64 // this might be called in external code context, // where g is not set. MOVBZ runtime·iscgo(SB), R6 - CMP R6, $0 + CMP R6, $0 BEQ 2(PC) BL runtime·load_g(SB) |