| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 |
- /* SPDX-License-Identifier: GPL-2.0-only */
- #include <linux/linkage.h>
- #include <asm/asm.h>
- #include <asm/alternative-macros.h>
- #include <asm/hwcap.h>
- /* int strcmp(const char *cs, const char *ct) */
- SYM_FUNC_START(strcmp)
- ALTERNATIVE("nop", "j strcmp_zbb", 0, RISCV_ISA_EXT_ZBB, CONFIG_RISCV_ISA_ZBB)
- /*
- * Returns
- * a0 - comparison result, value like strcmp
- *
- * Parameters
- * a0 - string1
- * a1 - string2
- *
- * Clobbers
- * t0, t1
- */
- 1:
- lbu t0, 0(a0)
- lbu t1, 0(a1)
- addi a0, a0, 1
- addi a1, a1, 1
- bne t0, t1, 2f
- bnez t0, 1b
- li a0, 0
- ret
- 2:
- /*
- * strcmp only needs to return (< 0, 0, > 0) values
- * not necessarily -1, 0, +1
- */
- sub a0, t0, t1
- ret
- /*
- * Variant of strcmp using the ZBB extension if available.
- * The code was published as part of the bitmanip manual
- * in Appendix A.
- */
- #ifdef CONFIG_RISCV_ISA_ZBB
- strcmp_zbb:
- .option push
- .option arch,+zbb
- /*
- * Returns
- * a0 - comparison result, value like strcmp
- *
- * Parameters
- * a0 - string1
- * a1 - string2
- *
- * Clobbers
- * t0, t1, t2, t3, t4
- */
- or t2, a0, a1
- li t4, -1
- and t2, t2, SZREG-1
- bnez t2, 3f
- /* Main loop for aligned string. */
- .p2align 3
- 1:
- REG_L t0, 0(a0)
- REG_L t1, 0(a1)
- orc.b t3, t0
- bne t3, t4, 2f
- addi a0, a0, SZREG
- addi a1, a1, SZREG
- beq t0, t1, 1b
- /*
- * Words don't match, and no null byte in the first
- * word. Get bytes in big-endian order and compare.
- */
- #ifndef CONFIG_CPU_BIG_ENDIAN
- rev8 t0, t0
- rev8 t1, t1
- #endif
- /* Synthesize (t0 >= t1) ? 1 : -1 in a branchless sequence. */
- sltu a0, t0, t1
- neg a0, a0
- ori a0, a0, 1
- ret
- 2:
- /*
- * Found a null byte.
- * If words don't match, fall back to simple loop.
- */
- bne t0, t1, 3f
- /* Otherwise, strings are equal. */
- li a0, 0
- ret
- /* Simple loop for misaligned strings. */
- .p2align 3
- 3:
- lbu t0, 0(a0)
- lbu t1, 0(a1)
- addi a0, a0, 1
- addi a1, a1, 1
- bne t0, t1, 4f
- bnez t0, 3b
- 4:
- sub a0, t0, t1
- ret
- .option pop
- #endif
- SYM_FUNC_END(strcmp)
- SYM_FUNC_ALIAS(__pi_strcmp, strcmp)
- EXPORT_SYMBOL(strcmp)
|