github.com/SandwichDev/go-internals@v0.0.0-20210605002614-12311ac6b2c5/bytealg/compare_arm.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 ·Compare(SB),NOSPLIT|NOFRAME,$0-28
     9  	MOVW	a_base+0(FP), R2
    10  	MOVW	a_len+4(FP), R0
    11  	MOVW	b_base+12(FP), R3
    12  	MOVW	b_len+16(FP), R1
    13  	ADD	$28, R13, R7
    14  	B	cmpbody<>(SB)
    15  
    16  TEXT runtime·cmpstring(SB),NOSPLIT|NOFRAME,$0-20
    17  	MOVW	a_base+0(FP), R2
    18  	MOVW	a_len+4(FP), R0
    19  	MOVW	b_base+8(FP), R3
    20  	MOVW	b_len+12(FP), R1
    21  	ADD	$20, R13, R7
    22  	B	cmpbody<>(SB)
    23  
    24  // On entry:
    25  // R0 is the length of a
    26  // R1 is the length of b
    27  // R2 points to the start of a
    28  // R3 points to the start of b
    29  // R7 points to return value (-1/0/1 will be written here)
    30  //
    31  // On exit:
    32  // R4, R5, R6 and R8 are clobbered
    33  TEXT cmpbody<>(SB),NOSPLIT|NOFRAME,$0-0
    34  	CMP	R2, R3
    35  	BEQ	samebytes
    36  	CMP 	R0, R1
    37  	MOVW 	R0, R6
    38  	MOVW.LT	R1, R6		// R6 is min(R0, R1)
    39  
    40  	CMP	$0, R6
    41  	BEQ	samebytes
    42  	CMP	$4, R6
    43  	ADD	R2, R6		// R2 is current byte in a, R6 is the end of the range to compare
    44  	BLT	byte_loop	// length < 4
    45  	AND	$3, R2, R8
    46  	CMP	$0, R8
    47  	BNE	byte_loop	// unaligned a, use byte-wise compare (TODO: try to align a)
    48  aligned_a:
    49  	AND	$3, R3, R8
    50  	CMP	$0, R8
    51  	BNE	byte_loop	// unaligned b, use byte-wise compare
    52  	AND	$0xfffffffc, R6, R8
    53  	// length >= 4
    54  chunk4_loop:
    55  	MOVW.P	4(R2), R4
    56  	MOVW.P	4(R3), R5
    57  	CMP	R4, R5
    58  	BNE	cmp
    59  	CMP	R2, R8
    60  	BNE	chunk4_loop
    61  	CMP	R2, R6
    62  	BEQ	samebytes	// all compared bytes were the same; compare lengths
    63  byte_loop:
    64  	MOVBU.P	1(R2), R4
    65  	MOVBU.P	1(R3), R5
    66  	CMP	R4, R5
    67  	BNE	ret
    68  	CMP	R2, R6
    69  	BNE	byte_loop
    70  samebytes:
    71  	CMP	R0, R1
    72  	MOVW.LT	$1, R0
    73  	MOVW.GT	$-1, R0
    74  	MOVW.EQ	$0, R0
    75  	MOVW	R0, (R7)
    76  	RET
    77  ret:
    78  	// bytes differed
    79  	MOVW.LT	$1, R0
    80  	MOVW.GT	$-1, R0
    81  	MOVW	R0, (R7)
    82  	RET
    83  cmp:
    84  	SUB	$4, R2, R2
    85  	SUB	$4, R3, R3
    86  	B	byte_loop