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 <mlhx@google.com>
This commit is contained in:
parent
395b0c3a24
commit
5d55730cf6
2 changed files with 12 additions and 0 deletions
|
@ -138,6 +138,13 @@ config MINIMAL_LIBC_LL_PRINTF
|
||||||
Build with long long printf enabled. This will increase the size of
|
Build with long long printf enabled. This will increase the size of
|
||||||
the image.
|
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
|
endif # MINIMAL_LIBC
|
||||||
|
|
||||||
config STDOUT_CONSOLE
|
config STDOUT_CONSOLE
|
||||||
|
|
|
@ -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;
|
unsigned char *d_byte = (unsigned char *)d;
|
||||||
const unsigned char *s_byte = (const unsigned char *)s;
|
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;
|
const uintptr_t mask = sizeof(mem_word_t) - 1;
|
||||||
|
|
||||||
if ((((uintptr_t)d ^ (uintptr_t)s_byte) & mask) == 0) {
|
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;
|
d_byte = (unsigned char *)d_word;
|
||||||
s_byte = (unsigned char *)s_word;
|
s_byte = (unsigned char *)s_word;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* do byte-sized copying until finished */
|
/* 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 *d_byte = (unsigned char *)buf;
|
||||||
unsigned char c_byte = (unsigned char)c;
|
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)) {
|
while (((uintptr_t)d_byte) & (sizeof(mem_word_t) - 1)) {
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
return buf;
|
return buf;
|
||||||
|
@ -380,6 +384,7 @@ void *memset(void *buf, int c, size_t n)
|
||||||
/* do byte-sized initialization until finished */
|
/* do byte-sized initialization until finished */
|
||||||
|
|
||||||
d_byte = (unsigned char *)d_word;
|
d_byte = (unsigned char *)d_word;
|
||||||
|
#endif
|
||||||
|
|
||||||
while (n > 0) {
|
while (n > 0) {
|
||||||
*(d_byte++) = c_byte;
|
*(d_byte++) = c_byte;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue