[v3,04/15] riscv: add vectorized strchrnul

Message ID 20260814022656.1071643-5-pincheng.plct@isrc.iscas.ac.cn
State New
Headers
Series riscv: vectorized str* routines |

Commit Message

Pincheng Wang Aug. 14, 2026, 2:26 a.m. UTC
  The vector implementation scans the string in vector-length chunks using
fault-only-first loads (vle8ff.v), returning a pointer to the first match
or to the terminating NUL without ever crossing into an unmapped page.
This provides significant performance improvements on RVV-capable
hardware.  Use conditional compilation to fall back to the generic
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    |  2 ++
 newlib/libc/machine/riscv/strchrnul-asm.S | 27 +++++++++++++++++++++++
 newlib/libc/machine/riscv/strchrnul.c     |  5 +++++
 3 files changed, 34 insertions(+)
 create mode 100644 newlib/libc/machine/riscv/strchrnul-asm.S
 create mode 100644 newlib/libc/machine/riscv/strchrnul.c
  

Patch

diff --git a/newlib/libc/machine/riscv/Makefile.inc b/newlib/libc/machine/riscv/Makefile.inc
index 01a0aaf50..3c13fbc1a 100644
--- a/newlib/libc/machine/riscv/Makefile.inc
+++ b/newlib/libc/machine/riscv/Makefile.inc
@@ -22,6 +22,8 @@  libc_a_SOURCES += \
 	%D%/stpcpy.c \
 	%D%/strchr-asm.S \
 	%D%/strchr.c \
+	%D%/strchrnul-asm.S \
+	%D%/strchrnul.c \
 	%D%/strcmp.S \
 	%D%/strcpy.c \
 	%D%/strlen-asm.S \
diff --git a/newlib/libc/machine/riscv/strchrnul-asm.S b/newlib/libc/machine/riscv/strchrnul-asm.S
new file mode 100644
index 000000000..dfe4bcd72
--- /dev/null
+++ b/newlib/libc/machine/riscv/strchrnul-asm.S
@@ -0,0 +1,27 @@ 
+#include <sys/asm.h>
+
+#if defined(__riscv_vector) && !defined(__OPTIMIZE_SIZE__) && !defined(PREFER_SIZE_OVER_SPEED)
+ENTRY(strchrnul)
+.Lloop:
+  vsetvli t0, zero, e8, m1, ta, ma
+  vle8ff.v v0, (a0)
+  vmseq.vx v8, v0, a1
+  vmseq.vi v9, v0, 0
+  vfirst.m a2, v8
+  vfirst.m a3, v9
+  bltz a2, .Lcheck_nul
+  bltz a3, .Lfound_char
+  bltu a2, a3, .Lfound_char
+.Lfound_nul:
+  add a0, a0, a3
+  ret
+.Lfound_char:
+  add a0, a0, a2
+  ret
+.Lcheck_nul:
+  bgez a3, .Lfound_nul
+  csrr a4, vl
+  add a0, a0, a4
+  j .Lloop
+END(strchrnul)
+#endif
diff --git a/newlib/libc/machine/riscv/strchrnul.c b/newlib/libc/machine/riscv/strchrnul.c
new file mode 100644
index 000000000..4a6d0e947
--- /dev/null
+++ b/newlib/libc/machine/riscv/strchrnul.c
@@ -0,0 +1,5 @@ 
+#if defined(__OPTIMIZE_SIZE__) || defined(PREFER_SIZE_OVER_SPEED) || !defined(__riscv_vector) || defined(__riscv_e)
+# include "../../string/strchrnul.c"
+#else
+/* strchrnul defined in strchrnul-asm.S */
+#endif