diff options
author | Andreas Kling <awesomekling@gmail.com> | 2019-01-12 18:13:21 +0100 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-01-12 18:14:40 +0100 |
commit | 24b2cadb82bd59137955ce72be3c73aa6503aa2e (patch) | |
tree | 6665b4b47195db81ec39932e72c31c31fdbc6ae3 /Kernel | |
parent | 20156f9ec54e45a65bbb7c8765710d7027ee1c1d (diff) | |
download | serenity-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.cpp | 43 |
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; } |