1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 19:17:44 +00:00

Let's do dword-at-a-time memcpy() and memset() in userspace as well.

Also fix a dumb bug that showed up when I was memsetting something other
than zeroes.
This commit is contained in:
Andreas Kling 2019-01-15 08:14:08 +01:00
parent a8e42bacf4
commit 14712ad9c5
3 changed files with 55 additions and 17 deletions

View file

@ -41,8 +41,8 @@ void* memset(void* dest_ptr, byte c, dword n)
if (!(dest & 0x3) && n >= 12) { if (!(dest & 0x3) && n >= 12) {
size_t dwords = n / sizeof(dword); size_t dwords = n / sizeof(dword);
dword expanded_c = c; dword expanded_c = c;
expanded_c <<= 8; expanded_c |= expanded_c << 8;
expanded_c <<= 16; expanded_c |= expanded_c << 16;
asm volatile( asm volatile(
"rep stosl\n" "rep stosl\n"
: "=D"(dest) : "=D"(dest)

View file

@ -3,6 +3,7 @@
#include <stdio.h> #include <stdio.h>
#include <signal.h> #include <signal.h>
#include <assert.h> #include <assert.h>
#include <AK/Types.h>
extern "C" { extern "C" {
@ -16,14 +17,6 @@ void bcopy(const void* src, void* dest, size_t n)
memmove(dest, src, n); memmove(dest, src, n);
} }
void* memset(void* dest, int c, size_t n)
{
uint8_t* bdest = (uint8_t*)dest;
for (; n; --n)
*(bdest++) = c;
return dest;
}
size_t strspn(const char* s, const char* accept) size_t strspn(const char* s, const char* accept)
{ {
const char* p = s; const char* p = s;
@ -90,15 +83,60 @@ int memcmp(const void* v1, const void* v2, size_t n)
return 0; return 0;
} }
void* memcpy(void* dest, const void* src, size_t n) void* memcpy(void *dest_ptr, const void *src_ptr, dword n)
{ {
auto* bdest = (unsigned char*)dest; dword dest = (dword)dest_ptr;
auto* bsrc = (const unsigned char*)src; dword src = (dword)src_ptr;
for (; n; --n) // FIXME: Support starting at an unaligned address.
*(bdest++) = *(bsrc++); if (!(dest & 0x3) && !(src & 0x3) && n >= 12) {
return dest; 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 dest_ptr;
}
asm volatile(
"rep movsb\n"
:: "S"(src), "D"(dest), "c"(n)
: "memory"
);
return dest_ptr;
} }
void* memset(void* dest_ptr, int c, dword n)
{
dword dest = (dword)dest_ptr;
// FIXME: Support starting at an unaligned address.
if (!(dest & 0x3) && n >= 12) {
size_t dwords = n / sizeof(dword);
dword expanded_c = (byte)c;
expanded_c |= expanded_c << 8;
expanded_c |= 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(
"rep stosb\n"
: "=D" (dest), "=c" (n)
: "0" (dest), "1" (n), "a" (c)
: "memory"
);
return dest_ptr;
}
void* memmove(void* dest, const void* src, size_t n) void* memmove(void* dest, const void* src, size_t n)
{ {
if (dest < src) if (dest < src)

View file

@ -97,7 +97,7 @@ void Painter::draw_glyph(const Point& point, char ch, Color color)
{ {
auto* bitmap = font().glyphBitmap(ch); auto* bitmap = font().glyphBitmap(ch);
if (!bitmap) { if (!bitmap) {
dbgprintf("Font doesn't have 0x%02x ('%c')\n", (byte)ch, ch); dbgprintf("Font doesn't have 0x%b ('%c')\n", (byte)ch, ch);
ASSERT_NOT_REACHED(); ASSERT_NOT_REACHED();
} }
int x = point.x(); int x = point.x();