1 /* Optimized strspn implementation for PowerPC64.
3 Copyright (C) 2014-2015 Free Software Foundation, Inc.
4 This file is part of the GNU C Library.
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.
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.
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/>. */
20 /* size_t [r3] strspn (const char *string [r3],
21 const char *needleAccept [r4] */
23 /* Performance gains are grabbed through following techniques:
26 > hashing avoids scanning of duplicate entries in needle
28 > unrolling when scanning for character in string
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
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,
42 5. Otherwise count is incremented and scanning continues
43 until end of string. */
50 /* PPC64 ELF ABI stack is aligned to 16 bytes. */
52 /* Clear the table with 0 values */
71 li r8, 1 /* r8=1, marker into hash if found in
73 cmpdi cr7, r10, 0 /* accept needle is NULL */
74 beq cr7, L(skipHashing) /* if needle is NULL, skip hashing */
76 .align 4 /* align section to 16 byte boundary */
78 stbx r8, r9, r10 /* update hash with marker for the pivot of
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 */
85 li r10, 0 /* load counter = 0 */
88 .align 4 /* align section to 16 byte boundary */
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
93 beq cr7, L(ret1stIndex) /* we have hit accept needle, return the
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
101 beq cr7, L(ret2ndIndex) /* we have hit accept needle, return the
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
108 beq cr7, L(ret3rdIndex) /* we have hit accept needle, return the
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
116 beq cr7,L(ret4thIndex) /* we have hit accept needle, return the
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
126 bne cr7, L(scanUnroll) /* continue scanning */
129 mr r3, r10 /* update r3 for return */
133 mr r3, r6 /* update r3 for return */
137 mr r3, r5 /* update r3 for return */
141 mr r3, r4 /* update r3 for return */
144 libc_hidden_builtin_def (strspn)