blob: e5a367c0e5c1aa2965e01833026218fa5b8935d9 [file] [log] [blame]
Yu Chien Peter Linbc5a5042023-08-09 18:49:30 +08001/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Taken from Linux arch/riscv/lib/strcmp.S
4 */
5
6#include <linux/linkage.h>
7#include <asm/asm.h>
8
9ENTRY(__strcmp)
10WEAK(strcmp)
11.option push
12.option arch,+zbb
13 /*
14 * Returns
15 * a0 - comparison result, value like strcmp
16 *
17 * Parameters
18 * a0 - string1
19 * a1 - string2
20 *
21 * Clobbers
22 * t0, t1, t2, t3, t4
23 */
24
25 or t2, a0, a1
26 li t4, -1
27 and t2, t2, SZREG-1
28 bnez t2, 3f
29
30 /* Main loop for aligned string. */
31 .p2align 3
321:
33 REG_L t0, 0(a0)
34 REG_L t1, 0(a1)
35 orc.b t3, t0
36 bne t3, t4, 2f
37 addi a0, a0, SZREG
38 addi a1, a1, SZREG
39 beq t0, t1, 1b
40
41 /*
42 * Words don't match, and no null byte in the first
43 * word. Get bytes in big-endian order and compare.
44 */
45#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
46 rev8 t0, t0
47 rev8 t1, t1
48#endif
49
50 /* Synthesize (t0 >= t1) ? 1 : -1 in a branchless sequence. */
51 sltu a0, t0, t1
52 neg a0, a0
53 ori a0, a0, 1
54 ret
55
562:
57 /*
58 * Found a null byte.
59 * If words don't match, fall back to simple loop.
60 */
61 bne t0, t1, 3f
62
63 /* Otherwise, strings are equal. */
64 li a0, 0
65 ret
66
67 /* Simple loop for misaligned strings. */
68 .p2align 3
693:
70 lbu t0, 0(a0)
71 lbu t1, 0(a1)
72 addi a0, a0, 1
73 addi a1, a1, 1
74 bne t0, t1, 4f
75 bnez t0, 3b
76
774:
78 sub a0, t0, t1
79 ret
80.option pop
81END(__strcmp)