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
87
View as plain text