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// for regabi the return value (-1/0/1) in R4
32TEXT cmpbody<>(SB),NOSPLIT|NOFRAME,$0
33 BEQ R4, R6, cmp_len // same start of a and b, then compare lengths
34
35 SGTU R5, R7, R9
36 BNE R9, b_lt_a
37 MOVV R5, R14
38 JMP entry
39b_lt_a:
40 MOVV R7, R14 // R14 is min(R5, R7)
41entry:
42 ADDV R4, R14, R12 // R4 start of a, R12 end of a
43 BEQ R4, R12, cmp_len // minlength is 0
44
45tail:
46 MOVV $2, R15
47 BLT R14, R15, cmp1 // min < 2
48 SLLV $1, R15
49 BLT R14, R15, cmp2 // min < 4
50 SLLV $1, R15
51 BLT R14, R15, cmp4 // min < 8
52 SLLV $1, R15
53 BLT R14, R15, cmp8 // min < 16
54 SLLV $1, R15
55 BLT R14, R15, cmp16 // min < 32
56
57// When min >= 32 bytes, enter the cmp32_loop loop processing:
58// take out 4 8-bytes from a and b in turn for comparison.
59cmp32_loop:
60 MOVV (R4), R8
61 MOVV (R6), R9
62 MOVV 8(R4), R10
63 MOVV 8(R6), R11
64 BNE R8, R9, cmp8a
65 BNE R10, R11, cmp8b
66 MOVV 16(R4), R8
67 MOVV 16(R6), R9
68 MOVV 24(R4), R10
69 MOVV 24(R6), R11
70 BNE R8, R9, cmp8a
71 BNE R10, R11, cmp8b
72 ADDV $32, R4
73 ADDV $32, R6
74 SUBV $32, R14
75 BGE R14, R15, cmp32_loop
76 BEQ R14, cmp_len
77
78check16:
79 MOVV $16, R15
80 BLT R14, R15, check8
81cmp16:
82 MOVV (R4), R8
83 MOVV (R6), R9
84 MOVV 8(R4), R10
85 MOVV 8(R6), R11
86 BNE R8, R9, cmp8a
87 BNE R10, R11, cmp8b
88 ADDV $16, R4
89 ADDV $16, R6
90 SUBV $16, R14
91 BEQ R14, cmp_len
92
93check8:
94 MOVV $8, R15
95 BLT R14, R15, check4
96cmp8:
97 MOVV (R4), R8
98 MOVV (R6), R9
99 BNE R8, R9, cmp8a
100 ADDV $8, R4
101 ADDV $8, R6
102 SUBV $8, R14
103 BEQ R14, cmp_len
104
105check4:
106 MOVV $4, R15
107 BLT R14, R15, check2
108cmp4:
109 MOVW (R4), R8
110 MOVW (R6), R9
111 BNE R8, R9, cmp8a
112 ADDV $4, R4
113 ADDV $4, R6
114 SUBV $4, R14
115 BEQ R14, cmp_len
116
117check2:
118 MOVV $2, R15
119 BLT R14, R15, cmp1
120cmp2:
121 MOVH (R4), R8
122 MOVH (R6), R9
123 BNE R8, R9, cmp8a
124 ADDV $2, R4
125 ADDV $2, R6
126 SUBV $2, R14
127 BEQ R14, cmp_len
128
129cmp1:
130 BEQ R14, cmp_len
131 MOVBU (R4), R8
132 MOVBU (R6), R9
133 BNE R8, R9, byte_cmp
134 JMP cmp_len
135
136 // Compare 8/4/2 bytes taken from R8/R9 that are known to differ.
137cmp8a:
138 MOVV R8, R10
139 MOVV R9, R11
140
141 // Compare 8/4/2 bytes taken from R10/R11 that are known to differ.
142cmp8b:
143 MOVV $0xff, R15
144
145 // Take single bytes from R10/R11 in turn for cyclic comparison.
146cmp8_loop:
147 AND R10, R15, R8
148 AND R11, R15, R9
149 BNE R8, R9, byte_cmp
150 SLLV $8, R15
151 JMP cmp8_loop
152
153 // Compare 1 bytes taken from R8/R9 that are known to differ.
154byte_cmp:
155 SGTU R8, R9, R4 // R4 = 1 if (R8 > R9)
156 BNE R0, R4, ret
157 MOVV $-1, R4
158 JMP ret
159
160cmp_len:
161 SGTU R5, R7, R8
162 SGTU R7, R5, R9
163 SUBV R9, R8, R4
164
165ret:
166 RET
View as plain text