[PATCH 02/17] riscv: add vectorized strnlen
Pincheng Wang <[email protected]> Thu, 16 Jul 2026 23:00:33 +0800
| 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 | 28 +++++++++++++++++++++++++ newlib/libc/machine/riscv/strnlen.c | 5 +++++ 3 files changed, 36 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..57948857b --- /dev/null +++ b/newlib/libc/machine/riscv/strnlen-asm.S @@ -0,0 +1,28 @@ +#if defined(__riscv_vector) && __riscv_xlen == 64 && !defined(__OPTIMIZE_SIZE__) && !defined(PREFER_SIZE_OVER_SPEED) +.text +.option push +.option arch, +v +.global strnlen +.type strnlen, @function +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 +.size strnlen, .-strnlen +.option pop +#endif diff --git a/newlib/libc/machine/riscv/strnlen.c b/newlib/libc/machine/riscv/strnlen.c new file mode 100644 index 000000000..bb2bc2cf0 --- /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) || __riscv_xlen != 64 +# include "../../string/strnlen.c" +#else +/* strnlen defined in strnlen-asm.S */ +#endif -- 2.39.5