]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
PowerPC LE strcmp and strncmp
authorAlan Modra <amodra@gmail.com>
Sat, 17 Aug 2013 09:11:17 +0000 (18:41 +0930)
committerAlan Modra <amodra@gmail.com>
Fri, 4 Oct 2013 01:09:52 +0000 (10:39 +0930)
http://sourceware.org/ml/libc-alpha/2013-08/msg00099.html

More little-endian support.  I leave the main strcmp loops unchanged,
(well, except for renumbering rTMP to something other than r0 since
it's needed in an addi insn) and modify the tail for little-endian.

I noticed some of the big-endian tail code was a little untidy so have
cleaned that up too.

* sysdeps/powerpc/powerpc64/strcmp.S (rTMP2): Define as r0.
(rTMP): Define as r11.
(strcmp): Add little-endian support.  Optimise tail.
* sysdeps/powerpc/powerpc32/strcmp.S: Similarly.
* sysdeps/powerpc/powerpc64/strncmp.S: Likewise.
* sysdeps/powerpc/powerpc32/strncmp.S: Likewise.
* sysdeps/powerpc/powerpc64/power4/strncmp.S: Likewise.
* sysdeps/powerpc/powerpc32/power4/strncmp.S: Likewise.
* sysdeps/powerpc/powerpc64/power7/strncmp.S: Likewise.
* sysdeps/powerpc/powerpc32/power7/strncmp.S: Likewise.

ChangeLog
sysdeps/powerpc/powerpc32/power4/strncmp.S
sysdeps/powerpc/powerpc32/power7/strncmp.S
sysdeps/powerpc/powerpc32/strcmp.S
sysdeps/powerpc/powerpc32/strncmp.S
sysdeps/powerpc/powerpc64/power4/strncmp.S
sysdeps/powerpc/powerpc64/power7/strncmp.S
sysdeps/powerpc/powerpc64/strcmp.S
sysdeps/powerpc/powerpc64/strncmp.S

index 8ecd153cfeaf86243e5aa889d2ddc5147df671dd..540cb943168bc6a7ff83af9a698736dc4ecde606 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2013-10-04  Alan Modra  <amodra@gmail.com>
+
+       * sysdeps/powerpc/powerpc64/strcmp.S (rTMP2): Define as r0.
+       (rTMP): Define as r11.
+       (strcmp): Add little-endian support.  Optimise tail.
+       * sysdeps/powerpc/powerpc32/strcmp.S: Similarly.
+       * sysdeps/powerpc/powerpc64/strncmp.S: Likewise.
+       * sysdeps/powerpc/powerpc32/strncmp.S: Likewise.
+       * sysdeps/powerpc/powerpc64/power4/strncmp.S: Likewise.
+       * sysdeps/powerpc/powerpc32/power4/strncmp.S: Likewise.
+       * sysdeps/powerpc/powerpc64/power7/strncmp.S: Likewise.
+       * sysdeps/powerpc/powerpc32/power7/strncmp.S: Likewise.
+
 2013-10-04  Alan Modra  <amodra@gmail.com>
 
        * sysdeps/powerpc/powerpc64/power7/strnlen.S (strnlen): Add
index 724d9084a9c4fc1f1dd1541810c9968fd464f5fd..89b961e78dc7260b4fe5e4c13c0555b66388ff1e 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 */
@@ -37,6 +37,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
@@ -75,12 +76,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
+       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
@@ -88,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
index fdae44d265ed16e974e5a1357f7e81912ecb1ecf..10c9d251b04466fe33dd83d3bdecaef38da311d6 100644 (file)
@@ -26,7 +26,7 @@
 
 EALIGN (strncmp,5,0)
 
-#define rTMP   r0
+#define rTMP2  r0
 #define rRTN   r3
 #define rSTR1  r3      /* first string arg */
 #define rSTR2  r4      /* second string arg */
@@ -39,6 +39,7 @@ EALIGN (strncmp,5,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
        nop
@@ -78,13 +79,45 @@ L(g1):      add     rTMP,rFEFE,rWORD1
 /* 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
@@ -92,28 +125,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
index 297ca3c1b2f523b26dfca1c7ac5838f0f900beff..91d60c905380134fb096014c4a06df04ec84b962 100644 (file)
@@ -24,7 +24,7 @@
 
 EALIGN (strcmp, 4, 0)
 
-#define rTMP   r0
+#define rTMP2  r0
 #define rRTN   r3
 #define rSTR1  r3      /* first string arg */
 #define rSTR2  r4      /* second string arg */
@@ -34,6 +34,7 @@ EALIGN (strcmp, 4, 0)
 #define r7F7F  r8      /* constant 0x7f7f7f7f */
 #define rNEG   r9      /* ~(word in s1 | 0x7f7f7f7f) */
 #define rBITDIF        r10     /* bits that differ in s1 & s2 words */
+#define rTMP   r11
 
 
        or      rTMP, rSTR2, rSTR1
@@ -56,10 +57,45 @@ L(g1):      add     rTMP, rFEFE, rWORD1
        and.    rTMP, rTMP, rNEG
        cmpw    cr1, rWORD1, rWORD2
        beq+    L(g0)
-L(endstring):
+
 /* 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):
+       addi    rTMP2, rTMP, -1
+       andc    rTMP2, rTMP2, rTMP
+       rlwimi  rTMP2, rTMP2, 1, 0, 30
+       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
@@ -84,7 +120,7 @@ L(different):
 L(highbit):
        ori     rRTN, rWORD2, 1
        blr
-
+#endif
 
 /* Oh well.  In this case, we just do a byte-by-byte comparison.  */
        .align 4
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
index 1276e16a59f5638812583af4827a738b5c6cfc21..5d136cfa21b0c63977a5fefdbe29738748710b4d 100644 (file)
@@ -25,7 +25,7 @@
 EALIGN (strncmp, 4, 0)
        CALL_MCOUNT 3
 
-#define rTMP   r0
+#define rTMP2  r0
 #define rRTN   r3
 #define rSTR1  r3      /* first string arg */
 #define rSTR2  r4      /* second string arg */
@@ -38,6 +38,7 @@ EALIGN (strncmp, 4, 0)
 #define r7F7F  r9      /* constant 0x7f7f7f7f7f7f7f7f */
 #define rNEG   r10     /* ~(word in s1 | 0x7f7f7f7f7f7f7f7f) */
 #define rBITDIF        r11     /* bits that differ in s1 & s2 words */
+#define rTMP   r12
 
        dcbt    0,rSTR1
        or      rTMP, rSTR2, rSTR1
@@ -79,12 +80,59 @@ 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):
+       addi    rTMP2, rTMP, -1
+       beq     cr1, L(equal)
+       andc    rTMP2, rTMP2, rTMP
+       rldimi  rTMP2, rTMP2, 1, 0
+       and     rWORD2, rWORD2, rTMP2   /* Mask off gunk.  */
+       and     rWORD1, rWORD1, rTMP2
+       cmpd    cr1, rWORD1, rWORD2
+       beq     cr1, L(equal)
+       xor     rBITDIF, rWORD1, rWORD2 /* rBITDIF has bits that differ.  */
+       neg     rNEG, rBITDIF
+       and     rNEG, rNEG, rBITDIF     /* rNEG has LS bit that differs.  */
+       cntlzd  rNEG, rNEG              /* bitcount of the bit.  */
+       andi.   rNEG, rNEG, 56          /* bitcount to LS byte that differs. */
+       sld     rWORD1, rWORD1, rNEG    /* shift left to clear MS bytes.  */
+       sld     rWORD2, rWORD2, rNEG
+       xor.    rBITDIF, rWORD1, rWORD2
+       sub     rRTN, rWORD1, rWORD2
+       blt-    L(highbit)
+       sradi   rRTN, rRTN, 63          /* must return an int.  */
+       ori     rRTN, rRTN, 1
+       blr
+L(equal):
+       li      rRTN, 0
+       blr
+
+L(different):
+       ld      rWORD1, -8(rSTR1)
+       xor     rBITDIF, rWORD1, rWORD2 /* rBITDIF has bits that differ.  */
+       neg     rNEG, rBITDIF
+       and     rNEG, rNEG, rBITDIF     /* rNEG has LS bit that differs.  */
+       cntlzd  rNEG, rNEG              /* bitcount of the bit.  */
+       andi.   rNEG, rNEG, 56          /* bitcount to LS byte that differs. */
+       sld     rWORD1, rWORD1, rNEG    /* shift left to clear MS bytes.  */
+       sld     rWORD2, rWORD2, rNEG
+       xor.    rBITDIF, rWORD1, rWORD2
+       sub     rRTN, rWORD1, rWORD2
+       blt-    L(highbit)
+       sradi   rRTN, rRTN, 63
+       ori     rRTN, rRTN, 1
+       blr
+L(highbit):
+       sradi   rRTN, rWORD2, 63
+       ori     rRTN, rRTN, 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)
        cntlzd  rBITDIF, rBITDIF
@@ -93,7 +141,7 @@ L(endstring):
        cmpd    cr1, rNEG, rBITDIF
        sub     rRTN, rWORD1, rWORD2
        blt-    cr1, L(equal)
-       sradi   rRTN, rRTN, 63
+       sradi   rRTN, rRTN, 63          /* must return an int.  */
        ori     rRTN, rRTN, 1
        blr
 L(equal):
@@ -101,7 +149,7 @@ L(equal):
        blr
 
 L(different):
-       ldu     rWORD1, -8(rSTR1)
+       ld      rWORD1, -8(rSTR1)
        xor.    rBITDIF, rWORD1, rWORD2
        sub     rRTN, rWORD1, rWORD2
        blt-    L(highbit)
@@ -109,11 +157,10 @@ L(different):
        ori     rRTN, rRTN, 1
        blr
 L(highbit):
-       srdi    rWORD2, rWORD2, 56
-       srdi    rWORD1, rWORD1, 56
-       sub     rRTN, rWORD1, rWORD2
+       sradi   rRTN, rWORD2, 63
+       ori     rRTN, rRTN, 1
        blr
-
+#endif
 
 /* Oh well.  In this case, we just do a byte-by-byte comparison.  */
        .align 4
index 77ecad5ab1533738ac324fbafe52a51cf5e45be4..e618b010bfccde20206f8f1ddb87e0e1078705b7 100644 (file)
@@ -27,7 +27,7 @@
 EALIGN (strncmp,5,0)
        CALL_MCOUNT 3
 
-#define rTMP   r0
+#define rTMP2  r0
 #define rRTN   r3
 #define rSTR1  r3      /* first string arg */
 #define rSTR2  r4      /* second string arg */
@@ -40,6 +40,7 @@ EALIGN (strncmp,5,0)
 #define r7F7F  r9      /* constant 0x7f7f7f7f7f7f7f7f */
 #define rNEG   r10     /* ~(word in s1 | 0x7f7f7f7f7f7f7f7f) */
 #define rBITDIF        r11     /* bits that differ in s1 & s2 words */
+#define rTMP   r12
 
        dcbt    0,rSTR1
        nop
@@ -83,12 +84,57 @@ 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):
+       addi    rTMP2, rTMP, -1
+       beq     cr1, L(equal)
+       andc    rTMP2, rTMP2, rTMP
+       rldimi  rTMP2, rTMP2, 1, 0
+       and     rWORD2, rWORD2, rTMP2   /* Mask off gunk.  */
+       and     rWORD1, rWORD1, rTMP2
+       cmpd    cr1, rWORD1, rWORD2
+       beq     cr1, L(equal)
+       cmpb    rBITDIF, rWORD1, rWORD2 /* 0xff on equal bytes.  */
+       addi    rNEG, rBITDIF, 1
+       orc     rNEG, rNEG, rBITDIF     /* 0's below LS differing byte.  */
+       sldi    rNEG, rNEG, 8           /* 1's above LS differing byte.  */
+       andc    rWORD1, rWORD1, rNEG    /* mask off MS bytes.  */
+       andc    rWORD2, rWORD2, rNEG
+       xor.    rBITDIF, rWORD1, rWORD2
+       sub     rRTN, rWORD1, rWORD2
+       blt     L(highbit)
+       sradi   rRTN, rRTN, 63          /* must return an int.  */
+       ori     rRTN, rRTN, 1
+       blr
+L(equal):
+       li      rRTN, 0
+       blr
+
+L(different):
+       ld      rWORD1, -8(rSTR1)
+       cmpb    rBITDIF, rWORD1, rWORD2 /* 0xff on equal bytes.  */
+       addi    rNEG, rBITDIF, 1
+       orc     rNEG, rNEG, rBITDIF     /* 0's below LS differing byte.  */
+       sldi    rNEG, rNEG, 8           /* 1's above LS differing byte.  */
+       andc    rWORD1, rWORD1, rNEG    /* mask off MS bytes.  */
+       andc    rWORD2, rWORD2, rNEG
+       xor.    rBITDIF, rWORD1, rWORD2
+       sub     rRTN, rWORD1, rWORD2
+       blt     L(highbit)
+       sradi   rRTN, rRTN, 63
+       ori     rRTN, rRTN, 1
+       blr
+L(highbit):
+       sradi   rRTN, rWORD2, 63
+       ori     rRTN, rRTN, 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)
        cntlzd  rBITDIF,rBITDIF
@@ -97,7 +143,7 @@ L(endstring):
        cmpd    cr1,rNEG,rBITDIF
        sub     rRTN,rWORD1,rWORD2
        blt     cr1,L(equal)
-       sradi   rRTN,rRTN,63
+       sradi   rRTN,rRTN,63            /* must return an int.  */
        ori     rRTN,rRTN,1
        blr
 L(equal):
@@ -105,7 +151,7 @@ L(equal):
        blr
 
 L(different):
-       ldu     rWORD1,-8(rSTR1)
+       ld      rWORD1,-8(rSTR1)
        xor.    rBITDIF,rWORD1,rWORD2
        sub     rRTN,rWORD1,rWORD2
        blt     L(highbit)
@@ -113,11 +159,10 @@ L(different):
        ori     rRTN,rRTN,1
        blr
 L(highbit):
-       srdi    rWORD2,rWORD2,56
-       srdi    rWORD1,rWORD1,56
-       sub     rRTN,rWORD1,rWORD2
+       sradi   rRTN,rWORD2,63
+       ori     rRTN,rRTN,1
        blr
-
+#endif
 
 /* Oh well.  In this case, we just do a byte-by-byte comparison.  */
        .align  4
index c9d6dac1217fe6ffab3c44f86b0e02e65b0f288d..70854689d3d1459867a9e5736ec2cb73a288c7de 100644 (file)
@@ -25,7 +25,7 @@
 EALIGN (strcmp, 4, 0)
        CALL_MCOUNT 2
 
-#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 (strcmp, 4, 0)
 #define r7F7F  r8      /* constant 0x7f7f7f7f7f7f7f7f */
 #define rNEG   r9      /* ~(word in s1 | 0x7f7f7f7f7f7f7f7f) */
 #define rBITDIF        r10     /* bits that differ in s1 & s2 words */
+#define rTMP   r11
 
        dcbt    0,rSTR1
        or      rTMP, rSTR2, rSTR1
@@ -58,19 +59,66 @@ L(g0):      ldu     rWORD1, 8(rSTR1)
        ldu     rWORD2, 8(rSTR2)
 L(g1): add     rTMP, rFEFE, rWORD1
        nor     rNEG, r7F7F, rWORD1
-
        and.    rTMP, rTMP, rNEG
        cmpd    cr1, rWORD1, rWORD2
        beq+    L(g0)
-L(endstring):
+
 /* 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):
+       addi    rTMP2, rTMP, -1
+       beq     cr1, L(equal)
+       andc    rTMP2, rTMP2, rTMP
+       rldimi  rTMP2, rTMP2, 1, 0
+       and     rWORD2, rWORD2, rTMP2   /* Mask off gunk.  */
+       and     rWORD1, rWORD1, rTMP2
+       cmpd    cr1, rWORD1, rWORD2
+       beq     cr1, L(equal)
+       xor     rBITDIF, rWORD1, rWORD2 /* rBITDIF has bits that differ.  */
+       neg     rNEG, rBITDIF
+       and     rNEG, rNEG, rBITDIF     /* rNEG has LS bit that differs.  */
+       cntlzd  rNEG, rNEG              /* bitcount of the bit.  */
+       andi.   rNEG, rNEG, 56          /* bitcount to LS byte that differs. */
+       sld     rWORD1, rWORD1, rNEG    /* shift left to clear MS bytes.  */
+       sld     rWORD2, rWORD2, rNEG
+       xor.    rBITDIF, rWORD1, rWORD2
+       sub     rRTN, rWORD1, rWORD2
+       blt-    L(highbit)
+       sradi   rRTN, rRTN, 63          /* must return an int.  */
+       ori     rRTN, rRTN, 1
+       blr
+L(equal):
+       li      rRTN, 0
+       blr
+
+L(different):
+       ld      rWORD1, -8(rSTR1)
+       xor     rBITDIF, rWORD1, rWORD2 /* rBITDIF has bits that differ.  */
+       neg     rNEG, rBITDIF
+       and     rNEG, rNEG, rBITDIF     /* rNEG has LS bit that differs.  */
+       cntlzd  rNEG, rNEG              /* bitcount of the bit.  */
+       andi.   rNEG, rNEG, 56          /* bitcount to LS byte that differs. */
+       sld     rWORD1, rWORD1, rNEG    /* shift left to clear MS bytes.  */
+       sld     rWORD2, rWORD2, rNEG
+       xor.    rBITDIF, rWORD1, rWORD2
+       sub     rRTN, rWORD1, rWORD2
+       blt-    L(highbit)
+       sradi   rRTN, rRTN, 63
+       ori     rRTN, rRTN, 1
+       blr
+L(highbit):
+       sradi   rRTN, rWORD2, 63
+       ori     rRTN, rRTN, 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)
        cntlzd  rBITDIF, rBITDIF
@@ -79,7 +127,7 @@ L(endstring):
        cmpd    cr1, rNEG, rBITDIF
        sub     rRTN, rWORD1, rWORD2
        blt-    cr1, L(equal)
-       sradi   rRTN, rRTN, 63
+       sradi   rRTN, rRTN, 63          /* must return an int.  */
        ori     rRTN, rRTN, 1
        blr
 L(equal):
@@ -95,11 +143,10 @@ L(different):
        ori     rRTN, rRTN, 1
        blr
 L(highbit):
-       srdi    rWORD2, rWORD2, 56
-       srdi    rWORD1, rWORD1, 56
-       sub     rRTN, rWORD1, rWORD2
+       sradi   rRTN, rWORD2, 63
+       ori     rRTN, rRTN, 1
        blr
-
+#endif
 
 /* Oh well.  In this case, we just do a byte-by-byte comparison.  */
        .align 4
index 779d9f7f6f271ac2fc40a092be60de7d19922ee4..8f842c4b26087d34260d9d61af62acb2e746547e 100644 (file)
@@ -25,7 +25,7 @@
 EALIGN (strncmp, 4, 0)
        CALL_MCOUNT 3
 
-#define rTMP   r0
+#define rTMP2  r0
 #define rRTN   r3
 #define rSTR1  r3      /* first string arg */
 #define rSTR2  r4      /* second string arg */
@@ -36,6 +36,7 @@ EALIGN (strncmp, 4, 0)
 #define r7F7F  r9      /* constant 0x7f7f7f7f7f7f7f7f */
 #define rNEG   r10     /* ~(word in s1 | 0x7f7f7f7f7f7f7f7f) */
 #define rBITDIF        r11     /* bits that differ in s1 & s2 words */
+#define rTMP   r12
 
        dcbt    0,rSTR1
        or      rTMP, rSTR2, rSTR1
@@ -77,12 +78,59 @@ 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):
+       addi    rTMP2, rTMP, -1
+       beq     cr1, L(equal)
+       andc    rTMP2, rTMP2, rTMP
+       rldimi  rTMP2, rTMP2, 1, 0
+       and     rWORD2, rWORD2, rTMP2   /* Mask off gunk.  */
+       and     rWORD1, rWORD1, rTMP2
+       cmpd    cr1, rWORD1, rWORD2
+       beq     cr1, L(equal)
+       xor     rBITDIF, rWORD1, rWORD2 /* rBITDIF has bits that differ.  */
+       neg     rNEG, rBITDIF
+       and     rNEG, rNEG, rBITDIF     /* rNEG has LS bit that differs.  */
+       cntlzd  rNEG, rNEG              /* bitcount of the bit.  */
+       andi.   rNEG, rNEG, 56          /* bitcount to LS byte that differs. */
+       sld     rWORD1, rWORD1, rNEG    /* shift left to clear MS bytes.  */
+       sld     rWORD2, rWORD2, rNEG
+       xor.    rBITDIF, rWORD1, rWORD2
+       sub     rRTN, rWORD1, rWORD2
+       blt-    L(highbit)
+       sradi   rRTN, rRTN, 63          /* must return an int.  */
+       ori     rRTN, rRTN, 1
+       blr
+L(equal):
+       li      rRTN, 0
+       blr
+
+L(different):
+       ld      rWORD1, -8(rSTR1)
+       xor     rBITDIF, rWORD1, rWORD2 /* rBITDIF has bits that differ.  */
+       neg     rNEG, rBITDIF
+       and     rNEG, rNEG, rBITDIF     /* rNEG has LS bit that differs.  */
+       cntlzd  rNEG, rNEG              /* bitcount of the bit.  */
+       andi.   rNEG, rNEG, 56          /* bitcount to LS byte that differs. */
+       sld     rWORD1, rWORD1, rNEG    /* shift left to clear MS bytes.  */
+       sld     rWORD2, rWORD2, rNEG
+       xor.    rBITDIF, rWORD1, rWORD2
+       sub     rRTN, rWORD1, rWORD2
+       blt-    L(highbit)
+       sradi   rRTN, rRTN, 63
+       ori     rRTN, rRTN, 1
+       blr
+L(highbit):
+       sradi   rRTN, rWORD2, 63
+       ori     rRTN, rRTN, 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)
        cntlzd  rBITDIF, rBITDIF
@@ -91,7 +139,7 @@ L(endstring):
        cmpd    cr1, rNEG, rBITDIF
        sub     rRTN, rWORD1, rWORD2
        blt-    cr1, L(equal)
-       sradi   rRTN, rRTN, 63
+       sradi   rRTN, rRTN, 63          /* must return an int.  */
        ori     rRTN, rRTN, 1
        blr
 L(equal):
@@ -99,7 +147,7 @@ L(equal):
        blr
 
 L(different):
-       ldu     rWORD1, -8(rSTR1)
+       ld      rWORD1, -8(rSTR1)
        xor.    rBITDIF, rWORD1, rWORD2
        sub     rRTN, rWORD1, rWORD2
        blt-    L(highbit)
@@ -107,11 +155,10 @@ L(different):
        ori     rRTN, rRTN, 1
        blr
 L(highbit):
-       srdi    rWORD2, rWORD2, 56
-       srdi    rWORD1, rWORD1, 56
-       sub     rRTN, rWORD1, rWORD2
+       sradi   rRTN, rWORD2, 63
+       ori     rRTN, rRTN, 1
        blr
-
+#endif
 
 /* Oh well.  In this case, we just do a byte-by-byte comparison.  */
        .align 4