]> git.ipfire.org Git - thirdparty/glibc.git/blobdiff - sysdeps/powerpc/powerpc32/strncmp.S
PowerPC LE strcmp and strncmp
[thirdparty/glibc.git] / sysdeps / powerpc / powerpc32 / strncmp.S
index fa345d293ccb52883526fa4a95adf090d3367feb..e36a160a80ec9fde9e66180bcef7d8155cdaf58a 100644 (file)
@@ -24,7 +24,7 @@
 
 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 */
@@ -35,6 +35,7 @@ EALIGN (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
@@ -73,12 +74,45 @@ L(g1):      add     rTMP, rFEFE, rWORD1
    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
+       rlwimi  rTMP2, rWORD2, 24, 0, 7
+       rlwimi  rTMP, rWORD1, 24, 0, 7
+       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
+       rlwimi  rTMP2, rWORD2, 24, 0, 7
+       rlwimi  rTMP, rWORD1, 24, 0, 7
+       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
@@ -86,28 +120,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