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

View as plain text