Text file src/internal/bytealg/equal_arm64.s

     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  // memequal_varlen(a, b unsafe.Pointer) bool
     9  TEXT runtime·memequal_varlen<ABIInternal>(SB),NOSPLIT,$0-17
    10  	MOVD	8(R26), R2    // compiler stores size at offset 8 in the closure
    11  	CBZ	R2, eq
    12  	B	runtime·memequal<ABIInternal>(SB)
    13  eq:
    14  	MOVD	$1, R0
    15  	RET
    16  
    17  // input:
    18  // R0: pointer a
    19  // R1: pointer b
    20  // R2: data len
    21  // at return: result in R0
    22  // memequal(a, b unsafe.Pointer, size uintptr) bool
    23  TEXT runtime·memequal<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-25
    24  	// short path to handle 0-byte case
    25  	CBZ     R2, equal
    26  	// short path to handle equal pointers
    27  	CMP     R0, R1
    28  	BEQ     equal
    29  	CMP	$1, R2
    30  	// handle 1-byte special case for better performance
    31  	BEQ	one
    32  	CMP	$16, R2
    33  	// handle specially if length < 16
    34  	BLO	tail
    35  	CMP	$33, R2
    36  	BHS	large
    37  pairwise_16_32:
    38  	// use pairwise loads for 16 <= len <= 32
    39  	LDP	(R0), (R16, R17)
    40  	LDP	(R1), (R24, R26)
    41  	CMP	R16, R24
    42  	CCMP	EQ, R17, R26, $0
    43  	BNE	not_equal
    44  	SUB	$16, R2, R16
    45  	CBZ	R16, equal
    46  	ADD	R0, R16, R24
    47  	ADD	R1, R16, R25
    48  	LDP	(R24), (R16, R17)
    49  	LDP	(R25), (R24, R26)
    50  	CMP	R16, R24
    51  	CCMP	EQ, R17, R26, $0
    52  	CSET	EQ, R0
    53  	RET
    54  	PCALIGN	$16
    55  tail:
    56  	// special compare of tail with length < 16
    57  	TBZ	$3, R2, lt_8
    58  	MOVD	(R0), R16
    59  	MOVD	(R1), R17
    60  	CMP	R16, R17
    61  	BNE	not_equal
    62  	SUB	$8, R2, R26	// offset of the last 8 bytes
    63  	MOVD	(R0)(R26), R16
    64  	MOVD	(R1)(R26), R17
    65  	CMP	R16, R17
    66  	CSET	EQ, R0
    67  	RET
    68  	PCALIGN	$16
    69  lt_8:
    70  	TBZ	$2, R2, lt_4
    71  	MOVWU	(R0), R16
    72  	MOVWU	(R1), R17
    73  	CMP	R16, R17
    74  	BNE	not_equal
    75  	SUB	$4, R2, R26	// offset of the last 4 bytes
    76  	MOVWU	(R0)(R26), R16
    77  	MOVWU	(R1)(R26), R17
    78  	CMP	R16, R17
    79  	CSET	EQ, R0
    80  	RET
    81  	PCALIGN	$16
    82  lt_4:
    83  	TBZ	$1, R2, lt_2
    84  	MOVHU.P	2(R0), R16
    85  	MOVHU.P	2(R1), R17
    86  	CMP	R16, R17
    87  	BNE	not_equal
    88  lt_2:
    89  	TBZ	$0, R2, equal
    90  one:
    91  	MOVBU	(R0), R16
    92  	MOVBU	(R1), R17
    93  	CMP	R16, R17
    94  	BNE	not_equal
    95  equal:
    96  	MOVD	$1, R0
    97  	RET
    98  not_equal:
    99  	MOVB	ZR, R0
   100  	RET
   101  large:
   102  	BIC	$0x3f, R2, R26
   103  	CBZ	R26, remainder_33_64
   104  	// work with 64-byte chunks
   105  	ADD	R0, R26		// end of chunks
   106  chunk64_loop:
   107  	VLD1.P	(R0), [V21.D2, V22.D2, V23.D2, V24.D2]
   108  	VLD1.P	(R1), [V25.D2, V26.D2, V27.D2, V28.D2]
   109  	VCMEQ	V21.D2, V25.D2, V21.D2
   110  	VCMEQ	V22.D2, V26.D2, V22.D2
   111  	VCMEQ	V23.D2, V27.D2, V23.D2
   112  	VCMEQ	V24.D2, V28.D2, V24.D2
   113  	VAND	V21.B16, V22.B16, V21.B16
   114  	VAND	V23.B16, V24.B16, V23.B16
   115  	VAND	V21.B16, V23.B16, V21.B16
   116  	CMP	R0, R26
   117  	VMOV	V21.D[0], R16
   118  	VMOV	V21.D[1], R17
   119  	CBZ	R16, not_equal
   120  	CBZ	R17, not_equal
   121  	BNE	chunk64_loop
   122  	AND	$0x3f, R2, R2
   123  	CBZ	R2, equal
   124  	CMP	$16, R2
   125  	BLO	tail
   126  	CMP	$33, R2
   127  	BLO	pairwise_16_32
   128  remainder_33_64:
   129  	// 33 <= len < 64
   130  	VLD1	(R0), [V21.D2, V22.D2]
   131  	VLD1	(R1), [V23.D2, V24.D2]
   132  	SUB	$32, R2, R26
   133  	ADD	R0, R26, R24
   134  	ADD	R1, R26, R25
   135  	VEOR	V23.B16, V21.B16, V21.B16
   136  	VEOR	V24.B16, V22.B16, V22.B16
   137  	VORR	V22.B16, V21.B16, V21.B16
   138  	VMOV	V21.D[0], R16
   139  	VMOV	V21.D[1], R17
   140  	ORR	R17, R16, R16
   141  	CBNZ	R16, not_equal
   142  	VLD1	(R24), [V21.D2, V22.D2]
   143  	VLD1	(R25), [V23.D2, V24.D2]
   144  	VEOR	V23.B16, V21.B16, V21.B16
   145  	VEOR	V24.B16, V22.B16, V22.B16
   146  	VORR	V22.B16, V21.B16, V21.B16
   147  	VMOV	V21.D[0], R16
   148  	VMOV	V21.D[1], R17
   149  	ORR	R17, R16, R16
   150  	CBNZ	R16, not_equal
   151  	B	equal
   152  

View as plain text