From: Kevin O'Connor Date: Mon, 20 Apr 2009 00:05:50 +0000 (-0400) Subject: Optimize memcpy. X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;ds=sidebyside;h=5d7b3f628b00710fa8e2b56ef80127e350e49806;p=seabios.git Optimize memcpy. Use __builtin_memcpy on small strings (gcc can inline these well). Use 4-byte copies when applicable - this is important when copying option roms from slow PCI space. --- diff --git a/src/util.c b/src/util.c index 88f134c..a39668b 100644 --- a/src/util.c +++ b/src/util.c @@ -181,12 +181,24 @@ memcpy_far(u16 d_seg, void *d_far, u16 s_seg, const void *s_far, size_t len) : "cc", "memory"); } -void * -memcpy(void *d1, const void *s1, size_t len) +noinline void * +__memcpy(void *d1, const void *s1, size_t len) { - u8 *d = (u8*)d1, *s = (u8*)s1; - while (len--) - *d++ = *s++; + void *d = d1; + if (((u32)d1 | (u32)s1 | len) & 3) { + // non-aligned memcpy + asm volatile( + "rep movsb (%%esi),%%es:(%%edi)\n" + : "+c"(len), "+S"(s1), "+D"(d) + : : "cc", "memory"); + return d1; + } + // Common case - use 4-byte copy + len /= 4; + asm volatile( + "rep movsl (%%esi),%%es:(%%edi)\n" + : "+c"(len), "+S"(s1), "+D"(d) + : : "cc", "memory"); return d1; } diff --git a/src/util.h b/src/util.h index f260e27..ceb775e 100644 --- a/src/util.h +++ b/src/util.h @@ -73,7 +73,11 @@ int memcmp(const void *s1, const void *s2, size_t n); size_t strlen(const char *s); int strcmp(const char *s1, const char *s2); void *memset(void *s, int c, size_t n); -void *memcpy(void *d1, const void *s1, size_t len); +void *__memcpy(void *d1, const void *s1, size_t len); +#define memcpy(d1, s1, len) ( \ + (__builtin_constant_p(len) && (len) <= 20) \ + ? __builtin_memcpy((d1), (s1), (len)) \ + : __memcpy((d1), (s1), (len))) inline void memcpy_far(u16 d_seg, void *d_far , u16 s_seg, const void *s_far, size_t len); void *memmove(void *d, const void *s, size_t len);