1/* rawmemchr (str, ch) -- Return pointer to first occurrence of CH in STR.
2   For SPARC v9.
3   Copyright (C) 1999-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#endif
28
29	/* Normally, this uses
30	   ((xword - 0x0101010101010101) & 0x8080808080808080) test
31	   to find out if any byte in xword could be zero. This is fast, but
32	   also gives false alarm for any byte in range 0x81-0xff. It does
33	   not matter for correctness, as if this test tells us there could
34	   be some zero byte, we check it byte by byte, but if bytes with
35	   high bits set are common in the strings, then this will give poor
36	   performance. You can #define EIGHTBIT_NOT_RARE and the algorithm
37	   will use one tick slower, but more precise test
38	   ((xword - 0x0101010101010101) & (~xword) & 0x8080808080808080),
39	   which does not give any false alarms (but if some bits are set,
40	   one cannot assume from it which bytes are zero and which are not).
41	   It is yet to be measured, what is the correct default for glibc
42	   in these days for an average user.
43	 */
44
45	.text
46	.align		32
47ENTRY(__rawmemchr)
48	and		%o1, 0xff, %o1			/* IEU0		Group		*/
49	sethi		%hi(0x01010101), %g1		/* IEU1				*/
50	ldub		[%o0], %o3			/* Load				*/
51	sll		%o1, 8, %o4			/* IEU0		Group		*/
52
53	or		%g1, %lo(0x01010101), %g1	/* IEU1				*/
54	sllx		%g1, 32, %g2			/* IEU0		Group		*/
55	or		%o4, %o1, %o4			/* IEU1				*/
56	andcc		%o0, 7, %g0			/* IEU1		Group		*/
57
58	sll		%o4, 16, %g5			/* IEU0				*/
59	or		%o4, %g5, %o4			/* IEU0		Group		*/
60	or		%g1, %g2, %g1			/* IEU1				*/
61	bne,pn		%icc, 32f			/* CTI				*/
62
63	 sllx		%o4, 32, %g5			/* IEU0		Group		*/
64	cmp		%o3, %o1			/* IEU1				*/
65	be,pn		%icc, 30f			/* CTI				*/
66	 sllx		%g1, 7, %g2			/* IEU0		Group		*/
67
6818:	ldx		[%o0], %o3			/* Load				*/
69	or		%o4, %g5, %o4			/* IEU1				*/
70	add		%o0, 8, %o0			/* IEU0		Group		*/
7119:	xor		%o3, %o4, %o3			/* IEU0		Group		*/
72
73	sub		%o3, %g1, %o2			/* IEU0		Group		*/
74#ifdef EIGHTBIT_NOT_RARE
75	andn		%o2, %o3, %o5			/* IEU0		Group		*/
76	ldxa		[%o0] ASI_PNF, %o3		/* Load				*/
77	andcc		%o5, %g2, %g0			/* IEU1		Group		*/
78#else
79	ldxa		[%o0] ASI_PNF, %o3		/* Load				*/
80	andcc		%o2, %g2, %g0			/* IEU1		Group		*/
81#endif
82	be,pt		%xcc, 19b			/* CTI				*/
83
84	 add		%o0, 8, %o0			/* IEU0				*/
85 	addcc		%o2, %g1, %g3			/* IEU1		Group		*/
86	srlx		%o2, 32, %o2			/* IEU0				*/
8720:	andcc		%o2, %g2, %g0			/* IEU1		Group		*/
88
89	be,pn		%xcc, 21f			/* CTI				*/
90	 srlx		%g3, 56, %o2			/* IEU0				*/
91	andcc		%o2, 0xff, %g0			/* IEU1		Group		*/
92	be,pn		%icc, 29f			/* CTI				*/
93
94	 srlx		%g3, 48, %o2			/* IEU0				*/
95	andcc		%o2, 0xff, %g0			/* IEU1		Group		*/
96	be,pn		%icc, 28f			/* CTI				*/
97	 srlx		%g3, 40, %o2			/* IEU0				*/
98
99	andcc		%o2, 0xff, %g0			/* IEU1		Group		*/
100	be,pn		%icc, 27f			/* CTI				*/
101	 srlx		%g3, 32, %o2			/* IEU0				*/
102	andcc		%o2, 0xff, %g0			/* IEU1		Group		*/
103
104	be,pn		%icc, 26f			/* CTI				*/
10521:	 srlx		%g3, 24, %o2			/* IEU0				*/
106	andcc		%o2, 0xff, %g0			/* IEU1		Group		*/
107	be,pn		%icc, 25f			/* CTI				*/
108
109	 srlx		%g3, 16, %o2			/* IEU0				*/
110	andcc		%o2, 0xff, %g0			/* IEU1		Group		*/
111	be,pn		%icc, 24f			/* CTI				*/
112	 srlx		%g3, 8, %o2			/* IEU0				*/
113
114	andcc		%o2, 0xff, %g0			/* IEU1		Group		*/
115	be,pn		%icc, 23f			/* CTI				*/
116	 xor		%o3, %o4, %o3			/* IEU0				*/
117	andcc		%g3, 0xff, %g0			/* IEU1		Group		*/
118
119	be,pn		%icc, 22f			/* CTI				*/
120	 sub		%o3, %g1, %o2			/* IEU0				*/
121	ldxa		[%o0] ASI_PNF, %o3		/* Load				*/
122	andcc		%o2, %g2, %g0			/* IEU1		Group		*/
123
124	be,pt		%xcc, 19b			/* CTI				*/
125	 add		%o0, 8, %o0			/* IEU0				*/
126	addcc		%o2, %g1, %g3			/* IEU1		Group		*/
127	ba,pt		%xcc, 20b			/* CTI				*/
128
129	 srlx		%o2, 32, %o2			/* IEU0				*/
130
131	.align		16
13222:	retl						/* CTI+IEU1	Group		*/
133	 add		%o0, -9, %o0			/* IEU0				*/
13423:	retl						/* CTI+IEU1	Group		*/
135	 add		%o0, -10, %o0			/* IEU0				*/
136
13724:	retl						/* CTI+IEU1	Group		*/
138	 add		%o0, -11, %o0			/* IEU0				*/
13925:	retl						/* CTI+IEU1	Group		*/
140	 add		%o0, -12, %o0			/* IEU0				*/
141
14226:	retl						/* CTI+IEU1	Group		*/
143	 add		%o0, -13, %o0			/* IEU0				*/
14427:	retl						/* CTI+IEU1	Group		*/
145	 add		%o0, -14, %o0			/* IEU0				*/
146
14728:	retl						/* CTI+IEU1	Group		*/
148	 add		%o0, -15, %o0			/* IEU0				*/
14929:	retl						/* CTI+IEU1	Group		*/
150	 add		%o0, -16, %o0			/* IEU0				*/
151
15230:	retl						/* CTI+IEU1	Group		*/
153	 nop						/* IEU0				*/
154
155	.align		16
15632:	andcc		%o0, 7, %g0			/* IEU1		Group		*/
157	be,a,pn		%icc, 18b			/* CTI				*/
158	 sllx		%g1, 7, %g2			/* IEU0				*/
159	add		%o0, 1, %o0			/* IEU0		Group		*/
160
161	cmp		%o3, %o1			/* IEU1				*/
162	bne,a,pt	%icc, 32b			/* CTI				*/
163	 lduba		[%o0] ASI_PNF, %o3		/* Load				*/
164	retl						/* CTI+IEU1	Group		*/
165
166	 add		%o0, -1, %o0			/* IEU0				*/
167END(__rawmemchr)
168
169libc_hidden_def (__rawmemchr)
170weak_alias (__rawmemchr, rawmemchr)
171