1/* SPDX-License-Identifier: GPL-2.0-only */
2
3#include <linux/linkage.h>
4#include <asm/asm.h>
5#include <asm/alternative-macros.h>
6#include <asm/hwcap.h>
7
8/* int strncmp(const char *cs, const char *ct, size_t count) */
9SYM_FUNC_START(strncmp)
10
11 ALTERNATIVE("nop", "j strncmp_zbb", 0, RISCV_ISA_EXT_ZBB, CONFIG_RISCV_ISA_ZBB)
12
13 /*
14 * Returns
15 * a0 - comparison result, value 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
24 */
25 li t2, 0
261:
27 beq a2, t2, 2f
28 lbu t0, 0(a0)
29 lbu t1, 0(a1)
30 addi a0, a0, 1
31 addi a1, a1, 1
32 bne t0, t1, 3f
33 addi t2, t2, 1
34 bnez t0, 1b
352:
36 li a0, 0
37 ret
383:
39 /*
40 * strncmp only needs to return (< 0, 0, > 0) values
41 * not necessarily -1, 0, +1
42 */
43 sub a0, t0, t1
44 ret
45
46/*
47 * Variant of strncmp using the ZBB extension if available
48 */
49#ifdef CONFIG_RISCV_ISA_ZBB
50strncmp_zbb:
51
52.option push
53.option arch,+zbb
54
55 /*
56 * Returns
57 * a0 - comparison result, like strncmp
58 *
59 * Parameters
60 * a0 - string1
61 * a1 - string2
62 * a2 - number of characters to compare
63 *
64 * Clobbers
65 * t0, t1, t2, t3, t4, t5, t6
66 */
67
68 or t2, a0, a1
69 li t5, -1
70 and t2, t2, SZREG-1
71 add t4, a0, a2
72 bnez t2, 3f
73
74 /* Adjust limit for fast-path. */
75 andi t6, t4, -SZREG
76
77 /* Main loop for aligned string. */
78 .p2align 3
791:
80 bge a0, t6, 3f
81 REG_L t0, 0(a0)
82 REG_L t1, 0(a1)
83 orc.b t3, t0
84 bne t3, t5, 2f
85 orc.b t3, t1
86 bne t3, t5, 2f
87 addi a0, a0, SZREG
88 addi a1, a1, SZREG
89 beq t0, t1, 1b
90
91 /*
92 * Words don't match, and no null byte in the first
93 * word. Get bytes in big-endian order and compare.
94 */
95#ifndef CONFIG_CPU_BIG_ENDIAN
96 rev8 t0, t0
97 rev8 t1, t1
98#endif
99
100 /* Synthesize (t0 >= t1) ? 1 : -1 in a branchless sequence. */
101 sltu a0, t0, t1
102 neg a0, a0
103 ori a0, a0, 1
104 ret
105
1062:
107 /*
108 * Found a null byte.
109 * If words don't match, fall back to simple loop.
110 */
111 bne t0, t1, 3f
112
113 /* Otherwise, strings are equal. */
114 li a0, 0
115 ret
116
117 /* Simple loop for misaligned strings. */
118 .p2align 3
1193:
120 bge a0, t4, 5f
121 lbu t0, 0(a0)
122 lbu t1, 0(a1)
123 addi a0, a0, 1
124 addi a1, a1, 1
125 bne t0, t1, 4f
126 bnez t0, 3b
127
1284:
129 sub a0, t0, t1
130 ret
131
1325:
133 li a0, 0
134 ret
135
136.option pop
137#endif
138SYM_FUNC_END(strncmp)
139

source code of linux/arch/riscv/lib/strncmp.S