1/* 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)
82