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(a, b unsafe.Pointer, size uintptr) bool
9 TEXT runtime·memequal<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-25
10 #ifndef GOEXPERIMENT_regabiargs
11 MOVD size+16(FP), R2
12 #endif
13 // short path to handle 0-byte case
14 CBZ R2, equal
15 #ifndef GOEXPERIMENT_regabiargs
16 MOVD a+0(FP), R0
17 MOVD b+8(FP), R1
18 MOVD $ret+24(FP), R8
19 #endif
20 B memeqbody<>(SB)
21 equal:
22 MOVD $1, R0
23 #ifndef GOEXPERIMENT_regabiargs
24 MOVB R0, ret+24(FP)
25 #endif
26 RET
27
28 // memequal_varlen(a, b unsafe.Pointer) bool
29 TEXT runtime·memequal_varlen<ABIInternal>(SB),NOSPLIT,$0-17
30 #ifndef GOEXPERIMENT_regabiargs
31 MOVD a+0(FP), R0
32 MOVD b+8(FP), R1
33 #endif
34 CMP R0, R1
35 BEQ eq
36 MOVD 8(R26), R2 // compiler stores size at offset 8 in the closure
37 CBZ R2, eq
38 #ifndef GOEXPERIMENT_regabiargs
39 MOVD $ret+16(FP), R8
40 #endif
41 B memeqbody<>(SB)
42 eq:
43 MOVD $1, R0
44 #ifndef GOEXPERIMENT_regabiargs
45 MOVB R0, ret+16(FP)
46 #endif
47 RET
48
49 // input:
50 // R0: pointer a
51 // R1: pointer b
52 // R2: data len
53 #ifdef GOEXPERIMENT_regabiargs
54 // at return: result in R0
55 #else
56 // R8: address to put result
57 #endif
58
59 TEXT memeqbody<>(SB),NOSPLIT,$0
60 CMP $1, R2
61 // handle 1-byte special case for better performance
62 BEQ one
63 CMP $16, R2
64 // handle specially if length < 16
65 BLO tail
66 BIC $0x3f, R2, R3
67 CBZ R3, chunk16
68 // work with 64-byte chunks
69 ADD R3, R0, R6 // end of chunks
70 chunk64_loop:
71 VLD1.P (R0), [V0.D2, V1.D2, V2.D2, V3.D2]
72 VLD1.P (R1), [V4.D2, V5.D2, V6.D2, V7.D2]
73 VCMEQ V0.D2, V4.D2, V8.D2
74 VCMEQ V1.D2, V5.D2, V9.D2
75 VCMEQ V2.D2, V6.D2, V10.D2
76 VCMEQ V3.D2, V7.D2, V11.D2
77 VAND V8.B16, V9.B16, V8.B16
78 VAND V8.B16, V10.B16, V8.B16
79 VAND V8.B16, V11.B16, V8.B16
80 CMP R0, R6
81 VMOV V8.D[0], R4
82 VMOV V8.D[1], R5
83 CBZ R4, not_equal
84 CBZ R5, not_equal
85 BNE chunk64_loop
86 AND $0x3f, R2, R2
87 CBZ R2, equal
88 chunk16:
89 // work with 16-byte chunks
90 BIC $0xf, R2, R3
91 CBZ R3, tail
92 ADD R3, R0, R6 // end of chunks
93 chunk16_loop:
94 LDP.P 16(R0), (R4, R5)
95 LDP.P 16(R1), (R7, R9)
96 EOR R4, R7
97 CBNZ R7, not_equal
98 EOR R5, R9
99 CBNZ R9, not_equal
100 CMP R0, R6
101 BNE chunk16_loop
102 AND $0xf, R2, R2
103 CBZ R2, equal
104 tail:
105 // special compare of tail with length < 16
106 TBZ $3, R2, lt_8
107 MOVD (R0), R4
108 MOVD (R1), R5
109 EOR R4, R5
110 CBNZ R5, not_equal
111 SUB $8, R2, R6 // offset of the last 8 bytes
112 MOVD (R0)(R6), R4
113 MOVD (R1)(R6), R5
114 EOR R4, R5
115 CBNZ R5, not_equal
116 B equal
117 lt_8:
118 TBZ $2, R2, lt_4
119 MOVWU (R0), R4
120 MOVWU (R1), R5
121 EOR R4, R5
122 CBNZ R5, not_equal
123 SUB $4, R2, R6 // offset of the last 4 bytes
124 MOVWU (R0)(R6), R4
125 MOVWU (R1)(R6), R5
126 EOR R4, R5
127 CBNZ R5, not_equal
128 B equal
129 lt_4:
130 TBZ $1, R2, lt_2
131 MOVHU.P 2(R0), R4
132 MOVHU.P 2(R1), R5
133 CMP R4, R5
134 BNE not_equal
135 lt_2:
136 TBZ $0, R2, equal
137 one:
138 MOVBU (R0), R4
139 MOVBU (R1), R5
140 CMP R4, R5
141 BNE not_equal
142 equal:
143 MOVD $1, R0
144 #ifndef GOEXPERIMENT_regabiargs
145 MOVB R0, (R8)
146 #endif
147 RET
148 not_equal:
149 #ifdef GOEXPERIMENT_regabiargs
150 MOVB ZR, R0
151 #else
152 MOVB ZR, (R8)
153 #endif
154 RET
155
View as plain text