2.9
[glibc/nacl-glibc.git] / sysdeps / sparc / sparc64 / strlen.S
blobcc15e4e3fb666109016263e0f4a02da7f16f8990
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
20    02111-1307 USA.  */
22 #include <sysdep.h>
23 #include <asm/asi.h>
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.
39          */
41         .text
42         .align          32
43 ENTRY(strlen)
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           */
69 #else
70         ldxa            [%o0] ASI_PNF, %o3              /* Load                         */
71         andcc           %o2, %g4, %g0                   /* IEU1         Group           */
72 #endif
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           */
81 #else
82         srlx            %o2, 32, %o2                    /* IEU0                         */
84 3:      andcc           %o2, %g4, %g0                   /* IEU1         Group           */
85 #endif
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                         */
158         nop
160 15:     ldub            [%o0], %o3                      /* Load         Group           */
161 16:     andcc           %o0, 7, %g0                     /* IEU1                         */
162         be,pn           %icc, 1b                        /* CTI                          */
163          nop                                            /* IEU0         Group           */
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                         */
173 END(strlen)
174 libc_hidden_builtin_def (strlen)