]> git.ipfire.org Git - thirdparty/glibc.git/blobdiff - sysdeps/powerpc/powerpc32/power7/strlen.S
Update copyright dates with scripts/update-copyrights.
[thirdparty/glibc.git] / sysdeps / powerpc / powerpc32 / power7 / strlen.S
index d6e93fb998f4ec6320e4458626f02973e042f2b1..ecc1c8e105fd1ae223477900af30506097fc229b 100644 (file)
@@ -1,5 +1,5 @@
 /* Optimized strlen implementation for PowerPC32/POWER7 using cmpb insn.
-   Copyright (C) 2010 Free Software Foundation, Inc.
+   Copyright (C) 2010-2016 Free Software Foundation, Inc.
    Contributed by Luis Machado <luisgpm@br.ibm.com>.
    This file is part of the GNU C Library.
 
    Lesser General Public License for more details.
 
    You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
-   02110-1301 USA.  */
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
 
 #include <sysdep.h>
-#include <bp-sym.h>
-#include <bp-asm.h>
 
 /* int [r3] strlen (char *s [r3])  */
        .machine  power7
-ENTRY (BP_SYM (strlen))
+ENTRY (strlen)
        CALL_MCOUNT
        dcbt    0,r3
        clrrwi  r4,r3,2       /* Align the address to word boundary.  */
@@ -32,7 +29,11 @@ ENTRY (BP_SYM (strlen))
        li      r0,0          /* Word with null chars to use with cmpb.  */
        li      r5,-1         /* MASK = 0xffffffffffffffff.  */
        lwz     r12,0(r4)     /* Load word from memory.  */
+#ifdef __LITTLE_ENDIAN__
+       slw     r5,r5,r6
+#else
        srw     r5,r5,r6      /* MASK = MASK >> padding.  */
+#endif
        orc     r9,r12,r5     /* Mask bits that are not part of the string.  */
        cmpb    r10,r9,r0     /* Check for null bytes in WORD1.  */
        cmpwi   cr7,r10,0     /* If r10 == 0, no null's have been found.  */
@@ -50,9 +51,6 @@ ENTRY (BP_SYM (strlen))
        cmpb    r10,r12,r0
        cmpwi   cr7,r10,0
        bne     cr7,L(done)
-       b       L(loop)       /* We branch here (rather than falling through)
-                                to skip the nops due to heavy alignment
-                                of the loop below.  */
 
        /* Main loop to look for the end of the string.  Since it's a
           small loop (< 8 instructions), align it to 32-bytes.  */
@@ -89,10 +87,16 @@ L(loop):
           0xff in the same position as the null byte in the original
           word from the string.  Use that to calculate the length.  */
 L(done):
-       cntlzw  r0,r10        /* Count leading zeroes before the match.  */
+#ifdef __LITTLE_ENDIAN__
+       addi    r9, r10, -1   /* Form a mask from trailing zeros.  */
+       andc    r9, r9, r10
+       popcntw r0, r9        /* Count the bits in the mask.  */
+#else
+       cntlzw  r0,r10        /* Count leading zeros before the match.  */
+#endif
        subf    r5,r3,r4
-       srwi    r0,r0,3       /* Convert leading zeroes to bytes.  */
+       srwi    r0,r0,3       /* Convert leading zeros to bytes.  */
        add     r3,r5,r0      /* Compute final length.  */
        blr
-END (BP_SYM (strlen))
+END (strlen)
 libc_hidden_builtin_def (strlen)