summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibC
diff options
context:
space:
mode:
authorHendiadyoin1 <leon2002.la@gmail.com>2021-04-07 15:11:13 +0200
committerAndreas Kling <kling@serenityos.org>2021-04-08 23:57:16 +0200
commite8ef10e2a6364889dc090f34a153cbbf26a8a6bc (patch)
tree5c7b7b9a0bf67506fddb822f9c067e5beb72b397 /Userland/Libraries/LibC
parent74de4795dcabf8d5bbea7390045a56ced8d2de51 (diff)
downloadserenity-e8ef10e2a6364889dc090f34a153cbbf26a8a6bc.zip
Kernel/LibC: Make memset implementations the same
I dont know why we do a fast path in the Kernel, but not in Userspace Also simplified the byte explosion in memset to "explode_byte" it even seemed so, that we missed the highest byte when memseting something
Diffstat (limited to 'Userland/Libraries/LibC')
-rw-r--r--Userland/Libraries/LibC/string.cpp21
1 files changed, 17 insertions, 4 deletions
diff --git a/Userland/Libraries/LibC/string.cpp b/Userland/Libraries/LibC/string.cpp
index 86a72b72a9..596e04c95e 100644
--- a/Userland/Libraries/LibC/string.cpp
+++ b/Userland/Libraries/LibC/string.cpp
@@ -142,13 +142,26 @@ void* memcpy(void* dest_ptr, const void* src_ptr, size_t n)
void* memset(void* dest_ptr, int c, size_t n)
{
- void* original_dest = dest_ptr;
+ size_t dest = (size_t)dest_ptr;
+ // FIXME: Support starting at an unaligned address.
+ if (!(dest & 0x3) && n >= 12) {
+ size_t size_ts = n / sizeof(size_t);
+ size_t expanded_c = explode_byte((u8)c);
+ asm volatile(
+ "rep stosl\n"
+ : "=D"(dest)
+ : "D"(dest), "c"(size_ts), "a"(expanded_c)
+ : "memory");
+ n -= size_ts * sizeof(size_t);
+ if (n == 0)
+ return dest_ptr;
+ }
asm volatile(
"rep stosb\n"
- : "=D"(dest_ptr), "=c"(n)
- : "0"(dest_ptr), "1"(n), "a"(c)
+ : "=D"(dest), "=c"(n)
+ : "0"(dest), "1"(n), "a"(c)
: "memory");
- return original_dest;
+ return dest_ptr;
}
#else
void* memcpy(void* dest_ptr, const void* src_ptr, size_t n)