[PATCH 01/17] riscv: add vectorized strlen

Pincheng Wang <[email protected]> Thu, 16 Jul 2026 23:00:32 +0800
Newsgroups gmane.comp.lib.newlib
Message-ID <[email protected]>
The vector implementation processes the string in vector-length chunks
using fault-only-first loads (vle8ff.v), which keeps a vector load from
ever crossing into an unmapped page, providing significant performance
improvements on RVV-capable hardware.  Use conditional compilation to
fall back to the scalar 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 |  1 +
 newlib/libc/machine/riscv/strlen-asm.S | 25 +++++++++++++++++++++++++
 newlib/libc/machine/riscv/strlen.c     |  5 +++++
 3 files changed, 31 insertions(+)
 create mode 100644 newlib/libc/machine/riscv/strlen-asm.S

diff --git a/newlib/libc/machine/riscv/Makefile.inc b/newlib/libc/machine/riscv/Makefile.inc
index b4c743ff6..a410a512f 100644
--- a/newlib/libc/machine/riscv/Makefile.inc
+++ b/newlib/libc/machine/riscv/Makefile.inc
@@ -22,4 +22,5 @@ libc_a_SOURCES += \
 	%D%/stpcpy.c \
 	%D%/strcmp.S \
 	%D%/strcpy.c \
+	%D%/strlen-asm.S \
 	%D%/strlen.c
diff --git a/newlib/libc/machine/riscv/strlen-asm.S b/newlib/libc/machine/riscv/strlen-asm.S
new file mode 100644
index 000000000..df2c12569
--- /dev/null
+++ b/newlib/libc/machine/riscv/strlen-asm.S
@@ -0,0 +1,25 @@
+#if defined(__riscv_vector) && __riscv_xlen == 64 && !defined(__OPTIMIZE_SIZE__) && !defined(PREFER_SIZE_OVER_SPEED)
+.text
+.option push
+.option arch, +v
+.global strlen
+.type strlen, @function
+strlen:
+  mv a1, a0
+.Lloop:
+  vsetvli a2, zero, e8, m2, ta, ma
+  vle8ff.v v0, (a1)
+  csrr a2, vl
+  vmseq.vi v2, v0, 0
+  vfirst.m a3, v2
+  add a1, a1, a2
+  bltz a3, .Lloop
+
+  add a0, a0, a2
+  add a1, a1, a3
+  sub a0, a1, a0
+
+  ret
+.size strlen, .-strlen
+.option pop
+#endif
diff --git a/newlib/libc/machine/riscv/strlen.c b/newlib/libc/machine/riscv/strlen.c
index 8ab5ce537..7a052064c 100644
--- a/newlib/libc/machine/riscv/strlen.c
+++ b/newlib/libc/machine/riscv/strlen.c
@@ -9,6 +9,10 @@
    http://www.opensource.org/licenses.
 */
 
+#if defined(__riscv_vector) && __riscv_xlen == 64 && !defined(__OPTIMIZE_SIZE__) && !defined(PREFER_SIZE_OVER_SPEED)
+/* strlen defined in strlen-asm.S */
+#else
+
 #include <sys/types.h>
 #include <string.h>
 #include <stdint.h>
@@ -66,3 +70,4 @@ size_t strlen(const char *str)
   #endif
 #endif /* not PREFER_SIZE_OVER_SPEED */
 }
+#endif /* not __riscv_vector */
-- 
2.39.5