1
2
3
4
5
6
7
8
9
10
11
12
13 #include <linux/linkage.h>
14 #include <asm/assembler.h>
15
16
17
18
19
20
21
22
23
24
25
26
27
28 #define REP8_01 0x0101010101010101
29 #define REP8_7f 0x7f7f7f7f7f7f7f7f
30 #define REP8_80 0x8080808080808080
31
32
33 src1 .req x0
34 src2 .req x1
35 limit .req x2
36 result .req x0
37
38
39 data1 .req x3
40 data1w .req w3
41 data2 .req x4
42 data2w .req w4
43 has_nul .req x5
44 diff .req x6
45 syndrome .req x7
46 tmp1 .req x8
47 tmp2 .req x9
48 tmp3 .req x10
49 zeroones .req x11
50 pos .req x12
51 limit_wd .req x13
52 mask .req x14
53 endloop .req x15
54
55 WEAK(strncmp)
56 cbz limit, .Lret0
57 eor tmp1, src1, src2
58 mov zeroones, #REP8_01
59 tst tmp1, #7
60 b.ne .Lmisaligned8
61 ands tmp1, src1, #7
62 b.ne .Lmutual_align
63
64
65
66
67
68 sub limit_wd, limit, #1
69 lsr limit_wd, limit_wd, #3
70
71
72
73
74
75
76 .Lloop_aligned:
77 ldr data1, [src1], #8
78 ldr data2, [src2], #8
79 .Lstart_realigned:
80 subs limit_wd, limit_wd, #1
81 sub tmp1, data1, zeroones
82 orr tmp2, data1, #REP8_7f
83 eor diff, data1, data2
84 csinv endloop, diff, xzr, pl
85 bics has_nul, tmp1, tmp2
86 ccmp endloop, #0, #0, eq
87 b.eq .Lloop_aligned
88
89
90 tbz limit_wd, #63, .Lnot_limit
91
92
93 ands limit, limit, #7
94 b.eq .Lnot_limit
95
96 lsl limit, limit, #3
97 mov mask, #~0
98 CPU_BE( lsr mask, mask, limit )
99 CPU_LE( lsl mask, mask, limit )
100 bic data1, data1, mask
101 bic data2, data2, mask
102
103
104 orr has_nul, has_nul, mask
105
106 .Lnot_limit:
107 orr syndrome, diff, has_nul
108 b .Lcal_cmpresult
109
110 .Lmutual_align:
111
112
113
114
115
116
117
118 bic src1, src1, #7
119 bic src2, src2, #7
120 ldr data1, [src1], #8
121 neg tmp3, tmp1, lsl #3
122 ldr data2, [src2], #8
123 mov tmp2, #~0
124 sub limit_wd, limit, #1
125
126 CPU_BE( lsl tmp2, tmp2, tmp3 )
127
128 CPU_LE( lsr tmp2, tmp2, tmp3 )
129
130 and tmp3, limit_wd, #7
131 lsr limit_wd, limit_wd, #3
132
133 add limit, limit, tmp1
134 add tmp3, tmp3, tmp1
135 orr data1, data1, tmp2
136 orr data2, data2, tmp2
137 add limit_wd, limit_wd, tmp3, lsr #3
138 b .Lstart_realigned
139
140
141 .Lmisaligned8:
142 cmp limit, #8
143 b.lo .Ltiny8proc
144
145
146
147 and tmp1, src1, #7
148 neg tmp1, tmp1
149 add tmp1, tmp1, #8
150 and tmp2, src2, #7
151 neg tmp2, tmp2
152 add tmp2, tmp2, #8
153 subs tmp3, tmp1, tmp2
154 csel pos, tmp1, tmp2, hi
155
156
157
158 sub limit, limit, pos
159 .Ltinycmp:
160 ldrb data1w, [src1], #1
161 ldrb data2w, [src2], #1
162 subs pos, pos, #1
163 ccmp data1w, #1, #0, ne
164 ccmp data1w, data2w, #0, cs
165 b.eq .Ltinycmp
166 cbnz pos, 1f
167 cmp data1w, #1
168 ccmp data1w, data2w, #0, cs
169 b.eq .Lstart_align
170 1:
171 sub result, data1, data2
172 ret
173
174 .Lstart_align:
175 lsr limit_wd, limit, #3
176 cbz limit_wd, .Lremain8
177
178 ands xzr, src1, #7
179 b.eq .Lrecal_offset
180 add src1, src1, tmp3
181 add src2, src2, tmp3
182 ldr data1, [src1], #8
183 ldr data2, [src2], #8
184
185 sub limit, limit, tmp3
186 lsr limit_wd, limit, #3
187 subs limit_wd, limit_wd, #1
188
189 sub tmp1, data1, zeroones
190 orr tmp2, data1, #REP8_7f
191 eor diff, data1, data2
192 csinv endloop, diff, xzr, ne
193 bics has_nul, tmp1, tmp2
194 ccmp endloop, #0, #0, eq
195 b.ne .Lunequal_proc
196
197 and tmp3, tmp3, #7
198 .Lrecal_offset:
199 neg pos, tmp3
200 .Lloopcmp_proc:
201
202
203
204
205
206
207
208
209
210 ldr data1, [src1,pos]
211 ldr data2, [src2,pos]
212 sub tmp1, data1, zeroones
213 orr tmp2, data1, #REP8_7f
214 bics has_nul, tmp1, tmp2
215 eor diff, data1, data2
216 csinv endloop, diff, xzr, eq
217 cbnz endloop, .Lunequal_proc
218
219
220 ldr data1, [src1], #8
221 ldr data2, [src2], #8
222 subs limit_wd, limit_wd, #1
223 sub tmp1, data1, zeroones
224 orr tmp2, data1, #REP8_7f
225 eor diff, data1, data2
226 csinv endloop, diff, xzr, ne
227 bics has_nul, tmp1, tmp2
228 ccmp endloop, #0, #0, eq
229 b.eq .Lloopcmp_proc
230
231 .Lunequal_proc:
232 orr syndrome, diff, has_nul
233 cbz syndrome, .Lremain8
234 .Lcal_cmpresult:
235
236
237
238
239 CPU_LE( rev syndrome, syndrome )
240 CPU_LE( rev data1, data1 )
241 CPU_LE( rev data2, data2 )
242
243
244
245
246
247
248
249
250 CPU_BE( cbnz has_nul, 1f )
251 CPU_BE( cmp data1, data2 )
252 CPU_BE( cset result, ne )
253 CPU_BE( cneg result, result, lo )
254 CPU_BE( ret )
255 CPU_BE( 1: )
256
257 CPU_BE( rev tmp3, data1 )
258 CPU_BE( sub tmp1, tmp3, zeroones )
259 CPU_BE( orr tmp2, tmp3, #REP8_7f )
260 CPU_BE( bic has_nul, tmp1, tmp2 )
261 CPU_BE( rev has_nul, has_nul )
262 CPU_BE( orr syndrome, diff, has_nul )
263
264
265
266
267
268
269 clz pos, syndrome
270 lsl data1, data1, pos
271 lsl data2, data2, pos
272
273
274
275
276 lsr data1, data1, #56
277 sub result, data1, data2, lsr #56
278 ret
279
280 .Lremain8:
281
282 ands limit, limit, #7
283 b.eq .Lret0
284 .Ltiny8proc:
285 ldrb data1w, [src1], #1
286 ldrb data2w, [src2], #1
287 subs limit, limit, #1
288
289 ccmp data1w, #1, #0, ne
290 ccmp data1w, data2w, #0, cs
291 b.eq .Ltiny8proc
292 sub result, data1, data2
293 ret
294
295 .Lret0:
296 mov result, #0
297 ret
298 ENDPIPROC(strncmp)
299 EXPORT_SYMBOL_NOKASAN(strncmp)