[PATCH v3 06/15] riscv: add vectorized strcmp
Pincheng Wang
pincheng.plct@isrc.iscas.ac.cn
Fri Aug 14 02:26:47 GMT 2026
The vector implementation compares both operands in vector-length chunks
using fault-only-first loads (vle8ff.v), detecting the terminating NUL and
the first differing byte in the same pass without ever crossing into an
unmapped page. This provides significant performance improvements on
RVV-capable hardware. Use conditional compilation to fall back to the
existing scalar implementation when __riscv_vector is not available,
maintaining compatibility with non-vector RISC-V systems.
Signed-off-by: Pincheng Wang <pincheng.plct@isrc.iscas.ac.cn>
---
newlib/libc/machine/riscv/Makefile.inc | 1 +
newlib/libc/machine/riscv/strcmp-asm.S | 51 ++++++++++++++++++++++++++
newlib/libc/machine/riscv/strcmp.S | 4 ++
3 files changed, 56 insertions(+)
create mode 100644 newlib/libc/machine/riscv/strcmp-asm.S
diff --git a/newlib/libc/machine/riscv/Makefile.inc b/newlib/libc/machine/riscv/Makefile.inc
index 4bb7fefbb..243195b36 100644
--- a/newlib/libc/machine/riscv/Makefile.inc
+++ b/newlib/libc/machine/riscv/Makefile.inc
@@ -24,6 +24,7 @@ libc_a_SOURCES += \
%D%/strchr.c \
%D%/strchrnul-asm.S \
%D%/strchrnul.c \
+ %D%/strcmp-asm.S \
%D%/strcmp.S \
%D%/strcpy.c \
%D%/strlen-asm.S \
diff --git a/newlib/libc/machine/riscv/strcmp-asm.S b/newlib/libc/machine/riscv/strcmp-asm.S
new file mode 100644
index 000000000..5592a88b6
--- /dev/null
+++ b/newlib/libc/machine/riscv/strcmp-asm.S
@@ -0,0 +1,51 @@
+#include <sys/asm.h>
+
+#if defined(__riscv_vector) && !defined(__OPTIMIZE_SIZE__) && !defined(PREFER_SIZE_OVER_SPEED)
+ENTRY(strcmp)
+.Lloop:
+ vsetvli a2, zero, e8, m1, ta, ma
+ vle8ff.v v0, (a0)
+ /* check if v0[i] == 0 */
+ vmseq.vx v16, v0, zero
+
+ vle8ff.v v8, (a1)
+ /* check if v0[i] != v8[i] */
+ vmsne.vv v17, v0, v8
+
+ /* find the index x for v0[x]==0 */
+ vfirst.m a3, v16
+ /* find the index x for v0[x]!=v8[x] */
+ vfirst.m a4, v17
+
+ bgez a3, .Lcheck1
+ bgez a4, .Lcheck2
+
+ /* get the current vl updated by vle8ff. */
+ csrr a2, vl
+ add a0, a0, a2
+ add a1, a1, a2
+ j .Lloop
+
+ /* a3>=0 */
+.Lcheck1:
+ bltz a4, .Lreturn_at_nul
+ blt a4, a3, .Lcheck2
+.Lreturn_at_nul:
+ /* a4<0, or a4>=0 && a3<=a4 */
+ add a0, a0, a3
+ add a1, a1, a3
+ lbu a3, 0(a0)
+ lbu a4, 0(a1)
+ sub a0, a3, a4
+ ret
+
+ /* a3<0 && a4>=0, or a4<a3 */
+.Lcheck2:
+ add a0, a0, a4
+ add a1, a1, a4
+ lbu a3, 0(a0)
+ lbu a4, 0(a1)
+ sub a0, a3, a4
+ ret
+END(strcmp)
+#endif
diff --git a/newlib/libc/machine/riscv/strcmp.S b/newlib/libc/machine/riscv/strcmp.S
index 1fd0f1440..8f2f406af 100644
--- a/newlib/libc/machine/riscv/strcmp.S
+++ b/newlib/libc/machine/riscv/strcmp.S
@@ -12,6 +12,8 @@
#include <sys/asm.h>
#include "newlib.h"
+#if !(defined(__riscv_vector) && !defined(__OPTIMIZE_SIZE__) && !defined(PREFER_SIZE_OVER_SPEED))
+
ENTRY(strcmp)
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
@@ -243,3 +245,5 @@ mask:
.dword 0x7f7f7f7f7f7f7f7f
#endif
#endif
+
+#endif /* not __riscv_vector */
--
2.39.5
More information about the Newlib
mailing list