Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/riscv/lib/strncmp.S
26424 views
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) */
9
SYM_FUNC_START(strncmp)
10
11
__ALTERNATIVE_CFG("nop", "j strncmp_zbb", 0, RISCV_ISA_EXT_ZBB,
12
IS_ENABLED(CONFIG_RISCV_ISA_ZBB) && IS_ENABLED(CONFIG_TOOLCHAIN_HAS_ZBB))
13
14
/*
15
* Returns
16
* a0 - comparison result, value like strncmp
17
*
18
* Parameters
19
* a0 - string1
20
* a1 - string2
21
* a2 - number of characters to compare
22
*
23
* Clobbers
24
* t0, t1, t2
25
*/
26
li t2, 0
27
1:
28
beq a2, t2, 2f
29
lbu t0, 0(a0)
30
lbu t1, 0(a1)
31
addi a0, a0, 1
32
addi a1, a1, 1
33
bne t0, t1, 3f
34
addi t2, t2, 1
35
bnez t0, 1b
36
2:
37
li a0, 0
38
ret
39
3:
40
/*
41
* strncmp only needs to return (< 0, 0, > 0) values
42
* not necessarily -1, 0, +1
43
*/
44
sub a0, t0, t1
45
ret
46
47
/*
48
* Variant of strncmp using the ZBB extension if available
49
*/
50
#if defined(CONFIG_RISCV_ISA_ZBB) && defined(CONFIG_TOOLCHAIN_HAS_ZBB)
51
strncmp_zbb:
52
53
.option push
54
.option arch,+zbb
55
56
/*
57
* Returns
58
* a0 - comparison result, like strncmp
59
*
60
* Parameters
61
* a0 - string1
62
* a1 - string2
63
* a2 - number of characters to compare
64
*
65
* Clobbers
66
* t0, t1, t2, t3, t4, t5, t6
67
*/
68
69
or t2, a0, a1
70
li t5, -1
71
and t2, t2, SZREG-1
72
add t4, a0, a2
73
bnez t2, 3f
74
75
/* Adjust limit for fast-path. */
76
andi t6, t4, -SZREG
77
78
/* Main loop for aligned string. */
79
.p2align 3
80
1:
81
bge a0, t6, 3f
82
REG_L t0, 0(a0)
83
REG_L t1, 0(a1)
84
orc.b t3, t0
85
bne t3, t5, 2f
86
orc.b t3, t1
87
bne t3, t5, 2f
88
addi a0, a0, SZREG
89
addi a1, a1, SZREG
90
beq t0, t1, 1b
91
92
/*
93
* Words don't match, and no null byte in the first
94
* word. Get bytes in big-endian order and compare.
95
*/
96
#ifndef CONFIG_CPU_BIG_ENDIAN
97
rev8 t0, t0
98
rev8 t1, t1
99
#endif
100
101
/* Synthesize (t0 >= t1) ? 1 : -1 in a branchless sequence. */
102
sltu a0, t0, t1
103
neg a0, a0
104
ori a0, a0, 1
105
ret
106
107
2:
108
/*
109
* Found a null byte.
110
* If words don't match, fall back to simple loop.
111
*/
112
bne t0, t1, 3f
113
114
/* Otherwise, strings are equal. */
115
li a0, 0
116
ret
117
118
/* Simple loop for misaligned strings. */
119
.p2align 3
120
3:
121
bge a0, t4, 5f
122
lbu t0, 0(a0)
123
lbu t1, 0(a1)
124
addi a0, a0, 1
125
addi a1, a1, 1
126
bne t0, t1, 4f
127
bnez t0, 3b
128
129
4:
130
sub a0, t0, t1
131
ret
132
133
5:
134
li a0, 0
135
ret
136
137
.option pop
138
#endif
139
SYM_FUNC_END(strncmp)
140
SYM_FUNC_ALIAS(__pi_strncmp, strncmp)
141
EXPORT_SYMBOL(strncmp)
142
143