1/* strchr (str, ch) -- Return pointer to first occurrence of CH in STR.
2   For SPARC v9.
3   Copyright (C) 1998-2022 Free Software Foundation, Inc.
4   This file is part of the GNU C Library.
5
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.
10
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.
15
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/>.  */
19
20#include <sysdep.h>
21#include <asm/asi.h>
22#ifndef XCC
23#define XCC xcc
24#define USE_BPR
25	.register	%g2, #scratch
26	.register	%g3, #scratch
27	.register	%g6, #scratch
28#endif
29
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.
44	 */
45
46	.text
47	.align		32
48ENTRY(strchr)
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				*/
53
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				*/
58
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				*/
63
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		*/
68
69	bne,a,pn	%icc, 15f			/* CTI				*/
70	 add		%o0, 1, %o0			/* IEU0				*/
71	ldx		[%o0], %o3			/* Load		Group		*/
721:	sllx		%g1, 7, %g2			/* IEU0				*/
73
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	*
80							 * %o3 =      value		*
81							 * %o4 =   value XOR c		*/
822:	sub		%o3, %g1, %o2			/* IEU0		Group		*/
83
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		*/
90#else
91	ldxa		[%o0] ASI_PNF, %o3		/* Load				*/
92	or		%o5, %o2, %o5			/* IEU0		Group		*/
93#endif
94	add		%o0, 8, %o0			/* IEU1				*/
95
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		*/
100
101	add		%o2, %g1, %o2			/* IEU1				*/
1023:	andcc		%g5, %g2, %g0			/* IEU1		Group		*/
103	be,pn		%xcc, 4f			/* CTI				*/
104	 srlx		%o2, 56, %g5			/* IEU0				*/
105
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		*/
110
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				*/
115
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				*/
120
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		*/
125
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				*/
130
131	 srlx		%o4, 32, %g5			/* IEU0				*/
132	andcc		%g5, 0xff, %g0			/* IEU1		Group		*/
133	be,pn		%icc, 9f			/* CTI				*/
1344:	 srlx		%o2, 24, %g5			/* IEU0				*/
135
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		*/
140
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				*/
145
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				*/
150
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		*/
155
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				*/
160
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		*/
165
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				*/
170
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				*/
175
176	 add		%o2, %g1, %o2			/* IEU1				*/
177
178	.align		16
1795:	retl						/* CTI+IEU1	Group		*/
180	 clr		%o0				/* IEU0				*/
1816:	retl						/* CTI+IEU1	Group		*/
182	 add		%o0, -16, %o0			/* IEU0				*/
183
1847:	retl						/* CTI+IEU1	Group		*/
185	 add		%o0, -15, %o0			/* IEU0				*/
1868:	retl						/* CTI+IEU1	Group		*/
187	 add		%o0, -14, %o0			/* IEU0				*/
188
1899:	retl						/* CTI+IEU1	Group		*/
190	 add		%o0, -13, %o0			/* IEU0				*/
19110:	retl						/* CTI+IEU1	Group		*/
192	 add		%o0, -12, %o0			/* IEU0				*/
193
19411:	retl						/* CTI+IEU1	Group		*/
195	 add		%o0, -11, %o0			/* IEU0				*/
19612:	retl						/* CTI+IEU1	Group		*/
197	 add		%o0, -10, %o0			/* IEU0				*/
198
19913:	retl						/* CTI+IEU1	Group		*/
200	 add		%o0, -9, %o0			/* IEU0				*/
20114: 	retl						/* CTI+IEU1	Group		*/
202	 nop						/* IEU0				*/
203
204	.align		16
20515:	ldub		[%o0], %o3			/* Load		Group		*/
20616:	andcc		%o0, 7, %g0			/* IEU1				*/
207	be,a,pn		%icc, 1b			/* CTI				*/
208	 ldx		[%o0], %o3			/* Load		Group		*/
209
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		*/
214
215	bne,a,pn	%icc, 16b			/* CTI				*/
216	 ldub		[%o0], %o3			/* Load				*/
217	retl						/* CTI+IEU1	Group		*/
218	 add		%o0, -1, %o0			/* IEU0				*/
219
220	/* strchr (str, 0)			*/
221	.align		32
222	nop
223	.align		16
22417:	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		*/
228
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		*/
233
234	brz,pn		%o3, 30f			/* CTI+IEU1			*/
235	 ldx		[%o0], %o3			/* Load				*/
23618:	add		%o0, 8, %o0			/* IEU0		Group		*/
23719:	sub		%o3, %g1, %o2			/* IEU0		Group		*/
238
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		*/
243#else
244	ldxa		[%o0] ASI_PNF, %o3		/* Load				*/
245	andcc		%o2, %g2, %g0			/* IEU1		Group		*/
246#endif
247	be,pt		%xcc, 19b			/* CTI				*/
248	 add		%o0, 8, %o0			/* IEU0				*/
249
250 	addcc		%o2, %g1, %g3			/* IEU1		Group		*/
251	srlx		%o2, 32, %o2			/* IEU0				*/
25220:	andcc		%o2, %g2, %g0			/* IEU1		Group		*/
253	be,pn		%xcc, 21f			/* CTI				*/
254
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				*/
259
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		*/
264
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				*/
269
27021:	 srlx		%g3, 24, %o2			/* IEU0				*/
271	andcc		%o2, 0xff, %g0			/* IEU1		Group		*/
272	be,pn		%icc, 25f			/* CTI				*/
273	 srlx		%g3, 16, %o2			/* IEU0				*/
274
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		*/
279
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				*/
284
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				*/
289
290	addcc		%o2, %g1, %g3			/* IEU1		Group		*/
291	ba,pt		%xcc, 20b			/* CTI				*/
292	 srlx		%o2, 32, %o2			/* IEU0				*/
293
294	.align		16
29522:	retl						/* CTI+IEU1	Group		*/
296	 add		%o0, -9, %o0			/* IEU0				*/
29723:	retl						/* CTI+IEU1	Group		*/
298	 add		%o0, -10, %o0			/* IEU0				*/
299
30024:	retl						/* CTI+IEU1	Group		*/
301	 add		%o0, -11, %o0			/* IEU0				*/
30225:	retl						/* CTI+IEU1	Group		*/
303	 add		%o0, -12, %o0			/* IEU0				*/
304
30526:	retl						/* CTI+IEU1	Group		*/
306	 add		%o0, -13, %o0			/* IEU0				*/
30727:	retl						/* CTI+IEU1	Group		*/
308	 add		%o0, -14, %o0			/* IEU0				*/
309
31028:	retl						/* CTI+IEU1	Group		*/
311	 add		%o0, -15, %o0			/* IEU0				*/
31229:	retl						/* CTI+IEU1	Group		*/
313	 add		%o0, -16, %o0			/* IEU0				*/
314
31530:	retl						/* CTI+IEU1	Group		*/
316	 nop						/* IEU0				*/
317
318	.align		16
31932:	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		*/
323
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				*/
328END(strchr)
329
330	.align		32
331ENTRY(strrchr)
332	andcc		%o1, 0xff, %o1			/* IEU1		Group		*/
333	be,pn		%icc, 17b			/* CTI				*/
334	 clr		%g4				/* IEU0				*/
335	andcc		%o0, 7, %g0			/* IEU1		Group		*/
336
337	bne,pn		%icc, 13f			/* CTI				*/
338	 sllx		%o1, 8, %g3			/* IEU0				*/
339	ldx		[%o0], %o3			/* Load		Group		*/
3401:	sethi		%hi(0x01010101), %g1		/* IEU0				*/
341
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		*/
346
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		*/
351
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	*
358							 * %o3 =   value		*
359							 * %o4 =   value XOR c		*/
3602:	sub		%o3, %g1, %o2			/* IEU0		Group		*/
361
3623:	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				*/
367
368	or		%o5, %g6, %o5			/* IEU0		Group		*/
369#else
370	ldxa		[%o0] ASI_PNF, %o3		/* Load				*/
371
372	or		%o5, %o2, %o5			/* IEU0		Group		*/
373#endif
374	add		%o0, 8, %o0			/* IEU1				*/
375	andcc		%o5, %g2, %g0			/* IEU1		Group		*/
376	be,a,pt		%xcc, 2b			/* CTI				*/
377
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		*/
382
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				*/
387
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				*/
392
393	 add		%o0, -16, %g4			/* IEU0		Group		*/
3944:	andcc		%g5, 0xff, %g0			/* IEU1		Group		*/
395	be,pn		%icc, 12f			/* CTI				*/
396	 srlx		%o4, 48, %g5			/* IEU0				*/
397
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		*/
402
4035:	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		*/
407
408	srlx		%o2, 32, %g5			/* IEU0				*/
409	be,a,pn		%icc, 6f			/* CTI				*/
410	 add		%o0, -14, %g4			/* IEU0		Group		*/
4116:	andcc		%g5, 0xff, %g0			/* IEU1		Group		*/
412
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				*/
417
418	 add		%o0, -13, %g4			/* IEU0				*/
4197:	srlx		%o2, 24, %g5			/* IEU0				*/
420	andcc		%g5, 0xff, %g0			/* IEU1		Group		*/
421	be,pn		%icc, 12f			/* CTI				*/
422
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				*/
427
428	 add		%o0, -12, %g4			/* IEU0		Group		*/
4298:	andcc		%g5, 0xff, %g0			/* IEU1		Group		*/
430	be,pn		%icc, 12f			/* CTI				*/
431	 srlx		%o4, 16, %g5			/* IEU0				*/
432
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		*/
437
4389:	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		*/
442
443	be,a,pn		%icc, 10f			/* CTI				*/
444	 add		%o0, -10, %g4			/* IEU0				*/
44510:	andcc		%o2, 0xff, %g0			/* IEU1		Group		*/
446	be,pn		%icc, 12f			/* CTI				*/
447
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				*/
452
45311:	ba,pt		%xcc, 3b			/* CTI		Group		*/
454	 xor		%o3, %g3, %o4			/* IEU0		Group		*/
45512:	retl						/* CTI+IEU1	Group		*/
456	 mov		%g4, %o0			/* IEU0				*/
457
458	.align		16
45913:	ldub		[%o0], %o3			/* Load		Group		*/
460	add		%o0, 1, %o0			/* IEU0				*/
46114:	andcc		%o3, 0xff, %g0			/* IEU1		Group		*/
462	be,pn		%icc, 12b			/* CTI				*/
463
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		*/
468
46915:	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		*/
473
474	 ldx		[%o0], %o3			/* Load				*/
475END(strrchr)
476
477weak_alias (strchr, index)
478weak_alias (strrchr, rindex)
479libc_hidden_builtin_def (strchr)
480libc_hidden_builtin_def (strrchr)
481