]> git.ipfire.org Git - thirdparty/glibc.git/blame - sysdeps/powerpc/powerpc64/strspn.S
Update copyright dates with scripts/update-copyrights.
[thirdparty/glibc.git] / sysdeps / powerpc / powerpc64 / strspn.S
CommitLineData
2e8a2de2 1/* Optimized strspn implementation for PowerPC64.
e65caf1f 2
b168057a 3 Copyright (C) 2014-2015 Free Software Foundation, Inc.
e65caf1f
VR
4 This file is part of the GNU C Library.
5
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
10
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, see
18 <http://www.gnu.org/licenses/>. */
19
20/* size_t [r3] strspn (const char *string [r3],
21 const char *needleAccept [r4] */
22
23/* Performance gains are grabbed through following techniques:
24
25 > hashing of needle.
26 > hashing avoids scanning of duplicate entries in needle
27 across the string.
e65caf1f
VR
28 > unrolling when scanning for character in string
29 across hash table. */
30
31/* Algorithm is as below:
32 1. A empty hash table/dictionary is created comprising of
33 256 ascii character set
34 2. When hash entry is found in needle , the hash index
35 is initialized to 1
36 3. The string is scanned until end and for every character,
37 its corresponding hash index is compared.
38 4. initial length of string (count) until first hit of
39 accept needle to be found is set to 0
40 4. If hash index is set to 1 for the index of string,
41 count is returned.
42 5. Otherwise count is incremented and scanning continues
43 until end of string. */
44
45#include <sysdep.h>
46
e65caf1f 47EALIGN(strspn, 4, 0)
2e8a2de2
AZ
48 CALL_MCOUNT 3
49
50 /* PPC64 ELF ABI stack is aligned to 16 bytes. */
51 addi r9,r1,-256
52 /* Clear the table with 0 values */
53 li r6, 0
54 li r8, 4
55 mtctr r8
56 mr r10, r9
57 .align 4
58L(zerohash):
59 std r6, 0(r10)
60 std r6, 8(r10)
61 std r6, 16(r10)
62 std r6, 24(r10)
63 std r6, 32(r10)
64 std r6, 40(r10)
65 std r6, 48(r10)
66 std r6, 56(r10)
67 addi r10, r10, 64
68 bdnz L(zerohash)
69
70 lbz r10,0(r4)
e65caf1f
VR
71 li r8, 1 /* r8=1, marker into hash if found in
72 needle */
e65caf1f
VR
73 cmpdi cr7, r10, 0 /* accept needle is NULL */
74 beq cr7, L(skipHashing) /* if needle is NULL, skip hashing */
75
2e8a2de2 76 .align 4 /* align section to 16 byte boundary */
e65caf1f
VR
77L(hashing):
78 stbx r8, r9, r10 /* update hash with marker for the pivot of
79 the needle */
80 lbzu r10, 1(r4) /* load needle into r10 and update to next */
81 cmpdi cr7, r10, 0 /* if needle is has reached NULL, continue */
82 bne cr7, L(hashing) /* loop to hash the needle */
83
84L(skipHashing):
85 li r10, 0 /* load counter = 0 */
86 b L(beginScan)
87
2e8a2de2 88 .align 4 /* align section to 16 byte boundary */
e65caf1f
VR
89L(scanUnroll):
90 lbzx r8, r9, r8 /* load r8 with hash value at index */
91 cmpwi cr7, r8, 0 /* if we hit marker in hash, we have found
92 accept needle */
93 beq cr7, L(ret1stIndex) /* we have hit accept needle, return the
94 count */
95
96 lbz r8, 1(r3) /* load string[1] into r8 */
97 addi r10, r10, 4 /* increment counter */
98 lbzx r8, r9, r8 /* load r8 with hash value at index */
99 cmpwi cr7, r8, 0 /* if we hit marker in hash, we have found
100 accept needle */
101 beq cr7, L(ret2ndIndex) /* we have hit accept needle, return the
102 count */
103
104 lbz r8, 2(r3) /* load string[2] into r8 */
105 lbzx r8, r9, r8 /* load r8 with hash value at index */
106 cmpwi cr7, r8, 0 /* if we hit marker in hash, we have found
107 accept needle */
108 beq cr7, L(ret3rdIndex) /* we have hit accept needle, return the
109 count */
110
111 lbz r8, 3(r3) /* load string[3] into r8 */
112 lbzx r8, r9, r8 /* load r8 with hash value at index */
113 addi r3, r3, 4 /* unroll factor , increment string by 4 */
114 cmpwi cr7, r8, 0 /* if we hit marker in hash, we have found
115 accept needle */
116 beq cr7,L(ret4thIndex) /* we have hit accept needle, return the
117 count */
118
119L(beginScan):
120 lbz r8, 0(r3) /* load string[0] into r8 */
121 addi r6, r10, 1 /* place holder for counter + 1 */
122 addi r5, r10, 2 /* place holder for counter + 2 */
123 addi r4, r10, 3 /* place holder for counter + 3 */
124 cmpdi cr7, r8, 0 /* if we hit marker in hash, we have found
125 accept needle */
126 bne cr7, L(scanUnroll) /* continue scanning */
127
128L(ret1stIndex):
129 mr r3, r10 /* update r3 for return */
130 blr /* return */
131
132L(ret2ndIndex):
133 mr r3, r6 /* update r3 for return */
134 blr /* return */
135
136L(ret3rdIndex):
137 mr r3, r5 /* update r3 for return */
138 blr /* return */
139
140L(ret4thIndex):
141 mr r3, r4 /* update r3 for return */
142 blr /* done */
143END(strspn)
144libc_hidden_builtin_def (strspn)