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

Pincheng Wang <[email protected]>
Newsgroups gmane.comp.lib.newlib
Message-ID <[email protected]>
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 <[email protected]>
---
 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

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
-- 
2.39.5
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.