blob: f35a771a4e81f7afc09d140604fb1ab7f0586d88 [file] [log] [blame]
From a4cdbc3086708450ae8163a2e2c93ba9b0f631fa Mon Sep 17 00:00:00 2001
From: Alex Van Damme <atv@google.com>
Date: Wed, 27 Mar 2024 07:13:37 +0000
Subject: [PATCH] Add memcpy-kelvin.c
---
newlib/libc/machine/riscv/Makefile.am | 2 +-
newlib/libc/machine/riscv/Makefile.in | 10 ++++-
newlib/libc/machine/riscv/memcpy-asm.S | 2 +-
newlib/libc/machine/riscv/memcpy-kelvin.c | 46 +++++++++++++++++++++++
newlib/libc/machine/riscv/memcpy.c | 2 +-
5 files changed, 57 insertions(+), 5 deletions(-)
create mode 100644 newlib/libc/machine/riscv/memcpy-kelvin.c
diff --git a/newlib/libc/machine/riscv/Makefile.am b/newlib/libc/machine/riscv/Makefile.am
index 017b4be2e..c18f728a1 100644
--- a/newlib/libc/machine/riscv/Makefile.am
+++ b/newlib/libc/machine/riscv/Makefile.am
@@ -8,7 +8,7 @@ AM_CCASFLAGS = $(INCLUDES)
noinst_LIBRARIES = lib.a
-lib_a_SOURCES = memmove.S memmove-stub.c memset.S memcpy-asm.S memcpy.c strlen.c \
+lib_a_SOURCES = memmove.S memmove-stub.c memset.S memcpy-asm.S memcpy.c memcpy-kelvin.c strlen.c \
strcpy.c strcmp.S setjmp.S ieeefp.c ffs.c
lib_a_CCASFLAGS=$(AM_CCASFLAGS)
lib_a_CFLAGS=$(AM_CFLAGS)
diff --git a/newlib/libc/machine/riscv/Makefile.in b/newlib/libc/machine/riscv/Makefile.in
index e6dee8763..0eefef21d 100644
--- a/newlib/libc/machine/riscv/Makefile.in
+++ b/newlib/libc/machine/riscv/Makefile.in
@@ -71,7 +71,7 @@ lib_a_AR = $(AR) $(ARFLAGS)
lib_a_LIBADD =
am_lib_a_OBJECTS = lib_a-memmove.$(OBJEXT) \
lib_a-memmove-stub.$(OBJEXT) lib_a-memset.$(OBJEXT) \
- lib_a-memcpy-asm.$(OBJEXT) lib_a-memcpy.$(OBJEXT) \
+ lib_a-memcpy-asm.$(OBJEXT) lib_a-memcpy.$(OBJEXT) lib_a-memcpy-kelvin.$(OBJEXT) \
lib_a-strlen.$(OBJEXT) lib_a-strcpy.$(OBJEXT) \
lib_a-strcmp.$(OBJEXT) lib_a-setjmp.$(OBJEXT) \
lib_a-ieeefp.$(OBJEXT) lib_a-ffs.$(OBJEXT)
@@ -200,7 +200,7 @@ AUTOMAKE_OPTIONS = cygnus
INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS)
AM_CCASFLAGS = $(INCLUDES)
noinst_LIBRARIES = lib.a
-lib_a_SOURCES = memmove.S memmove-stub.c memset.S memcpy-asm.S memcpy.c strlen.c \
+lib_a_SOURCES = memmove.S memmove-stub.c memset.S memcpy-asm.S memcpy.c memcpy-kelvin.c strlen.c \
strcpy.c strcmp.S setjmp.S ieeefp.c ffs.c
lib_a_CCASFLAGS = $(AM_CCASFLAGS)
@@ -313,6 +313,12 @@ lib_a-memcpy.o: memcpy.c
lib_a-memcpy.obj: memcpy.c
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-memcpy.obj `if test -f 'memcpy.c'; then $(CYGPATH_W) 'memcpy.c'; else $(CYGPATH_W) '$(srcdir)/memcpy.c'; fi`
+lib_a-memcpy-kelvin.o: memcpy-kelvin.c
+ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-memcpy-kelvin.o `test -f 'memcpy-kelvin.c' || echo '$(srcdir)/'`memcpy-kelvin.c
+
+lib_a-memcpy-kelvin.obj: memcpy-kelvin.c
+ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-memcpy-kelvin.obj `if test -f 'memcpy-kelvin.c'; then $(CYGPATH_W) 'memcpy-kelvin.c'; else $(CYGPATH_W) '$(srcdir)/memcpy-kelvin.c'; fi`
+
lib_a-strlen.o: strlen.c
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strlen.o `test -f 'strlen.c' || echo '$(srcdir)/'`strlen.c
diff --git a/newlib/libc/machine/riscv/memcpy-asm.S b/newlib/libc/machine/riscv/memcpy-asm.S
index 5571e4704..2a271b095 100644
--- a/newlib/libc/machine/riscv/memcpy-asm.S
+++ b/newlib/libc/machine/riscv/memcpy-asm.S
@@ -9,7 +9,7 @@
http://www.opensource.org/licenses.
*/
-#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
+#if (defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)) && !defined(__KELVIN__)
.text
.global memcpy
.type memcpy, @function
diff --git a/newlib/libc/machine/riscv/memcpy-kelvin.c b/newlib/libc/machine/riscv/memcpy-kelvin.c
new file mode 100644
index 000000000..6873b56c4
--- /dev/null
+++ b/newlib/libc/machine/riscv/memcpy-kelvin.c
@@ -0,0 +1,46 @@
+#if defined(__KELVIN__)
+
+#define __volatile_always__ volatile
+#define ARGS_F_A(FN, A0) FN " " #A0 "\n"
+#define ARGS_F_A_A(FN, A0, A1) FN " " #A0 ", " #A1 "\n"
+#define ARGS_F_A_A_A(FN, A0, A1, A2) FN " " #A0 ", " #A1 ", " #A2 "\n"
+#define ARGS_F_A_A_A_A(FN, A0, A1, A2, A3) \
+ FN " " #A0 ", " #A1 ", " #A2 ", " #A3 "\n"
+#define getvl_b_x_m(d, s) __asm__ __volatile__(ARGS_F_A_A("getvl.b.x.m", %0, %1) : "=r"(d) : "r"(s))
+#define vld_b_lp_xx_m(Vd, s, t) __asm__ __volatile_always__(ARGS_F_A_A_A("vld.b.lp.xx.m", Vd, %0, %1) : "=r"(s) : "r"(t), "0"(s) : "memory")
+#define vst_b_lp_xx_m(Vd, s, t) __asm__ __volatile_always__(ARGS_F_A_A_A("vst.b.lp.xx.m", Vd, %0, %1) : "=r"(s) : "r"(t), "0"(s) : "memory")
+#define vld_w_x_m(Vd, s) __asm__ __volatile_always__(ARGS_F_A_A("vld.w.x.m", Vd, %0) : : "r"(s) : "memory")
+#define vst_w_x_m(Vd, s) __asm__ __volatile_always__(ARGS_F_A_A("vst.w.x.m", Vd, %0) : : "r"(s) : "memory")
+
+#include <stddef.h>
+#include <stdint.h>
+
+void *
+memcpy(void *__restrict dst, const void *__restrict src, size_t n)
+{
+ const uint8_t *s = (const uint8_t *)(src);
+ uint8_t *d = (uint8_t *)(dst);
+ int vl;
+ // Storage for caller's v0-v7
+ uint32_t spill[8 * 8];
+ vst_w_x_m(v0, spill);
+ vst_w_x_m(v4, spill + 32);
+ while (1) {
+ if (n <= 0) break;
+ getvl_b_x_m(vl, n);
+ n -= vl;
+ vld_b_lp_xx_m(v0, s, vl);
+ vst_b_lp_xx_m(v0, d, vl);
+
+ if (n <= 0) break;
+ getvl_b_x_m(vl, n);
+ n -= vl;
+ vld_b_lp_xx_m(v4, s, vl);
+ vst_b_lp_xx_m(v4, d, vl);
+ }
+ vld_w_x_m(v0, spill);
+ vld_w_x_m(v4, spill + 32);
+ return dst;
+}
+
+#endif // defined(__KELVIN__)
diff --git a/newlib/libc/machine/riscv/memcpy.c b/newlib/libc/machine/riscv/memcpy.c
index 4098f3ab1..4e6c55071 100644
--- a/newlib/libc/machine/riscv/memcpy.c
+++ b/newlib/libc/machine/riscv/memcpy.c
@@ -9,7 +9,7 @@
http://www.opensource.org/licenses.
*/
-#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
+#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__) || defined(__KELVIN__)
//memcpy defined in memcpy-asm.S
#else
--
2.44.0.396.g6e790dbe36-goog