Re: [PATCH 00/17] riscv: vectorized str* routines

Kito Cheng <[email protected]> Mon, 3 Aug 2026 14:46:25 +0800
Newsgroups gmane.comp.lib.newlib
Message-ID <CA+yXCZB=0LVO-tgXk+Ls8zWKvzpMm6Nezxp=T+7eCjD0UZidzA@mail.gmail.com>
ack, this on my review queue :)

Pincheng Wang <[email protected]> =E6=96=BC 2026=E5=B9=B47=E6=
=9C=8816=E6=97=A5=E9=80=B1=E5=9B=9B =E4=B8=8B=E5=8D=8811:02=E5=AF=AB=E9=81=
=93=EF=BC=9A
>
> Hi all,
>
> This series adds RISC-V Vector Extension (RVV) implementations for the st=
r*
> 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 =3D=3D 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 targ=
ets are
> unaffected.  For strlen, strcmp, and strcpy the existing hand-optimized s=
calar
> 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 acros=
s a
> page boundary into an unmapped page.  The bounded routines (strnlen, strn=
cmp,
> strncpy, strncat, strncasecmp) additionally cap vl by the remaining count=
 so
> they never read past the n-th byte.  The set routines (strspn, strcspn, s=
trpbrk)
> 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 t=
he
> needle's first byte with a byte-wise verify that stops at a NUL, so neith=
er
> 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 foldin=
g 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 t=
o
> 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
>