Update.
[platform/upstream/glibc.git] / sysdeps / powerpc / strchr.s
1  # Optimized strchr implementation for PowerPC.
2  # Copyright (C) 1997 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 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.
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  # Library General Public License for more details.
14  #
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.
19
20  # See strlen.s for comments on how this works.
21
22         .section ".text"
23         .align 2
24         .globl strchr
25         .type strchr,@function
26 strchr:
27  # char * [r3] strchr (const char *s [r3] , int c [r4] )
28
29  # r0:  a temporary
30  # r3:  our return result.
31  # r4:  byte we're looking for, spread over the whole word
32  # r5:  the current word
33  # r6:  the constant 0xfefefeff (-0x01010101)
34  # r7:  the constant 0x7f7f7f7f
35  # r8:  pointer to the current word.
36  # r9:  a temporary
37  # r10: the number of bits we should ignore in the first word
38  # r11: a mask with the bits to ignore set to 0
39  # r12: a temporary
40         
41         rlwimi %r4,%r4,8,16,23
42         li   %r11,-1
43         rlwimi %r4,%r4,16,0,15
44         lis  %r6,0xfeff
45         lis  %r7,0x7f7f
46         clrrwi %r8,%r3,2
47         addi %r7,%r7,0x7f7f
48         addi %r6,%r6,0xfffffeff
49         rlwinm %r10,%r3,3,27,28
50  # Test the first (partial?) word.
51         lwz  %r5,0(%r8)
52         srw  %r11,%r11,%r10
53         orc  %r5,%r5,%r11
54         add  %r0,%r6,%r5
55         nor  %r9,%r7,%r5
56         and. %r0,%r0,%r9
57         xor  %r12,%r4,%r5
58         orc  %r12,%r12,%r11
59         b    loopentry
60         
61  # The loop.
62
63 loop:   lwzu %r5,4(%r8)
64         and. %r0,%r0,%r9
65  # Test for 0
66         add  %r0,%r6,%r5
67         nor  %r9,%r7,%r5
68         bne  foundit
69         and. %r0,%r0,%r9
70  # Start test for the bytes we're looking for
71         xor  %r12,%r4,%r5
72 loopentry:
73         add  %r0,%r6,%r12
74         nor  %r9,%r7,%r12
75         beq  loop
76  # There is a zero byte in the word, but may also be a matching byte (either
77  # before or after the zero byte). In fact, we may be looking for a
78  # zero byte, in which case we return a match. We guess that this hasn't
79  # happened, though.
80 missed: 
81         and. %r0,%r0,%r9
82         li   %r3,0
83         beqlr
84  # It did happen. Decide which one was first...
85  # I'm not sure if this is actually faster than a sequence of
86  # rotates, compares, and branches (we use it anyway because it's shorter).
87         and  %r6,%r7,%r5
88         or   %r11,%r7,%r5
89         and  %r0,%r7,%r12
90         or   %r10,%r7,%r12
91         add  %r6,%r6,%r7
92         add  %r0,%r0,%r7
93         nor  %r5,%r11,%r6
94         nor  %r9,%r10,%r0
95         cmplw %r5,%r9
96         bgtlr
97         cntlzw %r4,%r9
98         srwi %r4,%r4,3
99         add  %r3,%r8,%r4
100         blr
101
102 foundit:
103         and  %r0,%r7,%r12
104         or   %r10,%r7,%r12
105         add  %r0,%r0,%r7
106         nor  %r9,%r10,%r0
107         cntlzw %r4,%r9
108         subi %r8,%r8,4
109         srwi %r4,%r4,3
110         add  %r3,%r8,%r4
111         blr
112
113 0:
114         .size    strchr,0b-strchr
115
116         .globl index
117         .weak index
118         .set index,strchr