[PATCH v3 02/15] riscv: add vectorized strnlen

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); vl is additionally capped by the
remaining count so the scan never reads past the maxlen-th byte and never
crosses 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  |  4 +++-
 newlib/libc/machine/riscv/strnlen-asm.S | 24 ++++++++++++++++++++++++
 newlib/libc/machine/riscv/strnlen.c     |  5 +++++
 3 files changed, 32 insertions(+), 1 deletion(-)
 create mode 100644 newlib/libc/machine/riscv/strnlen-asm.S
 create mode 100644 newlib/libc/machine/riscv/strnlen.c

diff --git a/newlib/libc/machine/riscv/Makefile.inc b/newlib/libc/machine/riscv/Makefile.inc
index a410a512f..d3f72e471 100644
--- a/newlib/libc/machine/riscv/Makefile.inc
+++ b/newlib/libc/machine/riscv/Makefile.inc
@@ -23,4 +23,6 @@ libc_a_SOURCES += \
 	%D%/strcmp.S \
 	%D%/strcpy.c \
 	%D%/strlen-asm.S \
-	%D%/strlen.c
+	%D%/strlen.c \
+	%D%/strnlen-asm.S \
+	%D%/strnlen.c
diff --git a/newlib/libc/machine/riscv/strnlen-asm.S b/newlib/libc/machine/riscv/strnlen-asm.S
new file mode 100644
index 000000000..6ab9833db
--- /dev/null
+++ b/newlib/libc/machine/riscv/strnlen-asm.S
@@ -0,0 +1,24 @@
+#include <sys/asm.h>
+
+#if defined(__riscv_vector) && !defined(__OPTIMIZE_SIZE__) && !defined(PREFER_SIZE_OVER_SPEED)
+ENTRY(strnlen)
+  mv a2, a0
+  mv a0, a1
+.Lloop:
+  beqz a1, .Ldone
+  vsetvli zero, a1, e8, m1, ta, ma
+  vle8ff.v v0, (a2)
+  vmseq.vi v8, v0, 0
+  vfirst.m a4, v8      /* first occurrence of \0 */
+  csrr a3, vl
+  add a2, a2, a3
+  sub a1, a1, a3
+  bltz a4, .Lloop
+
+  add a1, a1, a3
+  sub a0, a0, a1
+  add a0, a0, a4
+.Ldone:
+  ret
+END(strnlen)
+#endif
diff --git a/newlib/libc/machine/riscv/strnlen.c b/newlib/libc/machine/riscv/strnlen.c
new file mode 100644
index 000000000..ca605b567
--- /dev/null
+++ b/newlib/libc/machine/riscv/strnlen.c
@@ -0,0 +1,5 @@
+#if defined(__OPTIMIZE_SIZE__) || defined(PREFER_SIZE_OVER_SPEED) || !defined(__riscv_vector)
+# include "../../string/strnlen.c"
+#else
+/* strnlen defined in strnlen-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.