]> sourceware.org Git - glibc.git/blame - sysdeps/powerpc/strchr.S
* sysdeps/unix/sysv/linux/powerpc/sysdep.h (ALIGNARG,
[glibc.git] / sysdeps / powerpc / strchr.S
CommitLineData
9a0a462c 1/* Optimized strchr implementation for PowerPC.
1d280d9f 2 Copyright (C) 1997, 1999, 2000 Free Software Foundation, Inc.
9a0a462c
UD
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
41bdb6e2
AJ
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.
9a0a462c
UD
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
41bdb6e2 13 Lesser General Public License for more details.
9a0a462c 14
41bdb6e2
AJ
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. */
9a0a462c
UD
19
20#include <sysdep.h>
b1fc7a6a
GM
21#include <bp-sym.h>
22#include <bp-asm.h>
9a0a462c
UD
23
24/* See strlen.s for comments on how this works. */
25
1d280d9f 26/* char * [r3] strchr (const char *s [r3] , int c [r4] ) */
9a0a462c 27
b1fc7a6a 28ENTRY (BP_SYM (strchr))
1d280d9f
GM
29
30#define rTMP1 r0
31#define rRTN r3 /* outgoing result */
b1fc7a6a
GM
32#if __BOUNDED_POINTERS__
33# define rSTR r4
34# define rCHR r5 /* byte we're looking for, spread over the whole word */
35# define rWORD r8 /* the current word */
36#else
dfef32ef 37# define rSTR r8 /* current word pointer */
b1fc7a6a
GM
38# define rCHR r4 /* byte we're looking for, spread over the whole word */
39# define rWORD r5 /* the current word */
40#endif
1d280d9f 41#define rCLZB rCHR /* leading zero byte count */
1d280d9f
GM
42#define rFEFE r6 /* constant 0xfefefeff (-0x01010101) */
43#define r7F7F r7 /* constant 0x7f7f7f7f */
1d280d9f
GM
44#define rTMP2 r9
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 */
47#define rTMP3 r12
48
b1fc7a6a
GM
49 CHECK_BOUNDS_LOW (rSTR, rTMP1, rTMP2)
50 STORE_RETURN_BOUNDS (rTMP1, rTMP2)
51
1d280d9f
GM
52 rlwimi rCHR, rCHR, 8, 16, 23
53 li rMASK, -1
54 rlwimi rCHR, rCHR, 16, 0, 15
dfef32ef 55 rlwinm rIGN, rRTN, 3, 27, 28
1d280d9f
GM
56 lis rFEFE, -0x101
57 lis r7F7F, 0x7f7f
dfef32ef 58 clrrwi rSTR, rRTN, 2
1d280d9f 59 addi rFEFE, rFEFE, -0x101
b1fc7a6a 60 addi r7F7F, r7F7F, 0x7f7f
9a0a462c 61/* Test the first (partial?) word. */
1d280d9f
GM
62 lwz rWORD, 0(rSTR)
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
70 b L(loopentry)
9a0a462c
UD
71
72/* The loop. */
73
1d280d9f
GM
74L(loop):lwzu rWORD, 4(rSTR)
75 and. rTMP1, rTMP1, rTMP2
76/* Test for 0. */
77 add rTMP1, rFEFE, rWORD
78 nor rTMP2, r7F7F, rWORD
79 bne L(foundit)
80 and. rTMP1, rTMP1, rTMP2
9a0a462c 81/* Start test for the bytes we're looking for. */
1d280d9f 82 xor rTMP3, rCHR, rWORD
9a0a462c 83L(loopentry):
1d280d9f
GM
84 add rTMP1, rFEFE, rTMP3
85 nor rTMP2, r7F7F, rTMP3
86 beq L(loop)
9a0a462c
UD
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
90 happened, though. */
91L(missed):
1d280d9f 92 and. rTMP1, rTMP1, rTMP2
dfef32ef 93 li rRTN, 0
b1fc7a6a 94 STORE_RETURN_VALUE (rSTR)
9a0a462c
UD
95 beqlr
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). */
1d280d9f
GM
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
107 cmplw rWORD, rTMP2
9a0a462c 108 bgtlr
1d280d9f
GM
109 cntlzw rCLZB, rTMP2
110 srwi rCLZB, rCLZB, 3
dfef32ef 111 add rRTN, rSTR, rCLZB
b1fc7a6a
GM
112 CHECK_BOUNDS_HIGH_RTN (rSTR, rTMP2, twlge)
113 STORE_RETURN_VALUE (rSTR)
9a0a462c
UD
114 blr
115
116L(foundit):
1d280d9f
GM
117 and rTMP1, r7F7F, rTMP3
118 or rIGN, r7F7F, rTMP3
119 add rTMP1, rTMP1, r7F7F
120 nor rTMP2, rIGN, rTMP1
121 cntlzw rCLZB, rTMP2
122 subi rSTR, rSTR, 4
123 srwi rCLZB, rCLZB, 3
dfef32ef 124 add rRTN, rSTR, rCLZB
b1fc7a6a
GM
125 CHECK_BOUNDS_HIGH_RTN (rSTR, rTMP2, twlge)
126 STORE_RETURN_VALUE (rSTR)
9a0a462c 127 blr
b1fc7a6a 128END (BP_SYM (strchr))
9a0a462c 129
b1fc7a6a 130weak_alias (BP_SYM (strchr), BP_SYM (index))
This page took 0.176651 seconds and 5 git commands to generate.