1 /* rawmemchr (str, ch) -- Return pointer to first occurrence of CH in STR.
3 Copyright (C) 1999, 2002 Free Software Foundation, Inc.
4 This file is part of the GNU C Library.
5 Contributed by Jakub Jelinek <jj@ultra.linux.cz>.
6 This version is developed using the same algorithm as the fast C
7 version which carries the following introduction:
8 Based on strlen implementation by Torbjorn Granlund (tege@sics.se),
9 with help from Dan Sahlin (dan@sics.se) and
10 commentary by Jim Blandy (jimb@ai.mit.edu);
11 adaptation to memchr suggested by Dick Karpinski (dick@cca.ucsf.edu),
12 and implemented by Roland McGrath (roland@ai.mit.edu).
14 The GNU C Library is free software; you can redistribute it and/or
15 modify it under the terms of the GNU Lesser General Public
16 License as published by the Free Software Foundation; either
17 version 2.1 of the License, or (at your option) any later version.
19 The GNU C Library is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 Lesser General Public License for more details.
24 You should have received a copy of the GNU Lesser General Public
25 License along with the GNU C Library; if not, write to the Free
26 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
34 .register %g2, #scratch
35 .register %g3, #scratch
38 /* Normally, this uses
39 ((xword - 0x0101010101010101) & 0x8080808080808080) test
40 to find out if any byte in xword could be zero. This is fast, but
41 also gives false alarm for any byte in range 0x81-0xff. It does
42 not matter for correctness, as if this test tells us there could
43 be some zero byte, we check it byte by byte, but if bytes with
44 high bits set are common in the strings, then this will give poor
45 performance. You can #define EIGHTBIT_NOT_RARE and the algorithm
46 will use one tick slower, but more precise test
47 ((xword - 0x0101010101010101) & (~xword) & 0x8080808080808080),
48 which does not give any false alarms (but if some bits are set,
49 one cannot assume from it which bytes are zero and which are not).
50 It is yet to be measured, what is the correct default for glibc
51 in these days for an average user.
57 and %o1, 0xff, %o1 /* IEU0 Group */
58 sethi %hi(0x01010101), %g1 /* IEU1 */
59 ldub [%o0], %o3 /* Load */
60 sll %o1, 8, %o4 /* IEU0 Group */
62 or %g1, %lo(0x01010101), %g1 /* IEU1 */
63 sllx %g1, 32, %g2 /* IEU0 Group */
64 or %o4, %o1, %o4 /* IEU1 */
65 andcc %o0, 7, %g0 /* IEU1 Group */
67 sll %o4, 16, %g5 /* IEU0 */
68 or %o4, %g5, %o4 /* IEU0 Group */
69 or %g1, %g2, %g1 /* IEU1 */
70 bne,pn %icc, 32f /* CTI */
72 sllx %o4, 32, %g5 /* IEU0 Group */
73 cmp %o3, %o1 /* IEU1 */
74 be,pn %icc, 30f /* CTI */
75 sllx %g1, 7, %g2 /* IEU0 Group */
77 18: ldx [%o0], %o3 /* Load */
78 or %o4, %g5, %o4 /* IEU1 */
79 add %o0, 8, %o0 /* IEU0 Group */
80 19: xor %o3, %o4, %o3 /* IEU0 Group */
82 sub %o3, %g1, %o2 /* IEU0 Group */
83 #ifdef EIGHTBIT_NOT_RARE
84 andn %o2, %o3, %o5 /* IEU0 Group */
85 ldxa [%o0] ASI_PNF, %o3 /* Load */
86 andcc %o5, %g2, %g0 /* IEU1 Group */
88 ldxa [%o0] ASI_PNF, %o3 /* Load */
89 andcc %o2, %g2, %g0 /* IEU1 Group */
91 be,pt %xcc, 19b /* CTI */
93 add %o0, 8, %o0 /* IEU0 */
94 addcc %o2, %g1, %g3 /* IEU1 Group */
95 srlx %o2, 32, %o2 /* IEU0 */
96 20: andcc %o2, %g2, %g0 /* IEU1 Group */
98 be,pn %xcc, 21f /* CTI */
99 srlx %g3, 56, %o2 /* IEU0 */
100 andcc %o2, 0xff, %g0 /* IEU1 Group */
101 be,pn %icc, 29f /* CTI */
103 srlx %g3, 48, %o2 /* IEU0 */
104 andcc %o2, 0xff, %g0 /* IEU1 Group */
105 be,pn %icc, 28f /* CTI */
106 srlx %g3, 40, %o2 /* IEU0 */
108 andcc %o2, 0xff, %g0 /* IEU1 Group */
109 be,pn %icc, 27f /* CTI */
110 srlx %g3, 32, %o2 /* IEU0 */
111 andcc %o2, 0xff, %g0 /* IEU1 Group */
113 be,pn %icc, 26f /* CTI */
114 21: srlx %g3, 24, %o2 /* IEU0 */
115 andcc %o2, 0xff, %g0 /* IEU1 Group */
116 be,pn %icc, 25f /* CTI */
118 srlx %g3, 16, %o2 /* IEU0 */
119 andcc %o2, 0xff, %g0 /* IEU1 Group */
120 be,pn %icc, 24f /* CTI */
121 srlx %g3, 8, %o2 /* IEU0 */
123 andcc %o2, 0xff, %g0 /* IEU1 Group */
124 be,pn %icc, 23f /* CTI */
125 xor %o3, %o4, %o3 /* IEU0 */
126 andcc %g3, 0xff, %g0 /* IEU1 Group */
128 be,pn %icc, 22f /* CTI */
129 sub %o3, %g1, %o2 /* IEU0 */
130 ldxa [%o0] ASI_PNF, %o3 /* Load */
131 andcc %o2, %g2, %g0 /* IEU1 Group */
133 be,pt %xcc, 19b /* CTI */
134 add %o0, 8, %o0 /* IEU0 */
135 addcc %o2, %g1, %g3 /* IEU1 Group */
136 ba,pt %xcc, 20b /* CTI */
138 srlx %o2, 32, %o2 /* IEU0 */
141 22: retl /* CTI+IEU1 Group */
142 add %o0, -9, %o0 /* IEU0 */
143 23: retl /* CTI+IEU1 Group */
144 add %o0, -10, %o0 /* IEU0 */
146 24: retl /* CTI+IEU1 Group */
147 add %o0, -11, %o0 /* IEU0 */
148 25: retl /* CTI+IEU1 Group */
149 add %o0, -12, %o0 /* IEU0 */
151 26: retl /* CTI+IEU1 Group */
152 add %o0, -13, %o0 /* IEU0 */
153 27: retl /* CTI+IEU1 Group */
154 add %o0, -14, %o0 /* IEU0 */
156 28: retl /* CTI+IEU1 Group */
157 add %o0, -15, %o0 /* IEU0 */
158 29: retl /* CTI+IEU1 Group */
159 add %o0, -16, %o0 /* IEU0 */
161 30: retl /* CTI+IEU1 Group */
165 32: andcc %o0, 7, %g0 /* IEU1 Group */
166 be,a,pn %icc, 18b /* CTI */
167 sllx %g1, 7, %g2 /* IEU0 */
168 add %o0, 1, %o0 /* IEU0 Group */
170 cmp %o3, %o1 /* IEU1 */
171 bne,a,pt %icc, 32b /* CTI */
172 lduba [%o0] ASI_PNF, %o3 /* Load */
173 retl /* CTI+IEU1 Group */
175 add %o0, -1, %o0 /* IEU0 */
178 libc_hidden_def (__rawmemchr)
179 weak_alias (__rawmemchr, rawmemchr)