summaryrefslogtreecommitdiff
path: root/Kernel
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-01-12 18:13:21 +0100
committerAndreas Kling <awesomekling@gmail.com>2019-01-12 18:14:40 +0100
commit24b2cadb82bd59137955ce72be3c73aa6503aa2e (patch)
tree6665b4b47195db81ec39932e72c31c31fdbc6ae3 /Kernel
parent20156f9ec54e45a65bbb7c8765710d7027ee1c1d (diff)
downloadserenity-24b2cadb82bd59137955ce72be3c73aa6503aa2e.zip
Make the kernel's memcpy() and memset() go fast with dword copies.
Also I learned that the ABI allows us to assume DF=0 on function entry.
Diffstat (limited to 'Kernel')
-rw-r--r--Kernel/StdLib.cpp43
1 files changed, 36 insertions, 7 deletions
diff --git a/Kernel/StdLib.cpp b/Kernel/StdLib.cpp
index 279f00214b..655fab3c6a 100644
--- a/Kernel/StdLib.cpp
+++ b/Kernel/StdLib.cpp
@@ -5,12 +5,27 @@
extern "C" {
-void memcpy(void *dest, const void *src, dword n)
+void memcpy(void *dest_ptr, const void *src_ptr, dword n)
{
- byte* bdest = (byte*)dest;
- const byte* bsrc = (const byte*)src;
- for (; n; --n)
- *(bdest++) = *(bsrc++);
+ dword dest = (dword)dest_ptr;
+ dword src = (dword)src_ptr;
+ if (n >= 12) {
+ size_t dwords = n / sizeof(dword);
+ asm volatile(
+ "rep movsl\n"
+ : "=S"(src), "=D"(dest)
+ : "S"(src), "D"(dest), "c"(dwords)
+ : "memory"
+ );
+ n -= dwords * sizeof(dword);
+ if (n == 0)
+ return;
+ }
+ asm volatile(
+ "rep movsb\n"
+ :: "S"(src), "D"(dest), "c"(n)
+ : "memory"
+ );
}
void strcpy(char* dest, const char *src)
@@ -21,12 +36,26 @@ void strcpy(char* dest, const char *src)
void* memset(void* dest_ptr, byte c, dword n)
{
dword dest = (dword)dest_ptr;
+ if (n >= 12) {
+ size_t dwords = n / sizeof(dword);
+ dword expanded_c = c;
+ expanded_c <<= 8;
+ expanded_c <<= 16;
+ asm volatile(
+ "rep stosl\n"
+ : "=D"(dest)
+ : "D"(dest), "c"(dwords), "a"(expanded_c)
+ : "memory"
+ );
+ n -= dwords * sizeof(dword);
+ if (n == 0)
+ return dest_ptr;
+ }
asm volatile(
- "cld\n"
"rep stosb\n"
: "=D" (dest), "=c" (n)
: "0" (dest), "1" (n), "a" (c)
- : "cc", "memory"
+ : "memory"
);
return dest_ptr;
}