github.com/hikaru7719/go@v0.0.0-20181025140707-c8b2ac68906a/src/internal/bytealg/equal_arm64.s (about)

     1  // Copyright 2018 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 "go_asm.h"
     6  #include "textflag.h"
     7  
     8  TEXT ·Equal(SB),NOSPLIT,$0-49
     9  	MOVD	a_len+8(FP), R1
    10  	MOVD	b_len+32(FP), R3
    11  	CMP	R1, R3
    12  	// unequal lengths are not equal
    13  	BNE	not_equal
    14  	// short path to handle 0-byte case
    15  	CBZ	R1, equal
    16  	MOVD	a_base+0(FP), R0
    17  	MOVD	b_base+24(FP), R2
    18  	MOVD	$ret+48(FP), R8
    19  	B	memeqbody<>(SB)
    20  equal:
    21  	MOVD	$1, R0
    22  	MOVB	R0, ret+48(FP)
    23  	RET
    24  not_equal:
    25  	MOVB	ZR, ret+48(FP)
    26  	RET
    27  
    28  TEXT bytes·Equal(SB),NOSPLIT,$0-49
    29  	FUNCDATA $0, ·Equal·args_stackmap(SB)
    30  	MOVD	a_len+8(FP), R1
    31  	MOVD	b_len+32(FP), R3
    32  	CMP	R1, R3
    33  	// unequal lengths are not equal
    34  	BNE	not_equal
    35  	// short path to handle 0-byte case
    36  	CBZ	R1, equal
    37  	MOVD	a_base+0(FP), R0
    38  	MOVD	b_base+24(FP), R2
    39  	MOVD	$ret+48(FP), R8
    40  	B	memeqbody<>(SB)
    41  equal:
    42  	MOVD	$1, R0
    43  	MOVB	R0, ret+48(FP)
    44  	RET
    45  not_equal:
    46  	MOVB	ZR, ret+48(FP)
    47  	RET
    48  
    49  // memequal(a, b unsafe.Pointer, size uintptr) bool
    50  TEXT runtime·memequal(SB),NOSPLIT|NOFRAME,$0-25
    51  	MOVD	size+16(FP), R1
    52  	// short path to handle 0-byte case
    53  	CBZ	R1, equal
    54  	MOVD	a+0(FP), R0
    55  	MOVD	b+8(FP), R2
    56  	MOVD	$ret+24(FP), R8
    57  	B	memeqbody<>(SB)
    58  equal:
    59  	MOVD	$1, R0
    60  	MOVB	R0, ret+24(FP)
    61  	RET
    62  
    63  // memequal_varlen(a, b unsafe.Pointer) bool
    64  TEXT runtime·memequal_varlen(SB),NOSPLIT,$40-17
    65  	MOVD	a+0(FP), R3
    66  	MOVD	b+8(FP), R4
    67  	CMP	R3, R4
    68  	BEQ	eq
    69  	MOVD	8(R26), R5    // compiler stores size at offset 8 in the closure
    70  	CBZ	R5, eq
    71  	MOVD	R3, 8(RSP)
    72  	MOVD	R4, 16(RSP)
    73  	MOVD	R5, 24(RSP)
    74  	BL	runtime·memequal(SB)
    75  	MOVBU	32(RSP), R3
    76  	MOVB	R3, ret+16(FP)
    77  	RET
    78  eq:
    79  	MOVD	$1, R3
    80  	MOVB	R3, ret+16(FP)
    81  	RET
    82  
    83  // input:
    84  // R0: pointer a
    85  // R1: data len
    86  // R2: pointer b
    87  // R8: address to put result
    88  TEXT memeqbody<>(SB),NOSPLIT,$0
    89  	CMP	$1, R1
    90  	// handle 1-byte special case for better performance
    91  	BEQ	one
    92  	CMP	$16, R1
    93  	// handle specially if length < 16
    94  	BLO	tail
    95  	BIC	$0x3f, R1, R3
    96  	CBZ	R3, chunk16
    97  	// work with 64-byte chunks
    98  	ADD	R3, R0, R6	// end of chunks
    99  chunk64_loop:
   100  	VLD1.P	(R0), [V0.D2, V1.D2, V2.D2, V3.D2]
   101  	VLD1.P	(R2), [V4.D2, V5.D2, V6.D2, V7.D2]
   102  	VCMEQ	V0.D2, V4.D2, V8.D2
   103  	VCMEQ	V1.D2, V5.D2, V9.D2
   104  	VCMEQ	V2.D2, V6.D2, V10.D2
   105  	VCMEQ	V3.D2, V7.D2, V11.D2
   106  	VAND	V8.B16, V9.B16, V8.B16
   107  	VAND	V8.B16, V10.B16, V8.B16
   108  	VAND	V8.B16, V11.B16, V8.B16
   109  	CMP	R0, R6
   110  	VMOV	V8.D[0], R4
   111  	VMOV	V8.D[1], R5
   112  	CBZ	R4, not_equal
   113  	CBZ	R5, not_equal
   114  	BNE	chunk64_loop
   115  	AND	$0x3f, R1, R1
   116  	CBZ	R1, equal
   117  chunk16:
   118  	// work with 16-byte chunks
   119  	BIC	$0xf, R1, R3
   120  	CBZ	R3, tail
   121  	ADD	R3, R0, R6	// end of chunks
   122  chunk16_loop:
   123  	LDP.P	16(R0), (R4, R5)
   124  	LDP.P	16(R2), (R7, R9)
   125  	EOR	R4, R7
   126  	CBNZ	R7, not_equal
   127  	EOR	R5, R9
   128  	CBNZ	R9, not_equal
   129  	CMP	R0, R6
   130  	BNE	chunk16_loop
   131  	AND	$0xf, R1, R1
   132  	CBZ	R1, equal
   133  tail:
   134  	// special compare of tail with length < 16
   135  	TBZ	$3, R1, lt_8
   136  	MOVD	(R0), R4
   137  	MOVD	(R2), R5
   138  	EOR	R4, R5
   139  	CBNZ	R5, not_equal
   140  	SUB	$8, R1, R6	// offset of the last 8 bytes
   141  	MOVD	(R0)(R6), R4
   142  	MOVD	(R2)(R6), R5
   143  	EOR	R4, R5
   144  	CBNZ	R5, not_equal
   145  	B	equal
   146  lt_8:
   147  	TBZ	$2, R1, lt_4
   148  	MOVWU	(R0), R4
   149  	MOVWU	(R2), R5
   150  	EOR	R4, R5
   151  	CBNZ	R5, not_equal
   152  	SUB	$4, R1, R6	// offset of the last 4 bytes
   153  	MOVWU	(R0)(R6), R4
   154  	MOVWU	(R2)(R6), R5
   155  	EOR	R4, R5
   156  	CBNZ	R5, not_equal
   157  	B	equal
   158  lt_4:
   159  	TBZ	$1, R1, lt_2
   160  	MOVHU.P	2(R0), R4
   161  	MOVHU.P	2(R2), R5
   162  	CMP	R4, R5
   163  	BNE	not_equal
   164  lt_2:
   165  	TBZ	$0, R1, equal
   166  one:
   167  	MOVBU	(R0), R4
   168  	MOVBU	(R2), R5
   169  	CMP	R4, R5
   170  	BNE	not_equal
   171  equal:
   172  	MOVD	$1, R0
   173  	MOVB	R0, (R8)
   174  	RET
   175  not_equal:
   176  	MOVB	ZR, (R8)
   177  	RET