diff options
Diffstat (limited to 'sysdeps/powerpc/strcmp.S')
-rw-r--r-- | sysdeps/powerpc/strcmp.S | 132 |
1 files changed, 65 insertions, 67 deletions
diff --git a/sysdeps/powerpc/strcmp.S b/sysdeps/powerpc/strcmp.S index 92e9858d13..1accdd70cb 100644 --- a/sysdeps/powerpc/strcmp.S +++ b/sysdeps/powerpc/strcmp.S @@ -21,95 +21,93 @@ /* See strlen.s for comments on how the end-of-string testing works. */ -EALIGN(strcmp,4,0) -/* int [r3] strcmp (const char *p1 [r3], const char *p2 [r4]) */ +/* int [r3] strcmp (const char *s1 [r3], const char *s2 [r4]) */ -/* General register assignments: - r0: temporary - r3: pointer to previous word in s1 - r4: pointer to previous word in s2 - r5: current word from s1 - r6: current word from s2 - r7: 0xfefefeff - r8: 0x7f7f7f7f - r9: ~(word in s1 | 0x7f7f7f7f) */ +EALIGN (strcmp, 4, 0) -/* Register assignments in the prologue: - r10: low 2 bits of p2-p1 - r11: mask to orc with r5/r6 */ +#define rTMP r0 +#define rRTN r3 /* return value */ +#define rSTR1 r3 /* first string arg */ +#define rSTR2 r4 /* second string arg */ +#define rWORD1 r5 /* current word in s1 */ +#define rWORD2 r6 /* current word in s2 */ +#define rFEFE r7 /* constant 0xfefefeff (-0x01010101) */ +#define r7F7F r8 /* constant 0x7f7f7f7f */ +#define rNEG r9 /* ~(word in s1 | 0x7f7f7f7f) */ +#define rBITDIF r10 /* bits that differ in s1 & s2 words */ - or r0,r4,r3 - clrlwi. r0,r0,30 - lis r7,0xfeff - bne L(unaligned) + or rTMP, rSTR2, rSTR1 + clrlwi. rTMP, rTMP, 30 + lis rFEFE, -0x101 + bne L(unaligned) - lwz r5,0(r3) - lwz r6,0(r4) - lis r8,0x7f7f - addi r7,r7,-0x101 - addi r8,r8,0x7f7f - b L(g1) + lwz rWORD1, 0(rSTR1) + lwz rWORD2, 0(rSTR2) + lis r7F7F, 0x7f7f + addi rFEFE, rFEFE, -0x101 + addi r7F7F, r7F7F, 0x7f7f + b L(g1) -L(g0): lwzu r5,4(r3) - bne cr1,L(different) - lwzu r6,4(r4) -L(g1): add r0,r7,r5 - nor r9,r8,r5 - and. r0,r0,r9 - cmpw cr1,r5,r6 - beq+ L(g0) +L(g0): lwzu rWORD1, 4(rSTR1) + bne cr1, L(different) + lwzu rWORD2, 4(rSTR2) +L(g1): add rTMP, rFEFE, rWORD1 + nor rNEG, r7F7F, 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... */ - and r0,r8,r5 - beq cr1,L(equal) - add r0,r0,r8 - xor. r10,r5,r6 - andc r9,r9,r0 - blt- L(highbit) - cntlzw r10,r10 - cntlzw r9,r9 - addi r9,r9,7 - cmpw cr1,r9,r10 - sub r3,r5,r6 - bgelr+ cr1 + 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 + cntlzw rNEG, rNEG + addi rNEG, rNEG, 7 + cmpw cr1, rNEG, rBITDIF + sub rRTN, rWORD1, rWORD2 + bgelr+ cr1 L(equal): - li r3,0 + li rRTN, 0 blr L(different): - lwz r5,-4(r3) - xor. r10,r5,r6 - sub r3,r5,r6 + lwz rWORD1, -4(rSTR1) + xor. rBITDIF, rWORD1, rWORD2 + sub rRTN, rWORD1, rWORD2 bgelr+ L(highbit): - ori r3,r6,1 + ori rRTN, rWORD2, 1 blr /* Oh well. In this case, we just do a byte-by-byte comparison. */ .align 4 L(unaligned): - lbz r5,0(r3) - lbz r6,0(r4) - b L(u1) + lbz rWORD1, 0(rSTR1) + lbz rWORD2, 0(rSTR2) + b L(u1) -L(u0): lbzu r5,1(r3) - bne- L(u4) - lbzu r6,1(r4) -L(u1): cmpwi cr1,r5,0 - beq- cr1,L(u3) - cmpw r5,r6 - bne- L(u3) - lbzu r5,1(r3) - lbzu r6,1(r4) - cmpwi cr1,r5,0 - cmpw r5,r6 - bne+ cr1,L(u0) -L(u3): sub r3,r5,r6 +L(u0): lbzu rWORD1, 1(rSTR1) + bne- L(u4) + lbzu rWORD2, 1(rSTR2) +L(u1): cmpwi cr1, rWORD1, 0 + beq- cr1, L(u3) + cmpw rWORD1, rWORD2 + bne- L(u3) + lbzu rWORD1, 1(rSTR1) + lbzu rWORD2, 1(rSTR2) + cmpwi cr1, rWORD1, 0 + cmpw rWORD1, rWORD2 + bne+ cr1, L(u0) +L(u3): sub rRTN, rWORD1, rWORD2 blr -L(u4): lbz r5,-1(r3) - sub r3,r5,r6 +L(u4): lbz rWORD1, -1(rSTR1) + sub rRTN, rWORD1, rWORD2 blr END(strcmp) |