From 5d55730cf69dac7c8f99dcb17b04307cd050948c Mon Sep 17 00:00:00 2001 From: Michael Hope Date: Fri, 25 Jun 2021 20:17:36 +0200 Subject: [PATCH] libc: minimal: add size optimized string functions The current implementations of memcpy and memset are optimized for performance and use a word based loop before the byte based loop. Add a config option that skips the word based loop. This saves 120 bytes on the Cortex-M0+ which is worthwhile on small apps like a bootloader. Enable by default if SIZE_OPTIMIZATIONS is set. Signed-off-by: Michael Hope --- lib/libc/Kconfig | 7 +++++++ lib/libc/minimal/source/string/string.c | 5 +++++ 2 files changed, 12 insertions(+) diff --git a/lib/libc/Kconfig b/lib/libc/Kconfig index d167d7221ac..b0b22f4f1b8 100644 --- a/lib/libc/Kconfig +++ b/lib/libc/Kconfig @@ -138,6 +138,13 @@ config MINIMAL_LIBC_LL_PRINTF Build with long long printf enabled. This will increase the size of the image. +config MINIMAL_LIBC_OPTIMIZE_STRING_FOR_SIZE + bool "Use size optimized string functions" + default y if SIZE_OPTIMIZATIONS + help + Enable smaller but potentially slower implementations of memcpy and + memset. On the Cortex-M0+ this reduces the total code size by 120 bytes. + endif # MINIMAL_LIBC config STDOUT_CONSOLE diff --git a/lib/libc/minimal/source/string/string.c b/lib/libc/minimal/source/string/string.c index 20996e478b3..1f889e9cc08 100644 --- a/lib/libc/minimal/source/string/string.c +++ b/lib/libc/minimal/source/string/string.c @@ -301,6 +301,8 @@ void *memcpy(void *_MLIBC_RESTRICT d, const void *_MLIBC_RESTRICT s, size_t n) unsigned char *d_byte = (unsigned char *)d; const unsigned char *s_byte = (const unsigned char *)s; + +#if !defined(CONFIG_MINIMAL_LIBC_OPTIMIZE_STRING_FOR_SIZE) const uintptr_t mask = sizeof(mem_word_t) - 1; if ((((uintptr_t)d ^ (uintptr_t)s_byte) & mask) == 0) { @@ -328,6 +330,7 @@ void *memcpy(void *_MLIBC_RESTRICT d, const void *_MLIBC_RESTRICT s, size_t n) d_byte = (unsigned char *)d_word; s_byte = (unsigned char *)s_word; } +#endif /* do byte-sized copying until finished */ @@ -353,6 +356,7 @@ void *memset(void *buf, int c, size_t n) unsigned char *d_byte = (unsigned char *)buf; unsigned char c_byte = (unsigned char)c; +#if !defined(CONFIG_MINIMAL_LIBC_OPTIMIZE_STRING_FOR_SIZE) while (((uintptr_t)d_byte) & (sizeof(mem_word_t) - 1)) { if (n == 0) { return buf; @@ -380,6 +384,7 @@ void *memset(void *buf, int c, size_t n) /* do byte-sized initialization until finished */ d_byte = (unsigned char *)d_word; +#endif while (n > 0) { *(d_byte++) = c_byte;