PowerPC LE strcmp and strncmp

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.
This commit is contained in:
Alan Modra 2013-08-17 18:41:17 +09:30
parent 33ee81de05
commit 8a7413f9b0
9 changed files with 393 additions and 81 deletions

View File

@ -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> 2013-10-04 Alan Modra <amodra@gmail.com>
* sysdeps/powerpc/powerpc64/power7/strnlen.S (strnlen): Add * sysdeps/powerpc/powerpc64/power7/strnlen.S (strnlen): Add

View File

@ -24,7 +24,7 @@
EALIGN (strncmp, 4, 0) EALIGN (strncmp, 4, 0)
#define rTMP r0 #define rTMP2 r0
#define rRTN r3 #define rRTN r3
#define rSTR1 r3 /* first string arg */ #define rSTR1 r3 /* first string arg */
#define rSTR2 r4 /* second string arg */ #define rSTR2 r4 /* second string arg */
@ -37,6 +37,7 @@ EALIGN (strncmp, 4, 0)
#define r7F7F r9 /* constant 0x7f7f7f7f */ #define r7F7F r9 /* constant 0x7f7f7f7f */
#define rNEG r10 /* ~(word in s1 | 0x7f7f7f7f) */ #define rNEG r10 /* ~(word in s1 | 0x7f7f7f7f) */
#define rBITDIF r11 /* bits that differ in s1 & s2 words */ #define rBITDIF r11 /* bits that differ in s1 & s2 words */
#define rTMP r12
dcbt 0,rSTR1 dcbt 0,rSTR1
or rTMP, rSTR2, 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 we don't compare two strings as different because of gunk beyond
the end of the strings... */ 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): L(endstring):
and rTMP, r7F7F, rWORD1 and rTMP, r7F7F, rWORD1
beq cr1, L(equal) beq cr1, L(equal)
add rTMP, rTMP, r7F7F add rTMP, rTMP, r7F7F
xor. rBITDIF, rWORD1, rWORD2 xor. rBITDIF, rWORD1, rWORD2
andc rNEG, rNEG, rTMP andc rNEG, rNEG, rTMP
blt- L(highbit) blt- L(highbit)
cntlzw rBITDIF, rBITDIF cntlzw rBITDIF, rBITDIF
@ -88,28 +122,20 @@ L(endstring):
addi rNEG, rNEG, 7 addi rNEG, rNEG, 7
cmpw cr1, rNEG, rBITDIF cmpw cr1, rNEG, rBITDIF
sub rRTN, rWORD1, rWORD2 sub rRTN, rWORD1, rWORD2
blt- cr1, L(equal) bgelr+ cr1
srawi rRTN, rRTN, 31
ori rRTN, rRTN, 1
blr
L(equal): L(equal):
li rRTN, 0 li rRTN, 0
blr blr
L(different): L(different):
lwzu rWORD1, -4(rSTR1) lwz rWORD1, -4(rSTR1)
xor. rBITDIF, rWORD1, rWORD2 xor. rBITDIF, rWORD1, rWORD2
sub rRTN, rWORD1, rWORD2 sub rRTN, rWORD1, rWORD2
blt- L(highbit) bgelr+
srawi rRTN, rRTN, 31
ori rRTN, rRTN, 1
blr
L(highbit): L(highbit):
srwi rWORD2, rWORD2, 24 ori rRTN, rWORD2, 1
srwi rWORD1, rWORD1, 24
sub rRTN, rWORD1, rWORD2
blr blr
#endif
/* Oh well. In this case, we just do a byte-by-byte comparison. */ /* Oh well. In this case, we just do a byte-by-byte comparison. */
.align 4 .align 4

View File

@ -26,7 +26,7 @@
EALIGN (strncmp,5,0) EALIGN (strncmp,5,0)
#define rTMP r0 #define rTMP2 r0
#define rRTN r3 #define rRTN r3
#define rSTR1 r3 /* first string arg */ #define rSTR1 r3 /* first string arg */
#define rSTR2 r4 /* second string arg */ #define rSTR2 r4 /* second string arg */
@ -39,6 +39,7 @@ EALIGN (strncmp,5,0)
#define r7F7F r9 /* constant 0x7f7f7f7f */ #define r7F7F r9 /* constant 0x7f7f7f7f */
#define rNEG r10 /* ~(word in s1 | 0x7f7f7f7f) */ #define rNEG r10 /* ~(word in s1 | 0x7f7f7f7f) */
#define rBITDIF r11 /* bits that differ in s1 & s2 words */ #define rBITDIF r11 /* bits that differ in s1 & s2 words */
#define rTMP r12
dcbt 0,rSTR1 dcbt 0,rSTR1
nop 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 /* 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 we don't compare two strings as different because of gunk beyond
the end of the strings... */ 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): L(endstring):
and rTMP,r7F7F,rWORD1 and rTMP,r7F7F,rWORD1
beq cr1,L(equal) beq cr1,L(equal)
add rTMP,rTMP,r7F7F add rTMP,rTMP,r7F7F
xor. rBITDIF,rWORD1,rWORD2 xor. rBITDIF,rWORD1,rWORD2
andc rNEG,rNEG,rTMP andc rNEG,rNEG,rTMP
blt L(highbit) blt L(highbit)
cntlzw rBITDIF,rBITDIF cntlzw rBITDIF,rBITDIF
@ -92,28 +125,20 @@ L(endstring):
addi rNEG,rNEG,7 addi rNEG,rNEG,7
cmpw cr1,rNEG,rBITDIF cmpw cr1,rNEG,rBITDIF
sub rRTN,rWORD1,rWORD2 sub rRTN,rWORD1,rWORD2
blt cr1,L(equal) bgelr cr1
srawi rRTN,rRTN,31
ori rRTN,rRTN,1
blr
L(equal): L(equal):
li rRTN,0 li rRTN,0
blr blr
L(different): L(different):
lwzu rWORD1,-4(rSTR1) lwz rWORD1,-4(rSTR1)
xor. rBITDIF,rWORD1,rWORD2 xor. rBITDIF,rWORD1,rWORD2
sub rRTN,rWORD1,rWORD2 sub rRTN,rWORD1,rWORD2
blt L(highbit) bgelr
srawi rRTN,rRTN,31
ori rRTN,rRTN,1
blr
L(highbit): L(highbit):
srwi rWORD2,rWORD2,24 ori rRTN, rWORD2, 1
srwi rWORD1,rWORD1,24
sub rRTN,rWORD1,rWORD2
blr blr
#endif
/* Oh well. In this case, we just do a byte-by-byte comparison. */ /* Oh well. In this case, we just do a byte-by-byte comparison. */
.align 4 .align 4

View File

@ -24,7 +24,7 @@
EALIGN (strcmp, 4, 0) EALIGN (strcmp, 4, 0)
#define rTMP r0 #define rTMP2 r0
#define rRTN r3 #define rRTN r3
#define rSTR1 r3 /* first string arg */ #define rSTR1 r3 /* first string arg */
#define rSTR2 r4 /* second string arg */ #define rSTR2 r4 /* second string arg */
@ -34,6 +34,7 @@ EALIGN (strcmp, 4, 0)
#define r7F7F r8 /* constant 0x7f7f7f7f */ #define r7F7F r8 /* constant 0x7f7f7f7f */
#define rNEG r9 /* ~(word in s1 | 0x7f7f7f7f) */ #define rNEG r9 /* ~(word in s1 | 0x7f7f7f7f) */
#define rBITDIF r10 /* bits that differ in s1 & s2 words */ #define rBITDIF r10 /* bits that differ in s1 & s2 words */
#define rTMP r11
or rTMP, rSTR2, rSTR1 or rTMP, rSTR2, rSTR1
@ -56,10 +57,45 @@ L(g1): add rTMP, rFEFE, rWORD1
and. rTMP, rTMP, rNEG and. rTMP, rTMP, rNEG
cmpw cr1, rWORD1, rWORD2 cmpw cr1, rWORD1, rWORD2
beq+ L(g0) beq+ L(g0)
L(endstring):
/* OK. We've hit the end of the string. We need to be careful that /* 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 we don't compare two strings as different because of gunk beyond
the end of the strings... */ 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 and rTMP, r7F7F, rWORD1
beq cr1, L(equal) beq cr1, L(equal)
add rTMP, rTMP, r7F7F add rTMP, rTMP, r7F7F
@ -84,7 +120,7 @@ L(different):
L(highbit): L(highbit):
ori rRTN, rWORD2, 1 ori rRTN, rWORD2, 1
blr blr
#endif
/* Oh well. In this case, we just do a byte-by-byte comparison. */ /* Oh well. In this case, we just do a byte-by-byte comparison. */
.align 4 .align 4

View File

@ -24,7 +24,7 @@
EALIGN (strncmp, 4, 0) EALIGN (strncmp, 4, 0)
#define rTMP r0 #define rTMP2 r0
#define rRTN r3 #define rRTN r3
#define rSTR1 r3 /* first string arg */ #define rSTR1 r3 /* first string arg */
#define rSTR2 r4 /* second string arg */ #define rSTR2 r4 /* second string arg */
@ -35,6 +35,7 @@ EALIGN (strncmp, 4, 0)
#define r7F7F r9 /* constant 0x7f7f7f7f */ #define r7F7F r9 /* constant 0x7f7f7f7f */
#define rNEG r10 /* ~(word in s1 | 0x7f7f7f7f) */ #define rNEG r10 /* ~(word in s1 | 0x7f7f7f7f) */
#define rBITDIF r11 /* bits that differ in s1 & s2 words */ #define rBITDIF r11 /* bits that differ in s1 & s2 words */
#define rTMP r12
dcbt 0,rSTR1 dcbt 0,rSTR1
or rTMP, rSTR2, 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 we don't compare two strings as different because of gunk beyond
the end of the strings... */ 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): L(endstring):
and rTMP, r7F7F, rWORD1 and rTMP, r7F7F, rWORD1
beq cr1, L(equal) beq cr1, L(equal)
add rTMP, rTMP, r7F7F add rTMP, rTMP, r7F7F
xor. rBITDIF, rWORD1, rWORD2 xor. rBITDIF, rWORD1, rWORD2
andc rNEG, rNEG, rTMP andc rNEG, rNEG, rTMP
blt- L(highbit) blt- L(highbit)
cntlzw rBITDIF, rBITDIF cntlzw rBITDIF, rBITDIF
@ -86,28 +120,20 @@ L(endstring):
addi rNEG, rNEG, 7 addi rNEG, rNEG, 7
cmpw cr1, rNEG, rBITDIF cmpw cr1, rNEG, rBITDIF
sub rRTN, rWORD1, rWORD2 sub rRTN, rWORD1, rWORD2
blt- cr1, L(equal) bgelr+ cr1
srawi rRTN, rRTN, 31
ori rRTN, rRTN, 1
blr
L(equal): L(equal):
li rRTN, 0 li rRTN, 0
blr blr
L(different): L(different):
lwzu rWORD1, -4(rSTR1) lwz rWORD1, -4(rSTR1)
xor. rBITDIF, rWORD1, rWORD2 xor. rBITDIF, rWORD1, rWORD2
sub rRTN, rWORD1, rWORD2 sub rRTN, rWORD1, rWORD2
blt- L(highbit) bgelr+
srawi rRTN, rRTN, 31
ori rRTN, rRTN, 1
blr
L(highbit): L(highbit):
srwi rWORD2, rWORD2, 24 ori rRTN, rWORD2, 1
srwi rWORD1, rWORD1, 24
sub rRTN, rWORD1, rWORD2
blr blr
#endif
/* Oh well. In this case, we just do a byte-by-byte comparison. */ /* Oh well. In this case, we just do a byte-by-byte comparison. */
.align 4 .align 4

View File

@ -25,7 +25,7 @@
EALIGN (strncmp, 4, 0) EALIGN (strncmp, 4, 0)
CALL_MCOUNT 3 CALL_MCOUNT 3
#define rTMP r0 #define rTMP2 r0
#define rRTN r3 #define rRTN r3
#define rSTR1 r3 /* first string arg */ #define rSTR1 r3 /* first string arg */
#define rSTR2 r4 /* second string arg */ #define rSTR2 r4 /* second string arg */
@ -38,6 +38,7 @@ EALIGN (strncmp, 4, 0)
#define r7F7F r9 /* constant 0x7f7f7f7f7f7f7f7f */ #define r7F7F r9 /* constant 0x7f7f7f7f7f7f7f7f */
#define rNEG r10 /* ~(word in s1 | 0x7f7f7f7f7f7f7f7f) */ #define rNEG r10 /* ~(word in s1 | 0x7f7f7f7f7f7f7f7f) */
#define rBITDIF r11 /* bits that differ in s1 & s2 words */ #define rBITDIF r11 /* bits that differ in s1 & s2 words */
#define rTMP r12
dcbt 0,rSTR1 dcbt 0,rSTR1
or rTMP, rSTR2, 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 we don't compare two strings as different because of gunk beyond
the end of the strings... */ 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): L(endstring):
and rTMP, r7F7F, rWORD1 and rTMP, r7F7F, rWORD1
beq cr1, L(equal) beq cr1, L(equal)
add rTMP, rTMP, r7F7F add rTMP, rTMP, r7F7F
xor. rBITDIF, rWORD1, rWORD2 xor. rBITDIF, rWORD1, rWORD2
andc rNEG, rNEG, rTMP andc rNEG, rNEG, rTMP
blt- L(highbit) blt- L(highbit)
cntlzd rBITDIF, rBITDIF cntlzd rBITDIF, rBITDIF
@ -93,7 +141,7 @@ L(endstring):
cmpd cr1, rNEG, rBITDIF cmpd cr1, rNEG, rBITDIF
sub rRTN, rWORD1, rWORD2 sub rRTN, rWORD1, rWORD2
blt- cr1, L(equal) blt- cr1, L(equal)
sradi rRTN, rRTN, 63 sradi rRTN, rRTN, 63 /* must return an int. */
ori rRTN, rRTN, 1 ori rRTN, rRTN, 1
blr blr
L(equal): L(equal):
@ -101,7 +149,7 @@ L(equal):
blr blr
L(different): L(different):
ldu rWORD1, -8(rSTR1) ld rWORD1, -8(rSTR1)
xor. rBITDIF, rWORD1, rWORD2 xor. rBITDIF, rWORD1, rWORD2
sub rRTN, rWORD1, rWORD2 sub rRTN, rWORD1, rWORD2
blt- L(highbit) blt- L(highbit)
@ -109,11 +157,10 @@ L(different):
ori rRTN, rRTN, 1 ori rRTN, rRTN, 1
blr blr
L(highbit): L(highbit):
srdi rWORD2, rWORD2, 56 sradi rRTN, rWORD2, 63
srdi rWORD1, rWORD1, 56 ori rRTN, rRTN, 1
sub rRTN, rWORD1, rWORD2
blr blr
#endif
/* Oh well. In this case, we just do a byte-by-byte comparison. */ /* Oh well. In this case, we just do a byte-by-byte comparison. */
.align 4 .align 4

View File

@ -27,7 +27,7 @@
EALIGN (strncmp,5,0) EALIGN (strncmp,5,0)
CALL_MCOUNT 3 CALL_MCOUNT 3
#define rTMP r0 #define rTMP2 r0
#define rRTN r3 #define rRTN r3
#define rSTR1 r3 /* first string arg */ #define rSTR1 r3 /* first string arg */
#define rSTR2 r4 /* second string arg */ #define rSTR2 r4 /* second string arg */
@ -40,6 +40,7 @@ EALIGN (strncmp,5,0)
#define r7F7F r9 /* constant 0x7f7f7f7f7f7f7f7f */ #define r7F7F r9 /* constant 0x7f7f7f7f7f7f7f7f */
#define rNEG r10 /* ~(word in s1 | 0x7f7f7f7f7f7f7f7f) */ #define rNEG r10 /* ~(word in s1 | 0x7f7f7f7f7f7f7f7f) */
#define rBITDIF r11 /* bits that differ in s1 & s2 words */ #define rBITDIF r11 /* bits that differ in s1 & s2 words */
#define rTMP r12
dcbt 0,rSTR1 dcbt 0,rSTR1
nop nop
@ -83,12 +84,57 @@ L(g1): add rTMP,rFEFE,rWORD1
we don't compare two strings as different because of gunk beyond we don't compare two strings as different because of gunk beyond
the end of the strings... */ 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): L(endstring):
and rTMP,r7F7F,rWORD1 and rTMP,r7F7F,rWORD1
beq cr1,L(equal) beq cr1,L(equal)
add rTMP,rTMP,r7F7F add rTMP,rTMP,r7F7F
xor. rBITDIF,rWORD1,rWORD2 xor. rBITDIF,rWORD1,rWORD2
andc rNEG,rNEG,rTMP andc rNEG,rNEG,rTMP
blt L(highbit) blt L(highbit)
cntlzd rBITDIF,rBITDIF cntlzd rBITDIF,rBITDIF
@ -97,7 +143,7 @@ L(endstring):
cmpd cr1,rNEG,rBITDIF cmpd cr1,rNEG,rBITDIF
sub rRTN,rWORD1,rWORD2 sub rRTN,rWORD1,rWORD2
blt cr1,L(equal) blt cr1,L(equal)
sradi rRTN,rRTN,63 sradi rRTN,rRTN,63 /* must return an int. */
ori rRTN,rRTN,1 ori rRTN,rRTN,1
blr blr
L(equal): L(equal):
@ -105,7 +151,7 @@ L(equal):
blr blr
L(different): L(different):
ldu rWORD1,-8(rSTR1) ld rWORD1,-8(rSTR1)
xor. rBITDIF,rWORD1,rWORD2 xor. rBITDIF,rWORD1,rWORD2
sub rRTN,rWORD1,rWORD2 sub rRTN,rWORD1,rWORD2
blt L(highbit) blt L(highbit)
@ -113,11 +159,10 @@ L(different):
ori rRTN,rRTN,1 ori rRTN,rRTN,1
blr blr
L(highbit): L(highbit):
srdi rWORD2,rWORD2,56 sradi rRTN,rWORD2,63
srdi rWORD1,rWORD1,56 ori rRTN,rRTN,1
sub rRTN,rWORD1,rWORD2
blr blr
#endif
/* Oh well. In this case, we just do a byte-by-byte comparison. */ /* Oh well. In this case, we just do a byte-by-byte comparison. */
.align 4 .align 4

View File

@ -25,7 +25,7 @@
EALIGN (strcmp, 4, 0) EALIGN (strcmp, 4, 0)
CALL_MCOUNT 2 CALL_MCOUNT 2
#define rTMP r0 #define rTMP2 r0
#define rRTN r3 #define rRTN r3
#define rSTR1 r3 /* first string arg */ #define rSTR1 r3 /* first string arg */
#define rSTR2 r4 /* second string arg */ #define rSTR2 r4 /* second string arg */
@ -35,6 +35,7 @@ EALIGN (strcmp, 4, 0)
#define r7F7F r8 /* constant 0x7f7f7f7f7f7f7f7f */ #define r7F7F r8 /* constant 0x7f7f7f7f7f7f7f7f */
#define rNEG r9 /* ~(word in s1 | 0x7f7f7f7f7f7f7f7f) */ #define rNEG r9 /* ~(word in s1 | 0x7f7f7f7f7f7f7f7f) */
#define rBITDIF r10 /* bits that differ in s1 & s2 words */ #define rBITDIF r10 /* bits that differ in s1 & s2 words */
#define rTMP r11
dcbt 0,rSTR1 dcbt 0,rSTR1
or rTMP, rSTR2, rSTR1 or rTMP, rSTR2, rSTR1
@ -58,19 +59,66 @@ L(g0): ldu rWORD1, 8(rSTR1)
ldu rWORD2, 8(rSTR2) ldu rWORD2, 8(rSTR2)
L(g1): add rTMP, rFEFE, rWORD1 L(g1): add rTMP, rFEFE, rWORD1
nor rNEG, r7F7F, rWORD1 nor rNEG, r7F7F, rWORD1
and. rTMP, rTMP, rNEG and. rTMP, rTMP, rNEG
cmpd cr1, rWORD1, rWORD2 cmpd cr1, rWORD1, rWORD2
beq+ L(g0) beq+ L(g0)
L(endstring):
/* OK. We've hit the end of the string. We need to be careful that /* 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 we don't compare two strings as different because of gunk beyond
the end of the strings... */ 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 and rTMP, r7F7F, rWORD1
beq cr1, L(equal) beq cr1, L(equal)
add rTMP, rTMP, r7F7F add rTMP, rTMP, r7F7F
xor. rBITDIF, rWORD1, rWORD2 xor. rBITDIF, rWORD1, rWORD2
andc rNEG, rNEG, rTMP andc rNEG, rNEG, rTMP
blt- L(highbit) blt- L(highbit)
cntlzd rBITDIF, rBITDIF cntlzd rBITDIF, rBITDIF
@ -79,7 +127,7 @@ L(endstring):
cmpd cr1, rNEG, rBITDIF cmpd cr1, rNEG, rBITDIF
sub rRTN, rWORD1, rWORD2 sub rRTN, rWORD1, rWORD2
blt- cr1, L(equal) blt- cr1, L(equal)
sradi rRTN, rRTN, 63 sradi rRTN, rRTN, 63 /* must return an int. */
ori rRTN, rRTN, 1 ori rRTN, rRTN, 1
blr blr
L(equal): L(equal):
@ -95,11 +143,10 @@ L(different):
ori rRTN, rRTN, 1 ori rRTN, rRTN, 1
blr blr
L(highbit): L(highbit):
srdi rWORD2, rWORD2, 56 sradi rRTN, rWORD2, 63
srdi rWORD1, rWORD1, 56 ori rRTN, rRTN, 1
sub rRTN, rWORD1, rWORD2
blr blr
#endif
/* Oh well. In this case, we just do a byte-by-byte comparison. */ /* Oh well. In this case, we just do a byte-by-byte comparison. */
.align 4 .align 4

View File

@ -25,7 +25,7 @@
EALIGN (strncmp, 4, 0) EALIGN (strncmp, 4, 0)
CALL_MCOUNT 3 CALL_MCOUNT 3
#define rTMP r0 #define rTMP2 r0
#define rRTN r3 #define rRTN r3
#define rSTR1 r3 /* first string arg */ #define rSTR1 r3 /* first string arg */
#define rSTR2 r4 /* second string arg */ #define rSTR2 r4 /* second string arg */
@ -36,6 +36,7 @@ EALIGN (strncmp, 4, 0)
#define r7F7F r9 /* constant 0x7f7f7f7f7f7f7f7f */ #define r7F7F r9 /* constant 0x7f7f7f7f7f7f7f7f */
#define rNEG r10 /* ~(word in s1 | 0x7f7f7f7f7f7f7f7f) */ #define rNEG r10 /* ~(word in s1 | 0x7f7f7f7f7f7f7f7f) */
#define rBITDIF r11 /* bits that differ in s1 & s2 words */ #define rBITDIF r11 /* bits that differ in s1 & s2 words */
#define rTMP r12
dcbt 0,rSTR1 dcbt 0,rSTR1
or rTMP, rSTR2, 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 we don't compare two strings as different because of gunk beyond
the end of the strings... */ 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): L(endstring):
and rTMP, r7F7F, rWORD1 and rTMP, r7F7F, rWORD1
beq cr1, L(equal) beq cr1, L(equal)
add rTMP, rTMP, r7F7F add rTMP, rTMP, r7F7F
xor. rBITDIF, rWORD1, rWORD2 xor. rBITDIF, rWORD1, rWORD2
andc rNEG, rNEG, rTMP andc rNEG, rNEG, rTMP
blt- L(highbit) blt- L(highbit)
cntlzd rBITDIF, rBITDIF cntlzd rBITDIF, rBITDIF
@ -91,7 +139,7 @@ L(endstring):
cmpd cr1, rNEG, rBITDIF cmpd cr1, rNEG, rBITDIF
sub rRTN, rWORD1, rWORD2 sub rRTN, rWORD1, rWORD2
blt- cr1, L(equal) blt- cr1, L(equal)
sradi rRTN, rRTN, 63 sradi rRTN, rRTN, 63 /* must return an int. */
ori rRTN, rRTN, 1 ori rRTN, rRTN, 1
blr blr
L(equal): L(equal):
@ -99,7 +147,7 @@ L(equal):
blr blr
L(different): L(different):
ldu rWORD1, -8(rSTR1) ld rWORD1, -8(rSTR1)
xor. rBITDIF, rWORD1, rWORD2 xor. rBITDIF, rWORD1, rWORD2
sub rRTN, rWORD1, rWORD2 sub rRTN, rWORD1, rWORD2
blt- L(highbit) blt- L(highbit)
@ -107,11 +155,10 @@ L(different):
ori rRTN, rRTN, 1 ori rRTN, rRTN, 1
blr blr
L(highbit): L(highbit):
srdi rWORD2, rWORD2, 56 sradi rRTN, rWORD2, 63
srdi rWORD1, rWORD1, 56 ori rRTN, rRTN, 1
sub rRTN, rWORD1, rWORD2
blr blr
#endif
/* Oh well. In this case, we just do a byte-by-byte comparison. */ /* Oh well. In this case, we just do a byte-by-byte comparison. */
.align 4 .align 4