1/* SPDX-License-Identifier: GPL-2.0 */ 2/* 3 * Taken from Linux arch/riscv/lib/strncmp.S 4 */ 5 6#include <linux/linkage.h> 7#include <asm/asm.h> 8 9ENTRY(__strncmp) 10WEAK(strncmp) 11.option push 12.option arch,+zbb 13 /* 14 * Returns 15 * a0 - comparison result, like strncmp 16 * 17 * Parameters 18 * a0 - string1 19 * a1 - string2 20 * a2 - number of characters to compare 21 * 22 * Clobbers 23 * t0, t1, t2, t3, t4, t5, t6 24 */ 25 26 or t2, a0, a1 27 li t5, -1 28 and t2, t2, SZREG-1 29 add t4, a0, a2 30 bnez t2, 3f 31 32 /* Adjust limit for fast-path. */ 33 andi t6, t4, -SZREG 34 35 /* Main loop for aligned string. */ 36 .p2align 3 371: 38 bge a0, t6, 3f 39 REG_L t0, 0(a0) 40 REG_L t1, 0(a1) 41 orc.b t3, t0 42 bne t3, t5, 2f 43 orc.b t3, t1 44 bne t3, t5, 2f 45 addi a0, a0, SZREG 46 addi a1, a1, SZREG 47 beq t0, t1, 1b 48 49 /* 50 * Words don't match, and no null byte in the first 51 * word. Get bytes in big-endian order and compare. 52 */ 53#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ 54 rev8 t0, t0 55 rev8 t1, t1 56#endif 57 58 /* Synthesize (t0 >= t1) ? 1 : -1 in a branchless sequence. */ 59 sltu a0, t0, t1 60 neg a0, a0 61 ori a0, a0, 1 62 ret 63 642: 65 /* 66 * Found a null byte. 67 * If words don't match, fall back to simple loop. 68 */ 69 bne t0, t1, 3f 70 71 /* Otherwise, strings are equal. */ 72 li a0, 0 73 ret 74 75 /* Simple loop for misaligned strings. */ 76 .p2align 3 773: 78 bge a0, t4, 5f 79 lbu t0, 0(a0) 80 lbu t1, 0(a1) 81 addi a0, a0, 1 82 addi a1, a1, 1 83 bne t0, t1, 4f 84 bnez t0, 3b 85 864: 87 sub a0, t0, t1 88 ret 89 905: 91 li a0, 0 92 ret 93.option pop 94END(__strncmp) 95