When both "dest" and "src" are aligned, copying the data in chunks (unsigned long) is more efficient than a byte-by-byte copy.
Also tweak '__aeabi_memcpy()', '__aeabi_memcpy4()', and '__aeabi_memcpy8()', since 'grub_memcpy()' is not inline anymore. Signed-off-by: Gary Lin <g...@suse.com> --- grub-core/kern/compiler-rt.c | 8 ++++---- grub-core/kern/misc.c | 30 ++++++++++++++++++++++++++++++ include/grub/misc.h | 8 +------- 3 files changed, 35 insertions(+), 11 deletions(-) diff --git a/grub-core/kern/compiler-rt.c b/grub-core/kern/compiler-rt.c index eda689a0c..8f3865e95 100644 --- a/grub-core/kern/compiler-rt.c +++ b/grub-core/kern/compiler-rt.c @@ -24,7 +24,7 @@ void * GRUB_BUILTIN_ATTR memcpy (void *dest, const void *src, grub_size_t n) { - return grub_memmove (dest, src, n); + return grub_memcpy (dest, src, n); } void * GRUB_BUILTIN_ATTR memmove (void *dest, const void *src, grub_size_t n) @@ -372,11 +372,11 @@ grub_int32_t __aeabi_idiv (grub_int32_t a, grub_int32_t b) __attribute__ ((alias ("__divsi3"))); void *__aeabi_memcpy (void *dest, const void *src, grub_size_t n) - __attribute__ ((alias ("grub_memcpy"))); + __attribute__ ((alias ("memcpy"))); void *__aeabi_memcpy4 (void *dest, const void *src, grub_size_t n) - __attribute__ ((alias ("grub_memcpy"))); + __attribute__ ((alias ("memcpy"))); void *__aeabi_memcpy8 (void *dest, const void *src, grub_size_t n) - __attribute__ ((alias ("grub_memcpy"))); + __attribute__ ((alias ("memcpy"))); void *__aeabi_memset (void *s, int c, grub_size_t n) __attribute__ ((alias ("memset"))); diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c index 2b7922393..016932583 100644 --- a/grub-core/kern/misc.c +++ b/grub-core/kern/misc.c @@ -99,6 +99,36 @@ grub_memmove (void *dest, const void *src, grub_size_t n) return dest; } +static void * +__memcpy_aligned (void *dest, const void *src, grub_size_t n) +{ + unsigned long *dw = (unsigned long *) dest; + const unsigned long *sw = (const unsigned long *) src; + grub_uint8_t *d; + const grub_uint8_t *s; + + for (; n >= sizeof (unsigned long); n -= sizeof (unsigned long)) + *dw++ = *sw++; + + d = (grub_uint8_t *) dw; + s = (const grub_uint8_t *) sw; + for (; n > 0; n--) + *d++ = *s++; + + return dest; +} + +void * +grub_memcpy (void *dest, const void *src, grub_size_t n) +{ + /* Check if 'dest' and 'src' are aligned */ + if (((grub_addr_t) dest & (sizeof (unsigned long) - 1)) == 0 && + ((grub_addr_t) src & (sizeof (unsigned long) - 1)) == 0) + return __memcpy_aligned (dest, src, n); + + return grub_memmove (dest, src, n); +} + char * grub_strcpy (char *dest, const char *src) { diff --git a/include/grub/misc.h b/include/grub/misc.h index e087e7b3e..b6b14ca55 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -38,6 +38,7 @@ #define grub_dprintf(condition, ...) grub_real_dprintf(GRUB_FILE, __LINE__, condition, __VA_ARGS__) void *EXPORT_FUNC(grub_memmove) (void *dest, const void *src, grub_size_t n); +void *EXPORT_FUNC(grub_memcpy) (void *dest, const void *src, grub_size_t n); char *EXPORT_FUNC(grub_strcpy) (char *dest, const char *src); static inline char * @@ -103,13 +104,6 @@ grub_strlcpy (char *dest, const char *src, grub_size_t size) return res; } -/* XXX: If grub_memmove is too slow, we must implement grub_memcpy. */ -static inline void * -grub_memcpy (void *dest, const void *src, grub_size_t n) -{ - return grub_memmove (dest, src, n); -} - #if defined(__x86_64__) && !defined (GRUB_UTIL) #if defined (__MINGW32__) || defined (__CYGWIN__) || defined (__MINGW64__) #define GRUB_ASM_ATTR __attribute__ ((sysv_abi)) -- 2.51.0 _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel