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
8TEXT ·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
16TEXT 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
33TEXT 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)
48aligned_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
54chunk4_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
63byte_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
70samebytes:
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
77ret:
78 // bytes differed
79 MOVW.LT $1, R0
80 MOVW.GT $-1, R0
81 MOVW R0, (R7)
82 RET
83cmp:
84 SUB $4, R2, R2
85 SUB $4, R3, R3
86 B byte_loop
View as plain text