Commit d8dcc2d8 authored by Willy Tarreau's avatar Willy Tarreau Committed by Paul E. McKenney

tools/nolibc/string: use unidirectional variants for memcpy()

Till now memcpy() relies on memmove(), but it's always included for libgcc,
so we have a larger than needed function. Let's implement two unidirectional
variants to copy from bottom to top and from top to bottom, and use the
former for memcpy(). The variants are optimized to be compact, and at the
same time the compiler is sometimes able to detect the loop and to replace
it with a "rep movsb". The new function is 24 bytes instead of 52 on x86_64.
Signed-off-by: default avatarWilly Tarreau <w@1wt.eu>
Signed-off-by: default avatarPaul E. McKenney <paulmck@kernel.org>
parent 830acd08
......@@ -25,6 +25,28 @@ int memcmp(const void *s1, const void *s2, size_t n)
return c1;
}
static __attribute__((unused))
void *_nolibc_memcpy_up(void *dst, const void *src, size_t len)
{
size_t pos = 0;
while (pos < len) {
((char *)dst)[pos] = ((const char *)src)[pos];
pos++;
}
return dst;
}
static __attribute__((unused))
void *_nolibc_memcpy_down(void *dst, const void *src, size_t len)
{
while (len) {
len--;
((char *)dst)[len] = ((const char *)src)[len];
}
return dst;
}
static __attribute__((unused))
void *memmove(void *dst, const void *src, size_t len)
{
......@@ -42,7 +64,7 @@ void *memmove(void *dst, const void *src, size_t len)
__attribute__((weak,unused))
void *memcpy(void *dst, const void *src, size_t len)
{
return memmove(dst, src, len);
return _nolibc_memcpy_up(dst, src, len);
}
static __attribute__((unused))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment