From d24bf915745de8e2c99e565c94d59a64ba24648c Mon Sep 17 00:00:00 2001 From: patacongo Date: Sun, 21 Oct 2012 01:31:56 +0000 Subject: [PATCH] Optimized memset() can be configured to do 64-bit stores git-svn-id: http://svn.code.sf.net/p/nuttx/code/trunk@5243 42af7a65-404d-4744-a932-0658087f49c3 --- nuttx/ChangeLog | 2 + nuttx/Documentation/NuttxPortingGuide.html | 12 +++- nuttx/configs/README.txt | 7 +- nuttx/lib/Kconfig | 7 ++ nuttx/lib/string/lib_memmove.c | 13 ++-- nuttx/lib/string/lib_memset.c | 80 ++++++++++++++++++---- 6 files changed, 100 insertions(+), 21 deletions(-) diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog index 82a4fd0926..44f38ee10a 100644 --- a/nuttx/ChangeLog +++ b/nuttx/ChangeLog @@ -3494,3 +3494,5 @@ * lib/strings/lib_memset.c: CONFIG_MEMSET_OPTSPEED will select a version of memset() optimized for speed. By default, memset() is optimized for size. + * lib/strings/lib_memset.c: CONFIG_MEMSET_64BIT will perform 64-bit + aligned memset() operations. diff --git a/nuttx/Documentation/NuttxPortingGuide.html b/nuttx/Documentation/NuttxPortingGuide.html index e43ca8a2fa..08c6534cb4 100644 --- a/nuttx/Documentation/NuttxPortingGuide.html +++ b/nuttx/Documentation/NuttxPortingGuide.html @@ -4457,7 +4457,7 @@ build

- And if CONFIG_MEMCPY_VIK, the following tuning options are available: + And if CONFIG_MEMCPY_VIK is selected, the following tuning options are available:

  • @@ -4483,6 +4483,14 @@ build Default: memset() is optimized for size.
  • +

    + And if CONFIG_MEMSET_OPTSPEED is selected, the following tuning option is available: +

    + +
  • The architecture may provide custom versions of certain standard header files: diff --git a/nuttx/configs/README.txt b/nuttx/configs/README.txt index 0bb531d67a..9714b0228c 100644 --- a/nuttx/configs/README.txt +++ b/nuttx/configs/README.txt @@ -628,7 +628,7 @@ defconfig -- This is a configuration file similar to the Linux function by Daniel Vik. See licensing information in the top-level COPYING file. Default: n - And if CONFIG_MEMCPY_VIK, the following tuning options are available: + And if CONFIG_MEMCPY_VIK is selected, the following tuning options are available: CONFIG_MEMCPY_PRE_INC_PTRS - Use pre-increment of pointers. Default is post increment of pointers. @@ -644,6 +644,11 @@ defconfig -- This is a configuration file similar to the Linux CONFIG_MEMSET_OPTSPEED - Select this option to use a version of memcpy() optimized for speed. Default: memcpy() is optimized for size. + And if CONFIG_MEMSET_OPTSPEED is selected, the following tuning option is + available: + + CONFIG_MEMSET_64BIT - Compiles memset() for 64 bit architectures + The architecture may provide custom versions of certain standard header files: diff --git a/nuttx/lib/Kconfig b/nuttx/lib/Kconfig index 0f25c89238..80c584ce92 100644 --- a/nuttx/lib/Kconfig +++ b/nuttx/lib/Kconfig @@ -219,6 +219,13 @@ config MEMSET_OPTSPEED Select this option to use a version of memcpy() optimized for speed. Default: memcpy() is optimized for size. +config MEMSET_64BIT + bool "64-bit memset()" + default n + depends on MEMSET_OPTSPEED + ---help--- + Compiles memset() for 64 bit architectures + config ARCH_STRCMP bool "strcmp()" default n diff --git a/nuttx/lib/string/lib_memmove.c b/nuttx/lib/string/lib_memmove.c index ecaeb54cf2..85cb79e174 100644 --- a/nuttx/lib/string/lib_memmove.c +++ b/nuttx/lib/string/lib_memmove.c @@ -56,17 +56,22 @@ void *memmove(void *dest, const void *src, size_t count) if (dest <= src) { tmp = (char*) dest; - s = (char*) src; + s = (char*) src; while (count--) - *tmp++ = *s++; + { + *tmp++ = *s++; + } } else { tmp = (char*) dest + count; - s = (char*) src + count; + s = (char*) src + count; while (count--) - *--tmp = *--s; + { + *--tmp = *--s; + } } + return dest; } #endif diff --git a/nuttx/lib/string/lib_memset.c b/nuttx/lib/string/lib_memset.c index c910d2ce04..2828f1ff86 100644 --- a/nuttx/lib/string/lib_memset.c +++ b/nuttx/lib/string/lib_memset.c @@ -1,4 +1,5 @@ -/************************************************************ + +/**************************************************************************** * lib/string/lib_memset.c * * Copyright (C) 2007, 2011 Gregory Nutt. All rights reserved. @@ -31,15 +32,12 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************/ + ****************************************************************************/ -/************************************************************ - * Compilation Switches - ************************************************************/ -/************************************************************ +/**************************************************************************** * Included Files - ************************************************************/ + ****************************************************************************/ #include @@ -49,9 +47,21 @@ #include #include -/************************************************************ +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Can't support CONFIG_MEMSET_64BIT if the platform does not have 64-bit + * integer types. + */ + +#ifndef CONFIG_HAVE_LONG_LONG +# undef CONFIG_MEMSET_64BIT +#endif + +/**************************************************************************** * Global Functions - ************************************************************/ + ****************************************************************************/ #ifndef CONFIG_ARCH_MEMSET void *memset(void *s, int c, size_t n) @@ -59,13 +69,15 @@ void *memset(void *s, int c, size_t n) #ifdef CONFIG_MEMSET_OPTSPEED /* This version is optimized for speed (you could do better * still by exploiting processor caching or memory burst - * knowledge. 64-bit support might improve performance as - * well. + * knowledge.) */ uintptr_t addr = (uintptr_t)s; - uint16_t val16 = ((uint16_t)c << 8) | (uint16_t)c; - uint32_t val32 = ((uint32_t)val16 << 16) | (uint32_t)val16; + uint16_t val16 = ((uint16_t)c << 8) | (uint16_t)c; + uint32_t val32 = ((uint32_t)val16 << 16) | (uint32_t)val16; +#ifdef CONFIG_MEMSET_64BIT + uint64_t val64 = ((uint64_t)val32 << 32) | (uint64_t)val32; +#endif /* Make sure that there is something to be cleared */ @@ -95,6 +107,7 @@ void *memset(void *s, int c, size_t n) n -= 2; } +#ifndef CONFIG_MEMSET_64BIT /* Loop while there are at least 32-bits left to be zeroed */ while (n >= 4) @@ -103,12 +116,51 @@ void *memset(void *s, int c, size_t n) addr += 4; n -= 4; } +#else + /* Align to a 32-bit boundary */ + + if (n >= 4) + { + /* Align to a 64-bit boundary (we know that the destination + * address is already aligned to at least a 32-bit boundary). + */ + + if ((addr & 7) != 0) + { + *(uint32_t*)addr = val32; + addr += 4; + n -= 4; + } + + /* Loop while there are at least 64-bits left to be zeroed */ + + while (n >= 8) + { + *(uint64_t*)addr = val64; + addr += 8; + n -= 8; + } + } +#endif } +#ifdef CONFIG_MEMSET_64BIT + /* We may get here with n in the range 0..7. If n >= 4, then we should + * have 64-bit alignment. + */ + + if (n >= 4) + { + *(uint32_t*)addr = val32; + addr += 4; + n -= 4; + } +#endif + /* We may get here under the following conditions: * * n = 0, addr may or may not be aligned - * n = 1, addr may or may not be aligned + * n = 1, addr is aligned to at least a 16-bit boundary * n = 2, addr is aligned to a 32-bit boundary * n = 3, addr is aligned to a 32-bit boundary */