[PATCH 06/17] riscv: add vectorized strcmp
Pincheng Wang
pincheng.plct@isrc.iscas.ac.cn
Thu Jul 16 15:00:37 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 | 55 ++++++++++++++++++++++++++
newlib/libc/machine/riscv/strcmp.S | 4 ++
3 files changed, 60 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..a858b8eab
--- /dev/null
+++ b/newlib/libc/machine/riscv/strcmp-asm.S
@@ -0,0 +1,55 @@
+#if defined(__riscv_vector) && __riscv_xlen == 64 && !defined(__OPTIMIZE_SIZE__) && !defined(PREFER_SIZE_OVER_SPEED)
+.text
+.option push
+.option arch, +v
+.global strcmp
+.type strcmp, @function
+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
+.size strcmp, .-strcmp
+.option pop
+#endif
diff --git a/newlib/libc/machine/riscv/strcmp.S b/newlib/libc/machine/riscv/strcmp.S
index 7668d3ef7..d4fad4de9 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) && __riscv_xlen == 64 && !defined(__OPTIMIZE_SIZE__) && !defined(PREFER_SIZE_OVER_SPEED))
+
.text
.globl strcmp
.type strcmp, @function
@@ -249,3 +251,5 @@ mask:
.dword 0x7f7f7f7f7f7f7f7f
#endif
#endif
+
+#endif /* not __riscv_vector */
--
2.39.5
More information about the Newlib
mailing list