Improve generic strpbrk performance
[glibc.git] / sysdeps / powerpc / powerpc64 / strpbrk.S
blob5e9d1a66aa1b6f15d300b3737e53923891ec4996
1 /* Optimized strpbrk implementation for PowerPC64.
2    Copyright (C) 2014-2016 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, see
17    <http://www.gnu.org/licenses/>.  */
19 #include <sysdep.h>
21 /* char [r3] *strpbrk(const char [r4] *s, const char [r5] *accept)  */
23 EALIGN (strpbrk, 4, 0)
24         CALL_MCOUNT 3
26         lbz     r10,0(r4)
27         cmpdi   cr7,r10,0       /* accept[0] == '\0' ?  */
28         beq     cr7,L(nullfound)
30         /* The idea to speed up the algorithm is to create a lookup table
31            for fast check if input character should be considered.  For ASCII
32            or ISO-8859-X character sets it has 256 positions.  */
34         /* PPC64 ELF ABI stack is aligned to 16 bytes.  */
35         addi    r9,r1,-256
36         /* Clear the table with 0 values  */
37         li      r6, 0
38         li      r7, 4
39         mtctr   r7
40         mr      r8, r9
41         .align  4
42 L(zerohash):
43         std     r6, 0(r8)
44         std     r6, 8(r8)
45         std     r6, 16(r8)
46         std     r6, 24(r8)
47         std     r6, 32(r8)
48         std     r6, 40(r8)
49         std     r6, 48(r8)
50         std     r6, 56(r8)
51         addi    r8, r8, 64
52         bdnz    L(zerohash)
54         /* Initialize the table as:
55            for (i=0; accept[i]; i++
56              table[accept[i]]] = 1  */
57         li      r0,1
58         .align 4
59 L(init_table):
60         stbx    r0,r9,r10
61         lbzu    r10,1(r4)
62         cmpdi   r0,r10,0
63         bne     cr0,L(init_table)
64 L(finish_table):
65         /* set table[0] = 1  */
66         li      r4,1
67         stb     r4,0(r9)
68         b       L(mainloop)
70         /* Unrool the loop 4 times and check using the table as:
71            i = 0;
72            while (1)
73              {
74                if (table[input[i++]] == 1)
75                  return (s[i -1] ? s + i - 1: NULL);
76                if (table[input[i++]] == 1)
77                  return (s[i -1] ? s + i - 1: NULL);
78                if (table[input[i++]] == 1)
79                  return (s[i -1] ? s + i - 1: NULL);
80                if (table[input[i++]] == 1)
81                  return (s[i -1] ? s + i - 1: NULL);
82              }  */
83         .align 4
84 L(unroll):
85         lbz     r0,1(r3)
86         lbzx    r8,r9,r0
87         cmpwi   cr6,r8,1
88         beq     cr6,L(checkend2)
89         lbz     r10,2(r3)
90         lbzx    r4,r9,r10
91         cmpwi   cr7,r4,1
92         beq     cr7,L(checkend3)
93         lbz     r12,3(r3)
94         addi    r3,r3,4
95         lbzx    r11,r9,r12
96         cmpwi   cr0,r11,1
97         beq     cr0,L(checkend)
98 L(mainloop):
99         lbz     r12,0(r3)
100         addi    r11,r3,1
101         addi    r5,r3,2
102         addi    r7,r3,3
103         lbzx    r6,r9,r12
104         cmpwi   cr1,r6,1
105         bne     cr1,L(unroll)
106         cmpdi   cr0,r12,0
107         beq     cr0,L(nullfound)
108 L(end):
109         blr
111         .align 4
112 L(checkend):
113         cmpdi   cr1,r12,0
114         mr      r3,r7
115         bne     cr1,L(end)
116 L(nullfound):
117         /* return NULL  */
118         li 3,0
119         blr
121         .align 4
122 L(checkend2):
123         cmpdi   cr7,r0,0
124         mr      r3,r11
125         beq     cr7,L(nullfound)
126         blr
128         .align 4
129 L(checkend3):
130         cmpdi   cr6,r10,0
131         mr      r3,r5
132         beq     cr6,L(nullfound)
133         blr
134 END (strpbrk)
135 libc_hidden_builtin_def (strpbrk)