* [PATCH] risc-v: Add support on mem* functions with V & B extension
@ 2022-10-31 14:11 朱娜
0 siblings, 0 replies; only message in thread
From: 朱娜 @ 2022-10-31 14:11 UTC (permalink / raw)
To: libc-alpha
[-- Attachment #1.1: Type: text/plain, Size: 1 bytes --]
[-- Attachment #2: 0001-risc-v-Add-support-on-mem-functions-with-V-B-extensi.patch --]
[-- Type: application/octet-stream, Size: 56120 bytes --]
From 3e2542ccdb5eeb12cc0b65a7d1a8e7d2f74e2626 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=9C=B1=E5=A8=9C?= <zhuna.1024@bytedance.com>
Date: Mon, 31 Oct 2022 21:57:49 +0800
Subject: [PATCH] risc-v: Add support on mem* functions with V & B extension
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
To: libc-alpha@sourceware.org
Hi. I wrote mem* functions, taking advantage of RISC-V V & B extensions. SIMD mechanism mostly learned from x86_64 & aarch64 SIMD implementation. Hope I got it right. IFUNCs resolved to multiarchs version by default.
Signed-off-by: 朱娜 <zhuna.1024@bytedance.com>
---
sysdeps/riscv/hp-timing.h | 39 +++++
sysdeps/riscv/init-arch.h | 4 +
sysdeps/riscv/multiarch/Makefile | 19 +++
sysdeps/riscv/multiarch/ifunc-impl-list.c | 58 ++++++++
sysdeps/riscv/multiarch/ifunc-memchr.h | 28 ++++
sysdeps/riscv/multiarch/ifunc-memcmp.h | 28 ++++
sysdeps/riscv/multiarch/ifunc-memcmpeq.h | 29 ++++
sysdeps/riscv/multiarch/ifunc-memcpy.h | 28 ++++
sysdeps/riscv/multiarch/ifunc-memset.h | 28 ++++
sysdeps/riscv/multiarch/memchr-rvv-vlen.S | 118 +++++++++++++++
sysdeps/riscv/multiarch/memchr-rvv.S | 132 +++++++++++++++++
sysdeps/riscv/multiarch/memchr.c | 35 +++++
sysdeps/riscv/multiarch/memcmp-rvv-vlen.S | 120 ++++++++++++++++
sysdeps/riscv/multiarch/memcmp-rvv.S | 158 +++++++++++++++++++++
sysdeps/riscv/multiarch/memcmp.c | 35 +++++
sysdeps/riscv/multiarch/memcmpeq.c | 35 +++++
sysdeps/riscv/multiarch/memcpy-rvv-vlen.S | 100 +++++++++++++
sysdeps/riscv/multiarch/memcpy-rvv.S | 127 +++++++++++++++++
sysdeps/riscv/multiarch/memcpy.c | 35 +++++
sysdeps/riscv/multiarch/memmove-rvv-vlen.S | 110 ++++++++++++++
sysdeps/riscv/multiarch/memmove-rvv.S | 138 ++++++++++++++++++
sysdeps/riscv/multiarch/memset-rvv-vlen.S | 94 ++++++++++++
sysdeps/riscv/multiarch/memset-rvv.S | 126 ++++++++++++++++
sysdeps/riscv/multiarch/memset.c | 35 +++++
24 files changed, 1659 insertions(+)
create mode 100644 sysdeps/riscv/hp-timing.h
create mode 100644 sysdeps/riscv/init-arch.h
create mode 100644 sysdeps/riscv/multiarch/Makefile
create mode 100644 sysdeps/riscv/multiarch/ifunc-impl-list.c
create mode 100644 sysdeps/riscv/multiarch/ifunc-memchr.h
create mode 100644 sysdeps/riscv/multiarch/ifunc-memcmp.h
create mode 100644 sysdeps/riscv/multiarch/ifunc-memcmpeq.h
create mode 100644 sysdeps/riscv/multiarch/ifunc-memcpy.h
create mode 100644 sysdeps/riscv/multiarch/ifunc-memset.h
create mode 100644 sysdeps/riscv/multiarch/memchr-rvv-vlen.S
create mode 100644 sysdeps/riscv/multiarch/memchr-rvv.S
create mode 100644 sysdeps/riscv/multiarch/memchr.c
create mode 100644 sysdeps/riscv/multiarch/memcmp-rvv-vlen.S
create mode 100644 sysdeps/riscv/multiarch/memcmp-rvv.S
create mode 100644 sysdeps/riscv/multiarch/memcmp.c
create mode 100644 sysdeps/riscv/multiarch/memcmpeq.c
create mode 100644 sysdeps/riscv/multiarch/memcpy-rvv-vlen.S
create mode 100644 sysdeps/riscv/multiarch/memcpy-rvv.S
create mode 100644 sysdeps/riscv/multiarch/memcpy.c
create mode 100644 sysdeps/riscv/multiarch/memmove-rvv-vlen.S
create mode 100644 sysdeps/riscv/multiarch/memmove-rvv.S
create mode 100644 sysdeps/riscv/multiarch/memset-rvv-vlen.S
create mode 100644 sysdeps/riscv/multiarch/memset-rvv.S
create mode 100644 sysdeps/riscv/multiarch/memset.c
diff --git a/sysdeps/riscv/hp-timing.h b/sysdeps/riscv/hp-timing.h
new file mode 100644
index 0000000000..f728d864a1
--- /dev/null
+++ b/sysdeps/riscv/hp-timing.h
@@ -0,0 +1,39 @@
+/* High precision, low overhead timing functions. RISC-V version.
+ Copyright (C) 2021-2022 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
+ <https://www.gnu.org/licenses/>. */
+
+#ifndef _HP_TIMING_H
+#define _HP_TIMING_H 1
+
+#include <time.h>
+#include <stdint.h>
+#include <hp-timing-common.h>
+#include <libc-symbols.h>
+
+/* Don't use inline timer in ld.so. */
+#if IS_IN(rtld)
+# define HP_TIMING_INLINE (0)
+#else
+# define HP_TIMING_INLINE (1)
+#endif
+
+typedef uint64_t hp_timing_t;
+
+#define HP_TIMING_NOW(var) \
+ __asm__ __volatile__ ("rdcycle %0 " : "=r" (var)) \
+
+#endif /* hp-timing.h */
diff --git a/sysdeps/riscv/init-arch.h b/sysdeps/riscv/init-arch.h
new file mode 100644
index 0000000000..85dfc4e398
--- /dev/null
+++ b/sysdeps/riscv/init-arch.h
@@ -0,0 +1,4 @@
+#include <ldsodefs.h>
+#include <ifunc-init.h>
+
+# define INIT_ARCH()
diff --git a/sysdeps/riscv/multiarch/Makefile b/sysdeps/riscv/multiarch/Makefile
new file mode 100644
index 0000000000..5bd02ab974
--- /dev/null
+++ b/sysdeps/riscv/multiarch/Makefile
@@ -0,0 +1,19 @@
+ifeq ($(subdir),string)
+sysdep_routines += \
+ memset-rvv \
+ memcpy-rvv \
+ memcmp-rvv \
+ memchr-rvv \
+ memmove-rvv \
+ memset-rvv-vlen \
+ memcpy-rvv-vlen \
+ memcmp-rvv-vlen \
+ memchr-rvv-vlen \
+ memmove-rvv-vlen \
+ # generic-memset \
+ # generic-memchr \
+ # generic-memcpy \
+ # generic-memcmp \
+
+# sysdep_routines
+endif
diff --git a/sysdeps/riscv/multiarch/ifunc-impl-list.c b/sysdeps/riscv/multiarch/ifunc-impl-list.c
new file mode 100644
index 0000000000..efb0d1cdb5
--- /dev/null
+++ b/sysdeps/riscv/multiarch/ifunc-impl-list.c
@@ -0,0 +1,58 @@
+/* Enumerate available IFUNC implementations of a function. RISCV64 version.
+ Copyright (C) 2012-2022 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
+ <https://www.gnu.org/licenses/>. */
+
+#include <assert.h>
+#include <string.h>
+#include <wchar.h>
+#include <ifunc-impl-list.h>
+#include <stdio.h>
+
+
+/* Fill ARRAY of MAX elements with IFUNC implementations for function
+ NAME supported on target machine and return the number of valid
+ entries. Each set of implementations for a given function is sorted in
+ descending order by ISA level. */
+
+size_t
+__libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ size_t max)
+{
+ size_t i = max;
+
+ /* Support sysdeps/riscv/multiarch/memset-rvv.S. */
+ IFUNC_IMPL (i, name, memset,
+ IFUNC_IMPL_ADD (array, i, memset, 1, memset_rvv)
+ IFUNC_IMPL_ADD (array, i, memset, 1, memset_rvv_vlen)
+ );
+ /* Support sysdeps/riscv/multiarch/memcpy-rvv.S. */
+ IFUNC_IMPL (i, name, memcpy,
+ IFUNC_IMPL_ADD (array, i, memcpy, 1, memcpy_rvv)
+ IFUNC_IMPL_ADD (array, i, memcpy, 1, memcpy_rvv_vlen)
+ );
+ /* Support sysdeps/riscv/multiarch/memcmp-rvv.S. */
+ IFUNC_IMPL (i, name, memcmp,
+ IFUNC_IMPL_ADD (array, i, memcmp, 1, memcmp_rvv)
+ IFUNC_IMPL_ADD (array, i, memcmp, 1, memcmp_rvv_vlen)
+ );
+ /* Support sysdeps/riscv/multiarch/memchr-rvv.S. */
+ IFUNC_IMPL (i, name, memchr,
+ IFUNC_IMPL_ADD (array, i, memchr, 1, memchr_rvv)
+ IFUNC_IMPL_ADD (array, i, memchr, 1, memchr_rvv_vlen)
+ );
+ return 0;
+}
diff --git a/sysdeps/riscv/multiarch/ifunc-memchr.h b/sysdeps/riscv/multiarch/ifunc-memchr.h
new file mode 100644
index 0000000000..25e2500864
--- /dev/null
+++ b/sysdeps/riscv/multiarch/ifunc-memchr.h
@@ -0,0 +1,28 @@
+/* All versions must be listed in ifunc-memchr.c.
+ Copyright (C) 2017-2022 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
+ <https://www.gnu.org/licenses/>. */
+
+#include <init-arch.h>
+
+extern __typeof (REDIRECT_NAME) memchr_rvv attribute_hidden;
+extern __typeof (REDIRECT_NAME) memchr_rvv_vlen attribute_hidden;
+
+static inline void *
+IFUNC_SELECTOR (void)
+{
+ return memchr_rvv_vlen;
+}
diff --git a/sysdeps/riscv/multiarch/ifunc-memcmp.h b/sysdeps/riscv/multiarch/ifunc-memcmp.h
new file mode 100644
index 0000000000..b86a6615b8
--- /dev/null
+++ b/sysdeps/riscv/multiarch/ifunc-memcmp.h
@@ -0,0 +1,28 @@
+/* All versions must be listed in ifunc-memcmp.c.
+ Copyright (C) 2017-2022 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
+ <https://www.gnu.org/licenses/>. */
+
+#include <init-arch.h>
+
+extern __typeof (REDIRECT_NAME) memcmp_rvv attribute_hidden;
+extern __typeof (REDIRECT_NAME) memcmp_rvv_vlen attribute_hidden;
+
+static inline void *
+IFUNC_SELECTOR (void)
+{
+ return memcmp_rvv_vlen;
+}
diff --git a/sysdeps/riscv/multiarch/ifunc-memcmpeq.h b/sysdeps/riscv/multiarch/ifunc-memcmpeq.h
new file mode 100644
index 0000000000..877edc94f4
--- /dev/null
+++ b/sysdeps/riscv/multiarch/ifunc-memcmpeq.h
@@ -0,0 +1,29 @@
+/* Common definition for __memcmpeq ifunc selections.
+ All versions must be listed in ifunc-impl-list.c.
+ Copyright (C) 2017-2022 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
+ <https://www.gnu.org/licenses/>. */
+
+# include <init-arch.h>
+
+extern __typeof (REDIRECT_NAME) memcmp_rvv attribute_hidden;
+extern __typeof (REDIRECT_NAME) memcmp_rvv_vlen attribute_hidden;
+
+static inline void *
+IFUNC_SELECTOR (void)
+{
+ return memcmp_rvv_vlen;
+}
diff --git a/sysdeps/riscv/multiarch/ifunc-memcpy.h b/sysdeps/riscv/multiarch/ifunc-memcpy.h
new file mode 100644
index 0000000000..d4e1d9004b
--- /dev/null
+++ b/sysdeps/riscv/multiarch/ifunc-memcpy.h
@@ -0,0 +1,28 @@
+/* All versions must be listed in ifunc-memcpy.c.
+ Copyright (C) 2017-2022 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
+ <https://www.gnu.org/licenses/>. */
+
+#include <init-arch.h>
+
+extern __typeof (REDIRECT_NAME) memcpy_rvv attribute_hidden;
+extern __typeof (REDIRECT_NAME) memcpy_rvv_vlen attribute_hidden;
+
+static inline void *
+IFUNC_SELECTOR (void)
+{
+ return memcpy_rvv_vlen;
+}
diff --git a/sysdeps/riscv/multiarch/ifunc-memset.h b/sysdeps/riscv/multiarch/ifunc-memset.h
new file mode 100644
index 0000000000..d8301009f2
--- /dev/null
+++ b/sysdeps/riscv/multiarch/ifunc-memset.h
@@ -0,0 +1,28 @@
+/* All versions must be listed in ifunc-memset.c.
+ Copyright (C) 2017-2022 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
+ <https://www.gnu.org/licenses/>. */
+
+#include <init-arch.h>
+
+extern __typeof (REDIRECT_NAME) memset_rvv attribute_hidden;
+extern __typeof (REDIRECT_NAME) memset_rvv_vlen attribute_hidden;
+
+static inline void *
+IFUNC_SELECTOR (void)
+{
+ return memset_rvv_vlen;
+}
diff --git a/sysdeps/riscv/multiarch/memchr-rvv-vlen.S b/sysdeps/riscv/multiarch/memchr-rvv-vlen.S
new file mode 100644
index 0000000000..26635aa5ff
--- /dev/null
+++ b/sysdeps/riscv/multiarch/memchr-rvv-vlen.S
@@ -0,0 +1,118 @@
+/* Copyright (C) 2017-2022 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
+ <https://www.gnu.org/licenses/>. */
+
+ .text
+ .globl memchr_rvv_vlen # -- Begin function memchr_rvv
+ .p2align 1
+ .type memchr_rvv_vlen,@function
+
+# a0: src a1: c a2: nbyte
+#define SRC a0
+#define SRC_END a7
+#define CC a1
+#define CC_U8 a6
+#define NBYTE a2
+# utilities
+#define VLEN a3
+#define CTZ_I a4
+#define XLEN a5
+#define ALIGN 8
+#define L(label) .memchr_rvv_vlen_##label
+
+memchr_rvv_vlen:
+ beqz NBYTE, L(not_found)
+ add SRC_END, SRC, NBYTE
+ addi XLEN, zero, 8 # xlen = 8B
+ # to uint8
+ andi CC, CC, 0xff
+ mv CC_U8, CC
+ # broadcast in uint64
+ slli t0, CC, 8 # t0 = CC << 8
+ or CC, t0, CC # CC = CC | t0
+ slli t0, CC, 16 # t0 = CC << 16
+ or CC, t0, CC # CC = CC | t0
+ slli t0, CC, 32 # t0 = CC << 32
+ or CC, t0, CC # CC = CC | t0
+# BEGIN small lengths
+ addi t1, zero, 16
+ addi VLEN, zero, -1
+ vsetvli VLEN, VLEN, e8, m8, ta, ma
+ # blt NBYTE, t1, L(less_m8x1)
+ slli t1, VLEN, 1
+ blt NBYTE, t1, L(m8x1_loop)
+# END small length
+# nbyte >= vlen x 2
+
+# BEGIN align on 8B
+ andi t0, SRC, 7
+ beqz t0, L(vec_set)
+ sub t0, zero, t0
+ addi t0, t0, 8
+ ld t2, (SRC)
+ xor t1, CC, t2
+ orc.b t3, t1
+ xori t3, t3, -1
+ ctz CTZ_I, t3
+ srli CTZ_I, CTZ_I, 3
+ bne CTZ_I, XLEN, L(found)
+ add SRC, SRC, t0
+# END align on 8B
+# BEGIN VEC STORE BULK
+L(vec_set):
+# t0: total vlen * 2 t1: src + total vlen * 2
+ slli t0, VLEN, 1
+ add t1, SRC, t0
+ blt SRC_END, t1, L(m8x2_loop_end) # branch if less than total vlen
+# use many t* to exploit data parallelism
+L(m8x2_loop):
+ vle8.v v0, (SRC)
+ add t2, SRC, VLEN
+ vle8.v v16, (t2)
+ vmseq.vx v8, v0, CC
+ vmseq.vx v24, v16, CC
+ vfirst.m CTZ_I, v8
+ bge CTZ_I, zero, L(found)
+ vfirst.m CTZ_I, v24
+ mv SRC, t2
+ bge CTZ_I, zero, L(found)
+ add SRC, SRC, VLEN
+ add t1, SRC, t0
+ bge SRC_END, t1, L(m8x2_loop) # branch if less than total vlen
+L(m8x2_loop_end):
+# END VEC STORE BULK
+ sub NBYTE, SRC_END, SRC
+ mv t1, NBYTE
+L(m8x1_loop):
+ mv NBYTE, t1
+ vsetvli VLEN, NBYTE, e8, m8, ta, ma
+ vle8.v v0, (SRC)
+ vmseq.vx v8, v0, CC
+ vfirst.m CTZ_I, v8
+ bge CTZ_I, zero, L(found)
+ add SRC, SRC, VLEN
+ sub t1, NBYTE, VLEN
+ bnez t1, L(m8x1_loop)
+ # not found
+ mv a0, zero
+ ret
+L(found):
+ add SRC, SRC, CTZ_I
+ bge SRC, SRC_END, L(not_found)
+ ret
+L(not_found):
+ mv a0, zero
+ ret
diff --git a/sysdeps/riscv/multiarch/memchr-rvv.S b/sysdeps/riscv/multiarch/memchr-rvv.S
new file mode 100644
index 0000000000..36b6ccb80f
--- /dev/null
+++ b/sysdeps/riscv/multiarch/memchr-rvv.S
@@ -0,0 +1,132 @@
+/* Copyright (C) 2017-2022 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
+ <https://www.gnu.org/licenses/>. */
+
+ .text
+ .globl memchr_rvv # -- Begin function memchr_rvv
+ .p2align 1
+ .type memchr_rvv,@function
+
+# a0: src a1: c a2: nbyte
+#define SRC a0
+#define SRC_END a7
+#define CC a1
+#define CC_U8 a6
+#define NBYTE a2
+# utilities
+#define VLEN a3
+#define CTZ_I a4
+#define XLEN a5
+#define ALIGN 8
+#define L(label) .memchr_rvv_##label
+
+memchr_rvv:
+ beqz NBYTE, L(not_found)
+ add SRC_END, SRC, NBYTE
+ addi XLEN, zero, 8 # xlen = 8B
+ # to uint8
+ andi CC, CC, 0xff
+ mv CC_U8, CC
+ # broadcast in uint64
+ slli t0, CC, 8 # t0 = CC << 8
+ or CC, t0, CC # CC = CC | t0
+ slli t0, CC, 16 # t0 = CC << 16
+ or CC, t0, CC # CC = CC | t0
+ slli t0, CC, 32 # t0 = CC << 32
+ or CC, t0, CC # CC = CC | t0
+# BEGIN small lengths
+ addi t1, zero, 16
+ addi VLEN, zero, -1
+ vsetvli VLEN, VLEN, e8, m8, ta, ma
+ blt NBYTE, t1, L(less_m8x1)
+ slli t1, VLEN, 1
+ blt NBYTE, t1, L(less_m8x2)
+# END small length
+# nbyte >= vlen x 2
+
+# BEGIN align on 8B
+ andi t0, SRC, 7
+ beqz t0, L(vec_set)
+ sub t0, zero, t0
+ addi t0, t0, 8
+ ld t2, (SRC)
+ xor t1, CC, t2
+ orc.b t3, t1
+ xori t3, t3, -1
+ ctz CTZ_I, t3
+ srli CTZ_I, CTZ_I, 3
+ bne CTZ_I, XLEN, L(found)
+ add SRC, SRC, t0
+# END align on 8B
+# BEGIN VEC STORE BULK
+L(vec_set):
+# t0: total vlen * 2 t1: src + total vlen * 2
+ slli t0, VLEN, 1
+ add t1, SRC, t0
+ blt SRC_END, t1, L(m8x2_loop_end) # branch if less than total vlen
+# use many t* to exploit data parallelism
+L(m8x2_loop):
+ vle8.v v0, (SRC)
+ add t2, SRC, VLEN
+ vle8.v v16, (t2)
+ vmseq.vx v8, v0, CC
+ vmseq.vx v24, v16, CC
+ vfirst.m CTZ_I, v8
+ bge CTZ_I, zero, L(found)
+ vfirst.m CTZ_I, v24
+ mv SRC, t2
+ bge CTZ_I, zero, L(found)
+ add SRC, SRC, VLEN
+ add t1, SRC, t0
+ bge SRC_END, t1, L(m8x2_loop) # branch if less than total vlen
+L(m8x2_loop_end):
+# END VEC STORE BULK
+ sub NBYTE, SRC_END, SRC
+
+L(less_m8x2):
+ blt NBYTE, VLEN, L(less_m8x1)
+ # nbyte >= vlen(m8) * 1
+ # 1 load followed by an overlap load
+ sub t1, SRC_END, VLEN
+ # first load
+ vle8.v v0, (SRC)
+ vmseq.vx v8, v0, CC
+ # overlap load
+ vle8.v v16, (t1)
+ vmseq.vx v24, v16, CC
+ vfirst.m CTZ_I, v8
+ bge CTZ_I, zero, L(found)
+ vfirst.m CTZ_I, v24
+ bge CTZ_I, zero, L(found)
+ # not found
+ mv a0, zero
+ ret
+L(less_m8x1):
+ vsetvli VLEN, NBYTE, e8, m8, ta, ma
+ vle8.v v0, (SRC)
+ vmseq.vx v8, v0, CC
+ vfirst.m CTZ_I, v8
+ bge CTZ_I, zero, L(found)
+ # not found
+ mv a0, zero
+ ret
+L(found):
+ add SRC, SRC, CTZ_I
+ bge SRC, SRC_END, L(not_found)
+ ret
+L(not_found):
+ mv a0, zero
+ ret
diff --git a/sysdeps/riscv/multiarch/memchr.c b/sysdeps/riscv/multiarch/memchr.c
new file mode 100644
index 0000000000..89391e7821
--- /dev/null
+++ b/sysdeps/riscv/multiarch/memchr.c
@@ -0,0 +1,35 @@
+/* Multiple versions of memchr.
+ All versions must be listed in ifunc-impl-list.c.
+ Copyright (C) 2017-2022 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
+ <https://www.gnu.org/licenses/>. */
+
+/* Define multiple versions only for the definition in libc. */
+#if IS_IN (libc)
+# define memchr __redirect_memchr
+# include <string.h>
+# undef memchr
+
+# define SYMBOL_NAME memchr
+# include "ifunc-memchr.h"
+
+libc_ifunc_redirected (__redirect_memchr, memchr, IFUNC_SELECTOR ());
+
+# ifdef SHARED
+__hidden_ver1 (memchr, __GI_memchr, __redirect_memchr)
+ __attribute__ ((visibility ("hidden"))) __attribute_copy__ (memchr);
+# endif
+#endif
diff --git a/sysdeps/riscv/multiarch/memcmp-rvv-vlen.S b/sysdeps/riscv/multiarch/memcmp-rvv-vlen.S
new file mode 100644
index 0000000000..875c5bbbf3
--- /dev/null
+++ b/sysdeps/riscv/multiarch/memcmp-rvv-vlen.S
@@ -0,0 +1,120 @@
+/* Copyright (C) 2017-2022 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
+ <https://www.gnu.org/licenses/>. */
+
+ .text
+ .globl memcmp_rvv_vlen # -- Begin function memchr_rvv
+ .p2align 1
+ .type memcmp_rvv_vlen,@function
+
+# a0: src1 a1: src2 a2: nbyte
+#define SRC1 a0
+#define SRC2 a1
+#define NBYTE a2
+#define SRC_END1 a5
+#define SRC_END2 a6
+# utilities
+#define VLEN a3
+#define XLEN a4
+#define MASK a7
+#define L(label) .memcmp_rvv_vlen_##label
+
+memcmp_rvv_vlen:
+ bnez NBYTE, L(gt_0)
+ mv a0, zero
+ ret
+L(gt_0):
+ add SRC_END1, SRC1, NBYTE
+ add SRC_END2, SRC2, NBYTE
+
+ addi VLEN, zero, -1
+ vsetvli VLEN, VLEN, e8, m8, ta, ma
+ # blt NBYTE, VLEN, L(less_m8x1)
+ slli t0, VLEN, 1
+ blt NBYTE, t0, L(m8x2_loop_end)
+# nbyte >= vlen x 2
+
+L(m8x2_loop):
+ # load first
+ vle8.v v0, (SRC1)
+ add t2, SRC1, VLEN
+ vle8.v v8, (SRC2)
+ add t3, SRC2, VLEN
+ # compare first
+ vmsne.vv v24, v0, v8
+ vfirst.m t1, v24
+ blt t1, zero, L(m8x2_loop_first_not_found)
+ # found in first load
+ vslidedown.vx v0, v0, t1
+ vslidedown.vx v8, v8, t1
+ vmv.x.s t0, v0
+ vmv.x.s t1, v8
+ andi t0, t0, 0xff
+ andi t1, t1, 0xff
+ sub a0, t0, t1
+ ret
+L(m8x2_loop_first_not_found):
+ # load second
+ vle8.v v16, (t2)
+ vle8.v v24, (t3)
+ # compare second
+ vmsne.vv v16, v16, v24
+ vfirst.m t1, v16
+ blt t1, zero, L(m8x2_loop_second_not_found)
+ # found in second load
+ vslidedown.vx v16, v16, t1
+ vslidedown.vx v24, v24, t1
+ vmv.x.s t0, v16
+ vmv.x.s t1, v24
+ andi t0, t0, 0xff
+ andi t1, t1, 0xff
+ sub a0, t0, t1
+ ret
+L(m8x2_loop_second_not_found):
+ add SRC1, t2, VLEN
+ add SRC2, t3, VLEN
+ add t1, SRC1, t0
+ blt t1, SRC_END1, L(m8x2_loop)
+L(m8x2_loop_end):
+# END VEC STORE BULK
+ sub NBYTE, SRC_END1, SRC1
+ mv t1, NBYTE
+L(m8x1_loop):
+ mv NBYTE, t1
+ vsetvli VLEN, NBYTE, e8, m8, ta, ma
+ vle8.v v0, (SRC1)
+ vle8.v v8, (SRC2)
+ vmsne.vv v24, v0, v8
+ vfirst.m t1, v24
+ blt t1, zero, L(m8x1_loop_not_found)
+ # found
+ vslidedown.vx v0, v0, t1
+ vslidedown.vx v8, v8, t1
+ vmv.x.s t0, v0
+ vmv.x.s t1, v8
+ andi t0, t0, 0xff
+ andi t1, t1, 0xff
+ sub a0, t0, t1
+ ret
+L(m8x1_loop_not_found):
+ add SRC1, SRC1, VLEN
+ add SRC2, SRC2, VLEN
+ sub t1, NBYTE, VLEN
+ bnez t1, L(m8x1_loop)
+ # not found
+ mv a0, zero
+ ret
+
\ No newline at end of file
diff --git a/sysdeps/riscv/multiarch/memcmp-rvv.S b/sysdeps/riscv/multiarch/memcmp-rvv.S
new file mode 100644
index 0000000000..b60486db21
--- /dev/null
+++ b/sysdeps/riscv/multiarch/memcmp-rvv.S
@@ -0,0 +1,158 @@
+/* Copyright (C) 2017-2022 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
+ <https://www.gnu.org/licenses/>. */
+
+ .text
+ .globl memcmp_rvv # -- Begin function memchr_rvv
+ .p2align 1
+ .type memcmp_rvv,@function
+
+# a0: src1 a1: src2 a2: nbyte
+#define SRC1 a0
+#define SRC2 a1
+#define NBYTE a2
+#define SRC_END1 a5
+#define SRC_END2 a6
+# utilities
+#define VLEN a3
+#define XLEN a4
+#define MASK a7
+#define L(label) .memcmp_rvv_##label
+
+memcmp_rvv:
+ bnez NBYTE, L(gt_0)
+ mv a0, zero
+ ret
+L(gt_0):
+ add SRC_END1, SRC1, NBYTE
+ add SRC_END2, SRC2, NBYTE
+
+ addi VLEN, zero, -1
+ vsetvli VLEN, VLEN, e8, m8, ta, ma
+ blt NBYTE, VLEN, L(less_m8x1)
+ slli t0, VLEN, 1
+ blt NBYTE, t0, L(less_m8x2)
+# nbyte >= vlen x 2
+
+L(m8x2_loop):
+ # load first
+ vle8.v v0, (SRC1)
+ add t2, SRC1, VLEN
+ vle8.v v8, (SRC2)
+ add t3, SRC2, VLEN
+ # compare first
+ vmsne.vv v24, v0, v8
+ vfirst.m t1, v24
+ blt t1, zero, L(m8x2_loop_first_not_found)
+ # found in first load
+ vslidedown.vx v0, v0, t1
+ vslidedown.vx v8, v8, t1
+ vmv.x.s t0, v0
+ vmv.x.s t1, v8
+ andi t0, t0, 0xff
+ andi t1, t1, 0xff
+ sub a0, t0, t1
+ ret
+L(m8x2_loop_first_not_found):
+ # load second
+ vle8.v v16, (t2)
+ vle8.v v24, (t3)
+ # compare second
+ vmsne.vv v16, v16, v24
+ vfirst.m t1, v16
+ blt t1, zero, L(m8x2_loop_second_not_found)
+ # found in second load
+ vslidedown.vx v16, v16, t1
+ vslidedown.vx v24, v24, t1
+ vmv.x.s t0, v16
+ vmv.x.s t1, v24
+ andi t0, t0, 0xff
+ andi t1, t1, 0xff
+ sub a0, t0, t1
+ ret
+L(m8x2_loop_second_not_found):
+ add SRC1, t2, VLEN
+ add SRC2, t3, VLEN
+ add t1, SRC1, t0
+ blt t1, SRC_END1, L(m8x2_loop)
+L(m8x2_loop_end):
+# END VEC STORE BULK
+ sub NBYTE, SRC_END1, SRC1
+
+L(less_m8x2):
+ blt NBYTE, VLEN, L(less_m8x1)
+ # nbyte >= vlen(m8) * 1
+ # 1 load followed by an overlap load
+ sub t1, SRC_END1, VLEN
+ sub t2, SRC_END2, VLEN
+ # first load
+ vle8.v v0, (SRC1)
+ vle8.v v8, (SRC2)
+ vmsne.vv v16, v0, v8
+ vfirst.m t0, v16
+ blt t0, zero, L(less_m8x2_first_not_found)
+ # found in vector
+ vslidedown.vx v0, v0, t0
+ vslidedown.vx v8, v8, t0
+ vmv.x.s t0, v0
+ vmv.x.s t1, v8
+ andi t0, t0, 0xff
+ andi t1, t1, 0xff
+ sub a0, t0, t1
+ ret
+L(less_m8x2_first_not_found):
+ # overlap load
+ vle8.v v16, (t1)
+ vle8.v v24, (t2)
+ vmsne.vv v0, v16, v24
+ vfirst.m t0, v0
+ blt t0, zero, L(less_m8x2_second_not_found)
+ # found in vector
+ vslidedown.vx v16, v16, t0
+ vslidedown.vx v24, v24, t0
+ vmv.x.s t0, v16
+ vmv.x.s t1, v24
+ andi t0, t0, 0xff
+ andi t1, t1, 0xff
+ sub a0, t0, t1
+ ret
+L(less_m8x2_second_not_found):
+ # identical
+ mv a0, zero
+ ret
+
+L(less_m8x1):
+ # addi t3, zero, 1
+ # beq NBYTE, t3, L(1byte)
+ vsetvli VLEN, NBYTE, e8, m8, ta, ma
+ vle8.v v0, (SRC1)
+ vle8.v v8, (SRC2)
+ vmsne.vv v16, v0, v8
+ vfirst.m t0, v16
+ blt t0, zero, L(less_m8x1_not_found)
+ # found in vector
+ vslidedown.vx v0, v0, t0
+ vslidedown.vx v8, v8, t0
+ vmv.x.s t0, v0
+ vmv.x.s t1, v8
+ andi t0, t0, 0xff
+ andi t1, t1, 0xff
+ sub a0, t0, t1
+ ret
+L(less_m8x1_not_found):
+ mv a0, zero
+ ret
+
\ No newline at end of file
diff --git a/sysdeps/riscv/multiarch/memcmp.c b/sysdeps/riscv/multiarch/memcmp.c
new file mode 100644
index 0000000000..bae29d8dad
--- /dev/null
+++ b/sysdeps/riscv/multiarch/memcmp.c
@@ -0,0 +1,35 @@
+/* Multiple versions of memcmp.
+ All versions must be listed in ifunc-impl-list.c.
+ Copyright (C) 2017-2022 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
+ <https://www.gnu.org/licenses/>. */
+
+/* Define multiple versions only for the definition in libc. */
+#if IS_IN (libc)
+# define memcmp __redirect_memcmp
+# include <string.h>
+# undef memcmp
+
+# define SYMBOL_NAME memcmp
+# include "ifunc-memcmp.h"
+
+libc_ifunc_redirected (__redirect_memcmp, memcmp, IFUNC_SELECTOR ());
+
+# ifdef SHARED
+__hidden_ver1 (memcmp, __GI_memcmp, __redirect_memcmp)
+ __attribute__ ((visibility ("hidden"))) __attribute_copy__ (memcmp);
+# endif
+#endif
diff --git a/sysdeps/riscv/multiarch/memcmpeq.c b/sysdeps/riscv/multiarch/memcmpeq.c
new file mode 100644
index 0000000000..aa1c8ad4de
--- /dev/null
+++ b/sysdeps/riscv/multiarch/memcmpeq.c
@@ -0,0 +1,35 @@
+/* Multiple versions of __memcmpeq.
+ All versions must be listed in ifunc-impl-list.c.
+ Copyright (C) 2017-2022 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
+ <https://www.gnu.org/licenses/>. */
+
+/* Define multiple versions only for the definition in libc. */
+#if IS_IN (libc)
+# define __memcmpeq __redirect___memcmpeq
+# include <string.h>
+# undef __memcmpeq
+
+# define SYMBOL_NAME __memcmpeq
+# include "ifunc-memcmpeq.h"
+
+libc_ifunc_redirected (__redirect___memcmpeq, __memcmpeq, IFUNC_SELECTOR ());
+
+# ifdef SHARED
+__hidden_ver1 (__memcmpeq, __GI___memcmpeq, __redirect___memcmpeq)
+ __attribute__ ((visibility ("hidden"))) __attribute_copy__ (__memcmpeq);
+# endif
+#endif
diff --git a/sysdeps/riscv/multiarch/memcpy-rvv-vlen.S b/sysdeps/riscv/multiarch/memcpy-rvv-vlen.S
new file mode 100644
index 0000000000..876c13f509
--- /dev/null
+++ b/sysdeps/riscv/multiarch/memcpy-rvv-vlen.S
@@ -0,0 +1,100 @@
+/* Copyright (C) 2017-2022 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
+ <https://www.gnu.org/licenses/>. */
+
+ .globl memcpy_rvv_vlen
+ .p2align 1
+ .type memcpy_rvv_vlen,@function
+# a0: dst a1: src a2: nbyte
+#define DST a5
+#define DST_END a6
+#define SRC a1
+#define SRC_END a4
+#define NBYTE a2
+# utilities
+#define VLEN a3
+#define ALIGN 8
+#define L(label) .memcpy_rvv_vlen_##label
+
+memcpy_rvv_vlen:
+ # return value
+ mv DST, a0
+ add DST_END, DST, NBYTE
+ add SRC_END, SRC, NBYTE
+# BEGIN small lengths
+ # addi t1, zero, 16
+ # blt NBYTE, t1, L(less_16bytes)
+ addi VLEN, zero, -1
+ vsetvli VLEN, VLEN, e8, m8, ta, ma
+ # blt NBYTE, VLEN, L(less_m8x1)
+ slli t1, VLEN, 2
+ blt NBYTE, t1, L(m8x4_loop_end)
+# END small length
+
+# BEGIN check alignment
+# align on 8B
+ andi t0, DST, 7
+ beqz t0, L(vec_set)
+ sub t0, zero, t0
+ addi t0, t0, 8
+ ld t1, (SRC)
+ sd t1, (DST)
+ add SRC, SRC, t0
+ add DST, DST, t0
+# END check alignment
+# BEGIN VEC STORE BULK
+L(vec_set):
+# t0: total vlen * 4 t1: dst + total vlen * 4
+ slli t0, VLEN, 2
+ add t1, DST, t0
+ blt DST_END, t1, L(m8x4_loop_end) # branch if less than total vlen
+# use many t* to exploit data parallelism
+L(m8x4_loop):
+ # loads
+ vle8.v v0, (SRC)
+ add t1, SRC, VLEN
+ vle8.v v8, (t1)
+ add t2, t1, VLEN
+ vle8.v v16, (t2)
+ add t3, t2, VLEN
+ vle8.v v24, (t3)
+ add SRC, t3, VLEN
+ # store
+ vse8.v v0, (DST)
+ add t1, DST, VLEN
+ vse8.v v8, (t1)
+ add t2, t1, VLEN
+ vse8.v v16, (t2)
+ add t3, t2, VLEN
+ vse8.v v24, (t3)
+ add DST, t3, VLEN
+ # check loop
+ add t4, DST, t0
+ bge DST_END, t4, L(m8x4_loop) # branch if less than total vlen
+L(m8x4_loop_end):
+# END VEC STORE BULK
+ sub NBYTE, DST_END, DST
+ mv t1, NBYTE
+L(m8x1_loop):
+ mv NBYTE, t1
+ vsetvli VLEN, NBYTE, e8, m8, ta, ma
+ vle8.v v0, (SRC)
+ vse8.v v0, (DST)
+ add SRC, SRC, VLEN
+ add DST, DST, VLEN
+ sub t1, NBYTE, VLEN
+ bnez t1, L(m8x1_loop)
+ ret
diff --git a/sysdeps/riscv/multiarch/memcpy-rvv.S b/sysdeps/riscv/multiarch/memcpy-rvv.S
new file mode 100644
index 0000000000..586a92ee50
--- /dev/null
+++ b/sysdeps/riscv/multiarch/memcpy-rvv.S
@@ -0,0 +1,127 @@
+/* Copyright (C) 2017-2022 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
+ <https://www.gnu.org/licenses/>. */
+
+ .globl memcpy_rvv
+ .p2align 1
+ .type memcpy_rvv,@function
+# a0: dst a1: src a2: nbyte
+#define DST a5
+#define DST_END a6
+#define SRC a1
+#define SRC_END a4
+#define NBYTE a2
+# utilities
+#define VLEN a3
+#define ALIGN 8
+#define L(label) .memcpy_rvv_##label
+
+memcpy_rvv:
+ # return value
+ mv DST, a0
+ add DST_END, DST, NBYTE
+ add SRC_END, SRC, NBYTE
+# BEGIN small lengths
+ # addi t1, zero, 16
+ # blt NBYTE, t1, L(less_16bytes)
+ addi VLEN, zero, -1
+ vsetvli VLEN, VLEN, e8, m8, ta, ma
+ blt NBYTE, VLEN, L(less_m8x1)
+ slli t1, VLEN, 2
+ blt NBYTE, t1, L(less_m8x4)
+# END small length
+
+# BEGIN check alignment
+# align on 8B
+ andi t0, DST, 7
+ beqz t0, L(vec_set)
+ sub t0, zero, t0
+ addi t0, t0, 8
+ ld t1, (SRC)
+ sd t1, (DST)
+ add SRC, SRC, t0
+ add DST, DST, t0
+# END check alignment
+# BEGIN VEC STORE BULK
+L(vec_set):
+# t0: total vlen * 4 t1: dst + total vlen * 4
+ slli t0, VLEN, 2
+ add t1, DST, t0
+ blt DST_END, t1, L(m8x4_loop_end) # branch if less than total vlen
+# use many t* to exploit data parallelism
+L(m8x4_loop):
+ # loads
+ vle8.v v0, (SRC)
+ add t1, SRC, VLEN
+ vle8.v v8, (t1)
+ add t2, t1, VLEN
+ vle8.v v16, (t2)
+ add t3, t2, VLEN
+ vle8.v v24, (t3)
+ add SRC, t3, VLEN
+ # store
+ vse8.v v0, (DST)
+ add t1, DST, VLEN
+ vse8.v v8, (t1)
+ add t2, t1, VLEN
+ vse8.v v16, (t2)
+ add t3, t2, VLEN
+ vse8.v v24, (t3)
+ add DST, t3, VLEN
+ # check loop
+ add t4, DST, t0
+ bge DST_END, t4, L(m8x4_loop) # branch if less than total vlen
+L(m8x4_loop_end):
+# END VEC STORE BULK
+ sub NBYTE, DST_END, DST
+L(less_m8x4):
+ slli t1, VLEN, 1
+ blt NBYTE, t1, L(less_m8x2)
+ # nbyte >= vlen(m8) * 2
+ # loads
+ vle8.v v0, (SRC)
+ add t1, SRC, VLEN
+ vle8.v v8, (t1)
+ sub t2, SRC_END, VLEN
+ vle8.v v24, (t2)
+ sub t3, t2, VLEN
+ vle8.v v16, (t3)
+ # stores
+ vse8.v v0, (DST)
+ add t1, DST, VLEN
+ vse8.v v8, (t1)
+ sub t2, DST_END, VLEN
+ vse8.v v24, (t2)
+ sub t3, t2, VLEN
+ vse8.v v16, (t3)
+ ret
+L(less_m8x2):
+ blt NBYTE, VLEN, L(less_m8x1)
+ # nbyte >= vlen(m8) * 1
+ # loads
+ vle8.v v0, (SRC)
+ sub t1, SRC_END, VLEN
+ vle8.v v8, (t1)
+ # stores
+ vse8.v v0, (DST)
+ sub t2, DST_END, VLEN
+ vse8.v v8, (t2)
+ ret
+L(less_m8x1):
+ vsetvli VLEN, NBYTE, e8, m8, ta, ma
+ vle8.v v8, (SRC)
+ vse8.v v8, (DST)
+ ret
diff --git a/sysdeps/riscv/multiarch/memcpy.c b/sysdeps/riscv/multiarch/memcpy.c
new file mode 100644
index 0000000000..7c90237ad9
--- /dev/null
+++ b/sysdeps/riscv/multiarch/memcpy.c
@@ -0,0 +1,35 @@
+/* Multiple versions of memcpy.
+ All versions must be listed in ifunc-impl-list.c.
+ Copyright (C) 2017-2022 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
+ <https://www.gnu.org/licenses/>. */
+
+/* Define multiple versions only for the definition in libc. */
+#if IS_IN (libc)
+# define memcpy __redirect_memcpy
+# include <string.h>
+# undef memcpy
+
+# define SYMBOL_NAME memcpy
+# include "ifunc-memcpy.h"
+
+libc_ifunc_redirected (__redirect_memcpy, memcpy, IFUNC_SELECTOR ());
+
+# ifdef SHARED
+__hidden_ver1 (memcpy, __GI_memcpy, __redirect_memcpy)
+ __attribute__ ((visibility ("hidden"))) __attribute_copy__ (memcpy);
+# endif
+#endif
diff --git a/sysdeps/riscv/multiarch/memmove-rvv-vlen.S b/sysdeps/riscv/multiarch/memmove-rvv-vlen.S
new file mode 100644
index 0000000000..edc7a7b0ef
--- /dev/null
+++ b/sysdeps/riscv/multiarch/memmove-rvv-vlen.S
@@ -0,0 +1,110 @@
+/* Copyright (C) 2017-2022 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
+ <https://www.gnu.org/licenses/>. */
+
+ .globl memmove_rvv_vlen
+ .p2align 1
+ .type memmove_rvv_vlen,@function
+# a0: dst a1: src a2: nbyte
+#define DST a5
+#define DST_END a6
+#define SRC a1
+#define SRC_END a4
+#define NBYTE a2
+# utilities
+#define VLEN a3
+#define ALIGN 8
+#define L(label) .memmove_rvv_vlen_##label
+
+memmove_rvv_vlen:
+ # return value
+ mv DST, a0
+ add DST_END, DST, NBYTE
+ add SRC_END, SRC, NBYTE
+# BEGIN overlapping condition
+ sub t0, DST, SRC
+ blt t0, NBYTE, L(overlapping) # use memcpy if dst - src >= nbyte
+ mv s1, ra
+ jal ra, memcpy_rvv
+ mv ra, s1
+ ret
+# END overlapping condition
+# BEGIN small lengths
+ # addi t1, zero, 16
+ # blt NBYTE, t1, L(less_16bytes)
+L(overlapping):
+ addi VLEN, zero, -1
+ vsetvli VLEN, VLEN, e8, m8, ta, ma
+ # blt NBYTE, VLEN, L(less_m8x1)
+ slli t1, VLEN, 2
+ blt NBYTE, t1, L(m8x4_loop_end)
+# END small length
+
+# BEGIN check alignment
+# align on 8B
+# hard to get alignment right
+ # andi t0, DST_END, 7
+ # beqz t0, L(vec_set)
+ # ld t1, -8(SRC_END)
+ # sd t1, -8(DST_END)
+ # sub SRC_END, SRC_END, t0
+ # sub DST_END, DST_END, t0
+# END check alignment
+# BEGIN VEC STORE BULK
+L(vec_set):
+# t0: total vlen * 4 t1: dst_end - total vlen * 4
+ slli t0, VLEN, 2
+ sub t1, DST_END, t0
+ blt t1, DST, L(m8x4_loop_end) # branch if less than total vlen
+# use many t* to exploit data parallelism
+L(m8x4_loop):
+ # loads
+ sub SRC_END, SRC_END, VLEN
+ vle8.v v0, (SRC_END)
+ sub t1, SRC_END, VLEN
+ vle8.v v8, (t1)
+ sub t2, t1, VLEN
+ vle8.v v16, (t2)
+ sub t3, t2, VLEN
+ vle8.v v24, (t3)
+ mv SRC_END, t3
+ # store
+ sub DST_END, DST_END, VLEN
+ vse8.v v0, (DST_END)
+ sub t1, DST_END, VLEN
+ vse8.v v8, (t1)
+ sub t2, t1, VLEN
+ vse8.v v16, (t2)
+ sub t3, t2, VLEN
+ vse8.v v24, (t3)
+ mv DST_END, t3
+ # check loop
+ sub t4, DST_END, t0
+ bge t4, DST, L(m8x4_loop) # branch if less than total vlen
+L(m8x4_loop_end):
+# END VEC STORE BULK
+ sub NBYTE, DST_END, DST
+ mv t1, NBYTE
+L(m8x1_loop):
+ mv NBYTE, t1
+ vsetvli VLEN, NBYTE, e8, m8, ta, ma
+ sub SRC_END, SRC_END, VLEN
+ sub DST_END, DST_END, VLEN
+ vle8.v v0, (SRC_END)
+ vse8.v v0, (DST_END)
+ sub t1, NBYTE, VLEN
+ bnez t1, L(m8x1_loop)
+ ret
diff --git a/sysdeps/riscv/multiarch/memmove-rvv.S b/sysdeps/riscv/multiarch/memmove-rvv.S
new file mode 100644
index 0000000000..8e40352a23
--- /dev/null
+++ b/sysdeps/riscv/multiarch/memmove-rvv.S
@@ -0,0 +1,138 @@
+/* Copyright (C) 2017-2022 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
+ <https://www.gnu.org/licenses/>. */
+
+ .globl memmove_rvv
+ .p2align 1
+ .type memmove_rvv,@function
+# a0: dst a1: src a2: nbyte
+#define DST a5
+#define DST_END a6
+#define SRC a1
+#define SRC_END a4
+#define NBYTE a2
+# utilities
+#define VLEN a3
+#define ALIGN 8
+#define L(label) .memmove_rvv_##label
+
+memmove_rvv:
+ # return value
+ mv DST, a0
+ add DST_END, DST, NBYTE
+ add SRC_END, SRC, NBYTE
+# BEGIN overlapping condition
+ sub t0, DST, SRC
+ blt t0, NBYTE, L(overlapping) # use memcpy if dst - src >= nbyte
+ mv s1, ra
+ jal ra, memcpy_rvv
+ mv ra, s1
+ ret
+# END overlapping condition
+# BEGIN small lengths
+ # addi t1, zero, 16
+ # blt NBYTE, t1, L(less_16bytes)
+L(overlapping):
+ addi VLEN, zero, -1
+ vsetvli VLEN, VLEN, e8, m8, ta, ma
+ # blt NBYTE, VLEN, L(less_m8x1)
+ slli t1, VLEN, 2
+ blt NBYTE, t1, L(less_m8x4)
+# END small length
+
+# BEGIN check alignment
+# align on 8B
+# hard to get alignment right
+ # andi t0, DST_END, 7
+ # beqz t0, L(vec_set)
+ # ld t1, -8(SRC_END)
+ # sd t1, -8(DST_END)
+ # sub SRC_END, SRC_END, t0
+ # sub DST_END, DST_END, t0
+# END check alignment
+# BEGIN VEC STORE BULK
+L(vec_set):
+# t0: total vlen * 4 t1: dst_end - total vlen * 4
+ slli t0, VLEN, 2
+ sub t1, DST_END, t0
+ blt t1, DST, L(m8x4_loop_end) # branch if less than total vlen
+# use many t* to exploit data parallelism
+L(m8x4_loop):
+ # loads
+ sub SRC_END, SRC_END, VLEN
+ vle8.v v0, (SRC_END)
+ sub t1, SRC_END, VLEN
+ vle8.v v8, (t1)
+ sub t2, t1, VLEN
+ vle8.v v16, (t2)
+ sub t3, t2, VLEN
+ vle8.v v24, (t3)
+ mv SRC_END, t3
+ # store
+ sub DST_END, DST_END, VLEN
+ vse8.v v0, (DST_END)
+ sub t1, DST_END, VLEN
+ vse8.v v8, (t1)
+ sub t2, t1, VLEN
+ vse8.v v16, (t2)
+ sub t3, t2, VLEN
+ vse8.v v24, (t3)
+ mv DST_END, t3
+ # check loop
+ sub t4, DST_END, t0
+ bge t4, DST, L(m8x4_loop) # branch if less than total vlen
+L(m8x4_loop_end):
+# END VEC STORE BULK
+ sub NBYTE, DST_END, DST
+L(less_m8x4):
+ slli t1, VLEN, 1
+ blt NBYTE, t1, L(less_m8x2)
+ # nbyte >= vlen(m8) * 2
+ # loads
+ vle8.v v0, (SRC)
+ add t1, SRC, VLEN
+ vle8.v v8, (t1)
+ sub t2, SRC_END, VLEN
+ vle8.v v24, (t2)
+ sub t3, t2, VLEN
+ vle8.v v16, (t3)
+ # stores
+ vse8.v v0, (DST)
+ add t1, DST, VLEN
+ vse8.v v8, (t1)
+ sub t2, DST_END, VLEN
+ vse8.v v24, (t2)
+ sub t3, t2, VLEN
+ vse8.v v16, (t3)
+ ret
+L(less_m8x2):
+ blt NBYTE, VLEN, L(less_m8x1)
+ # nbyte >= vlen(m8) * 1
+ # loads
+ vle8.v v0, (SRC)
+ sub t1, SRC_END, VLEN
+ vle8.v v8, (t1)
+ # stores
+ vse8.v v0, (DST)
+ sub t2, DST_END, VLEN
+ vse8.v v8, (t2)
+ ret
+L(less_m8x1):
+ vsetvli VLEN, NBYTE, e8, m8, ta, ma
+ vle8.v v8, (SRC)
+ vse8.v v8, (DST)
+ ret
+
\ No newline at end of file
diff --git a/sysdeps/riscv/multiarch/memset-rvv-vlen.S b/sysdeps/riscv/multiarch/memset-rvv-vlen.S
new file mode 100644
index 0000000000..2a015b6900
--- /dev/null
+++ b/sysdeps/riscv/multiarch/memset-rvv-vlen.S
@@ -0,0 +1,94 @@
+/* Copyright (C) 2017-2022 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
+ <https://www.gnu.org/licenses/>. */
+ .globl memset_rvv_vlen
+ .p2align 1
+ .type memset_rvv_vlen,@function
+# a0: dst a1: c a2: nbyte
+#define DST a5
+#define DST_END a7
+#define CC a1
+#define NBYTE a2
+# utilities
+#define VLEN a3
+#define A4 a4
+#define A6 a6
+#define ALIGN 8
+#define L(label) .memset_rvv_vlen_##label
+
+memset_rvv_vlen:
+ # return value
+ mv DST, a0
+ add DST_END, DST, NBYTE
+ # to uint8
+ andi CC, CC, 0xff
+ # broadcast in uint64
+ slli t0, CC, 8 # t0 = CC << 8
+ or CC, t0, CC # CC = CC | t0
+ slli t0, CC, 16 # t0 = CC << 16
+ or CC, t0, CC # CC = CC | t0
+ slli t0, CC, 32 # t0 = CC << 32
+ or CC, t0, CC # CC = CC | t0
+# BEGIN small lengths
+ # addi t1, zero, 16
+ # blt NBYTE, t1, L(less_16bytes)
+ addi VLEN, zero, -1
+ vsetvli VLEN, VLEN, e8, m8, ta, ma
+ vmv.v.x v8, CC
+ # blt NBYTE, VLEN, L(less_m8x1)
+ slli t1, VLEN, 2
+ blt NBYTE, t1, L(m8x4_loop_end)
+# END small length
+# nbyte >= vlen x 4
+
+# BEGIN align on 8B
+ andi t0, DST, 7
+ beqz t0, L(vec_set)
+ sub t0, zero, t0
+ addi t0, t0, 8
+ sd CC, (DST)
+ add DST, DST, t0
+# END align on 8B
+# BEGIN VEC STORE BULK
+L(vec_set):
+# t0: total vlen * 4 t1: dst + total vlen * 4
+ slli t0, VLEN, 2
+ add t1, DST, t0
+ blt DST_END, t1, L(m8x4_loop_end) # branch if less than total vlen
+# use many t* to exploit data parallelism
+L(m8x4_loop):
+ vse8.v v8, (DST)
+ add t2, DST, VLEN
+ vse8.v v8, (t2)
+ add t3, t2, VLEN
+ vse8.v v8, (t3)
+ add t4, t3, VLEN
+ vse8.v v8, (t4)
+ add DST, t4, VLEN
+ add t1, DST, t0
+ bge DST_END, t1, L(m8x4_loop) # branch if less than total vlen
+L(m8x4_loop_end):
+# END VEC STORE BULK
+ sub NBYTE, DST_END, DST
+ mv t1, NBYTE
+L(m8x1_loop):
+ mv NBYTE, t1
+ vsetvli t0, NBYTE, e8, m8, ta, ma
+ vse8.v v8, (DST)
+ add DST, DST, t0
+ sub t1, NBYTE, t0
+ bnez t1, L(m8x1_loop)
+ ret
diff --git a/sysdeps/riscv/multiarch/memset-rvv.S b/sysdeps/riscv/multiarch/memset-rvv.S
new file mode 100644
index 0000000000..e516185e61
--- /dev/null
+++ b/sysdeps/riscv/multiarch/memset-rvv.S
@@ -0,0 +1,126 @@
+/* Copyright (C) 2017-2022 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
+ <https://www.gnu.org/licenses/>. */
+
+ .globl memset_rvv
+ .p2align 1
+ .type memset_rvv,@function
+# a0: dst a1: c a2: nbyte
+#define DST a5
+#define DST_END a7
+#define CC a1
+#define NBYTE a2
+# utilities
+#define VLEN a3
+#define A4 a4
+#define A6 a6
+#define ALIGN 8
+#define L(label) .memset_rvv_##label
+
+memset_rvv:
+ # return value
+ mv DST, a0
+ add DST_END, DST, NBYTE
+ # to uint8
+ andi CC, CC, 0xff
+ # broadcast in uint64
+ slli t0, CC, 8 # t0 = CC << 8
+ or CC, t0, CC # CC = CC | t0
+ slli t0, CC, 16 # t0 = CC << 16
+ or CC, t0, CC # CC = CC | t0
+ slli t0, CC, 32 # t0 = CC << 32
+ or CC, t0, CC # CC = CC | t0
+# BEGIN small lengths
+ # addi t1, zero, 16
+ # blt NBYTE, t1, L(less_16bytes)
+ addi VLEN, zero, -1
+ vsetvli VLEN, VLEN, e8, m8, ta, ma
+ vmv.v.x v8, CC
+ blt NBYTE, VLEN, L(less_m8x1)
+ slli t1, VLEN, 2
+ blt NBYTE, t1, L(less_m8x4)
+# END small length
+# nbyte >= vlen x 4
+
+# BEGIN align on 8B
+ andi t0, DST, 7
+ beqz t0, L(vec_set)
+ sub t0, zero, t0
+ addi t0, t0, 8
+ sd CC, (DST)
+ add DST, DST, t0
+# END align on 8B
+# BEGIN VEC STORE BULK
+L(vec_set):
+# t0: total vlen * 4 t1: dst + total vlen * 4
+ slli t0, VLEN, 2
+ add t1, DST, t0
+ blt DST_END, t1, L(m8x4_loop_end) # branch if less than total vlen
+# use many t* to exploit data parallelism
+L(m8x4_loop):
+ vse8.v v8, (DST)
+ add t2, DST, VLEN
+ vse8.v v8, (t2)
+ add t3, t2, VLEN
+ vse8.v v8, (t3)
+ add t4, t3, VLEN
+ vse8.v v8, (t4)
+ add DST, t4, VLEN
+ add t1, DST, t0
+ bge DST_END, t1, L(m8x4_loop) # branch if less than total vlen
+L(m8x4_loop_end):
+# END VEC STORE BULK
+ sub NBYTE, DST_END, DST
+L(less_m8x4):
+ addi t1, zero, 3
+ mul t1, VLEN, t1
+ blt NBYTE, t1, L(less_m8x3)
+ # nbyte >= vlen(m8) * 3
+ # 3 stores followed by an overlap store
+ vse8.v v8, (DST)
+ add t2, DST, VLEN
+ vse8.v v8, (t2)
+ add t3, t2, VLEN
+ vse8.v v8, (t3)
+ # overlap store
+ sub t1, DST_END, VLEN
+ vse8.v v8, (t1)
+ ret
+L(less_m8x3):
+ slli t1, VLEN, 1
+ blt NBYTE, t1, L(less_m8x2)
+ # nbyte >= vlen(m8) * 2
+ # 2 stores followed by an overlap store
+ vse8.v v8, (DST)
+ add DST, DST, VLEN
+ vse8.v v8, (DST)
+ # overlap store
+ sub t1, DST_END, VLEN
+ vse8.v v8, (t1)
+ ret
+L(less_m8x2):
+ blt NBYTE, VLEN, L(less_m8x1)
+ # nbyte >= vlen(m8) * 1
+ # 1 stores followed by an overlap store
+ vse8.v v8, (DST)
+ # overlap store
+ sub t1, DST_END, VLEN
+ vse8.v v8, (t1)
+ ret
+L(less_m8x1):
+ vsetvli VLEN, NBYTE, e8, m8, ta, ma
+ vse8.v v8, (DST)
+ ret
diff --git a/sysdeps/riscv/multiarch/memset.c b/sysdeps/riscv/multiarch/memset.c
new file mode 100644
index 0000000000..7c93360699
--- /dev/null
+++ b/sysdeps/riscv/multiarch/memset.c
@@ -0,0 +1,35 @@
+/* Multiple versions of memset.
+ All versions must be listed in ifunc-impl-list.c.
+ Copyright (C) 2017-2022 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
+ <https://www.gnu.org/licenses/>. */
+
+/* Define multiple versions only for the definition in libc. */
+#if IS_IN (libc)
+# define memset __redirect_memset
+# include <string.h>
+# undef memset
+
+# define SYMBOL_NAME memset
+# include "ifunc-memset.h"
+
+libc_ifunc_redirected (__redirect_memset, memset, IFUNC_SELECTOR ());
+
+# ifdef SHARED
+__hidden_ver1 (memset, __GI_memset, __redirect_memset)
+ __attribute__ ((visibility ("hidden"))) __attribute_copy__ (memset);
+# endif
+#endif
--
2.20.1
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2022-10-31 14:11 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-10-31 14:11 [PATCH] risc-v: Add support on mem* functions with V & B extension 朱娜
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).