blob: 00e0fec3a667e5638cedf69ebca43c7051661337 [file] [log] [blame]
Yu Chien Peter Lin60814cb2023-08-09 18:49:30 +08001/* 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)