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
33src1 .req x0
34src2 .req x1
35limit .req x2
36result .req x0
37
38
39data1 .req x3
40data1w .req w3
41data2 .req x4
42data2w .req w4
43has_nul .req x5
44diff .req x6
45syndrome .req x7
46tmp1 .req x8
47tmp2 .req x9
48tmp3 .req x10
49zeroones .req x11
50pos .req x12
51limit_wd .req x13
52mask .req x14
53endloop .req x15
54
55WEAK(strncmp)
56 cbz limit, .Lret0
57 eor tmp1, src1, src2
58 mov zeroones,
59 tst tmp1,
60 b.ne .Lmisaligned8
61 ands tmp1, src1,
62 b.ne .Lmutual_align
63
64
65
66
67
68 sub limit_wd, limit,
69 lsr limit_wd, limit_wd,
70
71
72
73
74
75
76.Lloop_aligned:
77 ldr data1, [src1],
78 ldr data2, [src2],
79.Lstart_realigned:
80 subs limit_wd, limit_wd,
81 sub tmp1, data1, zeroones
82 orr tmp2, data1,
83 eor diff, data1, data2
84 csinv endloop, diff, xzr, pl
85 bics has_nul, tmp1, tmp2
86 ccmp endloop,
87 b.eq .Lloop_aligned
88
89
90 tbz limit_wd,
91
92
93 ands limit, limit,
94 b.eq .Lnot_limit
95
96 lsl limit, limit,
97 mov mask,
98CPU_BE( lsr mask, mask, limit )
99CPU_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,
119 bic src2, src2,
120 ldr data1, [src1],
121 neg tmp3, tmp1, lsl
122 ldr data2, [src2],
123 mov tmp2,
124 sub limit_wd, limit,
125
126CPU_BE( lsl tmp2, tmp2, tmp3 )
127
128CPU_LE( lsr tmp2, tmp2, tmp3 )
129
130 and tmp3, limit_wd,
131 lsr limit_wd, limit_wd,
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
138 b .Lstart_realigned
139
140
141.Lmisaligned8:
142 cmp limit,
143 b.lo .Ltiny8proc
144
145
146
147 and tmp1, src1,
148 neg tmp1, tmp1
149 add tmp1, tmp1,
150 and tmp2, src2,
151 neg tmp2, tmp2
152 add tmp2, tmp2,
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],
161 ldrb data2w, [src2],
162 subs pos, pos,
163 ccmp data1w,
164 ccmp data1w, data2w,
165 b.eq .Ltinycmp
166 cbnz pos, 1f
167 cmp data1w,
168 ccmp data1w, data2w,
169 b.eq .Lstart_align
1701:
171 sub result, data1, data2
172 ret
173
174.Lstart_align:
175 lsr limit_wd, limit,
176 cbz limit_wd, .Lremain8
177
178 ands xzr, src1,
179 b.eq .Lrecal_offset
180 add src1, src1, tmp3
181 add src2, src2, tmp3
182 ldr data1, [src1],
183 ldr data2, [src2],
184
185 sub limit, limit, tmp3
186 lsr limit_wd, limit,
187 subs limit_wd, limit_wd,
188
189 sub tmp1, data1, zeroones
190 orr tmp2, data1,
191 eor diff, data1, data2
192 csinv endloop, diff, xzr, ne
193 bics has_nul, tmp1, tmp2
194 ccmp endloop,
195 b.ne .Lunequal_proc
196
197 and tmp3, tmp3,
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,
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],
221 ldr data2, [src2],
222 subs limit_wd, limit_wd,
223 sub tmp1, data1, zeroones
224 orr tmp2, data1,
225 eor diff, data1, data2
226 csinv endloop, diff, xzr, ne
227 bics has_nul, tmp1, tmp2
228 ccmp endloop,
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
239CPU_LE( rev syndrome, syndrome )
240CPU_LE( rev data1, data1 )
241CPU_LE( rev data2, data2 )
242
243
244
245
246
247
248
249
250CPU_BE( cbnz has_nul, 1f )
251CPU_BE( cmp data1, data2 )
252CPU_BE( cset result, ne )
253CPU_BE( cneg result, result, lo )
254CPU_BE( ret )
255CPU_BE( 1: )
256
257CPU_BE( rev tmp3, data1 )
258CPU_BE( sub tmp1, tmp3, zeroones )
259CPU_BE( orr tmp2, tmp3,
260CPU_BE( bic has_nul, tmp1, tmp2 )
261CPU_BE( rev has_nul, has_nul )
262CPU_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,
277 sub result, data1, data2, lsr
278 ret
279
280.Lremain8:
281
282 ands limit, limit,
283 b.eq .Lret0
284.Ltiny8proc:
285 ldrb data1w, [src1],
286 ldrb data2w, [src2],
287 subs limit, limit,
288
289 ccmp data1w,
290 ccmp data1w, data2w,
291 b.eq .Ltiny8proc
292 sub result, data1, data2
293 ret
294
295.Lret0:
296 mov result,
297 ret
298ENDPIPROC(strncmp)
299EXPORT_SYMBOL_NOKASAN(strncmp)
300