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)