]> git.ipfire.org Git - thirdparty/glibc.git/blobdiff - sysdeps/powerpc/powerpc32/power4/strncmp.S
Update copyright notices with scripts/update-copyrights
[thirdparty/glibc.git] / sysdeps / powerpc / powerpc32 / power4 / strncmp.S
index 70541430d57161905cc8167af593325a374b23eb..348c129e0ab2bd7dc18c83b2e19ba51bcf242d46 100644 (file)
@@ -1,5 +1,5 @@
 /* Optimized strcmp implementation for PowerPC32.
-   Copyright (C) 2003, 2006, 2011 Free Software Foundation, Inc.
+   Copyright (C) 2003-2014 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
    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>
 
 /* See strlen.s for comments on how the end-of-string testing works.  */
 
 /* int [r3] strncmp (const char *s1 [r3], const char *s2 [r4], size_t size [r5])  */
 
-EALIGN (BP_SYM(strncmp), 4, 0)
+EALIGN (strncmp, 4, 0)
 
-#define rTMP   r0
+#define rTMP2  r0
 #define rRTN   r3
 #define rSTR1  r3      /* first string arg */
 #define rSTR2  r4      /* second string arg */
 #define rN     r5      /* max string length */
-/* Note:  The Bounded pointer support in this code is broken.  This code
-   was inherited from PPC32 and that support was never completed.  
-   Current PPC gcc does not support -fbounds-check or -fbounded-pointers.  */
 #define rWORD1 r6      /* current word in s1 */
 #define rWORD2 r7      /* current word in s2 */
 #define rWORD3  r10
@@ -43,6 +37,7 @@ EALIGN (BP_SYM(strncmp), 4, 0)
 #define r7F7F  r9      /* constant 0x7f7f7f7f */
 #define rNEG   r10     /* ~(word in s1 | 0x7f7f7f7f) */
 #define rBITDIF        r11     /* bits that differ in s1 & s2 words */
+#define rTMP   r12
 
        dcbt    0,rSTR1
        or      rTMP, rSTR2, rSTR1
@@ -52,13 +47,13 @@ EALIGN (BP_SYM(strncmp), 4, 0)
        cmplwi  cr1, rN, 0
        lis     rFEFE, -0x101
        bne     L(unaligned)
-/* We are word alligned so set up for two loops.  first a word
+/* We are word aligned so set up for two loops.  first a word
    loop, then fall into the byte loop if any residual.  */
        srwi.   rTMP, rN, 2
        clrlwi  rN, rN, 30
        addi    rFEFE, rFEFE, -0x101
        addi    r7F7F, r7F7F, 0x7f7f
-       cmplwi  cr1, rN, 0      
+       cmplwi  cr1, rN, 0
        beq     L(unaligned)
 
        mtctr   rTMP    /* Power4 wants mtctr 1st in dispatch group.  */
@@ -66,7 +61,7 @@ EALIGN (BP_SYM(strncmp), 4, 0)
        lwz     rWORD2, 0(rSTR2)
        b       L(g1)
 
-L(g0): 
+L(g0):
        lwzu    rWORD1, 4(rSTR1)
        bne-    cr1, L(different)
        lwzu    rWORD2, 4(rSTR2)
@@ -76,17 +71,50 @@ L(g1):      add     rTMP, rFEFE, rWORD1
        and.    rTMP, rTMP, rNEG
        cmpw    cr1, rWORD1, rWORD2
        beq+    L(g0)
-       
+
 /* OK. We've hit the end of the string. We need to be careful that
    we don't compare two strings as different because of gunk beyond
    the end of the strings...  */
-       
+
+#ifdef __LITTLE_ENDIAN__
+L(endstring):
+       slwi    rTMP, rTMP, 1
+       addi    rTMP2, rTMP, -1
+       andc    rTMP2, rTMP2, rTMP
+       and     rWORD2, rWORD2, rTMP2           /* Mask off gunk.  */
+       and     rWORD1, rWORD1, rTMP2
+       rlwinm  rTMP2, rWORD2, 8, 0xffffffff    /* Byte reverse word.  */
+       rlwinm  rTMP, rWORD1, 8, 0xffffffff
+       rldimi  rTMP2, rWORD2, 24, 32
+       rldimi  rTMP, rWORD1, 24, 32
+       rlwimi  rTMP2, rWORD2, 24, 16, 23
+       rlwimi  rTMP, rWORD1, 24, 16, 23
+       xor.    rBITDIF, rTMP, rTMP2
+       sub     rRTN, rTMP, rTMP2
+       bgelr+
+       ori     rRTN, rTMP2, 1
+       blr
+
+L(different):
+       lwz     rWORD1, -4(rSTR1)
+       rlwinm  rTMP2, rWORD2, 8, 0xffffffff    /* Byte reverse word.  */
+       rlwinm  rTMP, rWORD1, 8, 0xffffffff
+       rldimi  rTMP2, rWORD2, 24, 32
+       rldimi  rTMP, rWORD1, 24, 32
+       rlwimi  rTMP2, rWORD2, 24, 16, 23
+       rlwimi  rTMP, rWORD1, 24, 16, 23
+       xor.    rBITDIF, rTMP, rTMP2
+       sub     rRTN, rTMP, rTMP2
+       bgelr+
+       ori     rRTN, rTMP2, 1
+       blr
+
+#else
 L(endstring):
        and     rTMP, r7F7F, rWORD1
        beq     cr1, L(equal)
        add     rTMP, rTMP, r7F7F
        xor.    rBITDIF, rWORD1, rWORD2
-
        andc    rNEG, rNEG, rTMP
        blt-    L(highbit)
        cntlzw  rBITDIF, rBITDIF
@@ -94,28 +122,20 @@ L(endstring):
        addi    rNEG, rNEG, 7
        cmpw    cr1, rNEG, rBITDIF
        sub     rRTN, rWORD1, rWORD2
-       blt-    cr1, L(equal)
-       srawi   rRTN, rRTN, 31
-       ori     rRTN, rRTN, 1
-       blr
+       bgelr+  cr1
 L(equal):
        li      rRTN, 0
        blr
 
 L(different):
-       lwzu    rWORD1, -4(rSTR1)
+       lwz     rWORD1, -4(rSTR1)
        xor.    rBITDIF, rWORD1, rWORD2
        sub     rRTN, rWORD1, rWORD2
-       blt-    L(highbit)
-       srawi   rRTN, rRTN, 31
-       ori     rRTN, rRTN, 1
-       blr
+       bgelr+
 L(highbit):
-       srwi    rWORD2, rWORD2, 24
-       srwi    rWORD1, rWORD1, 24
-       sub     rRTN, rWORD1, rWORD2
+       ori     rRTN, rWORD2, 1
        blr
-
+#endif
 
 /* Oh well.  In this case, we just do a byte-by-byte comparison.  */
        .align 4
@@ -166,12 +186,11 @@ L(u1):
        b       L(u1)
 
 L(u3):  sub     rRTN, rWORD3, rWORD4
-        blr
+       blr
 L(u4): sub     rRTN, rWORD1, rWORD2
        blr
 L(ux):
        li      rRTN, 0
        blr
-END (BP_SYM (strncmp))
+END (strncmp)
 libc_hidden_builtin_def (strncmp)
-