Text file src/internal/bytealg/compare_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  TEXT ·Compare<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-56
     9  #ifdef GOEXPERIMENT_regabiargs
    10  	// R0 = a_base (want in R0)
    11  	// R1 = a_len  (want in R1)
    12  	// R2 = a_cap  (unused)
    13  	// R3 = b_base (want in R2)
    14  	// R4 = b_len  (want in R3)
    15  	// R5 = b_cap  (unused)
    16  	MOVD	R3, R2
    17  	MOVD	R4, R3
    18  #else
    19  	MOVD	a_base+0(FP), R0
    20  	MOVD	a_len+8(FP), R1
    21  	MOVD	b_base+24(FP), R2
    22  	MOVD	b_len+32(FP), R3
    23  	MOVD	$ret+48(FP), R7
    24  #endif
    25  	B	cmpbody<>(SB)
    26  
    27  TEXT runtime·cmpstring<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-40
    28  #ifdef GOEXPERIMENT_regabiargs
    29  	// R0 = a_base
    30  	// R1 = a_len
    31  	// R2 = b_base
    32  	// R3 = b_len
    33  #else
    34  	MOVD	a_base+0(FP), R0
    35  	MOVD	a_len+8(FP), R1
    36  	MOVD	b_base+16(FP), R2
    37  	MOVD	b_len+24(FP), R3
    38  	MOVD	$ret+32(FP), R7
    39  #endif
    40  	B	cmpbody<>(SB)
    41  
    42  // On entry:
    43  // R0 points to the start of a
    44  // R1 is the length of a
    45  // R2 points to the start of b
    46  // R3 is the length of b
    47  #ifndef GOEXPERIMENT_regabiargs
    48  // R7 points to return value (-1/0/1 will be written here)
    49  #endif
    50  //
    51  // On exit:
    52  #ifdef GOEXPERIMENT_regabiargs
    53  // R0 is the result
    54  #endif
    55  // R4, R5, R6, R8, R9 and R10 are clobbered
    56  TEXT cmpbody<>(SB),NOSPLIT|NOFRAME,$0-0
    57  	CMP	R0, R2
    58  	BEQ	samebytes         // same starting pointers; compare lengths
    59  	CMP	R1, R3
    60  	CSEL	LT, R3, R1, R6    // R6 is min(R1, R3)
    61  
    62  	CBZ	R6, samebytes
    63  	BIC	$0xf, R6, R10
    64  	CBZ	R10, small        // length < 16
    65  	ADD	R0, R10           // end of chunk16
    66  	// length >= 16
    67  chunk16_loop:
    68  	LDP.P	16(R0), (R4, R8)
    69  	LDP.P	16(R2), (R5, R9)
    70  	CMP	R4, R5
    71  	BNE	cmp
    72  	CMP	R8, R9
    73  	BNE	cmpnext
    74  	CMP	R10, R0
    75  	BNE	chunk16_loop
    76  	AND	$0xf, R6, R6
    77  	CBZ	R6, samebytes
    78  	SUBS	$8, R6
    79  	BLT	tail
    80  	// the length of tail > 8 bytes
    81  	MOVD.P	8(R0), R4
    82  	MOVD.P	8(R2), R5
    83  	CMP	R4, R5
    84  	BNE	cmp
    85  	SUB	$8, R6
    86  	// compare last 8 bytes
    87  tail:
    88  	MOVD	(R0)(R6), R4
    89  	MOVD	(R2)(R6), R5
    90  	CMP	R4, R5
    91  	BEQ	samebytes
    92  cmp:
    93  	REV	R4, R4
    94  	REV	R5, R5
    95  	CMP	R4, R5
    96  ret:
    97  	MOVD	$1, R0
    98  	CNEG	HI, R0, R0
    99  #ifndef GOEXPERIMENT_regabiargs
   100  	MOVD	R0, (R7)
   101  #endif
   102  	RET
   103  small:
   104  	TBZ	$3, R6, lt_8
   105  	MOVD	(R0), R4
   106  	MOVD	(R2), R5
   107  	CMP	R4, R5
   108  	BNE	cmp
   109  	SUBS	$8, R6
   110  	BEQ	samebytes
   111  	ADD	$8, R0
   112  	ADD	$8, R2
   113  	SUB	$8, R6
   114  	B	tail
   115  lt_8:
   116  	TBZ	$2, R6, lt_4
   117  	MOVWU	(R0), R4
   118  	MOVWU	(R2), R5
   119  	CMPW	R4, R5
   120  	BNE	cmp
   121  	SUBS	$4, R6
   122  	BEQ	samebytes
   123  	ADD	$4, R0
   124  	ADD	$4, R2
   125  lt_4:
   126  	TBZ	$1, R6, lt_2
   127  	MOVHU	(R0), R4
   128  	MOVHU	(R2), R5
   129  	CMPW	R4, R5
   130  	BNE	cmp
   131  	ADD	$2, R0
   132  	ADD	$2, R2
   133  lt_2:
   134  	TBZ	$0, R6, samebytes
   135  one:
   136  	MOVBU	(R0), R4
   137  	MOVBU	(R2), R5
   138  	CMPW	R4, R5
   139  	BNE	ret
   140  samebytes:
   141  	CMP	R3, R1
   142  	CSET	NE, R0
   143  	CNEG	LO, R0, R0
   144  #ifndef GOEXPERIMENT_regabiargs
   145  	MOVD	R0, (R7)
   146  #endif
   147  	RET
   148  cmpnext:
   149  	REV	R8, R4
   150  	REV	R9, R5
   151  	CMP	R4, R5
   152  	B	ret
   153  

View as plain text