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 // memequal_varlen(a, b unsafe.Pointer) bool
9 TEXT runtime·memequal_varlen<ABIInternal>(SB),NOSPLIT,$0-17
10 MOVD 8(R26), R2 // compiler stores size at offset 8 in the closure
11 CBZ R2, eq
12 B runtime·memequal<ABIInternal>(SB)
13 eq:
14 MOVD $1, R0
15 RET
16
17 // input:
18 // R0: pointer a
19 // R1: pointer b
20 // R2: data len
21 // at return: result in R0
22 // memequal(a, b unsafe.Pointer, size uintptr) bool
23 TEXT runtime·memequal<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-25
24 // short path to handle 0-byte case
25 CBZ R2, equal
26 // short path to handle equal pointers
27 CMP R0, R1
28 BEQ equal
29 CMP $1, R2
30 // handle 1-byte special case for better performance
31 BEQ one
32 CMP $16, R2
33 // handle specially if length < 16
34 BLO tail
35 CMP $33, R2
36 BHS large
37 pairwise_16_32:
38 // use pairwise loads for 16 <= len <= 32
39 LDP (R0), (R16, R17)
40 LDP (R1), (R24, R26)
41 CMP R16, R24
42 CCMP EQ, R17, R26, $0
43 BNE not_equal
44 SUB $16, R2, R16
45 CBZ R16, equal
46 ADD R0, R16, R24
47 ADD R1, R16, R25
48 LDP (R24), (R16, R17)
49 LDP (R25), (R24, R26)
50 CMP R16, R24
51 CCMP EQ, R17, R26, $0
52 CSET EQ, R0
53 RET
54 PCALIGN $16
55 tail:
56 // special compare of tail with length < 16
57 TBZ $3, R2, lt_8
58 MOVD (R0), R16
59 MOVD (R1), R17
60 CMP R16, R17
61 BNE not_equal
62 SUB $8, R2, R26 // offset of the last 8 bytes
63 MOVD (R0)(R26), R16
64 MOVD (R1)(R26), R17
65 CMP R16, R17
66 CSET EQ, R0
67 RET
68 PCALIGN $16
69 lt_8:
70 TBZ $2, R2, lt_4
71 MOVWU (R0), R16
72 MOVWU (R1), R17
73 CMP R16, R17
74 BNE not_equal
75 SUB $4, R2, R26 // offset of the last 4 bytes
76 MOVWU (R0)(R26), R16
77 MOVWU (R1)(R26), R17
78 CMP R16, R17
79 CSET EQ, R0
80 RET
81 PCALIGN $16
82 lt_4:
83 TBZ $1, R2, lt_2
84 MOVHU.P 2(R0), R16
85 MOVHU.P 2(R1), R17
86 CMP R16, R17
87 BNE not_equal
88 lt_2:
89 TBZ $0, R2, equal
90 one:
91 MOVBU (R0), R16
92 MOVBU (R1), R17
93 CMP R16, R17
94 BNE not_equal
95 equal:
96 MOVD $1, R0
97 RET
98 not_equal:
99 MOVB ZR, R0
100 RET
101 large:
102 BIC $0x3f, R2, R26
103 CBZ R26, remainder_33_64
104 // work with 64-byte chunks
105 ADD R0, R26 // end of chunks
106 chunk64_loop:
107 VLD1.P (R0), [V21.D2, V22.D2, V23.D2, V24.D2]
108 VLD1.P (R1), [V25.D2, V26.D2, V27.D2, V28.D2]
109 VCMEQ V21.D2, V25.D2, V21.D2
110 VCMEQ V22.D2, V26.D2, V22.D2
111 VCMEQ V23.D2, V27.D2, V23.D2
112 VCMEQ V24.D2, V28.D2, V24.D2
113 VAND V21.B16, V22.B16, V21.B16
114 VAND V23.B16, V24.B16, V23.B16
115 VAND V21.B16, V23.B16, V21.B16
116 CMP R0, R26
117 VMOV V21.D[0], R16
118 VMOV V21.D[1], R17
119 CBZ R16, not_equal
120 CBZ R17, not_equal
121 BNE chunk64_loop
122 AND $0x3f, R2, R2
123 CBZ R2, equal
124 CMP $16, R2
125 BLO tail
126 CMP $33, R2
127 BLO pairwise_16_32
128 remainder_33_64:
129 // 33 <= len < 64
130 VLD1 (R0), [V21.D2, V22.D2]
131 VLD1 (R1), [V23.D2, V24.D2]
132 SUB $32, R2, R26
133 ADD R0, R26, R24
134 ADD R1, R26, R25
135 VEOR V23.B16, V21.B16, V21.B16
136 VEOR V24.B16, V22.B16, V22.B16
137 VORR V22.B16, V21.B16, V21.B16
138 VMOV V21.D[0], R16
139 VMOV V21.D[1], R17
140 ORR R17, R16, R16
141 CBNZ R16, not_equal
142 VLD1 (R24), [V21.D2, V22.D2]
143 VLD1 (R25), [V23.D2, V24.D2]
144 VEOR V23.B16, V21.B16, V21.B16
145 VEOR V24.B16, V22.B16, V22.B16
146 VORR V22.B16, V21.B16, V21.B16
147 VMOV V21.D[0], R16
148 VMOV V21.D[1], R17
149 ORR R17, R16, R16
150 CBNZ R16, not_equal
151 B equal
152
View as plain text