]>
Commit | Line | Data |
---|---|---|
ae6b8730 RH |
1 | /* memchr (str, ch, n) -- Return pointer to first occurrence of CH in STR less |
2 | than N. | |
3 | For SPARC v9. | |
d614a753 | 4 | Copyright (C) 1998-2020 Free Software Foundation, Inc. |
ae6b8730 | 5 | This file is part of the GNU C Library. |
e6855a3b | 6 | Contributed by Jan Vondrák <jvon4518@ss1000.ms.mff.cuni.cz> and |
ae6b8730 | 7 | Jakub Jelinek <jj@ultra.linux.cz>. |
ae6b8730 RH |
8 | This version is developed using the same algorithm as the fast C |
9 | version which carries the following introduction: | |
ae6b8730 RH |
10 | Based on strlen implementation by Torbjorn Granlund (tege@sics.se), |
11 | with help from Dan Sahlin (dan@sics.se) and | |
12 | commentary by Jim Blandy (jimb@ai.mit.edu); | |
13 | adaptation to memchr suggested by Dick Karpinski (dick@cca.ucsf.edu), | |
14 | and implemented by Roland McGrath (roland@ai.mit.edu). | |
15 | ||
16 | The GNU C Library is free software; you can redistribute it and/or | |
41bdb6e2 AJ |
17 | modify it under the terms of the GNU Lesser General Public |
18 | License as published by the Free Software Foundation; either | |
19 | version 2.1 of the License, or (at your option) any later version. | |
ae6b8730 RH |
20 | |
21 | The GNU C Library is distributed in the hope that it will be useful, | |
22 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
23 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
41bdb6e2 | 24 | Lesser General Public License for more details. |
ae6b8730 | 25 | |
41bdb6e2 | 26 | You should have received a copy of the GNU Lesser General Public |
59ba27a6 | 27 | License along with the GNU C Library; if not, see |
5a82c748 | 28 | <https://www.gnu.org/licenses/>. */ |
ae6b8730 RH |
29 | |
30 | #include <sysdep.h> | |
31 | #include <asm/asi.h> | |
32 | #ifndef XCC | |
33 | #define XCC xcc | |
34 | #define USE_BPR | |
8cb079d4 UD |
35 | .register %g2, #scratch |
36 | .register %g3, #scratch | |
ae6b8730 RH |
37 | #endif |
38 | ||
39 | /* Normally, this uses | |
40 | ((xword - 0x0101010101010101) & 0x8080808080808080) test | |
41 | to find out if any byte in xword could be zero. This is fast, but | |
42 | also gives false alarm for any byte in range 0x81-0xff. It does | |
43 | not matter for correctness, as if this test tells us there could | |
44 | be some zero byte, we check it byte by byte, but if bytes with | |
45 | high bits set are common in the strings, then this will give poor | |
46 | performance. You can #define EIGHTBIT_NOT_RARE and the algorithm | |
47 | will use one tick slower, but more precise test | |
48 | ((xword - 0x0101010101010101) & (~xword) & 0x8080808080808080), | |
49 | which does not give any false alarms (but if some bits are set, | |
50 | one cannot assume from it which bytes are zero and which are not). | |
51 | It is yet to be measured, what is the correct default for glibc | |
52 | in these days for an average user. | |
53 | */ | |
54 | ||
55 | .text | |
56 | .align 32 | |
abf70633 | 57 | ENTRY(__memchr) |
407d26b7 | 58 | and %o1, 0xff, %o1 /* IEU0 Group */ |
ae6b8730 RH |
59 | #ifdef USE_BPR |
60 | brz,pn %o2, 12f /* CTI+IEU1 */ | |
61 | #else | |
62 | tst %o2 /* IEU1 */ | |
63 | be,pn %XCC, 12f /* CTI */ | |
ae6b8730 | 64 | #endif |
407d26b7 | 65 | sll %o1, 8, %g3 /* IEU0 Group */ |
aa4980fc DM |
66 | addcc %o0, %o2, %o2 /* IEU1 */ |
67 | movcs %XCC, -1, %o2 /* IEU0 Group */ | |
ae6b8730 | 68 | |
407d26b7 UD |
69 | sethi %hi(0x01010101), %g1 /* IEU0 Group */ |
70 | or %g3, %o1, %g3 /* IEU1 */ | |
ae6b8730 RH |
71 | ldub [%o0], %o3 /* Load */ |
72 | sllx %g3, 16, %g5 /* IEU0 Group */ | |
ae6b8730 | 73 | |
407d26b7 | 74 | or %g1, %lo(0x01010101), %g1 /* IEU1 */ |
ae6b8730 RH |
75 | sllx %g1, 32, %g2 /* IEU0 Group */ |
76 | or %g3, %g5, %g3 /* IEU1 */ | |
77 | sllx %g3, 32, %g5 /* IEU0 Group */ | |
ae6b8730 | 78 | |
407d26b7 | 79 | cmp %o3, %o1 /* IEU1 */ |
ae6b8730 RH |
80 | be,pn %xcc, 13f /* CTI */ |
81 | or %g1, %g2, %g1 /* IEU0 Group */ | |
82 | andcc %o0, 7, %g0 /* IEU1 */ | |
ae6b8730 | 83 | |
407d26b7 | 84 | bne,a,pn %icc, 21f /* CTI */ |
ae6b8730 RH |
85 | add %o0, 1, %o0 /* IEU0 Group */ |
86 | ldx [%o0], %o3 /* Load Group */ | |
87 | sllx %g1, 7, %g2 /* IEU0 */ | |
ae6b8730 | 88 | |
407d26b7 | 89 | or %g3, %g5, %g3 /* IEU1 */ |
ae6b8730 RH |
90 | 1: add %o0, 8, %o0 /* IEU0 Group */ |
91 | xor %o3, %g3, %o4 /* IEU1 */ | |
92 | /* %g1 = 0101010101010101 * | |
93 | * %g2 = 8080088080808080 * | |
94 | * %g3 = c c c c c c c c * | |
95 | * %o3 = value * | |
96 | * %o4 = value XOR c */ | |
97 | 2: cmp %o0, %o2 /* IEU1 Group */ | |
ae6b8730 | 98 | |
2daff75b | 99 | bgu,pn %XCC, 11f /* CTI */ |
ae6b8730 RH |
100 | ldxa [%o0] ASI_PNF, %o3 /* Load */ |
101 | sub %o4, %g1, %o5 /* IEU0 Group */ | |
102 | add %o0, 8, %o0 /* IEU1 */ | |
103 | #ifdef EIGHTBIT_NOT_RARE | |
104 | andn %o5, %o4, %o5 /* IEU0 Group */ | |
105 | #endif | |
ae6b8730 | 106 | |
407d26b7 | 107 | andcc %o5, %g2, %g0 /* IEU1 Group */ |
ae6b8730 RH |
108 | be,a,pt %xcc, 2b /* CTI */ |
109 | xor %o3, %g3, %o4 /* IEU0 */ | |
110 | srlx %o4, 56, %g5 /* IEU0 */ | |
ae6b8730 | 111 | |
407d26b7 | 112 | andcc %g5, 0xff, %g0 /* IEU1 Group */ |
ae6b8730 RH |
113 | be,pn %icc, 3f /* CTI */ |
114 | srlx %o4, 48, %g5 /* IEU0 */ | |
115 | andcc %g5, 0xff, %g0 /* IEU1 Group */ | |
ae6b8730 | 116 | |
407d26b7 | 117 | be,pn %icc, 4f /* CTI */ |
ae6b8730 RH |
118 | srlx %o4, 40, %g5 /* IEU0 */ |
119 | andcc %g5, 0xff, %g0 /* IEU1 Group */ | |
120 | be,pn %icc, 5f /* CTI */ | |
ae6b8730 | 121 | |
407d26b7 | 122 | srlx %o4, 32, %g5 /* IEU0 */ |
ae6b8730 RH |
123 | andcc %g5, 0xff, %g0 /* IEU1 Group */ |
124 | be,pn %icc, 6f /* CTI */ | |
125 | srlx %o4, 24, %g5 /* IEU0 */ | |
ae6b8730 | 126 | |
407d26b7 | 127 | andcc %g5, 0xff, %g0 /* IEU1 Group */ |
ae6b8730 RH |
128 | be,pn %icc, 7f /* CTI */ |
129 | srlx %o4, 16, %g5 /* IEU0 */ | |
130 | andcc %g5, 0xff, %g0 /* IEU1 Group */ | |
ae6b8730 | 131 | |
407d26b7 | 132 | be,pn %icc, 8f /* CTI */ |
ae6b8730 RH |
133 | srlx %o4, 8, %g5 /* IEU0 */ |
134 | andcc %g5, 0xff, %g0 /* IEU1 Group */ | |
135 | be,pn %icc, 9f /* CTI */ | |
ae6b8730 | 136 | |
407d26b7 | 137 | andcc %o4, 0xff, %g0 /* IEU1 Group */ |
ae6b8730 RH |
138 | bne,pt %icc, 2b /* CTI */ |
139 | xor %o3, %g3, %o4 /* IEU0 */ | |
140 | retl /* CTI+IEU1 Group */ | |
407d26b7 | 141 | |
ae6b8730 RH |
142 | add %o0, -9, %o0 /* IEU0 */ |
143 | ||
144 | .align 16 | |
145 | 3: retl /* CTI+IEU1 Group */ | |
146 | add %o0, -16, %o0 /* IEU0 */ | |
147 | 4: retl /* CTI+IEU1 Group */ | |
148 | add %o0, -15, %o0 /* IEU0 */ | |
149 | ||
150 | 5: retl /* CTI+IEU1 Group */ | |
151 | add %o0, -14, %o0 /* IEU0 */ | |
152 | 6: retl /* CTI+IEU1 Group */ | |
153 | add %o0, -13, %o0 /* IEU0 */ | |
154 | ||
155 | 7: retl /* CTI+IEU1 Group */ | |
156 | add %o0, -12, %o0 /* IEU0 */ | |
157 | 8: retl /* CTI+IEU1 Group */ | |
158 | add %o0, -11, %o0 /* IEU0 */ | |
159 | ||
160 | 9: retl /* CTI+IEU1 Group */ | |
161 | add %o0, -10, %o0 /* IEU0 */ | |
162 | 11: sub %o4, %g1, %o5 /* IEU0 Group */ | |
163 | sub %o0, 8, %o0 /* IEU1 */ | |
164 | ||
165 | andcc %o5, %g2, %g0 /* IEU1 Group */ | |
166 | be,pt %xcc, 12f /* CTI */ | |
167 | sub %o2, %o0, %o2 /* IEU0 */ | |
168 | tst %o2 /* IEU1 Group */ | |
169 | ||
170 | be,pn %XCC, 12f /* CTI */ | |
171 | srlx %o4, 56, %g5 /* IEU0 */ | |
172 | andcc %g5, 0xff, %g0 /* IEU1 Group */ | |
173 | be,pn %icc, 13f /* CTI */ | |
174 | ||
175 | cmp %o2, 1 /* IEU0 */ | |
176 | be,pn %XCC, 12f /* CTI Group */ | |
177 | srlx %o4, 48, %g5 /* IEU0 */ | |
178 | andcc %g5, 0xff, %g0 /* IEU1 Group */ | |
179 | ||
180 | be,pn %icc, 14f /* CTI */ | |
181 | cmp %o2, 2 /* IEU1 Group */ | |
182 | be,pn %XCC, 12f /* CTI */ | |
183 | srlx %o4, 40, %g5 /* IEU0 */ | |
184 | ||
185 | andcc %g5, 0xff, %g0 /* IEU1 Group */ | |
186 | be,pn %icc, 15f /* CTI */ | |
187 | cmp %o2, 3 /* IEU1 Group */ | |
188 | be,pn %XCC, 12f /* CTI */ | |
189 | ||
190 | srlx %o4, 32, %g5 /* IEU0 */ | |
191 | andcc %g5, 0xff, %g0 /* IEU1 Group */ | |
192 | be,pn %icc, 16f /* CTI */ | |
193 | cmp %o2, 4 /* IEU1 Group */ | |
194 | ||
195 | be,pn %XCC, 12f /* CTI */ | |
196 | srlx %o4, 24, %g5 /* IEU0 */ | |
197 | andcc %g5, 0xff, %g0 /* IEU1 Group */ | |
198 | be,pn %icc, 17f /* CTI */ | |
199 | ||
200 | cmp %o2, 5 /* IEU1 Group */ | |
201 | be,pn %XCC, 12f /* CTI */ | |
202 | srlx %o4, 16, %g5 /* IEU0 */ | |
203 | andcc %g5, 0xff, %g0 /* IEU1 Group */ | |
204 | ||
205 | be,pn %icc, 18f /* CTI */ | |
206 | cmp %o2, 6 /* IEU1 Group */ | |
207 | be,pn %XCC, 12f /* CTI */ | |
208 | srlx %o4, 8, %g5 /* IEU0 */ | |
209 | ||
210 | andcc %g5, 0xff, %g0 /* IEU1 Group */ | |
211 | be,pn %icc, 19f /* CTI */ | |
212 | nop /* IEU0 */ | |
213 | 12: retl /* CTI+IEU1 Group */ | |
214 | ||
215 | clr %o0 /* IEU0 */ | |
216 | nop /* Stub */ | |
217 | 13: retl /* CTI+IEU1 Group */ | |
218 | nop /* IEU0 */ | |
219 | ||
220 | 14: retl /* CTI+IEU1 Group */ | |
221 | add %o0, 1, %o0 /* IEU0 */ | |
222 | 15: retl /* CTI+IEU1 Group */ | |
223 | add %o0, 2, %o0 /* IEU0 */ | |
224 | ||
225 | 16: retl /* CTI+IEU1 Group */ | |
226 | add %o0, 3, %o0 /* IEU0 */ | |
227 | 17: retl /* CTI+IEU1 Group */ | |
228 | add %o0, 4, %o0 /* IEU0 */ | |
229 | ||
230 | 18: retl /* CTI+IEU1 Group */ | |
231 | add %o0, 5, %o0 /* IEU0 */ | |
232 | 19: retl /* CTI+IEU1 Group */ | |
233 | add %o0, 6, %o0 /* IEU0 */ | |
234 | ||
235 | 21: cmp %o0, %o2 /* IEU1 */ | |
236 | be,pn %XCC, 12b /* CTI */ | |
237 | sllx %g1, 7, %g2 /* IEU0 Group */ | |
238 | ldub [%o0], %o3 /* Load */ | |
239 | ||
240 | or %g3, %g5, %g3 /* IEU1 */ | |
241 | 22: andcc %o0, 7, %g0 /* IEU1 Group */ | |
242 | be,a,pn %icc, 1b /* CTI */ | |
243 | ldx [%o0], %o3 /* Load */ | |
244 | ||
245 | cmp %o3, %o1 /* IEU1 Group */ | |
246 | be,pn %xcc, 23f /* CTI */ | |
247 | add %o0, 1, %o0 /* IEU0 */ | |
248 | cmp %o0, %o2 /* IEU1 Group */ | |
249 | ||
250 | bne,a,pt %XCC, 22b /* CTI */ | |
251 | ldub [%o0], %o3 /* Load */ | |
252 | retl /* CTI+IEU1 Group */ | |
253 | clr %o0 /* IEU0 */ | |
254 | ||
255 | 23: retl /* CTI+IEU1 Group */ | |
256 | add %o0, -1, %o0 /* IEU0 */ | |
abf70633 GM |
257 | END(__memchr) |
258 | ||
259 | weak_alias (__memchr, memchr) | |
85dd1003 | 260 | libc_hidden_builtin_def (memchr) |