[PATCH 00/17] riscv: vectorized str* routines
Pincheng Wang <[email protected]> Thu, 16 Jul 2026 23:00:31 +0800
| Newsgroups | gmane.comp.lib.newlib |
|---|---|
| Message-ID | <[email protected]> |
Hi all,
This series adds RISC-V Vector Extension (RVV) implementations for the str*
family in Newlib, as a follow-up to the earlier mem* work (memset, memcpy,
memmove, and then memccpy, memchr, memcmp, mempcpy, memrchr, rawmemchr). It
covers the following 17 interfaces:
strlen, strnlen, strchr, strchrnul, strrchr, strcmp, strncmp, strcpy,
strncpy, strcat, strncat, strspn, strcspn, strpbrk, strstr, strcasecmp,
strncasecmp
Each routine follows the same integration pattern as the mem* series: a
hand-written <func>-asm.S guarded by
__riscv_vector && __riscv_xlen == 64
&& !__OPTIMIZE_SIZE__ && !PREFER_SIZE_OVER_SPEED
with a small <func>.c that falls back to the existing scalar or generic
implementation when the guard is not satisfied, so non-vector RISC-V targets are
unaffected. For strlen, strcmp, and strcpy the existing hand-optimized scalar
code is kept as the fallback.
Page-boundary safety was a primary concern. Every scan reads its input(s) with
fault-only-first loads (vle8ff.v): element 0 is always loaded and a fault on any
later element merely truncates vl, so a vector load is never forced across a
page boundary into an unmapped page. The bounded routines (strnlen, strncmp,
strncpy, strncat, strncasecmp) additionally cap vl by the remaining count so
they never read past the n-th byte. The set routines (strspn, strcspn, strpbrk)
build a 256-byte table on the stack and gather through it with vluxei8.v, which
only touches the fully-mapped table. strstr combines a vle8ff scan for the
needle's first byte with a byte-wise verify that stops at a NUL, so neither
phase crosses past the end of either string.
Please note that strcasecmp/strncasecmp fold only the ASCII letters A-Z, i.e.
they implement the C/POSIX locale. Targets that need locale-aware folding fall
through the guard to the generic implementation. I'm happy to drop these two if
the locale divergence is unwelcome.
As with the mem* series, this is a fair amount of hand-written assembly to
maintain; other architectures rarely optimize the whole str* family. I'm glad
to trim the set to whatever subset is considered worth carrying.
Comments and suggestions welcome.
Best regards,
Pincheng Wang
Pincheng Wang (17):
riscv: add vectorized strlen
riscv: add vectorized strnlen
riscv: add vectorized strchr
riscv: add vectorized strchrnul
riscv: add vectorized strrchr
riscv: add vectorized strcmp
riscv: add vectorized strncmp
riscv: add vectorized strcpy
riscv: add vectorized strncpy
riscv: add vectorized strcat
riscv: add vectorized strncat
riscv: add vectorized strspn
riscv: add vectorized strcspn
riscv: add vectorized strpbrk
riscv: add vectorized strstr
riscv: add vectorized strcasecmp
riscv: add vectorized strncasecmp
newlib/libc/machine/riscv/Makefile.inc | 33 ++++++++++-
newlib/libc/machine/riscv/strcasecmp-asm.S | 65 +++++++++++++++++++++
newlib/libc/machine/riscv/strcasecmp.c | 5 ++
newlib/libc/machine/riscv/strcat-asm.S | 40 +++++++++++++
newlib/libc/machine/riscv/strcat.c | 5 ++
newlib/libc/machine/riscv/strchr-asm.S | 29 +++++++++
newlib/libc/machine/riscv/strchr.c | 5 ++
newlib/libc/machine/riscv/strchrnul-asm.S | 31 ++++++++++
newlib/libc/machine/riscv/strchrnul.c | 5 ++
newlib/libc/machine/riscv/strcmp-asm.S | 55 +++++++++++++++++
newlib/libc/machine/riscv/strcmp.S | 4 ++
newlib/libc/machine/riscv/strcpy-asm.S | 24 ++++++++
newlib/libc/machine/riscv/strcpy.c | 5 ++
newlib/libc/machine/riscv/strcspn-asm.S | 55 +++++++++++++++++
newlib/libc/machine/riscv/strcspn.c | 5 ++
newlib/libc/machine/riscv/strlen-asm.S | 25 ++++++++
newlib/libc/machine/riscv/strlen.c | 5 ++
newlib/libc/machine/riscv/strncasecmp-asm.S | 63 ++++++++++++++++++++
newlib/libc/machine/riscv/strncasecmp.c | 5 ++
newlib/libc/machine/riscv/strncat-asm.S | 47 +++++++++++++++
newlib/libc/machine/riscv/strncat.c | 5 ++
newlib/libc/machine/riscv/strncmp-asm.S | 51 ++++++++++++++++
newlib/libc/machine/riscv/strncmp.c | 5 ++
newlib/libc/machine/riscv/strncpy-asm.S | 46 +++++++++++++++
newlib/libc/machine/riscv/strncpy.c | 5 ++
newlib/libc/machine/riscv/strnlen-asm.S | 28 +++++++++
newlib/libc/machine/riscv/strnlen.c | 5 ++
newlib/libc/machine/riscv/strpbrk-asm.S | 55 +++++++++++++++++
newlib/libc/machine/riscv/strpbrk.c | 5 ++
newlib/libc/machine/riscv/strrchr-asm.S | 42 +++++++++++++
newlib/libc/machine/riscv/strrchr.c | 5 ++
newlib/libc/machine/riscv/strspn-asm.S | 51 ++++++++++++++++
newlib/libc/machine/riscv/strspn.c | 5 ++
newlib/libc/machine/riscv/strstr-asm.S | 55 +++++++++++++++++
newlib/libc/machine/riscv/strstr.c | 5 ++
35 files changed, 878 insertions(+), 1 deletion(-)
create mode 100644 newlib/libc/machine/riscv/strcasecmp-asm.S
create mode 100644 newlib/libc/machine/riscv/strcasecmp.c
create mode 100644 newlib/libc/machine/riscv/strcat-asm.S
create mode 100644 newlib/libc/machine/riscv/strcat.c
create mode 100644 newlib/libc/machine/riscv/strchr-asm.S
create mode 100644 newlib/libc/machine/riscv/strchr.c
create mode 100644 newlib/libc/machine/riscv/strchrnul-asm.S
create mode 100644 newlib/libc/machine/riscv/strchrnul.c
create mode 100644 newlib/libc/machine/riscv/strcmp-asm.S
create mode 100644 newlib/libc/machine/riscv/strcpy-asm.S
create mode 100644 newlib/libc/machine/riscv/strcspn-asm.S
create mode 100644 newlib/libc/machine/riscv/strcspn.c
create mode 100644 newlib/libc/machine/riscv/strlen-asm.S
create mode 100644 newlib/libc/machine/riscv/strncasecmp-asm.S
create mode 100644 newlib/libc/machine/riscv/strncasecmp.c
create mode 100644 newlib/libc/machine/riscv/strncat-asm.S
create mode 100644 newlib/libc/machine/riscv/strncat.c
create mode 100644 newlib/libc/machine/riscv/strncmp-asm.S
create mode 100644 newlib/libc/machine/riscv/strncmp.c
create mode 100644 newlib/libc/machine/riscv/strncpy-asm.S
create mode 100644 newlib/libc/machine/riscv/strncpy.c
create mode 100644 newlib/libc/machine/riscv/strnlen-asm.S
create mode 100644 newlib/libc/machine/riscv/strnlen.c
create mode 100644 newlib/libc/machine/riscv/strpbrk-asm.S
create mode 100644 newlib/libc/machine/riscv/strpbrk.c
create mode 100644 newlib/libc/machine/riscv/strrchr-asm.S
create mode 100644 newlib/libc/machine/riscv/strrchr.c
create mode 100644 newlib/libc/machine/riscv/strspn-asm.S
create mode 100644 newlib/libc/machine/riscv/strspn.c
create mode 100644 newlib/libc/machine/riscv/strstr-asm.S
create mode 100644 newlib/libc/machine/riscv/strstr.c
--
2.39.5