]> code.bitgloo.com Git - clyne/osdev.git/commitdiff
use newlib memmove
authorClyne Sullivan <clyne@bitgloo.com>
Sat, 28 Sep 2024 14:28:10 +0000 (10:28 -0400)
committerClyne Sullivan <clyne@bitgloo.com>
Sat, 28 Sep 2024 14:28:10 +0000 (10:28 -0400)
Makefile
kernel.cpp
memmove.cpp [new file with mode: 0644]

index c8fb67f6d04006d0940bac2a3057c95332088dcf..f3674a67774e0eaaf9cf9d5f43bae3a718dfbd36 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -6,6 +6,7 @@ CXXFILES := acpi.cpp \
         gdt.cpp \
         idt.cpp \
         keyboard.cpp \
+        memmove.cpp \
         memory.cpp \
         multiboot.cpp \
         pic.cpp \
index 0cb581ffcca3c6814d43233b4f6c8928aca9f44d..26d5b7dc303f15d054484a0d641805ddf63d6aa1 100644 (file)
@@ -72,13 +72,3 @@ void kernel_main(void)
     }
 }
 
-extern "C"
-void memmove(char* dst, char* src, size_t sz) {
-    while (sz) {
-        *dst = *src;
-        ++dst;
-        ++src;
-        --sz;
-    }
-}
-
diff --git a/memmove.cpp b/memmove.cpp
new file mode 100644 (file)
index 0000000..06e37df
--- /dev/null
@@ -0,0 +1,78 @@
+/* Taken from newlib... */
+
+#include <cstring>
+#include <cstddef>
+#include <climits>
+
+/* Nonzero if either X or Y is not aligned on a "long" boundary.  */
+#define UNALIGNED(X, Y) \
+  (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
+
+/* How many bytes are copied each iteration of the 4X unrolled loop.  */
+#define BIGBLOCKSIZE    (sizeof (long) << 2)
+
+/* How many bytes are copied each iteration of the word copy loop.  */
+#define LITTLEBLOCKSIZE (sizeof (long))
+
+/* Threshhold for punting to the byte copier.  */
+#define TOO_SMALL(LEN)  ((LEN) < BIGBLOCKSIZE)
+
+extern "C"
+void *memmove (void *dst_void, const void *src_void, size_t length)
+{
+  char *dst = reinterpret_cast<char *>(dst_void);
+  const char *src = reinterpret_cast<const char *>(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;
+      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(length) && !UNALIGNED (src, dst))
+        {
+          aligned_dst = (long*)dst;
+          aligned_src = (long*)src;
+
+          /* Copy 4X long words at a time if possible.  */
+          while (length >= BIGBLOCKSIZE)
+            {
+              *aligned_dst++ = *aligned_src++;
+              *aligned_dst++ = *aligned_src++;
+              *aligned_dst++ = *aligned_src++;
+              *aligned_dst++ = *aligned_src++;
+              length -= BIGBLOCKSIZE;
+            }
+
+          /* Copy one long word at a time if possible.  */
+          while (length >= LITTLEBLOCKSIZE)
+            {
+              *aligned_dst++ = *aligned_src++;
+              length -= LITTLEBLOCKSIZE;
+            }
+
+          /* Pick up any residual with a byte copier.  */
+          dst = (char*)aligned_dst;
+          src = (char*)aligned_src;
+        }
+
+      while (length--)
+        {
+          *dst++ = *src++;
+        }
+    }
+
+  return dst_void;
+}
+