1 /* Optimized strchr implementation for PowerPC.
2 Copyright (C) 1997, 1999, 2000 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
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.
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.
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
24 /* See strlen.s for comments on how this works. */
26 /* char * [r3] strchr (const char *s [r3] , int c [r4] ) */
28 ENTRY (BP_SYM (strchr))
31 #define rRTN r3 /* outgoing result */
32 #if __BOUNDED_POINTERS__
34 # define rCHR r5 /* byte we're looking for, spread over the whole word */
35 # define rWORD r8 /* the current word */
37 # define rSTR r8 /* current word pointer */
38 # define rCHR r4 /* byte we're looking for, spread over the whole word */
39 # define rWORD r5 /* the current word */
41 #define rCLZB rCHR /* leading zero byte count */
42 #define rFEFE r6 /* constant 0xfefefeff (-0x01010101) */
43 #define r7F7F r7 /* constant 0x7f7f7f7f */
45 #define rIGN r10 /* number of bits we should ignore in the first word */
46 #define rMASK r11 /* mask with the bits to ignore set to 0 */
49 CHECK_BOUNDS_LOW (rSTR, rTMP1, rTMP2)
50 STORE_RETURN_BOUNDS (rTMP1, rTMP2)
52 rlwimi rCHR, rCHR, 8, 16, 23
54 rlwimi rCHR, rCHR, 16, 0, 15
55 rlwinm rIGN, rRTN, 3, 27, 28
59 addi rFEFE, rFEFE, -0x101
60 addi r7F7F, r7F7F, 0x7f7f
61 /* Test the first (partial?) word. */
63 srw rMASK, rMASK, rIGN
64 orc rWORD, rWORD, rMASK
65 add rTMP1, rFEFE, rWORD
66 nor rTMP2, r7F7F, rWORD
67 and. rTMP1, rTMP1, rTMP2
68 xor rTMP3, rCHR, rWORD
69 orc rTMP3, rTMP3, rMASK
74 L(loop):lwzu rWORD, 4(rSTR)
75 and. rTMP1, rTMP1, rTMP2
77 add rTMP1, rFEFE, rWORD
78 nor rTMP2, r7F7F, rWORD
80 and. rTMP1, rTMP1, rTMP2
81 /* Start test for the bytes we're looking for. */
82 xor rTMP3, rCHR, rWORD
84 add rTMP1, rFEFE, rTMP3
85 nor rTMP2, r7F7F, rTMP3
87 /* There is a zero byte in the word, but may also be a matching byte (either
88 before or after the zero byte). In fact, we may be looking for a
89 zero byte, in which case we return a match. We guess that this hasn't
92 and. rTMP1, rTMP1, rTMP2
94 STORE_RETURN_VALUE (rSTR)
96 /* It did happen. Decide which one was first...
97 I'm not sure if this is actually faster than a sequence of
98 rotates, compares, and branches (we use it anyway because it's shorter). */
99 and rFEFE, r7F7F, rWORD
100 or rMASK, r7F7F, rWORD
101 and rTMP1, r7F7F, rTMP3
102 or rIGN, r7F7F, rTMP3
103 add rFEFE, rFEFE, r7F7F
104 add rTMP1, rTMP1, r7F7F
105 nor rWORD, rMASK, rFEFE
106 nor rTMP2, rIGN, rTMP1
111 add rRTN, rSTR, rCLZB
112 CHECK_BOUNDS_HIGH_RTN (rSTR, rTMP2, twlge)
113 STORE_RETURN_VALUE (rSTR)
117 and rTMP1, r7F7F, rTMP3
118 or rIGN, r7F7F, rTMP3
119 add rTMP1, rTMP1, r7F7F
120 nor rTMP2, rIGN, rTMP1
124 add rRTN, rSTR, rCLZB
125 CHECK_BOUNDS_HIGH_RTN (rSTR, rTMP2, twlge)
126 STORE_RETURN_VALUE (rSTR)
128 END (BP_SYM (strchr))
130 weak_alias (BP_SYM (strchr), BP_SYM (index))