1 | /* rawmemchr (str, ch) -- Return pointer to first occurrence of CH in STR. |
2 | For SPARC v9. |
3 | Copyright (C) 1999-2024 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 |
47 | ENTRY(__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 | |
68 | 18: ldx [%o0], %o3 /* Load */ |
69 | or %o4, %g5, %o4 /* IEU1 */ |
70 | add %o0, 8, %o0 /* IEU0 Group */ |
71 | 19: 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 */ |
87 | 20: 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 */ |
105 | 21: 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 |
132 | 22: retl /* CTI+IEU1 Group */ |
133 | add %o0, -9, %o0 /* IEU0 */ |
134 | 23: retl /* CTI+IEU1 Group */ |
135 | add %o0, -10, %o0 /* IEU0 */ |
136 | |
137 | 24: retl /* CTI+IEU1 Group */ |
138 | add %o0, -11, %o0 /* IEU0 */ |
139 | 25: retl /* CTI+IEU1 Group */ |
140 | add %o0, -12, %o0 /* IEU0 */ |
141 | |
142 | 26: retl /* CTI+IEU1 Group */ |
143 | add %o0, -13, %o0 /* IEU0 */ |
144 | 27: retl /* CTI+IEU1 Group */ |
145 | add %o0, -14, %o0 /* IEU0 */ |
146 | |
147 | 28: retl /* CTI+IEU1 Group */ |
148 | add %o0, -15, %o0 /* IEU0 */ |
149 | 29: retl /* CTI+IEU1 Group */ |
150 | add %o0, -16, %o0 /* IEU0 */ |
151 | |
152 | 30: retl /* CTI+IEU1 Group */ |
153 | nop /* IEU0 */ |
154 | |
155 | .align 16 |
156 | 32: 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 */ |
167 | END(__rawmemchr) |
168 | |
169 | libc_hidden_def (__rawmemchr) |
170 | weak_alias (__rawmemchr, rawmemchr) |
171 | |