summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlessandro Rubini <rubini@unipv.it>2009-10-10 11:51:05 +0200
committerWolfgang Denk <wd@denx.de>2009-10-18 23:10:37 +0200
commitecd830b863e5c6ac5d804d3b3a92453a98d526fc (patch)
tree8c9d0bb8957f0e54a4759c8e5f80cbbad88f4686
parent9c5586aa19bbedf290d2a663813404d2db87dfa5 (diff)
downloadu-boot-imx-ecd830b863e5c6ac5d804d3b3a92453a98d526fc.zip
u-boot-imx-ecd830b863e5c6ac5d804d3b3a92453a98d526fc.tar.gz
u-boot-imx-ecd830b863e5c6ac5d804d3b3a92453a98d526fc.tar.bz2
lib_generic memcpy: copy one word at a time if possible
If source and destination are aligned, this copies ulong values until possible, trailing part is copied by byte. Thanks for the details to Wolfgang Denk, Mike Frysinger, Peter Tyser, Chris Moore. Signed-off-by: Alessandro Rubini <rubini@unipv.it> Acked-by: Andrea Gallo <andrea.gallo@stericsson.com> Acked-by: Mike Frysinger <vapier@gentoo.org>
-rw-r--r--lib_generic/string.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/lib_generic/string.c b/lib_generic/string.c
index 181eda6..61a45dc 100644
--- a/lib_generic/string.c
+++ b/lib_generic/string.c
@@ -446,12 +446,23 @@ char * bcopy(const char * src, char * dest, int count)
* You should not use this function to access IO space, use memcpy_toio()
* or memcpy_fromio() instead.
*/
-void * memcpy(void * dest,const void *src,size_t count)
+void * memcpy(void *dest, const void *src, size_t count)
{
- char *tmp = (char *) dest, *s = (char *) src;
-
+ unsigned long *dl = (unsigned long *)dest, *sl = (unsigned long *)src;
+ char *d8, *s8;
+
+ /* while all data is aligned (common case), copy a word at a time */
+ if ( (((ulong)dest | (ulong)src) & (sizeof(*dl) - 1)) == 0) {
+ while (count >= sizeof(*dl)) {
+ *dl++ = *sl++;
+ count -= sizeof(*dl);
+ }
+ }
+ /* copy the reset one byte at a time */
+ d8 = (char *)dl;
+ s8 = (char *)sl;
while (count--)
- *tmp++ = *s++;
+ *d8++ = *s8++;
return dest;
}