[PATCH 10/17] riscv: add vectorized strcat
Pincheng Wang <[email protected]> Thu, 16 Jul 2026 23:00:41 +0800
| Newsgroups | gmane.comp.lib.newlib |
|---|---|
| Message-ID | <[email protected]> |
The vector implementation locates the end of the destination and appends the source in vector-length chunks using fault-only-first loads (vle8ff.v), so neither string is ever read across 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 | 2 ++ newlib/libc/machine/riscv/strcat-asm.S | 40 ++++++++++++++++++++++++++ newlib/libc/machine/riscv/strcat.c | 5 ++++ 3 files changed, 47 insertions(+) create mode 100644 newlib/libc/machine/riscv/strcat-asm.S create mode 100644 newlib/libc/machine/riscv/strcat.c diff --git a/newlib/libc/machine/riscv/Makefile.inc b/newlib/libc/machine/riscv/Makefile.inc index db572be82..b8f4d2f9c 100644 --- a/newlib/libc/machine/riscv/Makefile.inc +++ b/newlib/libc/machine/riscv/Makefile.inc @@ -20,6 +20,8 @@ libc_a_SOURCES += \ %D%/memset.S \ %D%/setjmp.S \ %D%/stpcpy.c \ + %D%/strcat-asm.S \ + %D%/strcat.c \ %D%/strchr-asm.S \ %D%/strchr.c \ %D%/strchrnul-asm.S \ diff --git a/newlib/libc/machine/riscv/strcat-asm.S b/newlib/libc/machine/riscv/strcat-asm.S new file mode 100644 index 000000000..995b8c641 --- /dev/null +++ b/newlib/libc/machine/riscv/strcat-asm.S @@ -0,0 +1,40 @@ +#if defined(__riscv_vector) && __riscv_xlen == 64 && !defined(__OPTIMIZE_SIZE__) && !defined(PREFER_SIZE_OVER_SPEED) +.text +.option push +.option arch, +v +.global strcat +.type strcat, @function +strcat: + mv a2, a0 + /* Perform `strlen(a0)`. */ +.Lstrlen_loop: + vsetvli a3, zero, e8, m1, ta, ma + + vle8ff.v v8, (a2) + vmseq.vx v0, v8, zero + csrr a4, vl + vfirst.m a5, v0 + add a2, a2, a4 + bltz a5, .Lstrlen_loop + + sub a2, a2, a4 + add a2, a2, a5 + + /* Perform `strcpy(a0 + strlen(a0), a1)`. */ +.Lstrcpy_loop: + vsetvli a3, zero, e8, m1, ta, ma + + vle8ff.v v8, (a1) + vmseq.vx v1, v8, zero + csrr a4, vl + vfirst.m a5, v1 + vmsif.m v0, v1 + add a1, a1, a4 + vse8.v v8, (a2), v0.t + add a2, a2, a4 + bltz a5, .Lstrcpy_loop + + ret +.size strcat, .-strcat +.option pop +#endif diff --git a/newlib/libc/machine/riscv/strcat.c b/newlib/libc/machine/riscv/strcat.c new file mode 100644 index 000000000..915bf0360 --- /dev/null +++ b/newlib/libc/machine/riscv/strcat.c @@ -0,0 +1,5 @@ +#if defined(__OPTIMIZE_SIZE__) || defined(PREFER_SIZE_OVER_SPEED) || !defined(__riscv_vector) || __riscv_xlen != 64 +# include "../../string/strcat.c" +#else +/* strcat defined in strcat-asm.S */ +#endif -- 2.39.5