blob: da26d1f9c2c3fc31a7f9f50ea86f2d827039e96a [file] [log] [blame]
yuezonghe824eb0c2024-06-27 02:32:26 -07001/* strchr (str, ch) -- Return pointer to first occurrence of CH in STR.
2 For SPARC v9.
3 Copyright (C) 1998, 1999, 2003 Free Software Foundation, Inc.
4 This file is part of the GNU C Library.
5 Contributed by Jan Vondrak <jvon4518@ss1000.ms.mff.cuni.cz> and
6 Jakub Jelinek <jj@ultra.linux.cz>.
7
8 The GNU C Library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public
10 License as published by the Free Software Foundation; either
11 version 2.1 of the License, or (at your option) any later version.
12
13 The GNU C Library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public
19 License along with the GNU C Library; if not, write to the Free
20 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 02111-1307 USA. */
22
23#include <features.h>
24#include <asm/asi.h>
25#ifndef XCC
26#define XCC xcc
27#define USE_BPR
28 .register %g2, #scratch
29 .register %g3, #scratch
30 .register %g6, #scratch
31#endif
32
33 /* Normally, this uses
34 ((xword - 0x0101010101010101) & 0x8080808080808080) test
35 to find out if any byte in xword could be zero. This is fast, but
36 also gives false alarm for any byte in range 0x81-0xff. It does
37 not matter for correctness, as if this test tells us there could
38 be some zero byte, we check it byte by byte, but if bytes with
39 high bits set are common in the strings, then this will give poor
40 performance. You can #define EIGHTBIT_NOT_RARE and the algorithm
41 will use one tick slower, but more precise test
42 ((xword - 0x0101010101010101) & (~xword) & 0x8080808080808080),
43 which does not give any false alarms (but if some bits are set,
44 one cannot assume from it which bytes are zero and which are not).
45 It is yet to be measured, what is the correct default for glibc
46 in these days for an average user.
47 */
48
49 .text
50 .align 32
51ENTRY(strchr)
52 andcc %o1, 0xff, %o1 /* IEU1 Group */
53 be,pn %icc, 17f /* CTI */
54 sllx %o1, 8, %g3 /* IEU0 Group */
55 sethi %hi(0x01010101), %g1 /* IEU1 */
56
57 or %g3, %o1, %g3 /* IEU0 Group */
58 ldub [%o0], %o3 /* Load */
59 sllx %g3, 16, %g5 /* IEU0 Group */
60 or %g1, %lo(0x01010101), %g1 /* IEU1 */
61
62 sllx %g1, 32, %g2 /* IEU0 Group */
63 brz,pn %o3, 5f /* CTI+IEU1 */
64 orcc %g3, %g5, %g3 /* IEU1 Group */
65 sllx %g3, 32, %g5 /* IEU0 */
66
67 cmp %o3, %o1 /* IEU1 Group */
68 be,pn %xcc, 14f /* CTI */
69 or %g1, %g2, %g1 /* IEU0 */
70 andcc %o0, 7, %g0 /* IEU1 Group */
71
72 bne,a,pn %icc, 15f /* CTI */
73 add %o0, 1, %o0 /* IEU0 */
74 ldx [%o0], %o3 /* Load Group */
751: sllx %g1, 7, %g2 /* IEU0 */
76
77 or %g3, %g5, %g3 /* IEU1 */
78 add %o0, 8, %o0 /* IEU0 Group */
79 xor %o3, %g3, %o4 /* IEU1 */
80 /* %g1 = 0101010101010101 *
81 * %g2 = 8080088080808080 *
82 * %g3 = c c c c c c c c *
83 * %o3 = value *
84 * %o4 = value XOR c */
852: sub %o3, %g1, %o2 /* IEU0 Group */
86
87 sub %o4, %g1, %o5 /* IEU1 */
88#ifdef EIGHTBIT_NOT_RARE
89 andn %o2, %o3, %g6 /* IEU0 Group */
90 andn %o5, %o4, %o5 /* IEU1 */
91 ldxa [%o0] ASI_PNF, %o3 /* Load */
92 or %o5, %g6, %o5 /* IEU0 Group */
93#else
94 ldxa [%o0] ASI_PNF, %o3 /* Load */
95 or %o5, %o2, %o5 /* IEU0 Group */
96#endif
97 add %o0, 8, %o0 /* IEU1 */
98
99 andcc %o5, %g2, %g0 /* IEU1 Group */
100 be,a,pt %xcc, 2b /* CTI */
101 xor %o3, %g3, %o4 /* IEU0 */
102 srlx %o5, 32, %g5 /* IEU0 Group */
103
104 add %o2, %g1, %o2 /* IEU1 */
1053: andcc %g5, %g2, %g0 /* IEU1 Group */
106 be,pn %xcc, 4f /* CTI */
107 srlx %o2, 56, %g5 /* IEU0 */
108
109 andcc %g5, 0xff, %g0 /* IEU1 Group */
110 be,pn %icc, 5f /* CTI */
111 srlx %o4, 56, %g5 /* IEU0 */
112 andcc %g5, 0xff, %g0 /* IEU1 Group */
113
114 be,pn %icc, 6f /* CTI */
115 srlx %o2, 48, %g5 /* IEU0 */
116 andcc %g5, 0xff, %g0 /* IEU1 Group */
117 be,pn %icc, 5f /* CTI */
118
119 srlx %o4, 48, %g5 /* IEU0 */
120 andcc %g5, 0xff, %g0 /* IEU1 Group */
121 be,pn %icc, 7f /* CTI */
122 srlx %o2, 40, %g5 /* IEU0 */
123
124 andcc %g5, 0xff, %g0 /* IEU1 Group */
125 be,pn %icc, 5f /* CTI */
126 srlx %o4, 40, %g5 /* IEU0 */
127 andcc %g5, 0xff, %g0 /* IEU1 Group */
128
129 be,pn %icc, 8f /* CTI */
130 srlx %o2, 32, %g5 /* IEU0 */
131 andcc %g5, 0xff, %g0 /* IEU1 Group */
132 be,pn %icc, 5f /* CTI */
133
134 srlx %o4, 32, %g5 /* IEU0 */
135 andcc %g5, 0xff, %g0 /* IEU1 Group */
136 be,pn %icc, 9f /* CTI */
1374: srlx %o2, 24, %g5 /* IEU0 */
138
139 andcc %g5, 0xff, %g0 /* IEU1 Group */
140 be,pn %icc, 5f /* CTI */
141 srlx %o4, 24, %g5 /* IEU0 */
142 andcc %g5, 0xff, %g0 /* IEU1 Group */
143
144 be,pn %icc, 10f /* CTI */
145 srlx %o2, 16, %g5 /* IEU0 */
146 andcc %g5, 0xff, %g0 /* IEU1 Group */
147 be,pn %icc, 5f /* CTI */
148
149 srlx %o4, 16, %g5 /* IEU0 */
150 andcc %g5, 0xff, %g0 /* IEU1 Group */
151 be,pn %icc, 11f /* CTI */
152 srlx %o2, 8, %g5 /* IEU0 */
153
154 andcc %g5, 0xff, %g0 /* IEU1 Group */
155 be,pn %icc, 5f /* CTI */
156 srlx %o4, 8, %g5 /* IEU0 */
157 andcc %g5, 0xff, %g0 /* IEU1 Group */
158
159 be,pn %icc, 12f /* CTI */
160 andcc %o2, 0xff, %g0 /* IEU1 Group */
161 be,pn %icc, 5f /* CTI */
162 sub %o3, %g1, %o2 /* IEU0 */
163
164 andcc %o4, 0xff, %g0 /* IEU1 Group */
165 be,pn %icc, 13f /* CTI */
166 xor %o3, %g3, %o4 /* IEU0 */
167 ldxa [%o0] ASI_PNF, %o3 /* Load Group */
168
169 sub %o4, %g1, %o5 /* IEU0 */
170 or %o5, %o2, %o5 /* IEU1 */
171 add %o0, 8, %o0 /* IEU0 Group */
172 andcc %o5, %g2, %g0 /* IEU1 */
173
174 be,a,pt %xcc, 2b /* CTI */
175 xor %o3, %g3, %o4 /* IEU0 Group */
176 srlx %o5, 32, %g5 /* IEU0 Group */
177 ba,pt %xcc, 3b /* CTI */
178
179 add %o2, %g1, %o2 /* IEU1 */
180
181 .align 16
1825: retl /* CTI+IEU1 Group */
183 clr %o0 /* IEU0 */
1846: retl /* CTI+IEU1 Group */
185 add %o0, -16, %o0 /* IEU0 */
186
1877: retl /* CTI+IEU1 Group */
188 add %o0, -15, %o0 /* IEU0 */
1898: retl /* CTI+IEU1 Group */
190 add %o0, -14, %o0 /* IEU0 */
191
1929: retl /* CTI+IEU1 Group */
193 add %o0, -13, %o0 /* IEU0 */
19410: retl /* CTI+IEU1 Group */
195 add %o0, -12, %o0 /* IEU0 */
196
19711: retl /* CTI+IEU1 Group */
198 add %o0, -11, %o0 /* IEU0 */
19912: retl /* CTI+IEU1 Group */
200 add %o0, -10, %o0 /* IEU0 */
201
20213: retl /* CTI+IEU1 Group */
203 add %o0, -9, %o0 /* IEU0 */
20414: retl /* CTI+IEU1 Group */
205 nop /* IEU0 */
206
207 .align 16
20815: ldub [%o0], %o3 /* Load Group */
20916: andcc %o0, 7, %g0 /* IEU1 */
210 be,a,pn %icc, 1b /* CTI */
211 ldx [%o0], %o3 /* Load Group */
212
213 andcc %o3, 0xff, %g0 /* IEU1 Group */
214 be,pn %icc, 5b /* CTI */
215 add %o0, 1, %o0 /* IEU0 */
216 cmp %o3, %o1 /* IEU1 Group */
217
218 bne,a,pn %icc, 16b /* CTI */
219 ldub [%o0], %o3 /* Load */
220 retl /* CTI+IEU1 Group */
221 add %o0, -1, %o0 /* IEU0 */
222
223 /* strchr (str, 0) */
224 .align 32
225 nop
226 .align 16
22717: sethi %hi(0x01010101), %g1 /* IEU0 Group */
228 ldub [%o0], %o3 /* Load */
229 or %g1, %lo(0x01010101), %g1 /* IEU0 Group */
230 sllx %g1, 32, %g2 /* IEU0 Group */
231
232 andcc %o0, 7, %g0 /* IEU1 */
233 or %g1, %g2, %g1 /* IEU0 Group */
234 bne,pn %icc, 32f /* CTI */
235 sllx %g1, 7, %g2 /* IEU0 Group */
236
237 brz,pn %o3, 30f /* CTI+IEU1 */
238 ldx [%o0], %o3 /* Load */
23918: add %o0, 8, %o0 /* IEU0 Group */
24019: sub %o3, %g1, %o2 /* IEU0 Group */
241
242#ifdef EIGHTBIT_NOT_RARE
243 andn %o2, %o3, %g6 /* IEU0 Group */
244 ldxa [%o0] ASI_PNF, %o3 /* Load */
245 andcc %g6, %g2, %g0 /* IEU1 Group */
246#else
247 ldxa [%o0] ASI_PNF, %o3 /* Load */
248 andcc %o2, %g2, %g0 /* IEU1 Group */
249#endif
250 be,pt %xcc, 19b /* CTI */
251 add %o0, 8, %o0 /* IEU0 */
252
253 addcc %o2, %g1, %g3 /* IEU1 Group */
254 srlx %o2, 32, %o2 /* IEU0 */
25520: andcc %o2, %g2, %g0 /* IEU1 Group */
256 be,pn %xcc, 21f /* CTI */
257
258 srlx %g3, 56, %o2 /* IEU0 */
259 andcc %o2, 0xff, %g0 /* IEU1 Group */
260 be,pn %icc, 29f /* CTI */
261 srlx %g3, 48, %o2 /* IEU0 */
262
263 andcc %o2, 0xff, %g0 /* IEU1 Group */
264 be,pn %icc, 28f /* CTI */
265 srlx %g3, 40, %o2 /* IEU0 */
266 andcc %o2, 0xff, %g0 /* IEU1 Group */
267
268 be,pn %icc, 27f /* CTI */
269 srlx %g3, 32, %o2 /* IEU0 */
270 andcc %o2, 0xff, %g0 /* IEU1 Group */
271 be,pn %icc, 26f /* CTI */
272
27321: srlx %g3, 24, %o2 /* IEU0 */
274 andcc %o2, 0xff, %g0 /* IEU1 Group */
275 be,pn %icc, 25f /* CTI */
276 srlx %g3, 16, %o2 /* IEU0 */
277
278 andcc %o2, 0xff, %g0 /* IEU1 Group */
279 be,pn %icc, 24f /* CTI */
280 srlx %g3, 8, %o2 /* IEU0 */
281 andcc %o2, 0xff, %g0 /* IEU1 Group */
282
283 be,pn %icc, 23f /* CTI */
284 sub %o3, %g1, %o2 /* IEU0 */
285 andcc %g3, 0xff, %g0 /* IEU1 Group */
286 be,pn %icc, 22f /* CTI */
287
288 ldxa [%o0] ASI_PNF, %o3 /* Load */
289 andcc %o2, %g2, %g0 /* IEU1 Group */
290 be,pt %xcc, 19b /* CTI */
291 add %o0, 8, %o0 /* IEU0 */
292
293 addcc %o2, %g1, %g3 /* IEU1 Group */
294 ba,pt %xcc, 20b /* CTI */
295 srlx %o2, 32, %o2 /* IEU0 */
296
297 .align 16
29822: retl /* CTI+IEU1 Group */
299 add %o0, -9, %o0 /* IEU0 */
30023: retl /* CTI+IEU1 Group */
301 add %o0, -10, %o0 /* IEU0 */
302
30324: retl /* CTI+IEU1 Group */
304 add %o0, -11, %o0 /* IEU0 */
30525: retl /* CTI+IEU1 Group */
306 add %o0, -12, %o0 /* IEU0 */
307
30826: retl /* CTI+IEU1 Group */
309 add %o0, -13, %o0 /* IEU0 */
31027: retl /* CTI+IEU1 Group */
311 add %o0, -14, %o0 /* IEU0 */
312
31328: retl /* CTI+IEU1 Group */
314 add %o0, -15, %o0 /* IEU0 */
31529: retl /* CTI+IEU1 Group */
316 add %o0, -16, %o0 /* IEU0 */
317
31830: retl /* CTI+IEU1 Group */
319 nop /* IEU0 */
320
321 .align 16
32232: andcc %o0, 7, %g0 /* IEU1 Group */
323 be,a,pn %icc, 18b /* CTI */
324 ldx [%o0], %o3 /* Load */
325 add %o0, 1, %o0 /* IEU0 Group */
326
327 brnz,a,pt %o3, 32b /* CTI+IEU1 */
328 lduba [%o0] ASI_PNF, %o3 /* Load */
329 retl /* CTI+IEU1 Group */
330 add %o0, -1, %o0 /* IEU0 */
331END(strchr)
332libc_hidden_def(strchr)
333#ifdef __UCLIBC_SUSV3_LEGACY__
334strong_alias(strchr,index)
335#endif
336
337 .align 32
338ENTRY(strrchr)
339 andcc %o1, 0xff, %o1 /* IEU1 Group */
340 be,pn %icc, 17b /* CTI */
341 clr %g4 /* IEU0 */
342 andcc %o0, 7, %g0 /* IEU1 Group */
343
344 bne,pn %icc, 13f /* CTI */
345 sllx %o1, 8, %g3 /* IEU0 */
346 ldx [%o0], %o3 /* Load Group */
3471: sethi %hi(0x01010101), %g1 /* IEU0 */
348
349 or %g3, %o1, %g3 /* IEU1 */
350 sllx %g3, 16, %g5 /* IEU0 Group */
351 or %g1, %lo(0x01010101), %g1 /* IEU1 */
352 sllx %g1, 32, %g2 /* IEU0 Group */
353
354 or %g3, %g5, %g3 /* IEU1 */
355 sllx %g3, 32, %g5 /* IEU0 Group */
356 or %g1, %g2, %g1 /* IEU1 */
357 sllx %g1, 7, %g2 /* IEU0 Group */
358
359 or %g3, %g5, %g3 /* IEU1 */
360 add %o0, 8, %o0 /* IEU0 Group */
361 xor %o3, %g3, %o4 /* IEU1 */
362 /* %g1 = 0101010101010101 *
363 * %g2 = 8080088080808080 *
364 * %g3 = c c c c c c c c *
365 * %o3 = value *
366 * %o4 = value XOR c */
3672: sub %o3, %g1, %o2 /* IEU0 Group */
368
3693: sub %o4, %g1, %o5 /* IEU1 */
370#ifdef EIGHTBIT_NOT_RARE
371 andn %o2, %o3, %g6 /* IEU0 Group */
372 andn %o5, %o4, %o5 /* IEU1 */
373 ldxa [%o0] ASI_PNF, %o3 /* Load */
374
375 or %o5, %g6, %o5 /* IEU0 Group */
376#else
377 ldxa [%o0] ASI_PNF, %o3 /* Load */
378
379 or %o5, %o2, %o5 /* IEU0 Group */
380#endif
381 add %o0, 8, %o0 /* IEU1 */
382 andcc %o5, %g2, %g0 /* IEU1 Group */
383 be,a,pt %xcc, 2b /* CTI */
384
385 xor %o3, %g3, %o4 /* IEU0 */
386 srlx %o5, 32, %g5 /* IEU0 Group */
387 add %o2, %g1, %o2 /* IEU1 */
388 andcc %g5, %g2, %g0 /* IEU1 Group */
389
390 be,pn %xcc, 7f /* CTI */
391 srlx %o2, 56, %g5 /* IEU0 */
392 andcc %g5, 0xff, %g0 /* IEU1 Group */
393 be,pn %icc, 12f /* CTI */
394
395 srlx %o4, 56, %g5 /* IEU0 */
396 andcc %g5, 0xff, %g0 /* IEU1 Group */
397 srlx %o2, 48, %g5 /* IEU0 */
398 be,a,pn %icc, 4f /* CTI */
399
400 add %o0, -16, %g4 /* IEU0 Group */
4014: andcc %g5, 0xff, %g0 /* IEU1 Group */
402 be,pn %icc, 12f /* CTI */
403 srlx %o4, 48, %g5 /* IEU0 */
404
405 andcc %g5, 0xff, %g0 /* IEU1 Group */
406 srlx %o2, 40, %g5 /* IEU0 */
407 be,a,pn %icc, 5f /* CTI */
408 add %o0, -15, %g4 /* IEU0 Group */
409
4105: andcc %g5, 0xff, %g0 /* IEU1 Group */
411 be,pn %icc, 12f /* CTI */
412 srlx %o4, 40, %g5 /* IEU0 */
413 andcc %g5, 0xff, %g0 /* IEU1 Group */
414
415 srlx %o2, 32, %g5 /* IEU0 */
416 be,a,pn %icc, 6f /* CTI */
417 add %o0, -14, %g4 /* IEU0 Group */
4186: andcc %g5, 0xff, %g0 /* IEU1 Group */
419
420 be,pn %icc, 12f /* CTI */
421 srlx %o4, 32, %g5 /* IEU0 */
422 andcc %g5, 0xff, %g0 /* IEU1 Group */
423 be,a,pn %icc, 7f /* CTI */
424
425 add %o0, -13, %g4 /* IEU0 */
4267: srlx %o2, 24, %g5 /* IEU0 */
427 andcc %g5, 0xff, %g0 /* IEU1 Group */
428 be,pn %icc, 12f /* CTI */
429
430 srlx %o4, 24, %g5 /* IEU0 */
431 andcc %g5, 0xff, %g0 /* IEU1 Group */
432 srlx %o2, 16, %g5 /* IEU0 */
433 be,a,pn %icc, 8f /* CTI */
434
435 add %o0, -12, %g4 /* IEU0 Group */
4368: andcc %g5, 0xff, %g0 /* IEU1 Group */
437 be,pn %icc, 12f /* CTI */
438 srlx %o4, 16, %g5 /* IEU0 */
439
440 andcc %g5, 0xff, %g0 /* IEU1 Group */
441 srlx %o2, 8, %g5 /* IEU0 */
442 be,a,pn %icc, 9f /* CTI */
443 add %o0, -11, %g4 /* IEU0 Group */
444
4459: andcc %g5, 0xff, %g0 /* IEU1 Group */
446 be,pn %icc, 12f /* CTI */
447 srlx %o4, 8, %g5 /* IEU0 */
448 andcc %g5, 0xff, %g0 /* IEU1 Group */
449
450 be,a,pn %icc, 10f /* CTI */
451 add %o0, -10, %g4 /* IEU0 */
45210: andcc %o2, 0xff, %g0 /* IEU1 Group */
453 be,pn %icc, 12f /* CTI */
454
455 sub %o3, %g1, %o2 /* IEU0 */
456 andcc %o4, 0xff, %g0 /* IEU1 Group */
457 be,a,pn %icc, 11f /* CTI */
458 add %o0, -9, %g4 /* IEU0 */
459
46011: ba,pt %xcc, 3b /* CTI Group */
461 xor %o3, %g3, %o4 /* IEU0 Group */
46212: retl /* CTI+IEU1 Group */
463 mov %g4, %o0 /* IEU0 */
464
465 .align 16
46613: ldub [%o0], %o3 /* Load Group */
467 add %o0, 1, %o0 /* IEU0 */
46814: andcc %o3, 0xff, %g0 /* IEU1 Group */
469 be,pn %icc, 12b /* CTI */
470
471 cmp %o3, %o1 /* IEU1 Group */
472 ldub [%o0], %o3 /* Load */
473 be,a,pn %icc, 15f /* CTI */
474 add %o0, -1, %g4 /* IEU0 Group */
475
47615: andcc %o0, 7, %g0 /* IEU1 Group */
477 bne,a,pt %icc, 14b /* CTI */
478 add %o0, 1, %o0 /* IEU0 */
479 ba,pt %xcc, 1b /* CTI Group */
480
481 ldx [%o0], %o3 /* Load */
482END(strrchr)
483libc_hidden_def(strrchr)
484#ifdef __UCLIBC_SUSV3_LEGACY__
485strong_alias(strrchr,rindex)
486#endif