summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Delaunay <patrick.delaunay@foss.st.com>2020-12-11 14:59:23 +0100
committerTom Rini <trini@konsulko.com>2021-01-16 14:49:09 -0500
commit976a68a20d366e6497253bad9fe0d7a8e42a611c (patch)
treef4b242d831693ea73264ed44cb06d6f0912e83d4
parent67b2ed024373f830ffe10fd19b2533d093664ec8 (diff)
downloadu-boot-976a68a20d366e6497253bad9fe0d7a8e42a611c.tar.gz
u-boot-976a68a20d366e6497253bad9fe0d7a8e42a611c.tar.bz2
u-boot-976a68a20d366e6497253bad9fe0d7a8e42a611c.zip
string: Use memcpy() within memmove() when we can
A common use of memmove() can be handled by memcpy(). Also memcpy() includes an optimization for large sizes: it copies a word at a time. So we can get a speed-up by calling memcpy() to handle our move in this case. Update memmove() to call also memcpy() if the source don't overlap the destination (src + count <= dest). Signed-off-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
-rw-r--r--lib/string.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/lib/string.c b/lib/string.c
index ae7835f600..73b984123d 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -567,7 +567,19 @@ void * memmove(void * dest,const void *src,size_t count)
{
char *tmp, *s;
- if (dest <= src) {
+ if (dest <= src || (src + count) <= dest) {
+ /*
+ * Use the fast memcpy implementation (ARCH optimized or lib/string.c) when it is possible:
+ * - when dest is before src (assuming that memcpy is doing forward-copying)
+ * - when destination don't overlap the source buffer (src + count <= dest)
+ *
+ * WARNING: the first optimisation cause an issue, when __HAVE_ARCH_MEMCPY is defined,
+ * __HAVE_ARCH_MEMMOVE is not defined and if the memcpy ARCH-specific
+ * implementation is not doing a forward-copying.
+ *
+ * No issue today because memcpy is doing a forward-copying in lib/string.c and for ARM32
+ * architecture; no other arches use __HAVE_ARCH_MEMCPY without __HAVE_ARCH_MEMMOVE.
+ */
memcpy(dest, src, count);
} else {
tmp = (char *) dest + count;