Update.
[glibc.git] / sysdeps / powerpc / strchr.S
blob5367a5a4fe2ea4bf304909026348c7837ca64338
1 /* Optimized strchr implementation for PowerPC.
2    Copyright (C) 1997, 1999 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 Library General Public License as
7    published by the Free Software Foundation; either version 2 of the
8    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    Library General Public License for more details.
15    You should have received a copy of the GNU Library General Public
16    License along with the GNU C Library; see the file COPYING.LIB.  If not,
17    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18    Boston, MA 02111-1307, USA.  */
20 #include <sysdep.h>
22 /* See strlen.s for comments on how this works.  */
24 /* char * [r3] strchr (const char *s [r3] , int c [r4] )
26    r0:  a temporary
27    r3:  our return result.
28    r4:  byte we're looking for, spread over the whole word
29    r5:  the current word
30    r6:  the constant 0xfefefeff (-0x01010101)
31    r7:  the constant 0x7f7f7f7f
32    r8:  pointer to the current word.
33    r9:  a temporary
34    r10: the number of bits we should ignore in the first word
35    r11: a mask with the bits to ignore set to 0
36    r12: a temporary  */
37 ENTRY(strchr)
38         rlwimi r4,r4,8,16,23
39         li   r11,-1
40         rlwimi r4,r4,16,0,15
41         lis  r6,0xfeff
42         lis  r7,0x7f7f
43         clrrwi r8,r3,2
44         addi r7,r7,0x7f7f
45         addi r6,r6,0xfffffeff
46         rlwinm r10,r3,3,27,28
47 /* Test the first (partial?) word.  */
48         lwz  r5,0(r8)
49         srw  r11,r11,r10
50         orc  r5,r5,r11
51         add  r0,r6,r5
52         nor  r9,r7,r5
53         and. r0,r0,r9
54         xor  r12,r4,r5
55         orc  r12,r12,r11
56         b    L(loopentry)
58 /* The loop.  */
60 L(loop):lwzu r5,4(r8)
61         and. r0,r0,r9
62 /* Test for 0.  */
63         add  r0,r6,r5
64         nor  r9,r7,r5
65         bne  L(foundit)
66         and. r0,r0,r9
67 /* Start test for the bytes we're looking for.  */
68         xor  r12,r4,r5
69 L(loopentry):
70         add  r0,r6,r12
71         nor  r9,r7,r12
72         beq  L(loop)
73 /* There is a zero byte in the word, but may also be a matching byte (either
74    before or after the zero byte).  In fact, we may be looking for a
75    zero byte, in which case we return a match.  We guess that this hasn't
76    happened, though.  */
77 L(missed):
78         and. r0,r0,r9
79         li   r3,0
80         beqlr
81 /* It did happen. Decide which one was first...
82    I'm not sure if this is actually faster than a sequence of
83    rotates, compares, and branches (we use it anyway because it's shorter).  */
84         and  r6,r7,r5
85         or   r11,r7,r5
86         and  r0,r7,r12
87         or   r10,r7,r12
88         add  r6,r6,r7
89         add  r0,r0,r7
90         nor  r5,r11,r6
91         nor  r9,r10,r0
92         cmplw r5,r9
93         bgtlr
94         cntlzw r4,r9
95         srwi r4,r4,3
96         add  r3,r8,r4
97         blr
99 L(foundit):
100         and  r0,r7,r12
101         or   r10,r7,r12
102         add  r0,r0,r7
103         nor  r9,r10,r0
104         cntlzw r4,r9
105         subi r8,r8,4
106         srwi r4,r4,3
107         add  r3,r8,r4
108         blr
109 END(strchr)
111 weak_alias(strchr,index)