github.com/megatontech/mynoteforgo@v0.0.0-20200507084910-5d0c6ea6e890/源码/runtime/memmove_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  // func memmove(to, from unsafe.Pointer, n uintptr)
     8  TEXT runtime·memmove(SB), NOSPLIT|NOFRAME, $0-24
     9  	MOVD	to+0(FP), R3
    10  	MOVD	from+8(FP), R4
    11  	MOVD	n+16(FP), R5
    12  	CBNZ	R5, check
    13  	RET
    14  
    15  check:
    16  	CMP	$16, R5
    17  	BLE	copy16
    18  
    19  	AND	$~31, R5, R7	// R7 is N&~31
    20  	SUB	R7, R5, R6	// R6 is N&31
    21  
    22  	CMP	R3, R4
    23  	BLT	backward
    24  
    25  	// Copying forward proceeds by copying R7/8 words then copying R6 bytes.
    26  	// R3 and R4 are advanced as we copy.
    27  
    28          // (There may be implementations of armv8 where copying by bytes until
    29          // at least one of source or dest is word aligned is a worthwhile
    30          // optimization, but the on the one tested so far (xgene) it did not
    31          // make a significance difference.)
    32  
    33  	CBZ	R7, noforwardlarge	// Do we need to do any doubleword-by-doubleword copying?
    34  
    35  	ADD	R3, R7, R9	// R9 points just past where we copy by word
    36  
    37  forwardlargeloop:
    38  	LDP.P	32(R4), (R8, R10)
    39  	STP.P	(R8, R10), 32(R3)
    40  	LDP	-16(R4), (R11, R12)
    41  	STP	(R11, R12), -16(R3)
    42  	SUB 	$32, R7, R7
    43  	CBNZ	R7, forwardlargeloop
    44  
    45  noforwardlarge:
    46  	CBNZ	R6, forwardtail		// Do we need to do any byte-by-byte copying?
    47  	RET
    48  
    49  forwardtail:
    50  	ADD	R3, R6, R9	// R9 points just past the destination memory
    51  
    52  forwardtailloop:
    53  	MOVBU.P 1(R4), R8
    54  	MOVBU.P	R8, 1(R3)
    55  	CMP	R3, R9
    56  	BNE	forwardtailloop
    57  	RET
    58  
    59  	// Small copies: 1..16 bytes.
    60  copy16:
    61  	ADD	R4, R5, R8	// R8 points just past the last source byte
    62  	ADD	R3, R5, R9	// R9 points just past the last destination byte
    63  	CMP	$8, R5
    64  	BLT	copy7
    65  	MOVD	(R4), R6
    66  	MOVD	-8(R8), R7
    67  	MOVD	R6, (R3)
    68  	MOVD	R7, -8(R9)
    69  	RET
    70  
    71  copy7:
    72  	TBZ	$2, R5, copy3
    73  	MOVWU	(R4), R6
    74  	MOVWU	-4(R8), R7
    75  	MOVW	R6, (R3)
    76  	MOVW	R7, -4(R9)
    77  	RET
    78  
    79  copy3:
    80  	TBZ	$1, R5, copy1
    81  	MOVHU	(R4), R6
    82  	MOVHU	-2(R8), R7
    83  	MOVH	R6, (R3)
    84  	MOVH	R7, -2(R9)
    85  	RET
    86  
    87  copy1:
    88  	MOVBU	(R4), R6
    89  	MOVB	R6, (R3)
    90  	RET
    91  
    92  backward:
    93  	// Copying backwards proceeds by copying R6 bytes then copying R7/8 words.
    94  	// R3 and R4 are advanced to the end of the destination/source buffers
    95  	// respectively and moved back as we copy.
    96  
    97  	ADD	R4, R5, R4	// R4 points just past the last source byte
    98  	ADD	R3, R5, R3	// R3 points just past the last destination byte
    99  
   100  	CBZ	R6, nobackwardtail	// Do we need to do any byte-by-byte copying?
   101  
   102  	SUB	R6, R3, R9	// R9 points at the lowest destination byte that should be copied by byte.
   103  backwardtailloop:
   104  	MOVBU.W	-1(R4), R8
   105  	MOVBU.W	R8, -1(R3)
   106  	CMP	R9, R3
   107  	BNE	backwardtailloop
   108  
   109  nobackwardtail:
   110  	CBNZ     R7, backwardlarge	// Do we need to do any doubleword-by-doubleword copying?
   111  	RET
   112  
   113  backwardlarge:
   114          SUB	R7, R3, R9      // R9 points at the lowest destination byte
   115  
   116  backwardlargeloop:
   117  	LDP	-16(R4), (R8, R10)
   118  	STP	(R8, R10), -16(R3)
   119  	LDP.W	-32(R4), (R11, R12)
   120  	STP.W	(R11, R12), -32(R3)
   121  	CMP	R9, R3
   122  	BNE	backwardlargeloop
   123  	RET