[PATCH 4/4] RISC-V: strcmp [speed optimized]: optimize mismatch logic for targets with Zb* extension support
puranikvinit <[email protected]>
| Newsgroups | gmane.comp.lib.newlib |
|---|---|
| Message-ID | <[email protected]> |
Reworks the mismatch handling to use Zbb's ctz/clz instructions for faster byte difference detection, significantly improving performance on Zbb-capable targets. Non-Zbb targets retain the original logic for compatibility. Signed-off-by: puranikvinit <[email protected]> Reviewed-by: Christian Herber <[email protected]> --- newlib/libc/machine/riscv/strcmp.S | 155 ++++++++++++++++------------- 1 file changed, 85 insertions(+), 70 deletions(-) diff --git a/newlib/libc/machine/riscv/strcmp.S b/newlib/libc/machine/riscv/strcmp.S index 42c870c10..52622cb5d 100644 --- a/newlib/libc/machine/riscv/strcmp.S +++ b/newlib/libc/machine/riscv/strcmp.S @@ -99,78 +99,93 @@ strcmp: .Lmismatch: # words don't match, but a2 has no null byte. + #if __riscv_zbb + xor a4, a2, a3 -#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ - -#if __riscv_xlen == 64 - sll a4, a2, 48 - sll a5, a3, 48 - bne a4, a5, .Lmismatch_upper - sll a4, a2, 32 - sll a5, a3, 32 - bne a4, a5, .Lmismatch_upper -#endif - sll a4, a2, 16 - sll a5, a3, 16 - bne a4, a5, .Lmismatch_upper - - srl a4, a2, 8*SZREG-16 - srl a5, a3, 8*SZREG-16 - sub a0, a4, a5 - and a1, a0, 0xff - bnez a1, .Lfinal_upper_diff - ret - -.Lmismatch_upper: - srl a4, a4, 8*SZREG-16 - srl a5, a5, 8*SZREG-16 - sub a0, a4, a5 - and a1, a0, 0xff - bnez a1, .Lfinal_upper_diff - ret - -.Lfinal_upper_diff: - and a4, a4, 0xff - and a5, a5, 0xff - sub a0, a4, a5 - ret - -#else - -#if __riscv_xlen == 64 - srl a4, a2, 48 - srl a5, a3, 48 - bne a4, a5, .Lmismatch_lower - srl a4, a2, 32 - srl a5, a3, 32 - bne a4, a5, .Lmismatch_lower -#endif - srl a4, a2, 16 - srl a5, a3, 16 - bne a4, a5, .Lmismatch_lower - - srl a4, a2, 8 - srl a5, a3, 8 - bne a4, a5, .Lbyte_diff - and a4, a2, 0xff - and a5, a3, 0xff - -.Lbyte_diff: - sub a0, a4, a5 - ret - -.Lmismatch_lower: - srl a2, a4, 8 - srl a3, a5, 8 - bne a2, a3, .Lfinal_lower_diff - and a2, a4, 0xff - and a3, a5, 0xff - -.Lfinal_lower_diff: - sub a0, a2, a3 - ret + #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + ctz a5, a4 + #else + clz a5, a4 + #endif + andi a5, a5, -8 + + srl a2, a2, a5 + and a2, a2, 0xff + + srl a3, a3, a5 + and a3, a3, 0xff + + sub a0, a2, a3 + ret + #else + #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + #if __riscv_xlen == 64 + sll a4, a2, 48 + sll a5, a3, 48 + bne a4, a5, .Lmismatch_upper + sll a4, a2, 32 + sll a5, a3, 32 + bne a4, a5, .Lmismatch_upper + #endif + sll a4, a2, 16 + sll a5, a3, 16 + bne a4, a5, .Lmismatch_upper + + srl a4, a2, 8*SZREG-16 + srl a5, a3, 8*SZREG-16 + sub a0, a4, a5 + and a1, a0, 0xff + bnez a1, .Lfinal_upper_diff + ret -#endif + .Lmismatch_upper: + srl a4, a4, 8*SZREG-16 + srl a5, a5, 8*SZREG-16 + sub a0, a4, a5 + and a1, a0, 0xff + bnez a1, .Lfinal_upper_diff + ret + + .Lfinal_upper_diff: + and a4, a4, 0xff + and a5, a5, 0xff + sub a0, a4, a5 + ret + #else + #if __riscv_xlen == 64 + srl a4, a2, 48 + srl a5, a3, 48 + bne a4, a5, .Lmismatch_lower + srl a4, a2, 32 + srl a5, a3, 32 + bne a4, a5, .Lmismatch_lower + #endif + srl a4, a2, 16 + srl a5, a3, 16 + bne a4, a5, .Lmismatch_lower + + srl a4, a2, 8 + srl a5, a3, 8 + bne a4, a5, .Lbyte_diff + and a4, a2, 0xff + and a5, a3, 0xff + + .Lbyte_diff: + sub a0, a4, a5 + ret + + .Lmismatch_lower: + srl a2, a4, 8 + srl a3, a5, 8 + bne a2, a3, .Lfinal_lower_diff + and a2, a4, 0xff + and a3, a5, 0xff + + .Lfinal_lower_diff: + sub a0, a2, a3 + ret + #endif + #endif .Lmisaligned: # misaligned -- 2.34.1