[PATCH v3 00/15] riscv: vectorized str* routines

Pincheng Wang pincheng.plct@isrc.iscas.ac.cn
Fri Aug 14 02:26:41 GMT 2026


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 15 interfaces:

  strlen, strnlen, strchr, strchrnul, strrchr, strcmp, strncmp, strcpy,
  strncpy, strcat, strncat, strspn, strcspn, strpbrk, strstr

Each routine follows the same integration pattern as the mem* series: a
hand-written <func>-asm.S guarded by

  __riscv_vector && !__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 routines that need the full integer register set, the guard
also excludes __riscv_e.  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) 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.

Changes in v3:
  - Drop strcasecmp and strncasecmp from the series.
  - Remove the __riscv_xlen == 64 guard where the implementation is not
    XLEN-specific.
  - Exclude __riscv_e for routines that require registers outside the embedded
    integer register set.

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 (15):
  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

 newlib/libc/machine/riscv/Makefile.inc    | 29 ++++++++++++-
 newlib/libc/machine/riscv/strcat-asm.S    | 36 ++++++++++++++++
 newlib/libc/machine/riscv/strcat.c        |  5 +++
 newlib/libc/machine/riscv/strchr-asm.S    | 25 +++++++++++
 newlib/libc/machine/riscv/strchr.c        |  5 +++
 newlib/libc/machine/riscv/strchrnul-asm.S | 27 ++++++++++++
 newlib/libc/machine/riscv/strchrnul.c     |  5 +++
 newlib/libc/machine/riscv/strcmp-asm.S    | 51 +++++++++++++++++++++++
 newlib/libc/machine/riscv/strcmp.S        |  4 ++
 newlib/libc/machine/riscv/strcpy-asm.S    | 20 +++++++++
 newlib/libc/machine/riscv/strcpy.c        |  5 +++
 newlib/libc/machine/riscv/strcspn-asm.S   | 51 +++++++++++++++++++++++
 newlib/libc/machine/riscv/strcspn.c       |  5 +++
 newlib/libc/machine/riscv/strlen-asm.S    | 21 ++++++++++
 newlib/libc/machine/riscv/strlen.c        |  5 +++
 newlib/libc/machine/riscv/strncat-asm.S   | 43 +++++++++++++++++++
 newlib/libc/machine/riscv/strncat.c       |  5 +++
 newlib/libc/machine/riscv/strncmp-asm.S   | 47 +++++++++++++++++++++
 newlib/libc/machine/riscv/strncmp.c       |  5 +++
 newlib/libc/machine/riscv/strncpy-asm.S   | 42 +++++++++++++++++++
 newlib/libc/machine/riscv/strncpy.c       |  5 +++
 newlib/libc/machine/riscv/strnlen-asm.S   | 24 +++++++++++
 newlib/libc/machine/riscv/strnlen.c       |  5 +++
 newlib/libc/machine/riscv/strpbrk-asm.S   | 51 +++++++++++++++++++++++
 newlib/libc/machine/riscv/strpbrk.c       |  5 +++
 newlib/libc/machine/riscv/strrchr-asm.S   | 38 +++++++++++++++++
 newlib/libc/machine/riscv/strrchr.c       |  5 +++
 newlib/libc/machine/riscv/strspn-asm.S    | 47 +++++++++++++++++++++
 newlib/libc/machine/riscv/strspn.c        |  5 +++
 newlib/libc/machine/riscv/strstr-asm.S    | 51 +++++++++++++++++++++++
 newlib/libc/machine/riscv/strstr.c        |  5 +++
 31 files changed, 676 insertions(+), 1 deletion(-)
 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/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



More information about the Newlib mailing list