1// Copyright 2022 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
8TEXT ·Compare<ABIInternal>(SB),NOSPLIT,$0-56
9	// R4 = a_base
10	// R5 = a_len
11	// R6 = a_cap (unused)
12	// R7 = b_base (want in R6)
13	// R8 = b_len (want in R7)
14	// R9 = b_cap (unused)
15	MOVV	R7, R6
16	MOVV	R8, R7
17	JMP	cmpbody<>(SB)
18
19TEXT runtime·cmpstring<ABIInternal>(SB),NOSPLIT,$0-40
20	// R4 = a_base
21	// R5 = a_len
22	// R6 = b_base
23	// R7 = b_len
24	JMP	cmpbody<>(SB)
25
26// On entry:
27// R5 length of a
28// R7 length of b
29// R4 points to the start of a
30// R6 points to the start of b
31// R13 points to the return value (-1/0/1)
32TEXT cmpbody<>(SB),NOSPLIT|NOFRAME,$0
33	BEQ	R4, R6, samebytes // same start of a and b
34
35	SGTU	R5, R7, R9
36	BNE	R0, R9, r2_lt_r1
37	MOVV	R5, R14
38	JMP	entry
39r2_lt_r1:
40	MOVV	R7, R14	// R14 is min(R4, R5)
41entry:
42	ADDV	R4, R14, R12	// R6 start of a, R14 end of a
43	BEQ	R4, R12, samebytes // length is 0
44
45	SRLV	$4, R14		// R14 is number of chunks
46	BEQ	R0, R14, byte_loop
47
48	// make sure both a and b are aligned.
49	OR	R4, R6, R15
50	AND	$7, R15
51	BNE	R0, R15, byte_loop
52
53	PCALIGN	$16
54chunk16_loop:
55	BEQ	R0, R14, byte_loop
56	MOVV	(R4), R8
57	MOVV	(R6), R9
58	BNE	R8, R9, byte_loop
59	MOVV	8(R4), R16
60	MOVV	8(R6), R17
61	ADDV	$16, R4
62	ADDV	$16, R6
63	SUBVU	$1, R14
64	BEQ	R16, R17, chunk16_loop
65	SUBV	$8, R4
66	SUBV	$8, R6
67
68byte_loop:
69	BEQ	R4, R12, samebytes
70	MOVBU	(R4), R8
71	ADDVU	$1, R4
72	MOVBU	(R6), R9
73	ADDVU	$1, R6
74	BEQ	R8, R9, byte_loop
75
76byte_cmp:
77	SGTU	R8, R9, R4 // R12 = 1 if (R8 > R9)
78	BNE	R0, R4, ret
79	MOVV	$-1, R4
80	JMP	ret
81
82samebytes:
83	SGTU	R5, R7, R8
84	SGTU	R7, R5, R9
85	SUBV	R9, R8, R4
86
87ret:
88	RET
89