[PATCH v2 3/4] riscv: Add RVV implementations for str* routines
Yao Zihong
zihong.plct@isrc.iscas.ac.cn
Tue Sep 30 00:34:52 GMT 2025
This patch imports RVV-based implementations of the str* family:
strcat, strcmp, strcpy, strlen, strnlen,
strchr, strncat, strncmp, strncpy.
They assume RVV 1.0 with VLEN >= 32, support arbitrary VLEN, and work on
both RV32 and RV64. No page-size assumptions are made.
Note that this version rebases Hau Hsu’s v3 patch, with no logic changes.
Only symbol naming, formatting/spacing, and copyright years were updated
to match current tree conventions.
Based-on-patch-by: Hau Hsu <hau.hsu@sifive.com>
Based-on-patch-by: Jerry Shih <jerry.shih@sifive.com>
Based-on-patch-by: Nick Knight <nick.knight@sifive.com>
Co-authored-by: Hau Hsu <hau.hsu@sifive.com>
Co-authored-by: Jerry Shih <jerry.shih@sifive.com>
Co-authored-by: Nick Knight <nick.knight@sifive.com>
Signed-off-by: Yao Zihong <zihong.plct@isrc.iscas.ac.cn>
---
sysdeps/riscv/multiarch/strcat_vector.S | 74 +++++++++++++++++++
sysdeps/riscv/multiarch/strchr_vector.S | 63 ++++++++++++++++
sysdeps/riscv/multiarch/strcmp_vector.S | 92 ++++++++++++++++++++++++
sysdeps/riscv/multiarch/strcpy_vector.S | 58 +++++++++++++++
sysdeps/riscv/multiarch/strlen_vector.S | 56 +++++++++++++++
sysdeps/riscv/multiarch/strncat_vector.S | 85 ++++++++++++++++++++++
sysdeps/riscv/multiarch/strncmp_vector.S | 87 ++++++++++++++++++++++
sysdeps/riscv/multiarch/strncpy_vector.S | 88 +++++++++++++++++++++++
sysdeps/riscv/multiarch/strnlen_vector.S | 58 +++++++++++++++
9 files changed, 661 insertions(+)
create mode 100644 sysdeps/riscv/multiarch/strcat_vector.S
create mode 100644 sysdeps/riscv/multiarch/strchr_vector.S
create mode 100644 sysdeps/riscv/multiarch/strcmp_vector.S
create mode 100644 sysdeps/riscv/multiarch/strcpy_vector.S
create mode 100644 sysdeps/riscv/multiarch/strlen_vector.S
create mode 100644 sysdeps/riscv/multiarch/strncat_vector.S
create mode 100644 sysdeps/riscv/multiarch/strncmp_vector.S
create mode 100644 sysdeps/riscv/multiarch/strncpy_vector.S
create mode 100644 sysdeps/riscv/multiarch/strnlen_vector.S
diff --git a/sysdeps/riscv/multiarch/strcat_vector.S b/sysdeps/riscv/multiarch/strcat_vector.S
new file mode 100644
index 0000000000..cef369ec48
--- /dev/null
+++ b/sysdeps/riscv/multiarch/strcat_vector.S
@@ -0,0 +1,74 @@
+/* RVV versions strcat. RISC-V version.
+ Copyright (C) 2025 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+#include <sys/asm.h>
+
+#if IS_IN(libc)
+
+#define dst a0
+#define src a1
+#define dst_ptr a2
+
+#define ivl a3
+#define cur_vl a4
+#define active_elem_pos a5
+
+#define ELEM_LMUL_SETTING m1
+#define vmask1 v0
+#define vmask2 v1
+#define vstr1 v8
+#define vstr2 v16
+
+ENTRY (__strcat_vector)
+.option push
+.option arch, +v
+ mv dst_ptr, dst
+ /* Perform `strlen(dst)`. */
+L(strlen_loop):
+ vsetvli ivl, zero, e8, ELEM_LMUL_SETTING, ta, ma
+
+ vle8ff.v vstr1, (dst_ptr)
+ vmseq.vx vmask1, vstr1, zero
+ csrr cur_vl, vl
+ vfirst.m active_elem_pos, vmask1
+ add dst_ptr, dst_ptr, cur_vl
+ bltz active_elem_pos, L(strlen_loop)
+
+ sub dst_ptr, dst_ptr, cur_vl
+ add dst_ptr, dst_ptr, active_elem_pos
+
+ /* Perform `strcpy(dst, src)`. */
+L(strcpy_loop):
+ vsetvli ivl, zero, e8, ELEM_LMUL_SETTING, ta, ma
+
+ vle8ff.v vstr1, (src)
+ vmseq.vx vmask2, vstr1, zero
+ csrr cur_vl, vl
+ vfirst.m active_elem_pos, vmask2
+ vmsif.m vmask1, vmask2
+ add src, src, cur_vl
+ vse8.v vstr1, (dst_ptr), vmask1.t
+ add dst_ptr, dst_ptr, cur_vl
+ bltz active_elem_pos, L(strcpy_loop)
+
+ ret
+.option pop
+END (__strcat_vector)
+
+#endif
diff --git a/sysdeps/riscv/multiarch/strchr_vector.S b/sysdeps/riscv/multiarch/strchr_vector.S
new file mode 100644
index 0000000000..a7f80dbf47
--- /dev/null
+++ b/sysdeps/riscv/multiarch/strchr_vector.S
@@ -0,0 +1,63 @@
+/* RVV versions strchr. RISC-V version.
+ Copyright (C) 2025 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+#include <sys/asm.h>
+
+#if IS_IN(libc)
+
+#define str a0
+#define ch a1
+#define end_offset a2
+#define ch_offset a3
+#define temp1 a4
+#define temp2 a5
+#define cur_vl a6
+#define ivl t0
+
+#define ELEM_LMUL_SETTING m1
+#define vstr v0
+#define vmask_end v8
+#define vmask_ch v9
+
+ENTRY (__strchr_vector)
+.option push
+.option arch, +v
+L(strchr_loop):
+ vsetvli ivl, zero, e8, ELEM_LMUL_SETTING, ta, ma
+ vle8ff.v vstr, (str)
+ vmseq.vi vmask_end, vstr, 0
+ vmseq.vx vmask_ch, vstr, ch
+ vfirst.m end_offset, vmask_end /* first occurrence of \0 */
+ vfirst.m ch_offset, vmask_ch /* first occurrence of ch */
+ sltz temp1, ch_offset
+ sltu temp2, end_offset, ch_offset
+ or temp1, temp1, temp2
+ beqz temp1, L(found_ch) /* Found ch, not preceded by \0? */
+ csrr cur_vl, vl
+ add str, str, cur_vl
+ bltz end_offset, L(strchr_loop) /* Didn't find \0? */
+ li str, 0
+ ret
+L(found_ch):
+ add str, str, ch_offset
+ ret
+.option pop
+END (__strchr_vector)
+
+#endif
diff --git a/sysdeps/riscv/multiarch/strcmp_vector.S b/sysdeps/riscv/multiarch/strcmp_vector.S
new file mode 100644
index 0000000000..aba34bccda
--- /dev/null
+++ b/sysdeps/riscv/multiarch/strcmp_vector.S
@@ -0,0 +1,92 @@
+/* RVV versions strcmp. RISC-V version.
+ Copyright (C) 2025 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+#include <sys/asm.h>
+
+#if IS_IN(libc)
+
+#define result a0
+
+#define str1 a0
+#define str2 a1
+
+#define ivl a2
+#define temp1 a3
+#define temp2 a4
+
+#define vstr1 v0
+#define vstr2 v8
+#define vmask1 v16
+#define vmask2 v17
+
+ENTRY(__strcmp_vector)
+.option push
+.option arch, +v
+ /* lmul=1 */
+L(Loop):
+ vsetvli ivl, zero, e8, m1, ta, ma
+ vle8ff.v vstr1, (str1)
+ /* check if vstr1[i] == 0 */
+ vmseq.vx vmask1, vstr1, zero
+
+ vle8ff.v vstr2, (str2)
+ /* check if vstr1[i] != vstr2[i] */
+ vmsne.vv vmask2, vstr1, vstr2
+
+ /* find the index x for vstr1[x]==0 */
+ vfirst.m temp1, vmask1
+ /* find the index x for vstr1[x]!=vstr2[x] */
+ vfirst.m temp2, vmask2
+
+ bgez temp1, L(check1)
+ bgez temp2, L(check2)
+
+ /* get the current vl updated by vle8ff. */
+ csrr ivl, vl
+ add str1, str1, ivl
+ add str2, str2, ivl
+ j L(Loop)
+
+ /* temp1>=0 */
+L(check1):
+ bltz temp2, 1f
+ blt temp2, temp1, L(check2)
+1:
+ /* temp2<0 */
+ /* temp2>=0 && temp1<temp2 */
+ add str1, str1, temp1
+ add str2, str2, temp1
+ lbu temp1, 0(str1)
+ lbu temp2, 0(str2)
+ sub result, temp1, temp2
+ ret
+
+ /* temp1<0 */
+ /* temp2>=0 */
+L(check2):
+ add str1, str1, temp2
+ add str2, str2, temp2
+ lbu temp1, 0(str1)
+ lbu temp2, 0(str2)
+ sub result, temp1, temp2
+ ret
+.option pop
+END (__strcmp_vector)
+
+#endif
diff --git a/sysdeps/riscv/multiarch/strcpy_vector.S b/sysdeps/riscv/multiarch/strcpy_vector.S
new file mode 100644
index 0000000000..22295b7e8f
--- /dev/null
+++ b/sysdeps/riscv/multiarch/strcpy_vector.S
@@ -0,0 +1,58 @@
+/* RVV versions strcpy. RISC-V version.
+ Copyright (C) 2025 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+#include <sys/asm.h>
+
+#if IS_IN(libc)
+
+#define dst a0
+#define src a1
+#define dst_ptr a2
+
+#define ivl a3
+#define cur_vl a4
+#define active_elem_pos a5
+
+#define ELEM_LMUL_SETTING m1
+#define vmask1 v0
+#define vmask2 v1
+#define vstr1 v8
+#define vstr2 v16
+
+ENTRY (__strcpy_vector)
+.option push
+.option arch, +v
+ mv dst_ptr, dst
+L(strcpy_loop):
+ vsetvli ivl, zero, e8, ELEM_LMUL_SETTING, ta, ma
+ vle8ff.v vstr1, (src)
+ vmseq.vx vmask2, vstr1, zero
+ csrr cur_vl, vl
+ vfirst.m active_elem_pos, vmask2
+ vmsif.m vmask1, vmask2
+ add src, src, cur_vl
+ vse8.v vstr1, (dst_ptr), vmask1.t
+ add dst_ptr, dst_ptr, cur_vl
+ bltz active_elem_pos, L(strcpy_loop)
+
+ ret
+.option pop
+END (__strcpy_vector)
+
+#endif
diff --git a/sysdeps/riscv/multiarch/strlen_vector.S b/sysdeps/riscv/multiarch/strlen_vector.S
new file mode 100644
index 0000000000..c287ccb9e2
--- /dev/null
+++ b/sysdeps/riscv/multiarch/strlen_vector.S
@@ -0,0 +1,56 @@
+/* RVV versions strlen. RISC-V version.
+ Copyright (C) 2025 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+#include <sys/asm.h>
+
+#if IS_IN(libc)
+
+#define result a0
+#define str a0
+#define copy_str a1
+#define ivl a2
+#define cur_vl a2
+#define end_offset a3
+
+#define ELEM_LMUL_SETTING m2
+#define vstr v0
+#define vmask_end v2
+
+ENTRY (__strlen_vector)
+.option push
+.option arch, +v
+ mv copy_str, str
+L(loop):
+ vsetvli ivl, zero, e8, ELEM_LMUL_SETTING, ta, ma
+ vle8ff.v vstr, (copy_str)
+ csrr cur_vl, vl
+ vmseq.vi vmask_end, vstr, 0
+ vfirst.m end_offset, vmask_end
+ add copy_str, copy_str, cur_vl
+ bltz end_offset, L(loop)
+
+ add str, str, cur_vl
+ add copy_str, copy_str, end_offset
+ sub result, copy_str, result
+
+ ret
+.option pop
+END (__strlen_vector)
+
+#endif
diff --git a/sysdeps/riscv/multiarch/strncat_vector.S b/sysdeps/riscv/multiarch/strncat_vector.S
new file mode 100644
index 0000000000..c3bf57f5fa
--- /dev/null
+++ b/sysdeps/riscv/multiarch/strncat_vector.S
@@ -0,0 +1,85 @@
+/* RVV versions strncat. RISC-V version.
+ Copyright (C) 2025 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+#include <sys/asm.h>
+
+#if IS_IN(libc)
+
+#define dst a0
+#define src a1
+#define length a2
+#define dst_ptr a3
+
+#define ivl a4
+#define cur_vl a5
+#define activate_elem_pos a6
+
+#define ELEM_LMUL_SETTING m1
+#define vmask1 v0
+#define vmask2 v1
+#define vstr1 v8
+#define vstr2 v16
+
+ENTRY (__strncat_vector)
+.option push
+.option arch, +v
+ mv dst_ptr, dst
+ /* the strlen of dst. */
+L(strlen_loop):
+ vsetvli ivl, zero, e8, ELEM_LMUL_SETTING, ta, ma
+
+ vle8ff.v vstr1, (dst_ptr)
+ /* find the '\0'. */
+ vmseq.vx vmask1, vstr1, zero
+ csrr cur_vl, vl
+ vfirst.m activate_elem_pos, vmask1
+ add dst_ptr, dst_ptr, cur_vl
+ bltz activate_elem_pos, L(strlen_loop)
+
+ sub dst_ptr, dst_ptr, cur_vl
+ add dst_ptr, dst_ptr, activate_elem_pos
+
+ /* copy src to dst_ptr. */
+L(strcpy_loop):
+ vsetvli zero, length, e8, ELEM_LMUL_SETTING, ta, ma
+
+ vle8ff.v vstr1, (src)
+ vmseq.vx vmask2, vstr1, zero
+ csrr cur_vl, vl
+ vfirst.m activate_elem_pos, vmask2
+ vmsif.m vmask1, vmask2
+ add src, src, cur_vl
+ sub length, length, cur_vl
+ vse8.v vstr1, (dst_ptr), vmask1.t
+ add dst_ptr, dst_ptr, cur_vl
+ beqz length, L(fill_zero)
+ bltz activate_elem_pos, L(strcpy_loop)
+
+ ret
+
+L(fill_zero):
+ bgez activate_elem_pos, L(fill_zero_end)
+ sb zero, (dst_ptr)
+
+L(fill_zero_end):
+ ret
+.option pop
+END (__strncat_vector)
+
+#endif
diff --git a/sysdeps/riscv/multiarch/strncmp_vector.S b/sysdeps/riscv/multiarch/strncmp_vector.S
new file mode 100644
index 0000000000..277fdab15a
--- /dev/null
+++ b/sysdeps/riscv/multiarch/strncmp_vector.S
@@ -0,0 +1,87 @@
+/* RVV versions strncmp. RISC-V version.
+ Copyright (C) 2025 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http:/*www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+#include <sys/asm.h>
+
+#if IS_IN(libc)
+
+#define result a0
+
+#define str1 a0
+#define str2 a1
+#define length a2
+
+#define ivl a3
+#define temp1 a4
+#define temp2 a5
+
+#define ELEM_LMUL_SETTING m1
+#define vstr1 v0
+#define vstr2 v4
+#define vmask1 v8
+#define vmask2 v9
+
+ENTRY (__strncmp_vector)
+.option push
+.option arch, +v
+ beqz length, L(zero_length)
+L(loop):
+ vsetvli zero, length, e8, ELEM_LMUL_SETTING, ta, ma
+
+ vle8ff.v vstr1, (str1)
+ /* vstr1[i] == 0. */
+ vmseq.vx vmask1, vstr1, zero
+
+ vle8ff.v vstr2, (str2)
+ /* vstr1[i] != vstr2[i]. */
+ vmsne.vv vmask2, vstr1, vstr2
+
+ csrr ivl, vl
+
+ /* r = mask1 | mask2
+ We could use vfirst.m to get the first zero char or the
+ first different char between str1 and str2. */
+ vmor.mm vmask1, vmask1, vmask2
+
+ sub length, length, ivl
+
+ vfirst.m temp1, vmask1
+
+ bgez temp1, L(end_loop)
+
+ add str1, str1, ivl
+ add str2, str2, ivl
+ bnez length, L(loop)
+L(end_loop):
+
+ add str1, str1, temp1
+ add str2, str2, temp1
+ lbu temp1, 0(str1)
+ lbu temp2, 0(str2)
+
+ sub result, temp1, temp2
+ ret
+
+L(zero_length):
+ li result, 0
+ ret
+.option pop
+END (__strncmp_vector)
+
+#endif
diff --git a/sysdeps/riscv/multiarch/strncpy_vector.S b/sysdeps/riscv/multiarch/strncpy_vector.S
new file mode 100644
index 0000000000..3d53461ca2
--- /dev/null
+++ b/sysdeps/riscv/multiarch/strncpy_vector.S
@@ -0,0 +1,88 @@
+/* RVV versions strncpy. RISC-V version.
+ Copyright (C) 2025 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+#include <sys/asm.h>
+
+#if IS_IN(libc)
+
+#define dst a0
+#define src a1
+#define length a2
+#define dst_ptr a3
+
+#define ivl a4
+#define cur_vl a5
+#define active_elem_pos a6
+#define temp a7
+
+#define ELEM_LMUL_SETTING m1
+#define vmask1 v0
+#define vmask2 v1
+#define ZERO_FILL_ELEM_LMUL_SETTING m8
+#define vstr1 v8
+#define vstr2 v16
+
+ENTRY (__strncpy_vector)
+.option push
+.option arch, +v
+ mv dst_ptr, dst
+ /* Copy src to dst_ptr. */
+L(strcpy_loop):
+ vsetvli zero, length, e8, ELEM_LMUL_SETTING, ta, ma
+ vle8ff.v vstr1, (src)
+ vmseq.vx vmask2, vstr1, zero
+ csrr cur_vl, vl
+ vfirst.m active_elem_pos, vmask2
+ vmsif.m vmask1, vmask2
+ add src, src, cur_vl
+ sub length, length, cur_vl
+ vse8.v vstr1, (dst_ptr), vmask1.t
+ add dst_ptr, dst_ptr, cur_vl
+ bgez active_elem_pos, L(fill_zero)
+ bnez length, L(strcpy_loop)
+ ret
+
+ /* Fill the tail zero. */
+L(fill_zero):
+ /* We already copy the `\0` to dst. But we use `vfirst.m` to
+ get the `index` of `\0` position. We need to adjust `-1`
+ to get the correct remaining length for zero filling. */
+ sub temp, cur_vl, active_elem_pos
+ addi temp, temp, -1
+ add length, length, temp
+ /* Have an earily return for `strlen(src) + 1 == count` case. */
+ bnez length, 1f
+ ret
+1:
+ sub dst_ptr, dst_ptr, temp
+ vsetvli zero, length, e8, ZERO_FILL_ELEM_LMUL_SETTING, ta, ma
+ vmv.v.x vstr2, zero
+
+L(fill_zero_loop):
+ vsetvli ivl, length, e8, ZERO_FILL_ELEM_LMUL_SETTING, ta, ma
+ vse8.v vstr2, (dst_ptr)
+ sub length, length, ivl
+ add dst_ptr, dst_ptr, ivl
+ bnez length, L(fill_zero_loop)
+
+ ret
+.option pop
+END (__strncpy_vector)
+
+#endif
diff --git a/sysdeps/riscv/multiarch/strnlen_vector.S b/sysdeps/riscv/multiarch/strnlen_vector.S
new file mode 100644
index 0000000000..ffaf12bfbf
--- /dev/null
+++ b/sysdeps/riscv/multiarch/strnlen_vector.S
@@ -0,0 +1,58 @@
+/* RVV versions strnlen. RISC-V version.
+ Copyright (C) 2025 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+#include <sys/asm.h>
+
+#if IS_IN(libc)
+
+#define str a0
+#define copy_str a2
+#define ret_value a0
+#define max_len a1
+#define cur_vl a3
+#define end_offset a4
+
+#define ELEM_LMUL_SETTING m1
+#define vstr v0
+#define vmask_end v8
+
+ENTRY (__strnlen_vector)
+.option push
+.option arch, +v
+ mv copy_str, str
+ mv ret_value, max_len
+L(strnlen_vector_loop):
+ beqz max_len, L(end_strnlen_vector_loop)
+ vsetvli zero, max_len, e8, ELEM_LMUL_SETTING, ta, ma
+ vle8ff.v vstr, (copy_str)
+ vmseq.vi vmask_end, vstr, 0
+ vfirst.m end_offset, vmask_end /* first occurence of \0 */
+ csrr cur_vl, vl
+ add copy_str, copy_str, cur_vl
+ sub max_len, max_len, cur_vl
+ bltz end_offset, L(strnlen_vector_loop)
+ add max_len, max_len, cur_vl
+ sub ret_value, ret_value, max_len
+ add ret_value, ret_value, end_offset
+L(end_strnlen_vector_loop):
+ ret
+.option pop
+END (__strnlen_vector)
+
+#endif
--
2.47.2
More information about the Libc-alpha
mailing list