github.com/metacubex/gvisor@v0.0.0-20240320004321-933faba989ec/pkg/safecopy/memcpy_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 // handleMemcpyFault returns (the value stored in R0, the value stored in R1). 8 // Control is transferred to it when memcpy 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 memcpy so that it can undo any 12 // potential call frame set up by the assembler. 13 TEXT handleMemcpyFault(SB), NOSPLIT, $0-36 14 MOVD R0, addr+24(FP) 15 MOVW R1, sig+32(FP) 16 RET 17 18 // memcpy copies data from src to dst. If a SIGSEGV or SIGBUS signal is received 19 // during the copy, it returns the address that caused the fault and the number 20 // of the signal that was received. Otherwise, it returns an unspecified address 21 // and a signal number of 0. 22 // 23 // Data is copied in order, such that if a fault happens at address p, it is 24 // safe to assume that all data before p-maxRegisterSize has already been 25 // successfully copied. 26 // 27 // The code is derived from the Go source runtime.memmove. 28 // 29 // func memcpy(dst, src unsafe.Pointer, n uintptr) (fault unsafe.Pointer, sig int32) 30 TEXT ·memcpy(SB), NOSPLIT, $-8-36 31 // Store 0 as the returned signal number. If we run to completion, 32 // this is the value the caller will see; if a signal is received, 33 // handleMemcpyFault will store a different value in this address. 34 MOVW $0, sig+32(FP) 35 36 MOVD dst+0(FP), R3 37 MOVD src+8(FP), R4 38 MOVD n+16(FP), R5 39 CMP $0, R5 40 BNE check 41 RET 42 43 check: 44 AND $~7, R5, R7 // R7 is N&~7. 45 SUB R7, R5, R6 // R6 is N&7. 46 47 // Copying forward proceeds by copying R7/8 words then copying R6 bytes. 48 // R3 and R4 are advanced as we copy. 49 50 // (There may be implementations of armv8 where copying by bytes until 51 // at least one of source or dest is word aligned is a worthwhile 52 // optimization, but the on the one tested so far (xgene) it did not 53 // make a significance difference.) 54 55 CMP $0, R7 // Do we need to do any word-by-word copying? 56 BEQ noforwardlarge 57 ADD R3, R7, R9 // R9 points just past where we copy by word. 58 59 forwardlargeloop: 60 MOVD.P 8(R4), R8 // R8 is just a scratch register. 61 MOVD.P R8, 8(R3) 62 CMP R3, R9 63 BNE forwardlargeloop 64 65 noforwardlarge: 66 CMP $0, R6 // Do we need to do any byte-by-byte copying? 67 BNE forwardtail 68 RET 69 70 forwardtail: 71 ADD R3, R6, R9 // R9 points just past the destination memory. 72 73 forwardtailloop: 74 MOVBU.P 1(R4), R8 75 MOVBU.P R8, 1(R3) 76 CMP R3, R9 77 BNE forwardtailloop 78 RET 79 80 // func addrOfMemcpy() uintptr 81 TEXT ·addrOfMemcpy(SB), $0-8 82 MOVD $·memcpy(SB), R0 83 MOVD R0, ret+0(FP) 84 RET