1 /* Optimized strchrnul implementation for PowerPC64/POWER7 using cmpb insn.
2 Copyright (C) 2010 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/>. */
24 /* int [r3] strchrnul (char *s [r3], int c [r4]) */
26 ENTRY (BP_SYM(__strchrnul))
29 clrrdi r8,r3,3 /* Align the address to doubleword boundary. */
31 /* Replicate byte to doubleword. */
36 rlwinm r6,r3,3,26,28 /* Calculate padding. */
37 ld r12,0(r8) /* Load doubleword from memory. */
38 li r0,0 /* Doubleword with null chars to use
41 /* Now r4 has a doubleword of c bytes and r0 has
42 a doubleword of null bytes. */
44 cmpb r10,r12,r0 /* Compare each byte against c byte. */
45 cmpb r9,r12,r4 /* Compare each byte against null byte. */
47 /* Move the doublewords left and right to discard the bits that are
48 not part of the string and to bring them back as zeros. */
53 or r5,r9,r10 /* OR the results to speed things up. */
54 cmpdi cr7,r5,0 /* If r5 == 0, no c or null bytes
60 /* Are we now aligned to a quadword boundary? If so, skip to
61 the main loop. Otherwise, go through the alignment code. */
65 /* Handle DWORD2 of pair. */
72 b L(loop) /* We branch here (rather than falling through)
73 to skip the nops due to heavy alignment
78 /* Load two doublewords, compare and merge in a
79 single register for speed. This is an attempt
80 to speed up the null-checking process for bigger strings. */
93 /* OK, one (or both) of the doublewords contains a c/null byte. Check
94 the first doubleword and decrement the address in case the first
95 doubleword really contains a c/null byte. */
101 /* The c/null byte must be in the second doubleword. Adjust the
102 address again and move the result of cmpb to r10 so we can calculate
107 /* r5 has the output of the cmpb instruction, that is, it contains
108 0xff in the same position as the c/null byte in the original
109 doubleword from the string. Use that to calculate the pointer. */
111 cntlzd r0,r5 /* Count leading zeros before the match. */
112 srdi r0,r0,3 /* Convert leading zeros to bytes. */
113 add r3,r8,r0 /* Return address of matching c/null byte. */
115 END (BP_SYM (__strchrnul))
116 weak_alias (__strchrnul,strchrnul)
117 libc_hidden_builtin_def (__strchrnul)