1 /* strchr (str, ch) -- Return pointer to first occurrence of CH in STR.
3 Copyright (C) 1998-2021 Free Software Foundation, Inc.
4 This file is part of the GNU C Library.
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, see
18 <https://www.gnu.org/licenses/>. */
25 .register %g2, #scratch
26 .register %g3, #scratch
27 .register %g6, #scratch
30 /* Normally, this uses
31 ((xword - 0x0101010101010101) & 0x8080808080808080) test
32 to find out if any byte in xword could be zero. This is fast, but
33 also gives false alarm for any byte in range 0x81-0xff. It does
34 not matter for correctness, as if this test tells us there could
35 be some zero byte, we check it byte by byte, but if bytes with
36 high bits set are common in the strings, then this will give poor
37 performance. You can #define EIGHTBIT_NOT_RARE and the algorithm
38 will use one tick slower, but more precise test
39 ((xword - 0x0101010101010101) & (~xword) & 0x8080808080808080),
40 which does not give any false alarms (but if some bits are set,
41 one cannot assume from it which bytes are zero and which are not).
42 It is yet to be measured, what is the correct default for glibc
43 in these days for an average user.
49 andcc %o1, 0xff, %o1 /* IEU1 Group */
50 be,pn %icc, 17f /* CTI */
51 sllx %o1, 8, %g3 /* IEU0 Group */
52 sethi %hi(0x01010101), %g1 /* IEU1 */
54 or %g3, %o1, %g3 /* IEU0 Group */
55 ldub [%o0], %o3 /* Load */
56 sllx %g3, 16, %g5 /* IEU0 Group */
57 or %g1, %lo(0x01010101), %g1 /* IEU1 */
59 sllx %g1, 32, %g2 /* IEU0 Group */
60 brz,pn %o3, 5f /* CTI+IEU1 */
61 orcc %g3, %g5, %g3 /* IEU1 Group */
62 sllx %g3, 32, %g5 /* IEU0 */
64 cmp %o3, %o1 /* IEU1 Group */
65 be,pn %xcc, 14f /* CTI */
66 or %g1, %g2, %g1 /* IEU0 */
67 andcc %o0, 7, %g0 /* IEU1 Group */
69 bne,a,pn %icc, 15f /* CTI */
70 add %o0, 1, %o0 /* IEU0 */
71 ldx [%o0], %o3 /* Load Group */
72 1: sllx %g1, 7, %g2 /* IEU0 */
74 or %g3, %g5, %g3 /* IEU1 */
75 add %o0, 8, %o0 /* IEU0 Group */
76 xor %o3, %g3, %o4 /* IEU1 */
77 /* %g1 = 0101010101010101 *
78 * %g2 = 8080088080808080 *
79 * %g3 = c c c c c c c c *
81 * %o4 = value XOR c */
82 2: sub %o3, %g1, %o2 /* IEU0 Group */
84 sub %o4, %g1, %o5 /* IEU1 */
85 #ifdef EIGHTBIT_NOT_RARE
86 andn %o2, %o3, %g6 /* IEU0 Group */
87 andn %o5, %o4, %o5 /* IEU1 */
88 ldxa [%o0] ASI_PNF, %o3 /* Load */
89 or %o5, %g6, %o5 /* IEU0 Group */
91 ldxa [%o0] ASI_PNF, %o3 /* Load */
92 or %o5, %o2, %o5 /* IEU0 Group */
94 add %o0, 8, %o0 /* IEU1 */
96 andcc %o5, %g2, %g0 /* IEU1 Group */
97 be,a,pt %xcc, 2b /* CTI */
98 xor %o3, %g3, %o4 /* IEU0 */
99 srlx %o5, 32, %g5 /* IEU0 Group */
101 add %o2, %g1, %o2 /* IEU1 */
102 3: andcc %g5, %g2, %g0 /* IEU1 Group */
103 be,pn %xcc, 4f /* CTI */
104 srlx %o2, 56, %g5 /* IEU0 */
106 andcc %g5, 0xff, %g0 /* IEU1 Group */
107 be,pn %icc, 5f /* CTI */
108 srlx %o4, 56, %g5 /* IEU0 */
109 andcc %g5, 0xff, %g0 /* IEU1 Group */
111 be,pn %icc, 6f /* CTI */
112 srlx %o2, 48, %g5 /* IEU0 */
113 andcc %g5, 0xff, %g0 /* IEU1 Group */
114 be,pn %icc, 5f /* CTI */
116 srlx %o4, 48, %g5 /* IEU0 */
117 andcc %g5, 0xff, %g0 /* IEU1 Group */
118 be,pn %icc, 7f /* CTI */
119 srlx %o2, 40, %g5 /* IEU0 */
121 andcc %g5, 0xff, %g0 /* IEU1 Group */
122 be,pn %icc, 5f /* CTI */
123 srlx %o4, 40, %g5 /* IEU0 */
124 andcc %g5, 0xff, %g0 /* IEU1 Group */
126 be,pn %icc, 8f /* CTI */
127 srlx %o2, 32, %g5 /* IEU0 */
128 andcc %g5, 0xff, %g0 /* IEU1 Group */
129 be,pn %icc, 5f /* CTI */
131 srlx %o4, 32, %g5 /* IEU0 */
132 andcc %g5, 0xff, %g0 /* IEU1 Group */
133 be,pn %icc, 9f /* CTI */
134 4: srlx %o2, 24, %g5 /* IEU0 */
136 andcc %g5, 0xff, %g0 /* IEU1 Group */
137 be,pn %icc, 5f /* CTI */
138 srlx %o4, 24, %g5 /* IEU0 */
139 andcc %g5, 0xff, %g0 /* IEU1 Group */
141 be,pn %icc, 10f /* CTI */
142 srlx %o2, 16, %g5 /* IEU0 */
143 andcc %g5, 0xff, %g0 /* IEU1 Group */
144 be,pn %icc, 5f /* CTI */
146 srlx %o4, 16, %g5 /* IEU0 */
147 andcc %g5, 0xff, %g0 /* IEU1 Group */
148 be,pn %icc, 11f /* CTI */
149 srlx %o2, 8, %g5 /* IEU0 */
151 andcc %g5, 0xff, %g0 /* IEU1 Group */
152 be,pn %icc, 5f /* CTI */
153 srlx %o4, 8, %g5 /* IEU0 */
154 andcc %g5, 0xff, %g0 /* IEU1 Group */
156 be,pn %icc, 12f /* CTI */
157 andcc %o2, 0xff, %g0 /* IEU1 Group */
158 be,pn %icc, 5f /* CTI */
159 sub %o3, %g1, %o2 /* IEU0 */
161 andcc %o4, 0xff, %g0 /* IEU1 Group */
162 be,pn %icc, 13f /* CTI */
163 xor %o3, %g3, %o4 /* IEU0 */
164 ldxa [%o0] ASI_PNF, %o3 /* Load Group */
166 sub %o4, %g1, %o5 /* IEU0 */
167 or %o5, %o2, %o5 /* IEU1 */
168 add %o0, 8, %o0 /* IEU0 Group */
169 andcc %o5, %g2, %g0 /* IEU1 */
171 be,a,pt %xcc, 2b /* CTI */
172 xor %o3, %g3, %o4 /* IEU0 Group */
173 srlx %o5, 32, %g5 /* IEU0 Group */
174 ba,pt %xcc, 3b /* CTI */
176 add %o2, %g1, %o2 /* IEU1 */
179 5: retl /* CTI+IEU1 Group */
181 6: retl /* CTI+IEU1 Group */
182 add %o0, -16, %o0 /* IEU0 */
184 7: retl /* CTI+IEU1 Group */
185 add %o0, -15, %o0 /* IEU0 */
186 8: retl /* CTI+IEU1 Group */
187 add %o0, -14, %o0 /* IEU0 */
189 9: retl /* CTI+IEU1 Group */
190 add %o0, -13, %o0 /* IEU0 */
191 10: retl /* CTI+IEU1 Group */
192 add %o0, -12, %o0 /* IEU0 */
194 11: retl /* CTI+IEU1 Group */
195 add %o0, -11, %o0 /* IEU0 */
196 12: retl /* CTI+IEU1 Group */
197 add %o0, -10, %o0 /* IEU0 */
199 13: retl /* CTI+IEU1 Group */
200 add %o0, -9, %o0 /* IEU0 */
201 14: retl /* CTI+IEU1 Group */
205 15: ldub [%o0], %o3 /* Load Group */
206 16: andcc %o0, 7, %g0 /* IEU1 */
207 be,a,pn %icc, 1b /* CTI */
208 ldx [%o0], %o3 /* Load Group */
210 andcc %o3, 0xff, %g0 /* IEU1 Group */
211 be,pn %icc, 5b /* CTI */
212 add %o0, 1, %o0 /* IEU0 */
213 cmp %o3, %o1 /* IEU1 Group */
215 bne,a,pn %icc, 16b /* CTI */
216 ldub [%o0], %o3 /* Load */
217 retl /* CTI+IEU1 Group */
218 add %o0, -1, %o0 /* IEU0 */
220 /* strchr (str, 0) */
224 17: sethi %hi(0x01010101), %g1 /* IEU0 Group */
225 ldub [%o0], %o3 /* Load */
226 or %g1, %lo(0x01010101), %g1 /* IEU0 Group */
227 sllx %g1, 32, %g2 /* IEU0 Group */
229 andcc %o0, 7, %g0 /* IEU1 */
230 or %g1, %g2, %g1 /* IEU0 Group */
231 bne,pn %icc, 32f /* CTI */
232 sllx %g1, 7, %g2 /* IEU0 Group */
234 brz,pn %o3, 30f /* CTI+IEU1 */
235 ldx [%o0], %o3 /* Load */
236 18: add %o0, 8, %o0 /* IEU0 Group */
237 19: sub %o3, %g1, %o2 /* IEU0 Group */
239 #ifdef EIGHTBIT_NOT_RARE
240 andn %o2, %o3, %g6 /* IEU0 Group */
241 ldxa [%o0] ASI_PNF, %o3 /* Load */
242 andcc %g6, %g2, %g0 /* IEU1 Group */
244 ldxa [%o0] ASI_PNF, %o3 /* Load */
245 andcc %o2, %g2, %g0 /* IEU1 Group */
247 be,pt %xcc, 19b /* CTI */
248 add %o0, 8, %o0 /* IEU0 */
250 addcc %o2, %g1, %g3 /* IEU1 Group */
251 srlx %o2, 32, %o2 /* IEU0 */
252 20: andcc %o2, %g2, %g0 /* IEU1 Group */
253 be,pn %xcc, 21f /* CTI */
255 srlx %g3, 56, %o2 /* IEU0 */
256 andcc %o2, 0xff, %g0 /* IEU1 Group */
257 be,pn %icc, 29f /* CTI */
258 srlx %g3, 48, %o2 /* IEU0 */
260 andcc %o2, 0xff, %g0 /* IEU1 Group */
261 be,pn %icc, 28f /* CTI */
262 srlx %g3, 40, %o2 /* IEU0 */
263 andcc %o2, 0xff, %g0 /* IEU1 Group */
265 be,pn %icc, 27f /* CTI */
266 srlx %g3, 32, %o2 /* IEU0 */
267 andcc %o2, 0xff, %g0 /* IEU1 Group */
268 be,pn %icc, 26f /* CTI */
270 21: srlx %g3, 24, %o2 /* IEU0 */
271 andcc %o2, 0xff, %g0 /* IEU1 Group */
272 be,pn %icc, 25f /* CTI */
273 srlx %g3, 16, %o2 /* IEU0 */
275 andcc %o2, 0xff, %g0 /* IEU1 Group */
276 be,pn %icc, 24f /* CTI */
277 srlx %g3, 8, %o2 /* IEU0 */
278 andcc %o2, 0xff, %g0 /* IEU1 Group */
280 be,pn %icc, 23f /* CTI */
281 sub %o3, %g1, %o2 /* IEU0 */
282 andcc %g3, 0xff, %g0 /* IEU1 Group */
283 be,pn %icc, 22f /* CTI */
285 ldxa [%o0] ASI_PNF, %o3 /* Load */
286 andcc %o2, %g2, %g0 /* IEU1 Group */
287 be,pt %xcc, 19b /* CTI */
288 add %o0, 8, %o0 /* IEU0 */
290 addcc %o2, %g1, %g3 /* IEU1 Group */
291 ba,pt %xcc, 20b /* CTI */
292 srlx %o2, 32, %o2 /* IEU0 */
295 22: retl /* CTI+IEU1 Group */
296 add %o0, -9, %o0 /* IEU0 */
297 23: retl /* CTI+IEU1 Group */
298 add %o0, -10, %o0 /* IEU0 */
300 24: retl /* CTI+IEU1 Group */
301 add %o0, -11, %o0 /* IEU0 */
302 25: retl /* CTI+IEU1 Group */
303 add %o0, -12, %o0 /* IEU0 */
305 26: retl /* CTI+IEU1 Group */
306 add %o0, -13, %o0 /* IEU0 */
307 27: retl /* CTI+IEU1 Group */
308 add %o0, -14, %o0 /* IEU0 */
310 28: retl /* CTI+IEU1 Group */
311 add %o0, -15, %o0 /* IEU0 */
312 29: retl /* CTI+IEU1 Group */
313 add %o0, -16, %o0 /* IEU0 */
315 30: retl /* CTI+IEU1 Group */
319 32: andcc %o0, 7, %g0 /* IEU1 Group */
320 be,a,pn %icc, 18b /* CTI */
321 ldx [%o0], %o3 /* Load */
322 add %o0, 1, %o0 /* IEU0 Group */
324 brnz,a,pt %o3, 32b /* CTI+IEU1 */
325 lduba [%o0] ASI_PNF, %o3 /* Load */
326 retl /* CTI+IEU1 Group */
327 add %o0, -1, %o0 /* IEU0 */
332 andcc %o1, 0xff, %o1 /* IEU1 Group */
333 be,pn %icc, 17b /* CTI */
335 andcc %o0, 7, %g0 /* IEU1 Group */
337 bne,pn %icc, 13f /* CTI */
338 sllx %o1, 8, %g3 /* IEU0 */
339 ldx [%o0], %o3 /* Load Group */
340 1: sethi %hi(0x01010101), %g1 /* IEU0 */
342 or %g3, %o1, %g3 /* IEU1 */
343 sllx %g3, 16, %g5 /* IEU0 Group */
344 or %g1, %lo(0x01010101), %g1 /* IEU1 */
345 sllx %g1, 32, %g2 /* IEU0 Group */
347 or %g3, %g5, %g3 /* IEU1 */
348 sllx %g3, 32, %g5 /* IEU0 Group */
349 or %g1, %g2, %g1 /* IEU1 */
350 sllx %g1, 7, %g2 /* IEU0 Group */
352 or %g3, %g5, %g3 /* IEU1 */
353 add %o0, 8, %o0 /* IEU0 Group */
354 xor %o3, %g3, %o4 /* IEU1 */
355 /* %g1 = 0101010101010101 *
356 * %g2 = 8080088080808080 *
357 * %g3 = c c c c c c c c *
359 * %o4 = value XOR c */
360 2: sub %o3, %g1, %o2 /* IEU0 Group */
362 3: sub %o4, %g1, %o5 /* IEU1 */
363 #ifdef EIGHTBIT_NOT_RARE
364 andn %o2, %o3, %g6 /* IEU0 Group */
365 andn %o5, %o4, %o5 /* IEU1 */
366 ldxa [%o0] ASI_PNF, %o3 /* Load */
368 or %o5, %g6, %o5 /* IEU0 Group */
370 ldxa [%o0] ASI_PNF, %o3 /* Load */
372 or %o5, %o2, %o5 /* IEU0 Group */
374 add %o0, 8, %o0 /* IEU1 */
375 andcc %o5, %g2, %g0 /* IEU1 Group */
376 be,a,pt %xcc, 2b /* CTI */
378 xor %o3, %g3, %o4 /* IEU0 */
379 srlx %o5, 32, %g5 /* IEU0 Group */
380 add %o2, %g1, %o2 /* IEU1 */
381 andcc %g5, %g2, %g0 /* IEU1 Group */
383 be,pn %xcc, 7f /* CTI */
384 srlx %o2, 56, %g5 /* IEU0 */
385 andcc %g5, 0xff, %g0 /* IEU1 Group */
386 be,pn %icc, 12f /* CTI */
388 srlx %o4, 56, %g5 /* IEU0 */
389 andcc %g5, 0xff, %g0 /* IEU1 Group */
390 srlx %o2, 48, %g5 /* IEU0 */
391 be,a,pn %icc, 4f /* CTI */
393 add %o0, -16, %g4 /* IEU0 Group */
394 4: andcc %g5, 0xff, %g0 /* IEU1 Group */
395 be,pn %icc, 12f /* CTI */
396 srlx %o4, 48, %g5 /* IEU0 */
398 andcc %g5, 0xff, %g0 /* IEU1 Group */
399 srlx %o2, 40, %g5 /* IEU0 */
400 be,a,pn %icc, 5f /* CTI */
401 add %o0, -15, %g4 /* IEU0 Group */
403 5: andcc %g5, 0xff, %g0 /* IEU1 Group */
404 be,pn %icc, 12f /* CTI */
405 srlx %o4, 40, %g5 /* IEU0 */
406 andcc %g5, 0xff, %g0 /* IEU1 Group */
408 srlx %o2, 32, %g5 /* IEU0 */
409 be,a,pn %icc, 6f /* CTI */
410 add %o0, -14, %g4 /* IEU0 Group */
411 6: andcc %g5, 0xff, %g0 /* IEU1 Group */
413 be,pn %icc, 12f /* CTI */
414 srlx %o4, 32, %g5 /* IEU0 */
415 andcc %g5, 0xff, %g0 /* IEU1 Group */
416 be,a,pn %icc, 7f /* CTI */
418 add %o0, -13, %g4 /* IEU0 */
419 7: srlx %o2, 24, %g5 /* IEU0 */
420 andcc %g5, 0xff, %g0 /* IEU1 Group */
421 be,pn %icc, 12f /* CTI */
423 srlx %o4, 24, %g5 /* IEU0 */
424 andcc %g5, 0xff, %g0 /* IEU1 Group */
425 srlx %o2, 16, %g5 /* IEU0 */
426 be,a,pn %icc, 8f /* CTI */
428 add %o0, -12, %g4 /* IEU0 Group */
429 8: andcc %g5, 0xff, %g0 /* IEU1 Group */
430 be,pn %icc, 12f /* CTI */
431 srlx %o4, 16, %g5 /* IEU0 */
433 andcc %g5, 0xff, %g0 /* IEU1 Group */
434 srlx %o2, 8, %g5 /* IEU0 */
435 be,a,pn %icc, 9f /* CTI */
436 add %o0, -11, %g4 /* IEU0 Group */
438 9: andcc %g5, 0xff, %g0 /* IEU1 Group */
439 be,pn %icc, 12f /* CTI */
440 srlx %o4, 8, %g5 /* IEU0 */
441 andcc %g5, 0xff, %g0 /* IEU1 Group */
443 be,a,pn %icc, 10f /* CTI */
444 add %o0, -10, %g4 /* IEU0 */
445 10: andcc %o2, 0xff, %g0 /* IEU1 Group */
446 be,pn %icc, 12f /* CTI */
448 sub %o3, %g1, %o2 /* IEU0 */
449 andcc %o4, 0xff, %g0 /* IEU1 Group */
450 be,a,pn %icc, 11f /* CTI */
451 add %o0, -9, %g4 /* IEU0 */
453 11: ba,pt %xcc, 3b /* CTI Group */
454 xor %o3, %g3, %o4 /* IEU0 Group */
455 12: retl /* CTI+IEU1 Group */
456 mov %g4, %o0 /* IEU0 */
459 13: ldub [%o0], %o3 /* Load Group */
460 add %o0, 1, %o0 /* IEU0 */
461 14: andcc %o3, 0xff, %g0 /* IEU1 Group */
462 be,pn %icc, 12b /* CTI */
464 cmp %o3, %o1 /* IEU1 Group */
465 ldub [%o0], %o3 /* Load */
466 be,a,pn %icc, 15f /* CTI */
467 add %o0, -1, %g4 /* IEU0 Group */
469 15: andcc %o0, 7, %g0 /* IEU1 Group */
470 bne,a,pt %icc, 14b /* CTI */
471 add %o0, 1, %o0 /* IEU0 */
472 ba,pt %xcc, 1b /* CTI Group */
474 ldx [%o0], %o3 /* Load */
477 weak_alias (strchr, index)
478 weak_alias (strrchr, rindex)
479 libc_hidden_builtin_def (strchr)
480 libc_hidden_builtin_def (strrchr)