2.9
[glibc/nacl-glibc.git] / sysdeps / sparc / sparc64 / rawmemchr.S
blobde2e780c9aec6143a69481b0e7d63dff64146a34
1 /* rawmemchr (str, ch) -- Return pointer to first occurrence of CH in STR.
2    For SPARC v9.
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
27    02111-1307 USA.  */
29 #include <sysdep.h>
30 #include <asm/asi.h>
31 #ifndef XCC
32 #define XCC xcc
33 #define USE_BPR
34         .register       %g2, #scratch
35         .register       %g3, #scratch
36 #endif
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.
52          */
54         .text
55         .align          32
56 ENTRY(__rawmemchr)
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           */
61         
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           */
87 #else
88         ldxa            [%o0] ASI_PNF, %o3              /* Load                         */
89         andcc           %o2, %g2, %g0                   /* IEU1         Group           */
90 #endif
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                         */
140         .align          16
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           */
162          nop                                            /* IEU0                         */
164         .align          16
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                         */
176 END(__rawmemchr)
178 libc_hidden_def (__rawmemchr)
179 weak_alias (__rawmemchr, rawmemchr)