[PATCH v2 2/4] riscv: Add RVV implementations for mem* routines

Yao Zihong zihong.plct@isrc.iscas.ac.cn
Tue Sep 30 00:34:51 GMT 2025


This patch imports RVV-based implementations of the mem* family:
    memchr, memcmp, memcpy, memmove, __memcmpeq, memset.
They assume RVV 1.0 with VLEN >= 32, support arbitrary VLEN, and work on
both RV32 and RV64 platforms. 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: Yun Hsiang <yun.hsiang@sifive.com>
Co-authored-by: Hau Hsu <hau.hsu@sifive.com>
Co-authored-by: Jerry Shih <jerry.shih@sifive.com>
Co-authored-by: Yun Hsiang <yun.hsiang@sifive.com>
Signed-off-by: Yao Zihong <zihong.plct@isrc.iscas.ac.cn>
---
 sysdeps/riscv/multiarch/memchr_vector.S   | 65 ++++++++++++++++++++
 sysdeps/riscv/multiarch/memcmp_vector.S   | 73 +++++++++++++++++++++++
 sysdeps/riscv/multiarch/memcmpeq_vector.S | 67 +++++++++++++++++++++
 sysdeps/riscv/multiarch/memcpy_vector.S   | 53 ++++++++++++++++
 sysdeps/riscv/multiarch/memmove_vector.S  | 73 +++++++++++++++++++++++
 sysdeps/riscv/multiarch/memset_vector.S   | 52 ++++++++++++++++
 6 files changed, 383 insertions(+)
 create mode 100644 sysdeps/riscv/multiarch/memchr_vector.S
 create mode 100644 sysdeps/riscv/multiarch/memcmp_vector.S
 create mode 100644 sysdeps/riscv/multiarch/memcmpeq_vector.S
 create mode 100644 sysdeps/riscv/multiarch/memcpy_vector.S
 create mode 100644 sysdeps/riscv/multiarch/memmove_vector.S
 create mode 100644 sysdeps/riscv/multiarch/memset_vector.S

diff --git a/sysdeps/riscv/multiarch/memchr_vector.S b/sysdeps/riscv/multiarch/memchr_vector.S
new file mode 100644
index 0000000000..3c1b85884d
--- /dev/null
+++ b/sysdeps/riscv/multiarch/memchr_vector.S
@@ -0,0 +1,65 @@
+/* RVV versions memchr.  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 src a0
+#define value a1
+#define num a2
+
+#define ivl a3
+#define temp a4
+
+#define ELEM_LMUL_SETTING m8
+#define vdata v0
+#define vmask v8
+
+ENTRY (__memchr_vector)
+.option push
+.option arch, +v
+L(loop):
+    vsetvli zero, num, e8, ELEM_LMUL_SETTING, ta, ma
+
+    vle8ff.v vdata, (src)
+    /* Find the value inside the loaded data.  */
+    vmseq.vx vmask, vdata, value
+    vfirst.m temp, vmask
+
+    /* Skip the loop if we find the matched value.  */
+    bgez temp, L(found)
+
+    csrr ivl, vl
+    sub num, num, ivl
+    add src, src, ivl
+
+    bnez num, L(loop)
+
+    li result, 0
+    ret
+L(found):
+    add result, src, temp
+    ret
+.option pop
+END (__memchr_vector)
+
+#endif
diff --git a/sysdeps/riscv/multiarch/memcmp_vector.S b/sysdeps/riscv/multiarch/memcmp_vector.S
new file mode 100644
index 0000000000..1d4facfead
--- /dev/null
+++ b/sysdeps/riscv/multiarch/memcmp_vector.S
@@ -0,0 +1,73 @@
+/* RVV versions memcmp.  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 src1 a0
+#define src2 a1
+#define num a2
+
+#define ivl a3
+#define temp a4
+#define temp1 a5
+#define temp2 a6
+
+#define ELEM_LMUL_SETTING m8
+#define vdata1 v0
+#define vdata2 v8
+#define vmask v16
+
+ENTRY (__memcmp_vector)
+.option push
+.option arch, +v
+L(loop):
+    vsetvli ivl, num, e8, ELEM_LMUL_SETTING, ta, ma
+
+    vle8.v vdata1, (src1)
+    vle8.v vdata2, (src2)
+
+    vmsne.vv vmask, vdata1, vdata2
+    sub num, num, ivl
+    vfirst.m temp, vmask
+
+    /* Skip the loop if we find the different value between src1 and src2.  */
+    bgez temp, L(found)
+
+    add src1, src1, ivl
+    add src2, src2, ivl
+
+    bnez num, L(loop)
+
+    li result, 0
+    ret
+L(found):
+    add src1, src1, temp
+    add src2, src2, temp
+    lbu temp1, 0(src1)
+    lbu temp2, 0(src2)
+    sub result, temp1, temp2
+    ret
+.option pop
+END (__memcmp_vector)
+
+#endif
diff --git a/sysdeps/riscv/multiarch/memcmpeq_vector.S b/sysdeps/riscv/multiarch/memcmpeq_vector.S
new file mode 100644
index 0000000000..b0f9507372
--- /dev/null
+++ b/sysdeps/riscv/multiarch/memcmpeq_vector.S
@@ -0,0 +1,67 @@
+/* RVV versions memcmp.  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 src1 a0
+#define src2 a1
+#define num a2
+
+#define ivl a3
+#define temp a4
+
+#define ELEM_LMUL_SETTING m1
+#define vdata1 v0
+#define vdata2 v8
+#define vmask v16
+
+ENTRY (____memcmpeq_vector)
+.option push
+.option arch, +v
+L(loop):
+    vsetvli ivl, num, e8, ELEM_LMUL_SETTING, ta, ma
+
+    vle8.v vdata1, (src1)
+    vle8.v vdata2, (src2)
+
+    vmsne.vv vmask, vdata1, vdata2
+    sub num, num, ivl
+    vfirst.m temp, vmask
+
+    /* Skip the loop if we find the different value between src1 and src2. */
+    bgez temp, L(found)
+
+    add src1, src1, ivl
+    add src2, src2, ivl
+
+    bnez num, L(loop)
+
+    li result, 0
+    ret
+L(found):
+    mv result, ivl
+    ret
+.option pop
+END (____memcmpeq_vector)
+
+#endif
diff --git a/sysdeps/riscv/multiarch/memcpy_vector.S b/sysdeps/riscv/multiarch/memcpy_vector.S
new file mode 100644
index 0000000000..dad44e983b
--- /dev/null
+++ b/sysdeps/riscv/multiarch/memcpy_vector.S
@@ -0,0 +1,53 @@
+/* RVV versions memcpy.  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 num a2
+
+#define ivl a3
+#define dst_ptr a4
+
+#define ELEM_LMUL_SETTING m8
+#define vdata v0
+
+ENTRY (__memcpy_vector)
+.option push
+.option arch, +v
+    mv dst_ptr, dst
+L(loop):
+    vsetvli ivl, num, e8, ELEM_LMUL_SETTING, ta, ma
+
+    vle8.v vdata, (src)
+    sub num, num, ivl
+    add src, src, ivl
+    vse8.v vdata, (dst_ptr)
+    add dst_ptr, dst_ptr, ivl
+
+    bnez num, L(loop)
+
+    ret
+.option pop
+END (__memcpy_vector)
+
+#endif
diff --git a/sysdeps/riscv/multiarch/memmove_vector.S b/sysdeps/riscv/multiarch/memmove_vector.S
new file mode 100644
index 0000000000..885afe2f3e
--- /dev/null
+++ b/sysdeps/riscv/multiarch/memmove_vector.S
@@ -0,0 +1,73 @@
+/* RVV versions memmove.  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 num a2
+
+#define ivl a3
+#define dst_ptr a4
+#define src_backward_ptr a5
+#define dst_backward_ptr a6
+
+#define ELEM_LMUL_SETTING m8
+#define vdata v0
+
+ENTRY (__memmove_vector)
+.option push
+.option arch, +v
+    mv dst_ptr, dst
+
+    /* If src is equal or after dst, all data in src will be loaded before
+       overwrited for the overlapping case. We could use faster `forward-copy`.  */
+    bgeu src, dst, L(forward_copy_loop)
+    add src_backward_ptr, src, num
+    add dst_backward_ptr, dst, num
+    /* If dst inside source data range, we need to use `backward_copy_loop` to
+       handle the overlapping issue.  */
+    bltu dst, src_backward_ptr, L(backward_copy_loop)
+L(forward_copy_loop):
+    vsetvli ivl, num, e8, ELEM_LMUL_SETTING, ta, ma
+
+    vle8.v vdata, (src)
+    sub num, num, ivl
+    add src, src, ivl
+    vse8.v vdata, (dst_ptr)
+    add dst_ptr, dst_ptr, ivl
+
+    bnez num, L(forward_copy_loop)
+    ret
+L(backward_copy_loop):
+    vsetvli ivl, num, e8, ELEM_LMUL_SETTING, ta, ma
+
+    sub src_backward_ptr, src_backward_ptr, ivl
+    vle8.v vdata, (src_backward_ptr)
+    sub num, num, ivl
+    sub dst_backward_ptr, dst_backward_ptr, ivl
+    vse8.v vdata, (dst_backward_ptr)
+    bnez num, L(backward_copy_loop)
+    ret
+.option pop
+END (__memmove_vector)
+
+#endif
diff --git a/sysdeps/riscv/multiarch/memset_vector.S b/sysdeps/riscv/multiarch/memset_vector.S
new file mode 100644
index 0000000000..eaed07fe91
--- /dev/null
+++ b/sysdeps/riscv/multiarch/memset_vector.S
@@ -0,0 +1,52 @@
+/* RVV versions memset.  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 value a1
+#define num a2
+
+#define ivl a3
+#define dst_ptr a5
+
+#define ELEM_LMUL_SETTING m8
+#define vdata v0
+
+ENTRY (__memset_vector)
+.option push
+.option arch, +v
+    mv dst_ptr, dst
+
+    vsetvli ivl, num, e8, ELEM_LMUL_SETTING, ta, ma
+    vmv.v.x vdata, value
+L(loop):
+    vse8.v vdata, (dst_ptr)
+    sub num, num, ivl
+    add dst_ptr, dst_ptr, ivl
+    vsetvli ivl, num, e8, ELEM_LMUL_SETTING, ta, ma
+    bnez num, L(loop)
+
+    ret
+.option pop
+END (__memset_vector)
+
+#endif
-- 
2.47.2



More information about the Libc-alpha mailing list