]> git.ipfire.org Git - thirdparty/glibc.git/blob - sysdeps/powerpc/powerpc64/strchr.S
Update.
[thirdparty/glibc.git] / sysdeps / powerpc / powerpc64 / strchr.S
1 /* Optimized strchr implementation for PowerPC64.
2 Copyright (C) 1997, 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 02111-1307 USA. */
19
20 #include <sysdep.h>
21 #include <bp-sym.h>
22 #include <bp-asm.h>
23
24 /* See strlen.s for comments on how this works. */
25
26 /* char * [r3] strchr (const char *s [r3] , int c [r4] ) */
27
28 ENTRY (BP_SYM (strchr))
29
30 #define rTMP1 r0
31 #define rRTN r3 /* outgoing result */
32 /* Note: The Bounded pointer support in this code is broken. This code
33 was inherited from PPC32 and and that support was never completed.
34 Currently PPC gcc does not support -fbounds-check or -fbounded-pointers.
35 These artifacts are left in the code as a reminder in case we need
36 bounded pointer support in the future. */
37 #if __BOUNDED_POINTERS__
38 # define rSTR r4
39 # define rCHR r5 /* byte we're looking for, spread over the whole word */
40 # define rWORD r8 /* the current word */
41 #else
42 # define rSTR r8 /* current word pointer */
43 # define rCHR r4 /* byte we're looking for, spread over the whole word */
44 # define rWORD r5 /* the current word */
45 #endif
46 #define rCLZB rCHR /* leading zero byte count */
47 #define rFEFE r6 /* constant 0xfefefefefefefeff (-0x0101010101010101) */
48 #define r7F7F r7 /* constant 0x7f7f7f7f7f7f7f7f */
49 #define rTMP2 r9
50 #define rIGN r10 /* number of bits we should ignore in the first word */
51 #define rMASK r11 /* mask with the bits to ignore set to 0 */
52 #define rTMP3 r12
53
54 CHECK_BOUNDS_LOW (rSTR, rTMP1, rTMP2)
55 STORE_RETURN_BOUNDS (rTMP1, rTMP2)
56
57 dcbt 0,rRTN
58 rlwimi rCHR, rCHR, 8, 16, 23
59 li rMASK, -1
60 rlwimi rCHR, rCHR, 16, 0, 15
61 rlwinm rIGN, rRTN, 3, 26, 28
62 insrdi rCHR, rCHR, 32, 0
63 lis rFEFE, -0x101
64 lis r7F7F, 0x7f7f
65 clrrdi rSTR, rRTN, 3
66 addi rFEFE, rFEFE, -0x101
67 addi r7F7F, r7F7F, 0x7f7f
68 sldi rTMP1, rFEFE, 32
69 insrdi r7F7F, r7F7F, 32, 0
70 add rFEFE, rFEFE, rTMP1
71 /* Test the first (partial?) word. */
72 ld rWORD, 0(rSTR)
73 srd rMASK, rMASK, rIGN
74 orc rWORD, rWORD, rMASK
75 add rTMP1, rFEFE, rWORD
76 nor rTMP2, r7F7F, rWORD
77 and. rTMP1, rTMP1, rTMP2
78 xor rTMP3, rCHR, rWORD
79 orc rTMP3, rTMP3, rMASK
80 b L(loopentry)
81
82 /* The loop. */
83
84 L(loop):ldu rWORD, 8(rSTR)
85 and. rTMP1, rTMP1, rTMP2
86 /* Test for 0. */
87 add rTMP1, rFEFE, rWORD
88 nor rTMP2, r7F7F, rWORD
89 bne L(foundit)
90 and. rTMP1, rTMP1, rTMP2
91 /* Start test for the bytes we're looking for. */
92 xor rTMP3, rCHR, rWORD
93 L(loopentry):
94 add rTMP1, rFEFE, rTMP3
95 nor rTMP2, r7F7F, rTMP3
96 beq L(loop)
97 /* There is a zero byte in the word, but may also be a matching byte (either
98 before or after the zero byte). In fact, we may be looking for a
99 zero byte, in which case we return a match. We guess that this hasn't
100 happened, though. */
101 L(missed):
102 and. rTMP1, rTMP1, rTMP2
103 li rRTN, 0
104 STORE_RETURN_VALUE (rSTR)
105 beqlr
106 /* It did happen. Decide which one was first...
107 I'm not sure if this is actually faster than a sequence of
108 rotates, compares, and branches (we use it anyway because it's shorter). */
109 and rFEFE, r7F7F, rWORD
110 or rMASK, r7F7F, rWORD
111 and rTMP1, r7F7F, rTMP3
112 or rIGN, r7F7F, rTMP3
113 add rFEFE, rFEFE, r7F7F
114 add rTMP1, rTMP1, r7F7F
115 nor rWORD, rMASK, rFEFE
116 nor rTMP2, rIGN, rTMP1
117 cmpld rWORD, rTMP2
118 bgtlr
119 cntlzd rCLZB, rTMP2
120 srdi rCLZB, rCLZB, 3
121 add rRTN, rSTR, rCLZB
122 CHECK_BOUNDS_HIGH_RTN (rSTR, rTMP2, tdlge)
123 STORE_RETURN_VALUE (rSTR)
124 blr
125
126 L(foundit):
127 and rTMP1, r7F7F, rTMP3
128 or rIGN, r7F7F, rTMP3
129 add rTMP1, rTMP1, r7F7F
130 nor rTMP2, rIGN, rTMP1
131 cntlzd rCLZB, rTMP2
132 subi rSTR, rSTR, 8
133 srdi rCLZB, rCLZB, 3
134 add rRTN, rSTR, rCLZB
135 CHECK_BOUNDS_HIGH_RTN (rSTR, rTMP2, tdlge)
136 STORE_RETURN_VALUE (rSTR)
137 blr
138 END (BP_SYM (strchr))
139
140 weak_alias (BP_SYM (strchr), BP_SYM (index))
141 libc_hidden_builtin_def (strchr)