github.com/sagernet/gvisor@v0.0.0-20240428053021-e691de28565f/pkg/safecopy/memclr_arm64.s (about)

     1  // Copyright 2014 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  #include "textflag.h"
     6  
     7  // handleMemclrFault returns (the value stored in R0, the value stored in R1).
     8  // Control is transferred to it when memclr below receives SIGSEGV or SIGBUS,
     9  // with the faulting address stored in R0 and the signal number stored in R1.
    10  //
    11  // It must have the same frame configuration as memclr so that it can undo any
    12  // potential call frame set up by the assembler.
    13  TEXT handleMemclrFault(SB), NOSPLIT, $0-28
    14  	MOVD R0, addr+16(FP)
    15  	MOVW R1, sig+24(FP)
    16  	RET
    17  
    18  // See the corresponding doc in safecopy_unsafe.go
    19  //
    20  // The code is derived from runtime.memclrNoHeapPointers.
    21  //
    22  // func memclr(ptr unsafe.Pointer, n uintptr) (fault unsafe.Pointer, sig int32)
    23  TEXT ·memclr(SB), NOSPLIT, $0-28
    24  	// Store 0 as the returned signal number. If we run to completion,
    25  	// this is the value the caller will see; if a signal is received,
    26  	// handleMemclrFault will store a different value in this address.
    27  	MOVW $0, sig+24(FP)
    28  	MOVD ptr+0(FP), R0
    29  	MOVD n+8(FP), R1
    30  
    31  	// If size is less than 16 bytes, use tail_zero to zero what remains
    32  	CMP $16, R1
    33  	BLT tail_zero
    34  	// Get buffer offset into 16 byte aligned address for better performance
    35  	ANDS $15, R0, ZR
    36  	BNE unaligned_to_16
    37  aligned_to_16:
    38  	LSR $4, R1, R2
    39  zero_by_16:
    40  	STP.P (ZR, ZR), 16(R0) // Store pair with post index.
    41  	SUBS $1, R2, R2
    42  	BNE zero_by_16
    43  	ANDS $15, R1, R1
    44  	BEQ end
    45  
    46  	// Zero buffer with size=R1 < 16
    47  tail_zero:
    48  	TBZ $3, R1, tail_zero_4
    49  	MOVD.P ZR, 8(R0)
    50  tail_zero_4:
    51  	TBZ $2, R1, tail_zero_2
    52  	MOVW.P ZR, 4(R0)
    53  tail_zero_2:
    54  	TBZ $1, R1, tail_zero_1
    55  	MOVH.P ZR, 2(R0)
    56  tail_zero_1:
    57  	TBZ $0, R1, end
    58  	MOVB ZR, (R0)
    59  end:
    60  	RET
    61  
    62  unaligned_to_16:
    63  	MOVD R0, R2
    64  head_loop:
    65  	MOVBU.P ZR, 1(R0)
    66  	ANDS $15, R0, ZR
    67  	BNE head_loop
    68  	// Adjust length for what remains
    69  	SUB R2, R0, R3
    70  	SUB R3, R1
    71  	// If size is less than 16 bytes, use tail_zero to zero what remains
    72  	CMP $16, R1
    73  	BLT tail_zero
    74  	B aligned_to_16
    75  
    76  // func addrOfMemclr() uintptr
    77  TEXT ·addrOfMemclr(SB), $0-8
    78  	MOVD	$·memclr(SB), R0
    79  	MOVD	R0, ret+0(FP)
    80  	RET