]> git.ipfire.org Git - thirdparty/glibc.git/blob - sysdeps/sparc/sparc64/strchr.S
Update.
[thirdparty/glibc.git] / sysdeps / sparc / sparc64 / strchr.S
1 /* 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 <sysdep.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
51 ENTRY(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 */
75 1: 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 */
85 2: 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 */
105 3: 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 */
137 4: 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
182 5: retl /* CTI+IEU1 Group */
183 clr %o0 /* IEU0 */
184 6: retl /* CTI+IEU1 Group */
185 add %o0, -16, %o0 /* IEU0 */
186
187 7: retl /* CTI+IEU1 Group */
188 add %o0, -15, %o0 /* IEU0 */
189 8: retl /* CTI+IEU1 Group */
190 add %o0, -14, %o0 /* IEU0 */
191
192 9: retl /* CTI+IEU1 Group */
193 add %o0, -13, %o0 /* IEU0 */
194 10: retl /* CTI+IEU1 Group */
195 add %o0, -12, %o0 /* IEU0 */
196
197 11: retl /* CTI+IEU1 Group */
198 add %o0, -11, %o0 /* IEU0 */
199 12: retl /* CTI+IEU1 Group */
200 add %o0, -10, %o0 /* IEU0 */
201
202 13: retl /* CTI+IEU1 Group */
203 add %o0, -9, %o0 /* IEU0 */
204 14: retl /* CTI+IEU1 Group */
205 nop /* IEU0 */
206
207 .align 16
208 15: ldub [%o0], %o3 /* Load Group */
209 16: 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
227 17: 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 */
239 18: add %o0, 8, %o0 /* IEU0 Group */
240 19: 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 */
255 20: 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
273 21: 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
298 22: retl /* CTI+IEU1 Group */
299 add %o0, -9, %o0 /* IEU0 */
300 23: retl /* CTI+IEU1 Group */
301 add %o0, -10, %o0 /* IEU0 */
302
303 24: retl /* CTI+IEU1 Group */
304 add %o0, -11, %o0 /* IEU0 */
305 25: retl /* CTI+IEU1 Group */
306 add %o0, -12, %o0 /* IEU0 */
307
308 26: retl /* CTI+IEU1 Group */
309 add %o0, -13, %o0 /* IEU0 */
310 27: retl /* CTI+IEU1 Group */
311 add %o0, -14, %o0 /* IEU0 */
312
313 28: retl /* CTI+IEU1 Group */
314 add %o0, -15, %o0 /* IEU0 */
315 29: retl /* CTI+IEU1 Group */
316 add %o0, -16, %o0 /* IEU0 */
317
318 30: retl /* CTI+IEU1 Group */
319 nop /* IEU0 */
320
321 .align 16
322 32: 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 */
331 END(strchr)
332
333 .align 32
334 ENTRY(strrchr)
335 andcc %o1, 0xff, %o1 /* IEU1 Group */
336 be,pn %icc, 17b /* CTI */
337 clr %g4 /* IEU0 */
338 andcc %o0, 7, %g0 /* IEU1 Group */
339
340 bne,pn %icc, 13f /* CTI */
341 sllx %o1, 8, %g3 /* IEU0 */
342 ldx [%o0], %o3 /* Load Group */
343 1: sethi %hi(0x01010101), %g1 /* IEU0 */
344
345 or %g3, %o1, %g3 /* IEU1 */
346 sllx %g3, 16, %g5 /* IEU0 Group */
347 or %g1, %lo(0x01010101), %g1 /* IEU1 */
348 sllx %g1, 32, %g2 /* IEU0 Group */
349
350 or %g3, %g5, %g3 /* IEU1 */
351 sllx %g3, 32, %g5 /* IEU0 Group */
352 or %g1, %g2, %g1 /* IEU1 */
353 sllx %g1, 7, %g2 /* IEU0 Group */
354
355 or %g3, %g5, %g3 /* IEU1 */
356 add %o0, 8, %o0 /* IEU0 Group */
357 xor %o3, %g3, %o4 /* IEU1 */
358 /* %g1 = 0101010101010101 *
359 * %g2 = 8080088080808080 *
360 * %g3 = c c c c c c c c *
361 * %o3 = value *
362 * %o4 = value XOR c */
363 2: sub %o3, %g1, %o2 /* IEU0 Group */
364
365 3: sub %o4, %g1, %o5 /* IEU1 */
366 #ifdef EIGHTBIT_NOT_RARE
367 andn %o2, %o3, %g6 /* IEU0 Group */
368 andn %o5, %o4, %o5 /* IEU1 */
369 ldxa [%o0] ASI_PNF, %o3 /* Load */
370
371 or %o5, %g6, %o5 /* IEU0 Group */
372 #else
373 ldxa [%o0] ASI_PNF, %o3 /* Load */
374
375 or %o5, %o2, %o5 /* IEU0 Group */
376 #endif
377 add %o0, 8, %o0 /* IEU1 */
378 andcc %o5, %g2, %g0 /* IEU1 Group */
379 be,a,pt %xcc, 2b /* CTI */
380
381 xor %o3, %g3, %o4 /* IEU0 */
382 srlx %o5, 32, %g5 /* IEU0 Group */
383 add %o2, %g1, %o2 /* IEU1 */
384 andcc %g5, %g2, %g0 /* IEU1 Group */
385
386 be,pn %xcc, 7f /* CTI */
387 srlx %o2, 56, %g5 /* IEU0 */
388 andcc %g5, 0xff, %g0 /* IEU1 Group */
389 be,pn %icc, 12f /* CTI */
390
391 srlx %o4, 56, %g5 /* IEU0 */
392 andcc %g5, 0xff, %g0 /* IEU1 Group */
393 srlx %o2, 48, %g5 /* IEU0 */
394 be,a,pn %icc, 4f /* CTI */
395
396 add %o0, -16, %g4 /* IEU0 Group */
397 4: andcc %g5, 0xff, %g0 /* IEU1 Group */
398 be,pn %icc, 12f /* CTI */
399 srlx %o4, 48, %g5 /* IEU0 */
400
401 andcc %g5, 0xff, %g0 /* IEU1 Group */
402 srlx %o2, 40, %g5 /* IEU0 */
403 be,a,pn %icc, 5f /* CTI */
404 add %o0, -15, %g4 /* IEU0 Group */
405
406 5: andcc %g5, 0xff, %g0 /* IEU1 Group */
407 be,pn %icc, 12f /* CTI */
408 srlx %o4, 40, %g5 /* IEU0 */
409 andcc %g5, 0xff, %g0 /* IEU1 Group */
410
411 srlx %o2, 32, %g5 /* IEU0 */
412 be,a,pn %icc, 6f /* CTI */
413 add %o0, -14, %g4 /* IEU0 Group */
414 6: andcc %g5, 0xff, %g0 /* IEU1 Group */
415
416 be,pn %icc, 12f /* CTI */
417 srlx %o4, 32, %g5 /* IEU0 */
418 andcc %g5, 0xff, %g0 /* IEU1 Group */
419 be,a,pn %icc, 7f /* CTI */
420
421 add %o0, -13, %g4 /* IEU0 */
422 7: srlx %o2, 24, %g5 /* IEU0 */
423 andcc %g5, 0xff, %g0 /* IEU1 Group */
424 be,pn %icc, 12f /* CTI */
425
426 srlx %o4, 24, %g5 /* IEU0 */
427 andcc %g5, 0xff, %g0 /* IEU1 Group */
428 srlx %o2, 16, %g5 /* IEU0 */
429 be,a,pn %icc, 8f /* CTI */
430
431 add %o0, -12, %g4 /* IEU0 Group */
432 8: andcc %g5, 0xff, %g0 /* IEU1 Group */
433 be,pn %icc, 12f /* CTI */
434 srlx %o4, 16, %g5 /* IEU0 */
435
436 andcc %g5, 0xff, %g0 /* IEU1 Group */
437 srlx %o2, 8, %g5 /* IEU0 */
438 be,a,pn %icc, 9f /* CTI */
439 add %o0, -11, %g4 /* IEU0 Group */
440
441 9: andcc %g5, 0xff, %g0 /* IEU1 Group */
442 be,pn %icc, 12f /* CTI */
443 srlx %o4, 8, %g5 /* IEU0 */
444 andcc %g5, 0xff, %g0 /* IEU1 Group */
445
446 be,a,pn %icc, 10f /* CTI */
447 add %o0, -10, %g4 /* IEU0 */
448 10: andcc %o2, 0xff, %g0 /* IEU1 Group */
449 be,pn %icc, 12f /* CTI */
450
451 sub %o3, %g1, %o2 /* IEU0 */
452 andcc %o4, 0xff, %g0 /* IEU1 Group */
453 be,a,pn %icc, 11f /* CTI */
454 add %o0, -9, %g4 /* IEU0 */
455
456 11: ba,pt %xcc, 3b /* CTI Group */
457 xor %o3, %g3, %o4 /* IEU0 Group */
458 12: retl /* CTI+IEU1 Group */
459 mov %g4, %o0 /* IEU0 */
460
461 .align 16
462 13: ldub [%o0], %o3 /* Load Group */
463 add %o0, 1, %o0 /* IEU0 */
464 14: andcc %o3, 0xff, %g0 /* IEU1 Group */
465 be,pn %icc, 12b /* CTI */
466
467 cmp %o3, %o1 /* IEU1 Group */
468 ldub [%o0], %o3 /* Load */
469 be,a,pn %icc, 15f /* CTI */
470 add %o0, -1, %g4 /* IEU0 Group */
471
472 15: andcc %o0, 7, %g0 /* IEU1 Group */
473 bne,a,pt %icc, 14b /* CTI */
474 add %o0, 1, %o0 /* IEU0 */
475 ba,pt %xcc, 1b /* CTI Group */
476
477 ldx [%o0], %o3 /* Load */
478 END(strrchr)
479
480 weak_alias (strchr, index)
481 weak_alias (strrchr, rindex)