/* SPDX-License-Identifier: GPL-2.0 */ /* * Taken from Linux arch/riscv/lib/strncmp.S */ #include #include ENTRY(__strncmp) WEAK(strncmp) .option push .option arch,+zbb /* * Returns * a0 - comparison result, like strncmp * * Parameters * a0 - string1 * a1 - string2 * a2 - number of characters to compare * * Clobbers * t0, t1, t2, t3, t4, t5, t6 */ or t2, a0, a1 li t5, -1 and t2, t2, SZREG-1 add t4, a0, a2 bnez t2, 3f /* Adjust limit for fast-path. */ andi t6, t4, -SZREG /* Main loop for aligned string. */ .p2align 3 1: bge a0, t6, 3f REG_L t0, 0(a0) REG_L t1, 0(a1) orc.b t3, t0 bne t3, t5, 2f orc.b t3, t1 bne t3, t5, 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. */ #if __BYTE_ORDER__ == __ORDER_LITTLE_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: bge a0, t4, 5f 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 5: li a0, 0 ret .option pop END(__strncmp)