github.com/primecitizens/pcz/std@v0.2.1/core/gc/wb_arm64.s (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright 2023 The Prime Citizens 3 // 4 // Copyright 2015 The Go Authors. All rights reserved. 5 // Use of this source code is governed by a BSD-style 6 // license that can be found in the LICENSE file. 7 8 //go:build arm64 9 10 #include "textflag.h" 11 12 // gcWriteBarrier informs the GC about heap pointer writes. 13 // 14 // gcWriteBarrier does NOT follow the Go ABI. It accepts the 15 // number of bytes of buffer needed in R25, and returns a pointer 16 // to the buffer space in R25. 17 // It clobbers condition codes. 18 // It does not clobber any general-purpose registers except R27, 19 // but may clobber others (e.g., floating point registers) 20 // The act of CALLing gcWriteBarrier will clobber R30 (LR). 21 TEXT gcWriteBarrier<>(SB),NOSPLIT,$200 22 // Save the registers clobbered by the fast path. 23 STP (R0, R1), 184(RSP) 24 retry: 25 MOVD g_m(g), R0 26 MOVD m_p(R0), R0 27 MOVD (p_wbBuf+wbBuf_next)(R0), R1 28 MOVD (p_wbBuf+wbBuf_end)(R0), R27 29 // Increment wbBuf.next position. 30 ADD R25, R1 31 // Is the buffer full? 32 CMP R27, R1 33 BHI flush 34 // Commit to the larger buffer. 35 MOVD R1, (p_wbBuf+wbBuf_next)(R0) 36 // Make return value (the original next position) 37 SUB R25, R1, R25 38 // Restore registers. 39 LDP 184(RSP), (R0, R1) 40 RET 41 42 flush: 43 // Save all general purpose registers since these could be 44 // clobbered by wbBufFlush and were not saved by the caller. 45 // R0 and R1 already saved 46 STP (R2, R3), 1*8(RSP) 47 STP (R4, R5), 3*8(RSP) 48 STP (R6, R7), 5*8(RSP) 49 STP (R8, R9), 7*8(RSP) 50 STP (R10, R11), 9*8(RSP) 51 STP (R12, R13), 11*8(RSP) 52 STP (R14, R15), 13*8(RSP) 53 // R16, R17 may be clobbered by linker trampoline 54 // R18 is unused. 55 STP (R19, R20), 15*8(RSP) 56 STP (R21, R22), 17*8(RSP) 57 STP (R23, R24), 19*8(RSP) 58 STP (R25, R26), 21*8(RSP) 59 // R27 is temp register. 60 // R28 is g. 61 // R29 is frame pointer (unused). 62 // R30 is LR, which was saved by the prologue. 63 // R31 is SP. 64 65 CALL runtime·wbBufFlush(SB) 66 LDP 1*8(RSP), (R2, R3) 67 LDP 3*8(RSP), (R4, R5) 68 LDP 5*8(RSP), (R6, R7) 69 LDP 7*8(RSP), (R8, R9) 70 LDP 9*8(RSP), (R10, R11) 71 LDP 11*8(RSP), (R12, R13) 72 LDP 13*8(RSP), (R14, R15) 73 LDP 15*8(RSP), (R19, R20) 74 LDP 17*8(RSP), (R21, R22) 75 LDP 19*8(RSP), (R23, R24) 76 LDP 21*8(RSP), (R25, R26) 77 JMP retry 78 79 TEXT runtime·gcWriteBarrier1<ABIInternal>(SB),NOSPLIT,$0 80 MOVD $8, R25 81 JMP gcWriteBarrier<>(SB) 82 TEXT runtime·gcWriteBarrier2<ABIInternal>(SB),NOSPLIT,$0 83 MOVD $16, R25 84 JMP gcWriteBarrier<>(SB) 85 TEXT runtime·gcWriteBarrier3<ABIInternal>(SB),NOSPLIT,$0 86 MOVD $24, R25 87 JMP gcWriteBarrier<>(SB) 88 TEXT runtime·gcWriteBarrier4<ABIInternal>(SB),NOSPLIT,$0 89 MOVD $32, R25 90 JMP gcWriteBarrier<>(SB) 91 TEXT runtime·gcWriteBarrier5<ABIInternal>(SB),NOSPLIT,$0 92 MOVD $40, R25 93 JMP gcWriteBarrier<>(SB) 94 TEXT runtime·gcWriteBarrier6<ABIInternal>(SB),NOSPLIT,$0 95 MOVD $48, R25 96 JMP gcWriteBarrier<>(SB) 97 TEXT runtime·gcWriteBarrier7<ABIInternal>(SB),NOSPLIT,$0 98 MOVD $56, R25 99 JMP gcWriteBarrier<>(SB) 100 TEXT runtime·gcWriteBarrier8<ABIInternal>(SB),NOSPLIT,$0 101 MOVD $64, R25 102 JMP gcWriteBarrier<>(SB)