[PATCH v2 1/6] RISC-V: memmove() speed optimized: Add implementation

m fally marlene.fally@gmail.com
Tue Jun 17 15:07:30 GMT 2025


Copy the common implementation of memmove() to the RISC-V port.
Rename memmove.S to memmove-asm.S to keep naming of files
consistent between functions. Update Makefile.inc with the changed
filenames.

Reviewed-by: Christian Herber <christian.herber@oss.nxp.com>
Signed-off-by: m fally <marlene.fally@gmail.com>
---
 newlib/libc/machine/riscv/Makefile.inc        |  2 +-
 .../riscv/{memmove.S => memmove-asm.S}        |  0
 newlib/libc/machine/riscv/memmove-stub.c      | 14 ---
 newlib/libc/machine/riscv/memmove.c           | 99 +++++++++++++++++++
 4 files changed, 100 insertions(+), 15 deletions(-)
 rename newlib/libc/machine/riscv/{memmove.S => memmove-asm.S} (100%)
 delete mode 100644 newlib/libc/machine/riscv/memmove-stub.c
 create mode 100644 newlib/libc/machine/riscv/memmove.c

diff --git a/newlib/libc/machine/riscv/Makefile.inc b/newlib/libc/machine/riscv/Makefile.inc
index 85bed9177..3cc6e198f 100644
--- a/newlib/libc/machine/riscv/Makefile.inc
+++ b/newlib/libc/machine/riscv/Makefile.inc
@@ -1,3 +1,3 @@
 libc_a_SOURCES += \
-	%D%/memmove.S %D%/memmove-stub.c %D%/memset.S %D%/memcpy-asm.S %D%/memcpy.c %D%/strlen.c \
+	%D%/memmove-asm.S %D%/memmove.c %D%/memset.S %D%/memcpy-asm.S %D%/memcpy.c %D%/strlen.c \
 	%D%/strcpy.c %D%/stpcpy.c %D%/strcmp.S %D%/memchr.c %D%/memrchr.c %D%/setjmp.S %D%/ieeefp.c %D%/ffs.c
diff --git a/newlib/libc/machine/riscv/memmove.S b/newlib/libc/machine/riscv/memmove-asm.S
similarity index 100%
rename from newlib/libc/machine/riscv/memmove.S
rename to newlib/libc/machine/riscv/memmove-asm.S
diff --git a/newlib/libc/machine/riscv/memmove-stub.c b/newlib/libc/machine/riscv/memmove-stub.c
deleted file mode 100644
index d882e46c1..000000000
--- a/newlib/libc/machine/riscv/memmove-stub.c
+++ /dev/null
@@ -1,14 +0,0 @@
-/* Copyright (c) 2019  SiFive Inc. All rights reserved.
-
-   This copyrighted material is made available to anyone wishing to use,
-   modify, copy, or redistribute it subject to the terms and conditions
-   of the FreeBSD License.   This program is distributed in the hope that
-   it will be useful, but WITHOUT ANY WARRANTY expressed or implied,
-   including the implied warranties of MERCHANTABILITY or FITNESS FOR
-   A PARTICULAR PURPOSE.  A copy of this license is available at
-   http://www.opensource.org/licenses.
-*/
-
-#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
-#include "../../string/memmove.c"
-#endif
diff --git a/newlib/libc/machine/riscv/memmove.c b/newlib/libc/machine/riscv/memmove.c
new file mode 100644
index 000000000..b48da0905
--- /dev/null
+++ b/newlib/libc/machine/riscv/memmove.c
@@ -0,0 +1,99 @@
+/* Copyright (c) 2019  SiFive Inc. All rights reserved.
+
+   This copyrighted material is made available to anyone wishing to use,
+   modify, copy, or redistribute it subject to the terms and conditions
+   of the FreeBSD License.   This program is distributed in the hope that
+   it will be useful, but WITHOUT ANY WARRANTY expressed or implied,
+   including the implied warranties of MERCHANTABILITY or FITNESS FOR
+   A PARTICULAR PURPOSE.  A copy of this license is available at
+   http://www.opensource.org/licenses.
+*/
+
+#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
+/* memmove defined in memmove-asm.S */
+#else
+
+#include "../../string/local.h"
+#include <_ansi.h>
+#include <limits.h>
+#include <stddef.h>
+#include <string.h>
+
+/*SUPPRESS 20*/
+void *__inhibit_loop_to_libcall
+memmove (void *dst_void, const void *src_void, size_t length)
+{
+  char *dst = dst_void;
+  const char *src = src_void;
+  long *aligned_dst;
+  const long *aligned_src;
+
+  if (src < dst && dst < src + length)
+    {
+      /* Destructive overlap...have to copy backwards */
+      src += length;
+      dst += length;
+
+      if (!TOO_SMALL_LITTLE_BLOCK (length) && !UNALIGNED_X_Y (src, dst))
+        {
+          aligned_dst = (long *)dst;
+          aligned_src = (long *)src;
+
+          /* Copy one long word at a time if possible.  */
+          while (!TOO_SMALL_LITTLE_BLOCK (length))
+            {
+              *--aligned_dst = *--aligned_src;
+              length -= LITTLE_BLOCK_SIZE;
+            }
+
+          /* Pick up any residual with a byte copier.  */
+          dst = (char *)aligned_dst;
+          src = (char *)aligned_src;
+        }
+
+      while (length--)
+        {
+          *--dst = *--src;
+        }
+    }
+  else
+    {
+      /* Use optimizing algorithm for a non-destructive copy to closely
+         match memcpy. If the size is small or either SRC or DST is unaligned,
+         then punt into the byte copy loop.  This should be rare.  */
+      if (!TOO_SMALL_LITTLE_BLOCK (length) && !UNALIGNED_X_Y (src, dst))
+        {
+          aligned_dst = (long *)dst;
+          aligned_src = (long *)src;
+
+          /* Copy 4X long words at a time if possible.  */
+          while (!TOO_SMALL_BIG_BLOCK (length))
+            {
+              *aligned_dst++ = *aligned_src++;
+              *aligned_dst++ = *aligned_src++;
+              *aligned_dst++ = *aligned_src++;
+              *aligned_dst++ = *aligned_src++;
+              length -= BIG_BLOCK_SIZE;
+            }
+
+          /* Copy one long word at a time if possible.  */
+          while (!TOO_SMALL_LITTLE_BLOCK (length))
+            {
+              *aligned_dst++ = *aligned_src++;
+              length -= LITTLE_BLOCK_SIZE;
+            }
+
+          /* Pick up any residual with a byte copier.  */
+          dst = (char *)aligned_dst;
+          src = (char *)aligned_src;
+        }
+
+      while (length--)
+        {
+          *dst++ = *src++;
+        }
+    }
+
+  return dst_void;
+}
+#endif
-- 
2.49.0



More information about the Newlib mailing list