1 /* Optimized strchrnul implementation for PowerPC32/POWER7 using cmpb insn.
2 Copyright (C) 2010-2015 Free Software Foundation, Inc.
3 Contributed by Luis Machado <luisgpm@br.ibm.com>.
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/>. */
22 /* int [r3] strchrnul (char *s [r3], int c [r4]) */
27 clrrwi r8,r3,2 /* Align the address to word boundary. */
29 /* Replicate byte to word. */
33 rlwinm r6,r3,3,27,28 /* Calculate padding. */
34 lwz r12,0(r8) /* Load word from memory. */
35 li r0,0 /* Word with null chars to use
38 /* Now r4 has a word of c bytes and r0 has
39 a word of null bytes. */
41 cmpb r10,r12,r0 /* Compare each byte against c byte. */
42 cmpb r9,r12,r4 /* Compare each byte against null byte. */
44 /* Move the words left and right to discard the bits that are
45 not part of the string and bring them back as zeros. */
46 #ifdef __LITTLE_ENDIAN__
57 or r5,r9,r10 /* OR the results to speed things up. */
58 cmpwi cr7,r5,0 /* If r5 == 0, no c or null bytes
64 /* Are we now aligned to a doubleword boundary? If so, skip to
65 the main loop. Otherwise, go through the alignment code. */
69 /* Handle WORD2 of pair. */
76 b L(loop) /* We branch here (rather than falling through)
77 to skip the nops due to heavy alignment
82 /* Load two words, compare and merge in a
83 single register for speed. This is an attempt
84 to speed up the null-checking process for bigger strings. */
97 /* OK, one (or both) of the words contains a c/null byte. Check
98 the first word and decrement the address in case the first
99 word really contains a c/null byte. */
105 /* The c/null byte must be in the second word. Adjust the address
106 again and move the result of cmpb to r5 so we can calculate the
111 /* r5 has the output of the cmpb instruction, that is, it contains
112 0xff in the same position as the c/null byte in the original
113 word from the string. Use that to calculate the pointer. */
115 #ifdef __LITTLE_ENDIAN__
120 cntlzw r0,r5 /* Count leading zeros before the match. */
122 srwi r0,r0,3 /* Convert leading zeros to bytes. */
123 add r3,r8,r0 /* Return address of matching c/null byte. */
126 weak_alias (__strchrnul,strchrnul)
127 libc_hidden_builtin_def (__strchrnul)