[PATCH v3 00/15] riscv: vectorized str* routines
Pincheng Wang <[email protected]>
| 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 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