1 /* Determine the length of a string. For SPARC v9.
2 Copyright (C) 1998, 1999, 2003 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4 Contributed by Jan Vondrak <jvon4518@ss1000.ms.mff.cuni.cz> and
5 Jakub Jelinek <jj@ultra.linux.cz>.
7 The GNU C Library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
12 The GNU C Library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public
18 License along with the GNU C Library; if not, write to the Free
19 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
25 /* Normally, this uses
26 ((xword - 0x0101010101010101) & 0x8080808080808080) test
27 to find out if any byte in xword could be zero. This is fast, but
28 also gives false alarm for any byte in range 0x81-0xff. It does
29 not matter for correctness, as if this test tells us there could
30 be some zero byte, we check it byte by byte, but if bytes with
31 high bits set are common in the strings, then this will give poor
32 performance. You can #define EIGHTBIT_NOT_RARE and the algorithm
33 will use one tick slower, but more precise test
34 ((xword - 0x0101010101010101) & (~xword) & 0x8080808080808080),
35 which does not give any false alarms (but if some bits are set,
36 one cannot assume from it which bytes are zero and which are not).
37 It is yet to be measured, what is the correct default for glibc
38 in these days for an average user.
44 sethi %hi(0x01010101), %g1 /* IEU0 Group */
45 ldub [%o0], %o3 /* Load */
46 or %g1, %lo(0x01010101), %g1 /* IEU0 Group */
47 mov %o0, %o1 /* IEU1 */
49 sllx %g1, 32, %g4 /* IEU0 Group */
50 andcc %o0, 7, %g0 /* IEU1 */
51 or %g1, %g4, %g1 /* IEU0 Group */
52 brz,pn %o3, 13f /* CTI+IEU1 */
54 sllx %g1, 7, %g4 /* IEU0 Group */
55 bne,a,pn %icc, 15f /* CTI */
56 add %o0, 1, %o0 /* IEU1 */
57 /* %g1 = 0x0101010101010101 *
58 * %g4 = 0x8080808080808080 *
59 * %o0 = string pointer *
60 * %o1 = start of string */
61 1: ldx [%o0], %o3 /* Load Group */
63 add %o0, 8, %o0 /* IEU1 */
64 2: sub %o3, %g1, %o2 /* IEU0 Group */
65 #ifdef EIGHTBIT_NOT_RARE
66 andn %o2, %o3, %o5 /* IEU0 Group */
67 ldxa [%o0] ASI_PNF, %o3 /* Load */
68 andcc %o5, %g4, %g0 /* IEU1 Group */
70 ldxa [%o0] ASI_PNF, %o3 /* Load */
71 andcc %o2, %g4, %g0 /* IEU1 Group */
74 be,pt %xcc, 2b /* CTI */
75 add %o0, 8, %o0 /* IEU0 */
76 addcc %o2, %g1, %g5 /* IEU1 Group */
77 #ifdef EIGHTBIT_NOT_RARE
78 srlx %o5, 32, %o5 /* IEU0 */
80 3: andcc %o5, %g4, %g0 /* IEU1 Group */
82 srlx %o2, 32, %o2 /* IEU0 */
84 3: andcc %o2, %g4, %g0 /* IEU1 Group */
86 be,pn %xcc, 4f /* CTI */
87 srlx %g5, 56, %o2 /* IEU0 */
88 andcc %o2, 0xff, %g0 /* IEU1 Group */
90 be,pn %icc, 12f /* CTI */
91 srlx %g5, 48, %o2 /* IEU0 */
92 andcc %o2, 0xff, %g0 /* IEU1 Group */
93 be,pn %icc, 11f /* CTI */
95 srlx %g5, 40, %o2 /* IEU0 */
96 andcc %o2, 0xff, %g0 /* IEU1 Group */
97 be,pn %icc, 10f /* CTI */
98 srlx %g5, 32, %o2 /* IEU0 */
100 andcc %o2, 0xff, %g0 /* IEU1 Group */
101 be,pn %icc, 9f /* CTI */
102 4: srlx %g5, 24, %o2 /* IEU0 */
103 andcc %o2, 0xff, %g0 /* IEU1 Group */
105 be,pn %icc, 8f /* CTI */
106 srlx %g5, 16, %o2 /* IEU0 */
107 andcc %o2, 0xff, %g0 /* IEU1 Group */
108 be,pn %icc, 7f /* CTI */
110 srlx %g5, 8, %o2 /* IEU0 */
111 andcc %o2, 0xff, %g0 /* IEU1 Group */
112 be,pn %icc, 6f /* CTI */
113 sub %o3, %g1, %o2 /* IEU0 */
115 andcc %g5, 0xff, %g0 /* IEU1 Group */
116 be,pn %icc, 5f /* CTI */
117 ldxa [%o0] ASI_PNF, %o3 /* Load */
118 andcc %o2, %g4, %g0 /* IEU1 Group */
120 be,pt %xcc, 2b /* CTI */
121 add %o0, 8, %o0 /* IEU0 */
122 addcc %o2, %g1, %g5 /* IEU1 Group */
123 ba,pt %xcc, 3b /* CTI */
125 srlx %o2, 32, %o2 /* IEU0 */
126 5: add %o0, -9, %o0 /* IEU0 Group */
127 retl /* CTI+IEU1 Group */
128 sub %o0, %o1, %o0 /* IEU0 */
130 6: add %o0, -10, %o0 /* IEU0 Group */
131 retl /* CTI+IEU1 Group */
132 sub %o0, %o1, %o0 /* IEU0 */
133 7: add %o0, -11, %o0 /* IEU0 Group */
135 retl /* CTI+IEU1 Group */
136 sub %o0, %o1, %o0 /* IEU0 */
137 8: add %o0, -12, %o0 /* IEU0 Group */
138 retl /* CTI+IEU1 Group */
140 sub %o0, %o1, %o0 /* IEU0 */
141 9: add %o0, -13, %o0 /* IEU0 Group */
142 retl /* CTI+IEU1 Group */
143 sub %o0, %o1, %o0 /* IEU0 */
145 10: add %o0, -14, %o0 /* IEU0 Group */
146 retl /* CTI+IEU1 Group */
147 sub %o0, %o1, %o0 /* IEU0 */
148 11: add %o0, -15, %o0 /* IEU0 Group */
150 retl /* CTI+IEU1 Group */
151 sub %o0, %o1, %o0 /* IEU0 */
152 12: add %o0, -16, %o0 /* IEU0 Group */
153 retl /* CTI+IEU1 Group */
155 sub %o0, %o1, %o0 /* IEU0 */
156 13: retl /* CTI+IEU1 Group */
157 mov 0, %o0 /* IEU0 */
160 15: ldub [%o0], %o3 /* Load Group */
161 16: andcc %o0, 7, %g0 /* IEU1 */
162 be,pn %icc, 1b /* CTI */
165 add %o0, 1, %o0 /* IEU1 */
166 andcc %o3, 0xff, %g0 /* IEU1 Group */
167 bne,a,pt %icc, 16b /* CTI */
168 lduba [%o0] ASI_PNF, %o3 /* Load */
170 add %o0, -1, %o0 /* IEU0 Group */
171 retl /* CTI+IEU1 Group */
172 sub %o0, %o1, %o0 /* IEU0 */
174 libc_hidden_builtin_def (strlen)