mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-11 07:40:05 +00:00
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:
parent
33ee81de05
commit
8a7413f9b0
13
ChangeLog
13
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>
|
2013-10-04 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
* sysdeps/powerpc/powerpc64/power7/strnlen.S (strnlen): Add
|
* sysdeps/powerpc/powerpc64/power7/strnlen.S (strnlen): Add
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user