From 88ac32e3bb96d29553ee04923156d5fa4baa8c92 Mon Sep 17 00:00:00 2001 From: Sebastian Sumpf Date: Thu, 2 Aug 2012 16:39:16 +0200 Subject: [PATCH] Base: New 'memcpy' implementation Added CPU specific memcpy function ('memcpy_cpu'), which is tried first in default 'memcpy'. Improved default 'memcpy' to copy eight byte chunks. --- base/include/arm/cpu/string.h | 56 +++++++++++++++++++++++++++++++++++ base/include/util/string.h | 24 ++++++++++++--- base/include/x86/cpu/string.h | 32 ++++++++++++++++++++ 3 files changed, 108 insertions(+), 4 deletions(-) create mode 100644 base/include/arm/cpu/string.h create mode 100644 base/include/x86/cpu/string.h diff --git a/base/include/arm/cpu/string.h b/base/include/arm/cpu/string.h new file mode 100644 index 0000000000..7b37d8d122 --- /dev/null +++ b/base/include/arm/cpu/string.h @@ -0,0 +1,56 @@ +/* + * \brief Cpu specifi memcpy + * \author Sebastian Sumpf + * \author Stefan Kalkowski + * \date 2012-08-02 + */ + +/* + * Copyright (C) 2012 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _INCLUDE__ARM__CPU__STRING_H_ +#define _INCLUDE__ARM__CPU__STRING_H_ + +namespace Genode +{ + /** + * Copy memory block + * + * \param dst destination memory block + * \param src source memory block + * \param size number of bytes to copy + * + * \return Number of bytes not copied + */ + inline size_t memcpy_cpu(void *dst, const void *src, size_t size) + { + unsigned char *d = (unsigned char *)dst, *s = (unsigned char *)src; + + /* check 4 byte; alignment */ + size_t d_align = (size_t)d & 0x3; + size_t s_align = (size_t)s & 0x3; + + /* at least 32 bytes, 4 byte aligned, same alignment */ + if (size < 32 || (d_align | s_align) || (d_align ^ s_align)) + return size; + + /* copy to 4 byte alignment */ + for (size_t i = 0; i < s_align; i++, *d++ = *s++, size--); + + /* copy 32 byte chunks */ + for (; size >= 32; size -= 32) { + asm volatile ("ldmia %0!, {r3 - r10} \n\t" + "stmia %1!, {r3 - r10} \n\t" + : "+r" (s), "+r" (d) + :: "r3","r4","r5","r6","r7","r8","r9","r10"); + } + + return size; + } +} + +#endif /* _INCLUDE__ARM__CPU__STRING_H_ */ diff --git a/base/include/util/string.h b/base/include/util/string.h index a96a32924c..b43b5f19e3 100644 --- a/base/include/util/string.h +++ b/base/include/util/string.h @@ -1,6 +1,7 @@ /* * \brief String utility functions * \author Norman Feske + * \author Sebastian Sumpf * \date 2006-05-10 */ @@ -16,6 +17,7 @@ #include #include +#include namespace Genode { @@ -61,10 +63,24 @@ namespace Genode { char *d = (char *)dst, *s = (char *)src; size_t i; - if (s > d) - for (i = 0; i < size; i++, *d++ = *s++); - else - for (d += size, s += size, i = size; i-- > 0; *(--d) = *(--s)); + /* try cpu specific version first */ + if ((i = size - memcpy_cpu(dst, src, size)) == size) + return dst; + + d += i; s += i; size -= i; + + /* copy eight byte chunks */ + for (i = size >> 3; i > 0; i--, *d++ = *s++, + *d++ = *s++, + *d++ = *s++, + *d++ = *s++, + *d++ = *s++, + *d++ = *s++, + *d++ = *s++, + *d++ = *s++); + + /* copy left over */ + for (i = 0; i < (size & 0x7); i++, *d++ = *s++); return dst; } diff --git a/base/include/x86/cpu/string.h b/base/include/x86/cpu/string.h new file mode 100644 index 0000000000..a25e7b096d --- /dev/null +++ b/base/include/x86/cpu/string.h @@ -0,0 +1,32 @@ +/* + * \brief Cpu specifi memcpy + * \author Sebastian Sumpf + * \date 2012-08-02 + */ + +/* + * Copyright (C) 2012 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _INCLUDE__X86__CPU__STRING_H_ +#define _INCLUDE__X86__CPU__STRING_H_ + +namespace Genode +{ + /** + * Copy memory block + * + * \param dst destination memory block + * \param src source memory block + * \param size number of bytes to copy + * + * \return Number of bytes not copied + */ + inline size_t memcpy_cpu(void *dst, const void *src, size_t size) { + return size; } +} + +#endif /* _INCLUDE__X86__CPU__STRING_H_ */