From f07aba5c1ef8ba50abcf9ea57fc49e914794d700 Mon Sep 17 00:00:00 2001 From: yangguangcai Date: Tue, 22 Oct 2024 14:03:24 +0800 Subject: [PATCH] libc string:Separate code. Separate the code that follows the BSD license into independent files. Signed-off-by: yangguangcai --- LICENSE | 32 +++--- libs/libc/string/CMakeLists.txt | 57 +++++++--- libs/libc/string/Make.defs | 30 ++++-- libs/libc/string/lib_bsdmemccpy.c | 140 ++++++++++++++++++++++++ libs/libc/string/lib_bsdmemchr.c | 150 ++++++++++++++++++++++++++ libs/libc/string/lib_bsdmemcmp.c | 104 ++++++++++++++++++ libs/libc/string/lib_bsdmemcpy.c | 109 +++++++++++++++++++ libs/libc/string/lib_bsdmemrchr.c | 147 +++++++++++++++++++++++++ libs/libc/string/lib_bsdstpcpy.c | 95 ++++++++++++++++ libs/libc/string/lib_bsdstpncpy.c | 125 +++++++++++++++++++++ libs/libc/string/lib_bsdstrcat.c | 87 +++++++++++++++ libs/libc/string/lib_bsdstrchr.c | 161 ++++++++++++++++++++++++++++ libs/libc/string/lib_bsdstrchrnul.c | 55 ++++++++++ libs/libc/string/lib_bsdstrcmp.c | 99 +++++++++++++++++ libs/libc/string/lib_bsdstrcpy.c | 98 +++++++++++++++++ libs/libc/string/lib_bsdstrlen.c | 92 ++++++++++++++++ libs/libc/string/lib_bsdstrncmp.c | 117 ++++++++++++++++++++ libs/libc/string/lib_bsdstrncpy.c | 124 +++++++++++++++++++++ libs/libc/string/lib_bsdstrrchr.c | 58 ++++++++++ libs/libc/string/lib_memccpy.c | 96 ----------------- libs/libc/string/lib_memchr.c | 103 ------------------ libs/libc/string/lib_memcmp.c | 69 ------------ libs/libc/string/lib_memcpy.c | 70 ------------ libs/libc/string/lib_memrchr.c | 103 ------------------ libs/libc/string/lib_stpcpy.c | 49 --------- libs/libc/string/lib_stpncpy.c | 72 ------------- libs/libc/string/lib_strcat.c | 54 ---------- libs/libc/string/lib_strchr.c | 114 -------------------- libs/libc/string/lib_strchrnul.c | 6 -- libs/libc/string/lib_strcmp.c | 67 ------------ libs/libc/string/lib_strcpy.c | 54 ---------- libs/libc/string/lib_strlen.c | 61 ----------- libs/libc/string/lib_strncmp.c | 86 --------------- libs/libc/string/lib_strncpy.c | 72 ------------- libs/libc/string/lib_strrchr.c | 19 ---- 35 files changed, 1841 insertions(+), 1134 deletions(-) create mode 100644 libs/libc/string/lib_bsdmemccpy.c create mode 100644 libs/libc/string/lib_bsdmemchr.c create mode 100644 libs/libc/string/lib_bsdmemcmp.c create mode 100644 libs/libc/string/lib_bsdmemcpy.c create mode 100644 libs/libc/string/lib_bsdmemrchr.c create mode 100644 libs/libc/string/lib_bsdstpcpy.c create mode 100644 libs/libc/string/lib_bsdstpncpy.c create mode 100644 libs/libc/string/lib_bsdstrcat.c create mode 100644 libs/libc/string/lib_bsdstrchr.c create mode 100644 libs/libc/string/lib_bsdstrchrnul.c create mode 100644 libs/libc/string/lib_bsdstrcmp.c create mode 100644 libs/libc/string/lib_bsdstrcpy.c create mode 100644 libs/libc/string/lib_bsdstrlen.c create mode 100644 libs/libc/string/lib_bsdstrncmp.c create mode 100644 libs/libc/string/lib_bsdstrncpy.c create mode 100644 libs/libc/string/lib_bsdstrrchr.c diff --git a/LICENSE b/LICENSE index 9d9c89e9ef..c2413baa83 100644 --- a/LICENSE +++ b/LICENSE @@ -8667,22 +8667,22 @@ drivers/i3c/internals.h SPDX-License-Identifier: Apache-2.0 -libs/libc/string/lib_memccpy.c -libs/libc/string/lib_memchr.c -libs/libc/string/lib_memcmp.c -libs/libc/string/lib_memcpy.c -libs/libc/string/lib_memrchr.c -libs/libc/string/lib_stpcpy.c -libs/libc/string/lib_stpncpy.c -libs/libc/string/lib_strcat.c -libs/libc/string/lib_strchr.c -libs/libc/string/lib_strchrnul.c -libs/libc/string/lib_strcmp.c -libs/libc/string/lib_strcpy.c -libs/libc/string/lib_strlen.c -libs/libc/string/lib_strncmp.c -libs/libc/string/lib_strncpy.c -libs/libc/string/lib_strrchr.c +libs/libc/string/lib_bsdmemccpy.c +libs/libc/string/lib_bsdmemchr.c +libs/libc/string/lib_bsdmemcmp.c +libs/libc/string/lib_bsdmemcpy.c +libs/libc/string/lib_bsdmemrchr.c +libs/libc/string/lib_bsdstpcpy.c +libs/libc/string/lib_bsdstpncpy.c +libs/libc/string/lib_bsdstrcat.c +libs/libc/string/lib_bsdstrchr.c +libs/libc/string/lib_bsdstrchrnul.c +libs/libc/string/lib_bsdstrcmp.c +libs/libc/string/lib_bsdstrcpy.c +libs/libc/string/lib_bsdstrlen.c +libs/libc/string/lib_bsdstrncmp.c +libs/libc/string/lib_bsdstrncpy.c +libs/libc/string/lib_bsdstrrchr.c ====================== Copyright (c) 1994-2009 Red Hat, Inc. All rights reserved. diff --git a/libs/libc/string/CMakeLists.txt b/libs/libc/string/CMakeLists.txt index cde0c623bc..ee96ab147d 100644 --- a/libs/libc/string/CMakeLists.txt +++ b/libs/libc/string/CMakeLists.txt @@ -31,28 +31,20 @@ set(SRCS lib_flsl.c lib_flsll.c lib_isbasedigit.c - lib_memccpy.c - lib_memrchr.c lib_memmem.c lib_popcount.c lib_popcountl.c lib_popcountll.c lib_skipspace.c - lib_stpcpy.c - lib_stpncpy.c lib_strcasecmp.c - lib_strcat.c lib_strcspn.c - lib_strchrnul.c lib_strdup.c lib_strerror.c lib_strncasecmp.c lib_strncat.c - lib_strncmp.c lib_strndup.c lib_strcasestr.c lib_strpbrk.c - lib_strrchr.c lib_strspn.c lib_strstr.c lib_strtok.c @@ -68,21 +60,16 @@ set(SRCS lib_strverscmp.c lib_mempcpy.c lib_rawmemchr.c - lib_memchr.c - lib_memcmp.c lib_memmove.c lib_memset.c - lib_strchr.c - lib_strcmp.c - lib_strcpy.c lib_strlcat.c lib_strlcpy.c - lib_strlen.c - lib_strncpy.c lib_strnlen.c) if(CONFIG_MEMCPY_VIK) list(APPEND SRCS lib_vikmemcpy.c) +elseif(CONFIG_LIBC_STRING_OPTIMIZE) + list(APPEND SRCS lib_bsdmemcpy.c) else() list(APPEND SRCS lib_memcpy.c) endif() @@ -91,4 +78,44 @@ if(CONFIG_LIBC_LOCALE) list(APPEND SRCS lib_strcoll.c lib_strxfrm.c) endif() +if(CONFIG_LIBC_STRING_OPTIMIZE) + list( + APPEND + SRCS + lib_bsdmemccpy.c + lib_bsdmemcmp.c + lib_bsdmemrchr.c + lib_bsdstpncpy.c + lib_bsdstrchr.c + lib_bsdstrcmp.c + lib_bsdstrlen.c + lib_bsdstrncpy.c + lib_bsdmemchr.c + lib_bsdstpcpy.c + lib_bsdstrcat.c + lib_bsdstrchrnul.c + lib_bsdstrcpy.c + lib_bsdstrncmp.c + lib_bsdstrrchr.c) +else() + list( + APPEND + SRCS + lib_memccpy.c + lib_memcmp.c + lib_memrchr.c + lib_stpncpy.c + lib_strchr.c + lib_strcmp.c + lib_strlen.c + lib_strncpy.c + lib_memchr.c + lib_stpcpy.c + lib_strcat.c + lib_strchrnul.c + lib_strcpy.c + lib_strncmp.c + lib_strrchr.c) +endif() + target_sources(c PRIVATE ${SRCS}) diff --git a/libs/libc/string/Make.defs b/libs/libc/string/Make.defs index 0f8ac1d451..ad167779ee 100644 --- a/libs/libc/string/Make.defs +++ b/libs/libc/string/Make.defs @@ -23,23 +23,25 @@ # Add the string C files to the build CSRCS += lib_ffs.c lib_ffsl.c lib_ffsll.c lib_fls.c lib_flsl.c -CSRCS += lib_flsll.c lib_isbasedigit.c lib_memccpy.c lib_memrchr.c lib_memmem.c +CSRCS += lib_flsll.c lib_isbasedigit.c lib_memmem.c CSRCS += lib_popcount.c lib_popcountl.c lib_popcountll.c -CSRCS += lib_skipspace.c lib_stpcpy.c lib_stpncpy.c lib_strcasecmp.c -CSRCS += lib_strcat.c lib_strcspn.c lib_strchrnul.c lib_strdup.c -CSRCS += lib_strerror.c lib_strncasecmp.c lib_strncat.c lib_strncmp.c -CSRCS += lib_strndup.c lib_strcasestr.c lib_strpbrk.c lib_strrchr.c +CSRCS += lib_skipspace.c lib_strcasecmp.c +CSRCS += lib_strcspn.c lib_strdup.c +CSRCS += lib_strerror.c lib_strncasecmp.c lib_strncat.c +CSRCS += lib_strndup.c lib_strcasestr.c lib_strpbrk.c CSRCS += lib_strspn.c lib_strstr.c lib_strtok.c lib_strtokr.c CSRCS += lib_strsep.c lib_strerrorr.c lib_explicit_bzero.c lib_strsignal.c CSRCS += lib_index.c lib_rindex.c lib_timingsafe_bcmp.c lib_strverscmp.c CSRCS += lib_mempcpy.c lib_rawmemchr.c lib_bzero.c -CSRCS += lib_memchr.c lib_memcmp.c lib_memmove.c lib_memset.c -CSRCS += lib_strchr.c lib_strcmp.c lib_strcpy.c lib_strlcat.c -CSRCS += lib_strlcpy.c lib_strlen.c lib_strncpy.c lib_strnlen.c +CSRCS += lib_memmove.c lib_memset.c +CSRCS += lib_strlcat.c +CSRCS += lib_strlcpy.c lib_strnlen.c ifeq ($(CONFIG_MEMCPY_VIK),y) CSRCS += lib_vikmemcpy.c +else ifeq ($(CONFIG_LIBC_STRING_OPTIMIZE),y) +CSRCS += lib_bsdmemcpy.c else CSRCS += lib_memcpy.c endif @@ -48,6 +50,18 @@ ifeq ($(CONFIG_LIBC_LOCALE),y) CSRCS += lib_strcoll.c lib_strxfrm.c endif +ifeq ($(CONFIG_LIBC_STRING_OPTIMIZE),y) +CSRCS += lib_bsdmemccpy.c lib_bsdmemcmp.c lib_bsdmemrchr.c lib_bsdstpncpy.c +CSRCS += lib_bsdstrchr.c lib_bsdstrcmp.c lib_bsdstrlen.c lib_bsdstrncpy.c +CSRCS += lib_bsdmemchr.c lib_bsdstpcpy.c lib_bsdstrcat.c lib_bsdstrchrnul.c +CSRCS += lib_bsdstrcpy.c lib_bsdstrncmp.c lib_bsdstrrchr.c +else +CSRCS += lib_memccpy.c lib_memcmp.c lib_memrchr.c lib_stpncpy.c +CSRCS += lib_strchr.c lib_strcmp.c lib_strlen.c lib_strncpy.c +CSRCS += lib_memchr.c lib_stpcpy.c lib_strcat.c lib_strchrnul.c +CSRCS += lib_strcpy.c lib_strncmp.c lib_strrchr.c +endif + # Add the string directory to the build DEPPATH += --dep-path string diff --git a/libs/libc/string/lib_bsdmemccpy.c b/libs/libc/string/lib_bsdmemccpy.c new file mode 100644 index 0000000000..7b922cb6b5 --- /dev/null +++ b/libs/libc/string/lib_bsdmemccpy.c @@ -0,0 +1,140 @@ +/**************************************************************************** + * libs/libc/string/lib_bsdmemccpy.c + * + * Copyright (c) 1994-2009 Red Hat, Inc. All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the BSD License. This program is distributed in the hope that + * it will be useful, but WITHOUT ANY WARRANTY expressed or implied, + * including the implied warranties of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. A copy of this license is available at + * http://www.opensource.org/licenses. Any Red Hat trademarks that are + * incorporated in the source code or documentation are not subject to + * the BSD License and may only be used or replicated with the express + * permission of Red Hat, Inc. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Nonzero if either x or y is not aligned on a "long" boundary. */ + +#define UNALIGNED(x, y) \ + (((long)(uintptr_t)(x) & (sizeof(long) - 1)) | ((long)(uintptr_t)(y) & (sizeof(long) - 1))) + +/* How many bytes are copied each iteration of the word copy loop. */ + +#define LITTLEBLOCKSIZE (sizeof(long)) + +/* Threshhold for punting to the byte copier. */ + +#define TOO_SMALL(len) ((len) < LITTLEBLOCKSIZE) + +/* Macros for detecting endchar */ + +#if LONG_MAX == 2147483647 +# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080) +#elif LONG_MAX == 9223372036854775807 +/* Nonzero if x (a long int) contains a NULL byte. */ + +# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080) +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: memccpy + * + * Description: + * The memccpy() function copies bytes from memory area s2 into s1, + * stopping after the first occurrence of byte c (converted to an unsigned + * char) is copied, or after n bytes are copied, whichever comes first. If + * copying takes place between objects that overlap, the behavior is + * undefined. + * + * Returned Value: + * The memccpy() function returns a pointer to the byte after the copy of c + * in s1, or a null pointer if c was not found in the first n bytes of s2. + * + ****************************************************************************/ + +#undef memccpy /* See mm/README.txt */ +FAR void *memccpy(FAR void *s1, FAR const void *s2, int c, size_t n) +{ + FAR void *ptr = NULL; + FAR unsigned char *pout = (FAR unsigned char *)s1; + FAR const unsigned char *pin = (FAR const unsigned char *)s2; + FAR long *paligned_out; + FAR const long *paligned_in; + unsigned char endchar = c & 0xff; + + /* If the size is small, or either pin or pout is unaligned, + * then punt into the byte copy loop. This should be rare. + */ + + if (!TOO_SMALL(n) && !UNALIGNED(pin, pout)) + { + unsigned int i; + unsigned long mask = 0; + + paligned_out = (FAR long *)pout; + paligned_in = (FAR long *)pin; + + /* The fast code reads the ASCII one word at a time and only + * performs the bytewise search on word-sized segments if they + * contain the search character, which is detected by XORing + * the word-sized segment with a word-sized block of the search + * character and then detecting for the presence of NULL in the + * result. + */ + + for (i = 0; i < LITTLEBLOCKSIZE; i++) + { + mask = (mask << 8) + endchar; + } + + /* Copy one long word at a time if possible. */ + + while (n >= LITTLEBLOCKSIZE) + { + unsigned long buffer = (unsigned long)(*paligned_in); + buffer ^= mask; + if (DETECTNULL(buffer)) + { + break; /* endchar is found, go byte by byte from here */ + } + + *paligned_out++ = *paligned_in++; + n -= LITTLEBLOCKSIZE; + } + + /* Pick up any residual with a byte copier. */ + + pout = (FAR unsigned char *)paligned_out; + pin = (FAR unsigned char *)paligned_in; + } + + while (n--) + { + if ((*pout++ = *pin++) == endchar) + { + ptr = pout; + break; + } + } + + return ptr; +} diff --git a/libs/libc/string/lib_bsdmemchr.c b/libs/libc/string/lib_bsdmemchr.c new file mode 100644 index 0000000000..d0b8c30b1f --- /dev/null +++ b/libs/libc/string/lib_bsdmemchr.c @@ -0,0 +1,150 @@ +/**************************************************************************** + * libs/libc/string/lib_bsdmemchr.c + * + * Copyright (c) 1994-2009 Red Hat, Inc. All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the BSD License. This program is distributed in the hope that + * it will be useful, but WITHOUT ANY WARRANTY expressed or implied, + * including the implied warranties of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. A copy of this license is available at + * http://www.opensource.org/licenses. Any Red Hat trademarks that are + * incorporated in the source code or documentation are not subject to + * the BSD License and may only be used or replicated with the express + * permission of Red Hat, Inc. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "libc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define UNALIGNED(x) ((long)(uintptr_t)(x) & (sizeof(long) - 1)) + +/* How many bytes are loaded each iteration of the word copy loop. */ + +#define LBLOCKSIZE (sizeof(long)) + +/* Threshhold for punting to the bytewise iterator. */ + +#define TOO_SMALL(len) ((len) < LBLOCKSIZE) + +#if LONG_MAX == 2147483647 +# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080) +#elif LONG_MAX == 9223372036854775807 +/* Nonzero if x (a long int) contains a NULL byte. */ + +# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080) +#endif + +/* DETECTCHAR returns nonzero if (long)x contains the byte used + * to fill (long)mask. + */ + +#define DETECTCHAR(x, mask) (DETECTNULL((x) ^ (mask))) + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: memchr + * + * Description: + * The memchr() function locates the first occurrence of 'c' (converted to + * an unsigned char) in the initial 'n' bytes (each interpreted as + * unsigned char) of the object pointed to by s. + * + * Returned Value: + * The memchr() function returns a pointer to the located byte, or a null + * pointer if the byte does not occur in the object. + * + ****************************************************************************/ + +#if !defined(CONFIG_LIBC_ARCH_MEMCHR) && defined(LIBC_BUILD_MEMCHR) +#undef memchr /* See mm/README.txt */ +FAR void *memchr(FAR const void *s, int c, size_t n) +{ + FAR const unsigned char *p = (FAR const unsigned char *)s; + FAR unsigned long *asrc; + unsigned char d = c; + unsigned long mask; + unsigned int i; + + while (UNALIGNED(p)) + { + if (!n--) + { + return NULL; + } + + if (*p == d) + { + return (FAR void *)p; + } + + p++; + } + + if (!TOO_SMALL(n)) + { + /* If we get this far, we know that n is large and p is + * word-aligned. + * The fast code reads the source one word at a time and only + * performs the bytewise search on word-sized segments if they + * contain the search character, which is detected by XORing + * the word-sized segment with a word-sized block of the search + * character and then detecting for the presence of NUL in the + * result. + */ + + asrc = (FAR unsigned long *)p; + mask = d << 8 | d; + mask = mask << 16 | mask; + for (i = 32; i < LBLOCKSIZE * 8; i <<= 1) + { + mask = (mask << i) | mask; + } + + while (n >= LBLOCKSIZE) + { + if (DETECTCHAR(*asrc, mask)) + { + break; + } + + n -= LBLOCKSIZE; + asrc++; + } + + /* If there are fewer than LBLOCKSIZE characters left, + * then we resort to the bytewise loop. + */ + + p = (FAR unsigned char *)asrc; + } + + while (n--) + { + if (*p == d) + { + return (FAR void *)p; + } + + p++; + } + + return NULL; +} +#endif diff --git a/libs/libc/string/lib_bsdmemcmp.c b/libs/libc/string/lib_bsdmemcmp.c new file mode 100644 index 0000000000..614f1fefd4 --- /dev/null +++ b/libs/libc/string/lib_bsdmemcmp.c @@ -0,0 +1,104 @@ +/**************************************************************************** + * libs/libc/string/lib_bsdmemcmp.c + * + * Copyright (c) 1994-2009 Red Hat, Inc. All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the BSD License. This program is distributed in the hope that + * it will be useful, but WITHOUT ANY WARRANTY expressed or implied, + * including the implied warranties of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. A copy of this license is available at + * http://www.opensource.org/licenses. Any Red Hat trademarks that are + * incorporated in the source code or documentation are not subject to + * the BSD License and may only be used or replicated with the express + * permission of Red Hat, Inc. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include "libc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Nonzero if either x or y is not aligned on a "long" boundary. */ + +#define UNALIGNED(x, y) \ + (((long)(uintptr_t)(x) & (sizeof(long) - 1)) | ((long)(uintptr_t)(y) & (sizeof(long) - 1))) + +/* How many bytes are copied each iteration of the word copy loop. */ + +#define LBLOCKSIZE (sizeof(long)) + +/* Threshhold for punting to the byte copier. */ + +#define TOO_SMALL(len) ((len) < LBLOCKSIZE) + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#if !defined(CONFIG_LIBC_ARCH_MEMCMP) && defined(LIBC_BUILD_MEMCMP) +#undef memcmp /* See mm/README.txt */ +no_builtin("memcmp") +int memcmp(FAR const void *s1, FAR const void *s2, size_t n) +{ + FAR unsigned char *p1 = (FAR unsigned char *)s1; + FAR unsigned char *p2 = (FAR unsigned char *)s2; + FAR unsigned long *a1; + FAR unsigned long *a2; + + /* If the size is too small, or either pointer is unaligned, + * then we punt to the byte compare loop. Hopefully this will + * not turn up in inner loops. + */ + + if (!TOO_SMALL(n) && !UNALIGNED(p1, p2)) + { + /* Otherwise, load and compare the blocks of memory one + * word at a time. + */ + + a1 = (FAR unsigned long *)p1; + a2 = (FAR unsigned long *)p2; + while (n >= LBLOCKSIZE) + { + if (*a1 != *a2) + { + break; + } + + a1++; + a2++; + n -= LBLOCKSIZE; + } + + /* check s mod LBLOCKSIZE remaining characters */ + + p1 = (FAR unsigned char *)a1; + p2 = (FAR unsigned char *)a2; + } + + while (n--) + { + if (*p1 != *p2) + { + return *p1 - *p2; + } + + p1++; + p2++; + } + + return 0; +} +#endif diff --git a/libs/libc/string/lib_bsdmemcpy.c b/libs/libc/string/lib_bsdmemcpy.c new file mode 100644 index 0000000000..21607b1fc7 --- /dev/null +++ b/libs/libc/string/lib_bsdmemcpy.c @@ -0,0 +1,109 @@ +/**************************************************************************** + * libs/libc/string/lib_bsdmemcpy.c + * + * Copyright (c) 1994-2009 Red Hat, Inc. All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the BSD License. This program is distributed in the hope that + * it will be useful, but WITHOUT ANY WARRANTY expressed or implied, + * including the implied warranties of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. A copy of this license is available at + * http://www.opensource.org/licenses. Any Red Hat trademarks that are + * incorporated in the source code or documentation are not subject to + * the BSD License and may only be used or replicated with the express + * permission of Red Hat, Inc. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include "libc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Nonzero if either x or y is not aligned on a "long" boundary. */ + +#define UNALIGNED(x, y) \ + (((long)(uintptr_t)(x) & (sizeof(long) - 1)) | ((long)(uintptr_t)(y) & (sizeof(long) - 1))) + +/* How many bytes are copied each iteration of the 4X unrolled loop. */ + +#define BIGBLOCKSIZE (sizeof(long) << 2) + +/* How many bytes are copied each iteration of the word copy loop. */ + +#define LITTLEBLOCKSIZE (sizeof(long)) + +/* Threshhold for punting to the byte copier. */ + +#define TOO_SMALL(len) ((len) < BIGBLOCKSIZE) + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: memcpy + ****************************************************************************/ + +#if !defined(CONFIG_LIBC_ARCH_MEMCPY) && defined(LIBC_BUILD_MEMCPY) +#undef memcpy /* See mm/README.txt */ +no_builtin("memcpy") +FAR void *memcpy(FAR void *dest, FAR const void *src, size_t n) +{ + FAR char *pout = dest; + FAR const char *pin = src; + FAR long *paligned_out; + FAR const long *paligned_in; + + /* If the size is small, or either pin or pout is unaligned, + * then punt into the byte copy loop. This should be rare. + */ + + if (!TOO_SMALL(n) && !UNALIGNED(pin, pout)) + { + paligned_out = (FAR long *)pout; + paligned_in = (FAR long *)pin; + + /* Copy 4X long words at a time if possible. */ + + while (n >= BIGBLOCKSIZE) + { + *paligned_out++ = *paligned_in++; + *paligned_out++ = *paligned_in++; + *paligned_out++ = *paligned_in++; + *paligned_out++ = *paligned_in++; + n -= BIGBLOCKSIZE; + } + + /* Copy one long word at a time if possible. */ + + while (n >= LITTLEBLOCKSIZE) + { + *paligned_out++ = *paligned_in++; + n -= LITTLEBLOCKSIZE; + } + + /* Pick up any residual with a byte copier. */ + + pout = (FAR char *)paligned_out; + pin = (FAR char *)paligned_in; + } + + while (n--) + { + *pout++ = *pin++; + } + + return dest; +} +#endif diff --git a/libs/libc/string/lib_bsdmemrchr.c b/libs/libc/string/lib_bsdmemrchr.c new file mode 100644 index 0000000000..7c8f829e4f --- /dev/null +++ b/libs/libc/string/lib_bsdmemrchr.c @@ -0,0 +1,147 @@ +/**************************************************************************** + * libs/libc/string/lib_bsdmemrchr.c + * + * Copyright (c) 1994-2009 Red Hat, Inc. All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the BSD License. This program is distributed in the hope that + * it will be useful, but WITHOUT ANY WARRANTY expressed or implied, + * including the implied warranties of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. A copy of this license is available at + * http://www.opensource.org/licenses. Any Red Hat trademarks that are + * incorporated in the source code or documentation are not subject to + * the BSD License and may only be used or replicated with the express + * permission of Red Hat, Inc. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Nonzero if x is not aligned on a "long" boundary. */ + +#define UNALIGNED(x) ((long)(uintptr_t)((x) + 1) & (sizeof(long) - 1)) + +/* How many bytes are loaded each iteration of the word copy loop. */ + +#define LBLOCKSIZE (sizeof(long)) + +/* Threshhold for punting to the bytewise iterator. */ + +#define TOO_SMALL(len) ((len) < LBLOCKSIZE) + +/* Macros for detecting endchar */ + +#if LONG_MAX == 2147483647 +# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080) +#elif LONG_MAX == 9223372036854775807 +/* Nonzero if x (a long int) contains a NULL byte. */ + +# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080) +#endif + +#define DETECTCHAR(x, mask) (DETECTNULL((x) ^ (mask))) + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: memrchr + * + * Description: + * The memrchr() function locates the last occurrence of 'c' (converted to + * an unsigned char) in the initial 'n' bytes (each interpreted as + * unsigned char) of the object pointed to by s. + * + * Returned Value: + * The memrchr() function returns a pointer to the located byte, or a null + * pointer if the byte does not occur in the object. + * + ****************************************************************************/ + +#undef memrchr /* See mm/README.txt */ +FAR void *memrchr(FAR const void *s, int c, size_t n) +{ + FAR const unsigned char *src0 = + (FAR const unsigned char *)s + n - 1; + FAR unsigned long *asrc; + unsigned char d = c; + unsigned long mask; + unsigned int i; + + while (UNALIGNED(src0)) + { + if (!n--) + { + return NULL; + } + + if (*src0 == d) + { + return (FAR void *)src0; + } + + src0--; + } + + if (!TOO_SMALL(n)) + { + /* If we get this far, we know that n is large and src0 is + * word-aligned. + * The fast code reads the source one word at a time and only + * performs the bytewise search on word-sized segments if they + * contain the search character, which is detected by XORing + * the word-sized segment with a word-sized block of the search + * character and then detecting for the presence of NUL in the + * result. + */ + + asrc = (FAR unsigned long *)(src0 - LBLOCKSIZE + 1); + mask = d << 8 | d; + mask = mask << 16 | mask; + for (i = 32; i < LBLOCKSIZE * 8; i <<= 1) + { + mask = (mask << i) | mask; + } + + while (n >= LBLOCKSIZE) + { + if (DETECTCHAR(*asrc, mask)) + { + break; + } + + n -= LBLOCKSIZE; + asrc--; + } + + /* If there are fewer than LBLOCKSIZE characters left, + * then we resort to the bytewise loop. + */ + + src0 = (FAR unsigned char *)asrc + LBLOCKSIZE - 1; + } + + while (n--) + { + if (*src0 == d) + { + return (FAR void *)src0; + } + + src0--; + } + + return NULL; +} diff --git a/libs/libc/string/lib_bsdstpcpy.c b/libs/libc/string/lib_bsdstpcpy.c new file mode 100644 index 0000000000..7edcc8d79a --- /dev/null +++ b/libs/libc/string/lib_bsdstpcpy.c @@ -0,0 +1,95 @@ +/**************************************************************************** + * libs/libc/string/lib_bsdstpcpy.c + * + * Copyright (c) 1994-2009 Red Hat, Inc. All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the BSD License. This program is distributed in the hope that + * it will be useful, but WITHOUT ANY WARRANTY expressed or implied, + * including the implied warranties of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. A copy of this license is available at + * http://www.opensource.org/licenses. Any Red Hat trademarks that are + * incorporated in the source code or documentation are not subject to + * the BSD License and may only be used or replicated with the express + * permission of Red Hat, Inc. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Nonzero if either x or y is not aligned on a "long" boundary. */ + +#define UNALIGNED(x, y) \ + (((long)(uintptr_t)(x) & (sizeof(long) - 1)) | ((long)(uintptr_t)(y) & (sizeof(long) - 1))) + +/* Macros for detecting endchar */ + +#if LONG_MAX == 2147483647 +# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080) +#elif LONG_MAX == 9223372036854775807 +/* Nonzero if x (a long int) contains a NULL byte. */ + +# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080) +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stpcpy + * + * Description: + * Copies the string pointed to by 'src' (including the terminating NUL + * character) into the array pointed to by 'dest'. + * + * Returned Value: + * The stpcpy() function returns a pointer to the terminating NUL + * character copied into the 'dest' buffer + * + ****************************************************************************/ + +#ifndef CONFIG_LIBC_ARCH_STPCPY +#undef stpcpy /* See mm/README.txt */ +nosanitize_address +FAR char *stpcpy(FAR char *dest, FAR const char *src) +{ + FAR long *aligned_dst; + FAR const long *aligned_src; + + /* If src or dest is unaligned, then copy bytes. */ + + if (!UNALIGNED(src, dest)) + { + aligned_dst = (FAR long *)dest; + aligned_src = (FAR long *)src; + + /* src and dest are both "long int" aligned, try to do "long int" + * sized copies. + */ + + while (!DETECTNULL(*aligned_src)) + { + *aligned_dst++ = *aligned_src++; + } + + dest = (FAR char *)aligned_dst; + src = (FAR char *)aligned_src; + } + + while ((*dest++ = *src++) != '\0'); + + return --dest; +} +#endif diff --git a/libs/libc/string/lib_bsdstpncpy.c b/libs/libc/string/lib_bsdstpncpy.c new file mode 100644 index 0000000000..1d4f43a15d --- /dev/null +++ b/libs/libc/string/lib_bsdstpncpy.c @@ -0,0 +1,125 @@ +/**************************************************************************** + * libs/libc/string/lib_bsdstpncpy.c + * + * Copyright (c) 1994-2009 Red Hat, Inc. All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the BSD License. This program is distributed in the hope that + * it will be useful, but WITHOUT ANY WARRANTY expressed or implied, + * including the implied warranties of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. A copy of this license is available at + * http://www.opensource.org/licenses. Any Red Hat trademarks that are + * incorporated in the source code or documentation are not subject to + * the BSD License and may only be used or replicated with the express + * permission of Red Hat, Inc. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Nonzero if either x or y is not aligned on a "long" boundary. */ + +#define UNALIGNED(x, y) \ + (((long)(uintptr_t)(x) & (sizeof(long) - 1)) | ((long)(uintptr_t)(y) & (sizeof(long) - 1))) + +/* How many bytes are loaded each iteration of the word copy loop. */ + +#define LBLOCKSIZE (sizeof(long)) + +/* Macros for detecting endchar */ + +#if LONG_MAX == 2147483647 +#define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080) +#elif LONG_MAX == 9223372036854775807 +/* Nonzero if x (a long int) contains a NULL byte. */ + +#define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080) +#endif + +#define TOO_SMALL(len) ((len) < sizeof(long)) + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stpncpy + * + * Description: + * Copies the string pointed to by 'src' (including the terminating NUL + * character) into the array pointed to by 'dest'. strncpy() will not + * copy more than 'n' bytes from 'src' to 'dest' array (including the + * NUL terminator). + * + * If the array pointed to by 'src' is a string that is shorter than 'n' + * bytes, NUL characters will be appended to the copy in the array + * pointed to by 'dest', until 'n' bytes in all are written. + * + * If copying takes place between objects that overlap, the behavior is + * undefined. + * + * Returned Value: + * If a NUL character is written to the destination, the stpncpy() + * function will return the address of the first such NUL character. + * Otherwise, it will return &dest[n] + * + ****************************************************************************/ + +#ifndef CONFIG_LIBC_ARCH_STPNCPY +#undef stpncpy /* See mm/README.txt */ +FAR char *stpncpy(FAR char *dest, FAR const char *src, size_t n) +{ + FAR char *ret = NULL; + FAR long *aligned_dst; + FAR const long *aligned_src; + + /* If src and dest is aligned and n large enough, then copy words. */ + + if (!UNALIGNED(src, dest) && !TOO_SMALL(n)) + { + aligned_dst = (FAR long *)dest; + aligned_src = (FAR long *)src; + + /* src and dest are both "long int" aligned, try to do "long int" + * sized copies. + */ + + while (n >= LBLOCKSIZE && !DETECTNULL(*aligned_src)) + { + n -= LBLOCKSIZE; + *aligned_dst++ = *aligned_src++; + } + + dest = (FAR char *)aligned_dst; + src = (FAR char *)aligned_src; + } + + while (n > 0) + { + --n; + if ((*dest++ = *src++) == '\0') + { + ret = dest - 1; + break; + } + } + + while (n-- > 0) + { + *dest++ = '\0'; + } + + return ret ? ret : dest; +} +#endif diff --git a/libs/libc/string/lib_bsdstrcat.c b/libs/libc/string/lib_bsdstrcat.c new file mode 100644 index 0000000000..ced88d72d9 --- /dev/null +++ b/libs/libc/string/lib_bsdstrcat.c @@ -0,0 +1,87 @@ +/**************************************************************************** + * libs/libc/string/lib_bsdstrcat.c + * + * Copyright (c) 1994-2009 Red Hat, Inc. All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the BSD License. This program is distributed in the hope that + * it will be useful, but WITHOUT ANY WARRANTY expressed or implied, + * including the implied warranties of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. A copy of this license is available at + * http://www.opensource.org/licenses. Any Red Hat trademarks that are + * incorporated in the source code or documentation are not subject to + * the BSD License and may only be used or replicated with the express + * permission of Red Hat, Inc. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "libc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define ALIGNED(x) \ + (((long)(uintptr_t)(x) & (sizeof(long) - 1)) == 0) + +/* Macros for detecting endchar */ + +#if LONG_MAX == 2147483647 +# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080) +#elif LONG_MAX == 9223372036854775807 +/* Nonzero if x (a long int) contains a NULL byte. */ + +# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080) +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#if !defined(CONFIG_LIBC_ARCH_STRCAT) && defined(LIBC_BUILD_STRCAT) +#undef strcat /* See mm/README.txt */ +nosanitize_address +FAR char *strcat(FAR char *dest, FAR const char *src) +{ + FAR char *ret = dest; + + /* Skip over the data in dest as quickly as possible. */ + + if (ALIGNED(dest)) + { + FAR unsigned long *aligned_s1 = (FAR unsigned long *)dest; + while (!DETECTNULL(*aligned_s1)) + { + aligned_s1++; + } + + dest = (FAR char *)aligned_s1; + } + + while (*dest) + { + dest++; + } + + /* dest now points to the its trailing null character, we can + * just use strcpy to do the work for us now. + * ?!? We might want to just include strcpy here. + * Also, this will cause many more unaligned string copies because + * dest is much less likely to be aligned. I don't know if its worth + * tweaking strcpy to handle this better. + */ + + strcpy(dest, src); + + return ret; +} +#endif diff --git a/libs/libc/string/lib_bsdstrchr.c b/libs/libc/string/lib_bsdstrchr.c new file mode 100644 index 0000000000..6223f27658 --- /dev/null +++ b/libs/libc/string/lib_bsdstrchr.c @@ -0,0 +1,161 @@ +/**************************************************************************** + * libs/libc/string/lib_bsdstrchr.c + * + * Copyright (c) 1994-2009 Red Hat, Inc. All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the BSD License. This program is distributed in the hope that + * it will be useful, but WITHOUT ANY WARRANTY expressed or implied, + * including the implied warranties of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. A copy of this license is available at + * http://www.opensource.org/licenses. Any Red Hat trademarks that are + * incorporated in the source code or documentation are not subject to + * the BSD License and may only be used or replicated with the express + * permission of Red Hat, Inc. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "libc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define UNALIGNED(x) ((long)(uintptr_t)(x) & (sizeof(long) - 1)) + +/* How many bytes are loaded each iteration of the word copy loop. */ + +#define LBLOCKSIZE (sizeof(long)) + +/* Macros for detecting endchar */ + +#if LONG_MAX == 2147483647 +# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080) +#elif LONG_MAX == 9223372036854775807 +/* Nonzero if x (a long int) contains a NULL byte. */ + +# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080) +#endif + +#define DETECTCHAR(x, mask) (DETECTNULL((x) ^ (mask))) + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: strchr + * + * Description: + * The strchr() function locates the first occurrence of 'c' (converted to + * a char) in the string pointed to by 's'. The terminating null byte is + * considered to be part of the string. + * + * Returned Value: + * Upon completion, strchr() returns a pointer to the byte, or a null + * pointer if the byte was not found. + * + ****************************************************************************/ + +#if !defined(CONFIG_LIBC_ARCH_STRCHR) && defined(LIBC_BUILD_STRCHR) +#undef strchr /* See mm/README.txt */ +nosanitize_address +FAR char *strchr(FAR const char *s, int c) +{ + FAR const unsigned char *s1 = (FAR const unsigned char *)s; + FAR unsigned long *aligned_addr; + unsigned char i = c; + unsigned long mask; + unsigned long j; + + /* Special case for finding 0. */ + + if (!i) + { + while (UNALIGNED(s1)) + { + if (!*s1) + { + return (FAR char *)s1; + } + + s1++; + } + + /* Operate a word at a time. */ + + aligned_addr = (FAR unsigned long *)s1; + while (!DETECTNULL(*aligned_addr)) + { + aligned_addr++; + } + + /* Found the end of string. */ + + s1 = (FAR const unsigned char *)aligned_addr; + while (*s1) + { + s1++; + } + + return (FAR char *)s1; + } + + /* All other bytes. Align the pointer, then search a long at a time. */ + + while (UNALIGNED(s1)) + { + if (!*s1) + { + return NULL; + } + + if (*s1 == i) + { + return (FAR char *)s1; + } + + s1++; + } + + mask = i; + for (j = 8; j < LBLOCKSIZE * 8; j <<= 1) + { + mask = (mask << j) | mask; + } + + aligned_addr = (FAR unsigned long *)s1; + while (!DETECTNULL(*aligned_addr) && !DETECTCHAR(*aligned_addr, mask)) + { + aligned_addr++; + } + + /* The block of bytes currently pointed to by aligned_addr + * contains either a null or the target char, or both. We + * catch it using the bytewise search. + */ + + s1 = (FAR unsigned char *)aligned_addr; + + while (*s1 && *s1 != i) + { + s1++; + } + + if (*s1 == i) + { + return (FAR char *)s1; + } + + return NULL; +} +#endif diff --git a/libs/libc/string/lib_bsdstrchrnul.c b/libs/libc/string/lib_bsdstrchrnul.c new file mode 100644 index 0000000000..5e3129005d --- /dev/null +++ b/libs/libc/string/lib_bsdstrchrnul.c @@ -0,0 +1,55 @@ +/**************************************************************************** + * libs/libc/string/lib_bsdstrchrnul.c + * + * Copyright (c) 1994-2009 Red Hat, Inc. All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the BSD License. This program is distributed in the hope that + * it will be useful, but WITHOUT ANY WARRANTY expressed or implied, + * including the implied warranties of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. A copy of this license is available at + * http://www.opensource.org/licenses. Any Red Hat trademarks that are + * incorporated in the source code or documentation are not subject to + * the BSD License and may only be used or replicated with the express + * permission of Red Hat, Inc. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "libc.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: strchrnul + * + * Description: + * The strchrnul() function locates the first occurrence of 'c' (converted + * to a char) in the string pointed to by 's'. The terminating null byte is + * considered to be part of the string. + * + * Returned Value: + * Upon completion, strchrnul() returns a pointer to the byte, or a + * pointer to null if the byte was not found. + * + ****************************************************************************/ + +#if !defined(CONFIG_LIBC_ARCH_STRCHRNUL) && defined(LIBC_BUILD_STRCHRNUL) +#undef strchrnul /* See mm/README.txt */ +FAR char *strchrnul(FAR const char *s, int c) +{ + FAR char *s1 = strchr(s, c); + + return s1 ? s1 : (FAR char *)s + strlen(s); +} +#endif diff --git a/libs/libc/string/lib_bsdstrcmp.c b/libs/libc/string/lib_bsdstrcmp.c new file mode 100644 index 0000000000..270bcbaf87 --- /dev/null +++ b/libs/libc/string/lib_bsdstrcmp.c @@ -0,0 +1,99 @@ +/**************************************************************************** + * libs/libc/string/lib_bsdstrcmp.c + * + * Copyright (c) 1994-2009 Red Hat, Inc. All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the BSD License. This program is distributed in the hope that + * it will be useful, but WITHOUT ANY WARRANTY expressed or implied, + * including the implied warranties of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. A copy of this license is available at + * http://www.opensource.org/licenses. Any Red Hat trademarks that are + * incorporated in the source code or documentation are not subject to + * the BSD License and may only be used or replicated with the express + * permission of Red Hat, Inc. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "libc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Nonzero if either x or y is not aligned on a "long" boundary. */ + +#define UNALIGNED(x, y) \ + (((long)(uintptr_t)(x) & (sizeof(long) - 1)) | ((long)(uintptr_t)(y) & (sizeof(long) - 1))) + +/* Macros for detecting endchar */ + +#if LONG_MAX == 2147483647 +# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080) +#elif LONG_MAX == 9223372036854775807 +/* Nonzero if x (a long int) contains a NULL byte. */ + +# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080) +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#if !defined(CONFIG_LIBC_ARCH_STRCMP) && defined(LIBC_BUILD_STRCMP) +#undef strcmp /* See mm/README.txt */ +nosanitize_address +int strcmp(FAR const char *cs, FAR const char *ct) +{ + FAR unsigned long *a1; + FAR unsigned long *a2; + + /* If cs or ct are unaligned, then compare bytes. */ + + if (!UNALIGNED(cs, ct)) + { + /* If cs and ct are word-aligned, compare them a word at a time. */ + + a1 = (FAR unsigned long *)cs; + a2 = (FAR unsigned long *)ct; + while (*a1 == *a2) + { + /* To get here, *a1 == *a2, thus if we find a null in *a1, + * then the strings must be equal, so return zero. + */ + + if (DETECTNULL(*a1)) + { + return 0; + } + + a1++; + a2++; + } + + /* A difference was detected in last few bytes of cs, + * so search bytewise. + */ + + cs = (FAR char *)a1; + ct = (FAR char *)a2; + } + + while (*cs != '\0' && *cs == *ct) + { + cs++; + ct++; + } + + return (*(FAR unsigned char *)cs) - (*(FAR unsigned char *)ct); +} +#endif diff --git a/libs/libc/string/lib_bsdstrcpy.c b/libs/libc/string/lib_bsdstrcpy.c new file mode 100644 index 0000000000..7a674d9655 --- /dev/null +++ b/libs/libc/string/lib_bsdstrcpy.c @@ -0,0 +1,98 @@ +/**************************************************************************** + * libs/libc/string/lib_bsdstrcpy.c + * + * Copyright (c) 1994-2009 Red Hat, Inc. All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the BSD License. This program is distributed in the hope that + * it will be useful, but WITHOUT ANY WARRANTY expressed or implied, + * including the implied warranties of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. A copy of this license is available at + * http://www.opensource.org/licenses. Any Red Hat trademarks that are + * incorporated in the source code or documentation are not subject to + * the BSD License and may only be used or replicated with the express + * permission of Red Hat, Inc. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "libc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Nonzero if either x or y is not aligned on a "long" boundary. */ + +#define UNALIGNED(x, y) \ + (((long)(uintptr_t)(x) & (sizeof(long) - 1)) | ((long)(uintptr_t)(y) & (sizeof(long) - 1))) + +/* Macros for detecting endchar */ + +#if LONG_MAX == 2147483647 +# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080) +#elif LONG_MAX == 9223372036854775807 +/* Nonzero if x (a long int) contains a NULL byte. */ + +# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080) +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: strcpy + * + * Description: + * Copies the string pointed to by 'src' (including the terminating NUL + * character) into the array pointed to by 'des'. + * + * Returned Value: + * The strcpy() function returns the 'dest' pointer + * + ****************************************************************************/ + +#if !defined(CONFIG_LIBC_ARCH_STRCPY) && defined(LIBC_BUILD_STRCPY) +#undef strcpy /* See mm/README.txt */ +nosanitize_address +FAR char *strcpy(FAR char *dest, FAR const char *src) +{ + FAR char *dst0 = dest; + FAR const char *src0 = src; + FAR unsigned long *aligned_dst; + FAR const unsigned long *aligned_src; + + /* If SRC or DEST is unaligned, then copy bytes. */ + + if (!UNALIGNED(src0, dst0)) + { + aligned_dst = (FAR unsigned long *)dst0; + aligned_src = (FAR unsigned long *)src0; + + /* SRC and DEST are both "long int" aligned, try to do "long int" + * sized copies. + */ + + while (!DETECTNULL(*aligned_src)) + { + *aligned_dst++ = *aligned_src++; + } + + dst0 = (FAR char *)aligned_dst; + src0 = (FAR char *)aligned_src; + } + + while ((*dst0++ = *src0++) != '\0'); + + return dest; +} +#endif diff --git a/libs/libc/string/lib_bsdstrlen.c b/libs/libc/string/lib_bsdstrlen.c new file mode 100644 index 0000000000..082aa9b00b --- /dev/null +++ b/libs/libc/string/lib_bsdstrlen.c @@ -0,0 +1,92 @@ +/**************************************************************************** + * libs/libc/string/lib_bsdstrlen.c + * + * Copyright (c) 1994-2009 Red Hat, Inc. All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the BSD License. This program is distributed in the hope that + * it will be useful, but WITHOUT ANY WARRANTY expressed or implied, + * including the implied warranties of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. A copy of this license is available at + * http://www.opensource.org/licenses. Any Red Hat trademarks that are + * incorporated in the source code or documentation are not subject to + * the BSD License and may only be used or replicated with the express + * permission of Red Hat, Inc. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include "libc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define LBLOCKSIZE (sizeof(long)) +#define UNALIGNED(x) ((long)(uintptr_t)(x) & (LBLOCKSIZE - 1)) + +/* Macros for detecting endchar */ + +#if LONG_MAX == 2147483647 +# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080) +#elif LONG_MAX == 9223372036854775807 +/* Nonzero if x (a long int) contains a NULL byte. */ + +# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080) +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#if !defined(CONFIG_LIBC_ARCH_STRLEN) && defined(LIBC_BUILD_STRLEN) +#undef strlen /* See mm/README.txt */ +nosanitize_address +size_t strlen(FAR const char *s) +{ + FAR const char *start = s; + FAR unsigned long *aligned_addr; + + /* Align the pointer, so we can search a word at a time. */ + + while (UNALIGNED(s)) + { + if (!*s) + { + return s - start; + } + + s++; + } + + /* If the string is word-aligned, we can check for the presence of + * a null in each word-sized block. + */ + + aligned_addr = (FAR unsigned long *)s; + while (!DETECTNULL(*aligned_addr)) + { + aligned_addr++; + } + + /* Once a null is detected, we check each byte in that block for a + * precise position of the null. + */ + + s = (FAR char *)aligned_addr; + while (*s) + { + s++; + } + + return s - start; +} +#endif diff --git a/libs/libc/string/lib_bsdstrncmp.c b/libs/libc/string/lib_bsdstrncmp.c new file mode 100644 index 0000000000..829bb84a1f --- /dev/null +++ b/libs/libc/string/lib_bsdstrncmp.c @@ -0,0 +1,117 @@ +/**************************************************************************** + * libs/libc/string/lib_bsdstrncmp.c + * + * Copyright (c) 1994-2009 Red Hat, Inc. All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the BSD License. This program is distributed in the hope that + * it will be useful, but WITHOUT ANY WARRANTY expressed or implied, + * including the implied warranties of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. A copy of this license is available at + * http://www.opensource.org/licenses. Any Red Hat trademarks that are + * incorporated in the source code or documentation are not subject to + * the BSD License and may only be used or replicated with the express + * permission of Red Hat, Inc. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include "libc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define LBLOCKSIZE (sizeof(long)) + +/* Nonzero if either x or y is not aligned on a "long" boundary. */ + +#define UNALIGNED(x, y) \ + (((long)(uintptr_t)(x) & (sizeof(long) - 1)) | ((long)(uintptr_t)(y) & (sizeof(long) - 1))) + +/* Macros for detecting endchar */ + +#if LONG_MAX == 2147483647 +# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080) +#elif LONG_MAX == 9223372036854775807 +/* Nonzero if x (a long int) contains a NULL byte. */ + +# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080) +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#if !defined(CONFIG_LIBC_ARCH_STRNCMP) && defined(LIBC_BUILD_STRNCMP) +#undef strncmp /* See mm/README.txt */ +nosanitize_address +int strncmp(FAR const char *cs, FAR const char *ct, size_t nb) +{ + FAR unsigned long *a1; + FAR unsigned long *a2; + + if (nb == 0) + { + return 0; + } + + /* If cs or ct are unaligned, then compare bytes. */ + + if (!UNALIGNED(cs, ct)) + { + /* If cs and ct are word-aligned, compare them a word at a time. */ + + a1 = (FAR unsigned long *)cs; + a2 = (FAR unsigned long *)ct; + while (nb >= LBLOCKSIZE && *a1 == *a2) + { + nb -= LBLOCKSIZE; + + /* If we've run out of bytes or hit a null, return zero + * since we already know *a1 == *a2. + */ + + if (nb == 0 || DETECTNULL(*a1)) + { + return 0; + } + + a1++; + a2++; + } + + /* A difference was detected in last few bytes of cs, so search + * bytewise. + */ + + cs = (FAR char *)a1; + ct = (FAR char *)a2; + } + + while (nb-- > 0 && *cs == *ct) + { + /* If we've run out of bytes or hit a null, return zero + * since we already know *cs == *ct. + */ + + if (nb == 0 || *cs == '\0') + { + return 0; + } + + cs++; + ct++; + } + + return *cs - *ct; +} +#endif diff --git a/libs/libc/string/lib_bsdstrncpy.c b/libs/libc/string/lib_bsdstrncpy.c new file mode 100644 index 0000000000..29e1aa3f49 --- /dev/null +++ b/libs/libc/string/lib_bsdstrncpy.c @@ -0,0 +1,124 @@ +/**************************************************************************** + * libs/libc/string/lib_bsdstrncpy.c + * + * Copyright (c) 1994-2009 Red Hat, Inc. All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the BSD License. This program is distributed in the hope that + * it will be useful, but WITHOUT ANY WARRANTY expressed or implied, + * including the implied warranties of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. A copy of this license is available at + * http://www.opensource.org/licenses. Any Red Hat trademarks that are + * incorporated in the source code or documentation are not subject to + * the BSD License and may only be used or replicated with the express + * permission of Red Hat, Inc. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include "libc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define LBLOCKSIZE (sizeof(long)) + +/* Nonzero if either x or y is not aligned on a "long" boundary. */ + +#define UNALIGNED(x, y) \ + (((long)(uintptr_t)(x) & (sizeof(long) - 1)) | ((long)(uintptr_t)(y) & (sizeof(long) - 1))) + +/* Macros for detecting endchar */ + +#if LONG_MAX == 2147483647 +# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080) +#elif LONG_MAX == 9223372036854775807 +/* Nonzero if x (a long int) contains a NULL byte. */ + +# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080) +#endif + +#define TOO_SMALL(len) ((len) < sizeof(long)) + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: strncpy + * + * Description: + * Copies the string pointed to by 'src' (including the terminating NUL + * character) into the array pointed to by 'dest'. strncpy() will not + * copy more than 'n' bytes from 'src' to 'dest' array (including the + * NUL terminator). + * + * If the array pointed to by 'src' is a string that is shorter than 'n' + * bytes, NUL characters will be appended to the copy in the array + * pointed to by 'dest', until 'n' bytes in all are written. + * + * If copying takes place between objects that overlap, the behavior is + * undefined. + * + * Returned Value: + * The strncpy() function returns the pointer to 'dest' + * + ****************************************************************************/ + +#if !defined(CONFIG_LIBC_ARCH_STRNCPY) && defined(LIBC_BUILD_STRNCPY) +#undef strncpy /* See mm/README.txt */ +nosanitize_address +FAR char *strncpy(FAR char *dest, FAR const char *src, size_t n) +{ + FAR char *dst0 = dest; + FAR const char *src0 = src; + FAR long *aligned_dst; + FAR const long *aligned_src; + + /* If src and dest is aligned and n large enough, then copy words. */ + + if (!UNALIGNED(src0, dst0) && !TOO_SMALL(n)) + { + aligned_dst = (FAR long *)dst0; + aligned_src = (FAR long *)src0; + + /* src and dest are both "long int" aligned, try to do "long int" + * sized copies. + */ + + while (n >= LBLOCKSIZE && !DETECTNULL(*aligned_src)) + { + n -= LBLOCKSIZE; + *aligned_dst++ = *aligned_src++; + } + + dst0 = (FAR char *)aligned_dst; + src0 = (FAR char *)aligned_src; + } + + while (n > 0) + { + --n; + if ((*dst0++ = *src0++) == '\0') + { + break; + } + } + + while (n-- > 0) + { + *dst0++ = '\0'; + } + + return dest; +} +#endif diff --git a/libs/libc/string/lib_bsdstrrchr.c b/libs/libc/string/lib_bsdstrrchr.c new file mode 100644 index 0000000000..e98a45e4cc --- /dev/null +++ b/libs/libc/string/lib_bsdstrrchr.c @@ -0,0 +1,58 @@ +/**************************************************************************** + * libs/libc/string/lib_bsdstrrchr.c + * + * Copyright (c) 1994-2009 Red Hat, Inc. All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the BSD License. This program is distributed in the hope that + * it will be useful, but WITHOUT ANY WARRANTY expressed or implied, + * including the implied warranties of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. A copy of this license is available at + * http://www.opensource.org/licenses. Any Red Hat trademarks that are + * incorporated in the source code or documentation are not subject to + * the BSD License and may only be used or replicated with the express + * permission of Red Hat, Inc. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "libc.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/* The strrchr() function returns a pointer to the last + * occurrence of the character c in the string s. + */ + +#if !defined(CONFIG_LIBC_ARCH_STRRCHR) && defined(LIBC_BUILD_STRRCHR) +#undef strrchr /* See mm/README.txt */ +FAR char *strrchr(FAR const char *s, int c) +{ + FAR const char *last = NULL; + + if (c) + { + while ((s = strchr(s, c))) + { + last = s; + s++; + } + } + else + { + last = strchr(s, c); + } + + return (FAR char *)last; +} +#endif diff --git a/libs/libc/string/lib_memccpy.c b/libs/libc/string/lib_memccpy.c index 3cb34c0d2d..283e5650cf 100644 --- a/libs/libc/string/lib_memccpy.c +++ b/libs/libc/string/lib_memccpy.c @@ -28,36 +28,6 @@ #include #include -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -#ifdef CONFIG_LIBC_STRING_OPTIMIZE -/* Nonzero if either x or y is not aligned on a "long" boundary. */ - -#define UNALIGNED(x, y) \ - (((long)(uintptr_t)(x) & (sizeof(long) - 1)) | ((long)(uintptr_t)(y) & (sizeof(long) - 1))) - -/* How many bytes are copied each iteration of the word copy loop. */ - -#define LITTLEBLOCKSIZE (sizeof(long)) - -/* Threshhold for punting to the byte copier. */ - -#define TOO_SMALL(len) ((len) < LITTLEBLOCKSIZE) - -/* Macros for detecting endchar */ - -#if LONG_MAX == 2147483647 -# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080) -#elif LONG_MAX == 9223372036854775807 -/* Nonzero if x (a long int) contains a NULL byte. */ - -# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080) -#endif - -#endif - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -81,71 +51,6 @@ #undef memccpy /* See mm/README.txt */ FAR void *memccpy(FAR void *s1, FAR const void *s2, int c, size_t n) { -#ifdef CONFIG_LIBC_STRING_OPTIMIZE - FAR void *ptr = NULL; - FAR unsigned char *pout = (FAR unsigned char *)s1; - FAR const unsigned char *pin = (FAR const unsigned char *)s2; - FAR long *paligned_out; - FAR const long *paligned_in; - unsigned char endchar = c & 0xff; - - /* If the size is small, or either pin or pout is unaligned, - * then punt into the byte copy loop. This should be rare. - */ - - if (!TOO_SMALL(n) && !UNALIGNED(pin, pout)) - { - unsigned int i; - unsigned long mask = 0; - - paligned_out = (FAR long *)pout; - paligned_in = (FAR long *)pin; - - /* The fast code reads the ASCII one word at a time and only - * performs the bytewise search on word-sized segments if they - * contain the search character, which is detected by XORing - * the word-sized segment with a word-sized block of the search - * character and then detecting for the presence of NULL in the - * result. - */ - - for (i = 0; i < LITTLEBLOCKSIZE; i++) - { - mask = (mask << 8) + endchar; - } - - /* Copy one long word at a time if possible. */ - - while (n >= LITTLEBLOCKSIZE) - { - unsigned long buffer = (unsigned long)(*paligned_in); - buffer ^= mask; - if (DETECTNULL(buffer)) - { - break; /* endchar is found, go byte by byte from here */ - } - - *paligned_out++ = *paligned_in++; - n -= LITTLEBLOCKSIZE; - } - - /* Pick up any residual with a byte copier. */ - - pout = (FAR unsigned char *)paligned_out; - pin = (FAR unsigned char *)paligned_in; - } - - while (n--) - { - if ((*pout++ = *pin++) == endchar) - { - ptr = pout; - break; - } - } - - return ptr; -#else FAR unsigned char *pout = (FAR unsigned char *)s1; FAR unsigned char *pin = (FAR unsigned char *)s2; @@ -170,5 +75,4 @@ FAR void *memccpy(FAR void *s1, FAR const void *s2, int c, size_t n) /* C was not found in the first n bytes of s2 */ return NULL; -#endif } diff --git a/libs/libc/string/lib_memchr.c b/libs/libc/string/lib_memchr.c index e651f21b67..2c24e3256f 100644 --- a/libs/libc/string/lib_memchr.c +++ b/libs/libc/string/lib_memchr.c @@ -30,38 +30,6 @@ #include "libc.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -#ifdef CONFIG_LIBC_STRING_OPTIMIZE - -#define UNALIGNED(x) ((long)(uintptr_t)(x) & (sizeof(long) - 1)) - -/* How many bytes are loaded each iteration of the word copy loop. */ - -#define LBLOCKSIZE (sizeof(long)) - -/* Threshhold for punting to the bytewise iterator. */ - -#define TOO_SMALL(len) ((len) < LBLOCKSIZE) - -#if LONG_MAX == 2147483647 -# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080) -#elif LONG_MAX == 9223372036854775807 -/* Nonzero if x (a long int) contains a NULL byte. */ - -# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080) -#endif - -/* DETECTCHAR returns nonzero if (long)x contains the byte used - * to fill (long)mask. - */ - -#define DETECTCHAR(x, mask) (DETECTNULL((x) ^ (mask))) - -#endif - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -84,76 +52,6 @@ #undef memchr /* See mm/README.txt */ FAR void *memchr(FAR const void *s, int c, size_t n) { -#ifdef CONFIG_LIBC_STRING_OPTIMIZE - FAR const unsigned char *p = (FAR const unsigned char *)s; - FAR unsigned long *asrc; - unsigned char d = c; - unsigned long mask; - unsigned int i; - - while (UNALIGNED(p)) - { - if (!n--) - { - return NULL; - } - - if (*p == d) - { - return (FAR void *)p; - } - - p++; - } - - if (!TOO_SMALL(n)) - { - /* If we get this far, we know that n is large and p is - * word-aligned. - * The fast code reads the source one word at a time and only - * performs the bytewise search on word-sized segments if they - * contain the search character, which is detected by XORing - * the word-sized segment with a word-sized block of the search - * character and then detecting for the presence of NUL in the - * result. - */ - - asrc = (FAR unsigned long *)p; - mask = d << 8 | d; - mask = mask << 16 | mask; - for (i = 32; i < LBLOCKSIZE * 8; i <<= 1) - { - mask = (mask << i) | mask; - } - - while (n >= LBLOCKSIZE) - { - if (DETECTCHAR(*asrc, mask)) - { - break; - } - - n -= LBLOCKSIZE; - asrc++; - } - - /* If there are fewer than LBLOCKSIZE characters left, - * then we resort to the bytewise loop. - */ - - p = (FAR unsigned char *)asrc; - } - - while (n--) - { - if (*p == d) - { - return (FAR void *)p; - } - - p++; - } -#else FAR const unsigned char *p = (FAR const unsigned char *)s; while (n--) @@ -165,7 +63,6 @@ FAR void *memchr(FAR const void *s, int c, size_t n) p++; } -#endif return NULL; } diff --git a/libs/libc/string/lib_memcmp.c b/libs/libc/string/lib_memcmp.c index 4960a810fb..251cbf7bba 100644 --- a/libs/libc/string/lib_memcmp.c +++ b/libs/libc/string/lib_memcmp.c @@ -30,26 +30,6 @@ #include "libc.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -#ifdef CONFIG_LIBC_STRING_OPTIMIZE -/* Nonzero if either x or y is not aligned on a "long" boundary. */ - -#define UNALIGNED(x, y) \ - (((long)(uintptr_t)(x) & (sizeof(long) - 1)) | ((long)(uintptr_t)(y) & (sizeof(long) - 1))) - -/* How many bytes are copied each iteration of the word copy loop. */ - -#define LBLOCKSIZE (sizeof(long)) - -/* Threshhold for punting to the byte copier. */ - -#define TOO_SMALL(len) ((len) < LBLOCKSIZE) - -#endif - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -59,54 +39,6 @@ no_builtin("memcmp") int memcmp(FAR const void *s1, FAR const void *s2, size_t n) { -#ifdef CONFIG_LIBC_STRING_OPTIMIZE - FAR unsigned char *p1 = (FAR unsigned char *)s1; - FAR unsigned char *p2 = (FAR unsigned char *)s2; - FAR unsigned long *a1; - FAR unsigned long *a2; - - /* If the size is too small, or either pointer is unaligned, - * then we punt to the byte compare loop. Hopefully this will - * not turn up in inner loops. - */ - - if (!TOO_SMALL(n) && !UNALIGNED(p1, p2)) - { - /* Otherwise, load and compare the blocks of memory one - * word at a time. - */ - - a1 = (FAR unsigned long *)p1; - a2 = (FAR unsigned long *)p2; - while (n >= LBLOCKSIZE) - { - if (*a1 != *a2) - { - break; - } - - a1++; - a2++; - n -= LBLOCKSIZE; - } - - /* check s mod LBLOCKSIZE remaining characters */ - - p1 = (FAR unsigned char *)a1; - p2 = (FAR unsigned char *)a2; - } - - while (n--) - { - if (*p1 != *p2) - { - return *p1 - *p2; - } - - p1++; - p2++; - } -#else FAR unsigned char *p1 = (FAR unsigned char *)s1; FAR unsigned char *p2 = (FAR unsigned char *)s2; @@ -124,7 +56,6 @@ int memcmp(FAR const void *s1, FAR const void *s2, size_t n) p1++; p2++; } -#endif return 0; } diff --git a/libs/libc/string/lib_memcpy.c b/libs/libc/string/lib_memcpy.c index 66367cb2f2..c1ff6ae1e8 100644 --- a/libs/libc/string/lib_memcpy.c +++ b/libs/libc/string/lib_memcpy.c @@ -30,30 +30,6 @@ #include "libc.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -#ifdef CONFIG_LIBC_STRING_OPTIMIZE -/* Nonzero if either x or y is not aligned on a "long" boundary. */ - -#define UNALIGNED(x, y) \ - (((long)(uintptr_t)(x) & (sizeof(long) - 1)) | ((long)(uintptr_t)(y) & (sizeof(long) - 1))) - -/* How many bytes are copied each iteration of the 4X unrolled loop. */ - -#define BIGBLOCKSIZE (sizeof(long) << 2) - -/* How many bytes are copied each iteration of the word copy loop. */ - -#define LITTLEBLOCKSIZE (sizeof(long)) - -/* Threshhold for punting to the byte copier. */ - -#define TOO_SMALL(len) ((len) < BIGBLOCKSIZE) - -#endif - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -67,58 +43,12 @@ no_builtin("memcpy") FAR void *memcpy(FAR void *dest, FAR const void *src, size_t n) { -#ifdef CONFIG_LIBC_STRING_OPTIMIZE - FAR char *pout = dest; - FAR const char *pin = src; - FAR long *paligned_out; - FAR const long *paligned_in; - - /* If the size is small, or either pin or pout is unaligned, - * then punt into the byte copy loop. This should be rare. - */ - - if (!TOO_SMALL(n) && !UNALIGNED(pin, pout)) - { - paligned_out = (FAR long *)pout; - paligned_in = (FAR long *)pin; - - /* Copy 4X long words at a time if possible. */ - - while (n >= BIGBLOCKSIZE) - { - *paligned_out++ = *paligned_in++; - *paligned_out++ = *paligned_in++; - *paligned_out++ = *paligned_in++; - *paligned_out++ = *paligned_in++; - n -= BIGBLOCKSIZE; - } - - /* Copy one long word at a time if possible. */ - - while (n >= LITTLEBLOCKSIZE) - { - *paligned_out++ = *paligned_in++; - n -= LITTLEBLOCKSIZE; - } - - /* Pick up any residual with a byte copier. */ - - pout = (FAR char *)paligned_out; - pin = (FAR char *)paligned_in; - } - - while (n--) - { - *pout++ = *pin++; - } -#else FAR unsigned char *pout = (FAR unsigned char *)dest; FAR unsigned char *pin = (FAR unsigned char *)src; while (n-- > 0) { *pout++ = *pin++; } -#endif return dest; } diff --git a/libs/libc/string/lib_memrchr.c b/libs/libc/string/lib_memrchr.c index e8a07e7565..9a8f4a69d6 100644 --- a/libs/libc/string/lib_memrchr.c +++ b/libs/libc/string/lib_memrchr.c @@ -28,37 +28,6 @@ #include -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -#ifdef CONFIG_LIBC_STRING_OPTIMIZE -/* Nonzero if x is not aligned on a "long" boundary. */ - -#define UNALIGNED(x) ((long)(uintptr_t)((x) + 1) & (sizeof(long) - 1)) - -/* How many bytes are loaded each iteration of the word copy loop. */ - -#define LBLOCKSIZE (sizeof(long)) - -/* Threshhold for punting to the bytewise iterator. */ - -#define TOO_SMALL(len) ((len) < LBLOCKSIZE) - -/* Macros for detecting endchar */ - -#if LONG_MAX == 2147483647 -# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080) -#elif LONG_MAX == 9223372036854775807 -/* Nonzero if x (a long int) contains a NULL byte. */ - -# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080) -#endif - -#define DETECTCHAR(x, mask) (DETECTNULL((x) ^ (mask))) - -#endif - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -80,77 +49,6 @@ #undef memrchr /* See mm/README.txt */ FAR void *memrchr(FAR const void *s, int c, size_t n) { -#ifdef CONFIG_LIBC_STRING_OPTIMIZE - FAR const unsigned char *src0 = - (FAR const unsigned char *)s + n - 1; - FAR unsigned long *asrc; - unsigned char d = c; - unsigned long mask; - unsigned int i; - - while (UNALIGNED(src0)) - { - if (!n--) - { - return NULL; - } - - if (*src0 == d) - { - return (FAR void *)src0; - } - - src0--; - } - - if (!TOO_SMALL(n)) - { - /* If we get this far, we know that n is large and src0 is - * word-aligned. - * The fast code reads the source one word at a time and only - * performs the bytewise search on word-sized segments if they - * contain the search character, which is detected by XORing - * the word-sized segment with a word-sized block of the search - * character and then detecting for the presence of NUL in the - * result. - */ - - asrc = (FAR unsigned long *)(src0 - LBLOCKSIZE + 1); - mask = d << 8 | d; - mask = mask << 16 | mask; - for (i = 32; i < LBLOCKSIZE * 8; i <<= 1) - { - mask = (mask << i) | mask; - } - - while (n >= LBLOCKSIZE) - { - if (DETECTCHAR(*asrc, mask)) - { - break; - } - - n -= LBLOCKSIZE; - asrc--; - } - - /* If there are fewer than LBLOCKSIZE characters left, - * then we resort to the bytewise loop. - */ - - src0 = (FAR unsigned char *)asrc + LBLOCKSIZE - 1; - } - - while (n--) - { - if (*src0 == d) - { - return (FAR void *)src0; - } - - src0--; - } -#else FAR const unsigned char *p = (FAR const unsigned char *)s + n; while (n--) @@ -160,7 +58,6 @@ FAR void *memrchr(FAR const void *s, int c, size_t n) return (FAR void *)p; } } -#endif return NULL; } diff --git a/libs/libc/string/lib_stpcpy.c b/libs/libc/string/lib_stpcpy.c index 8728d4c222..ae1a9cbfb9 100644 --- a/libs/libc/string/lib_stpcpy.c +++ b/libs/libc/string/lib_stpcpy.c @@ -28,28 +28,6 @@ #include -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -#ifdef CONFIG_LIBC_STRING_OPTIMIZE -/* Nonzero if either x or y is not aligned on a "long" boundary. */ - -#define UNALIGNED(x, y) \ - (((long)(uintptr_t)(x) & (sizeof(long) - 1)) | ((long)(uintptr_t)(y) & (sizeof(long) - 1))) - -/* Macros for detecting endchar */ - -#if LONG_MAX == 2147483647 -# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080) -#elif LONG_MAX == 9223372036854775807 -/* Nonzero if x (a long int) contains a NULL byte. */ - -# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080) -#endif - -#endif - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -69,36 +47,9 @@ #ifndef CONFIG_LIBC_ARCH_STPCPY #undef stpcpy /* See mm/README.txt */ -nosanitize_address FAR char *stpcpy(FAR char *dest, FAR const char *src) { -#ifdef CONFIG_LIBC_STRING_OPTIMIZE - FAR long *aligned_dst; - FAR const long *aligned_src; - - /* If src or dest is unaligned, then copy bytes. */ - - if (!UNALIGNED(src, dest)) - { - aligned_dst = (FAR long *)dest; - aligned_src = (FAR long *)src; - - /* src and dest are both "long int" aligned, try to do "long int" - * sized copies. - */ - - while (!DETECTNULL(*aligned_src)) - { - *aligned_dst++ = *aligned_src++; - } - - dest = (FAR char *)aligned_dst; - src = (FAR char *)aligned_src; - } -#endif - while ((*dest++ = *src++) != '\0'); - return --dest; } #endif diff --git a/libs/libc/string/lib_stpncpy.c b/libs/libc/string/lib_stpncpy.c index b33c0b77d4..acbc1f3a45 100644 --- a/libs/libc/string/lib_stpncpy.c +++ b/libs/libc/string/lib_stpncpy.c @@ -28,34 +28,6 @@ #include #include -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -#ifdef CONFIG_LIBC_STRING_OPTIMIZE -/* Nonzero if either x or y is not aligned on a "long" boundary. */ - -#define UNALIGNED(x, y) \ - (((long)(uintptr_t)(x) & (sizeof(long) - 1)) | ((long)(uintptr_t)(y) & (sizeof(long) - 1))) - -/* How many bytes are loaded each iteration of the word copy loop. */ - -#define LBLOCKSIZE (sizeof(long)) - -/* Macros for detecting endchar */ - -#if LONG_MAX == 2147483647 -#define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080) -#elif LONG_MAX == 9223372036854775807 -/* Nonzero if x (a long int) contains a NULL byte. */ - -#define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080) -#endif - -#define TOO_SMALL(len) ((len) < sizeof(long)) - -#endif - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -87,49 +59,6 @@ #undef stpncpy /* See mm/README.txt */ FAR char *stpncpy(FAR char *dest, FAR const char *src, size_t n) { -#ifdef CONFIG_LIBC_STRING_OPTIMIZE - FAR char *ret = NULL; - FAR long *aligned_dst; - FAR const long *aligned_src; - - /* If src and dest is aligned and n large enough, then copy words. */ - - if (!UNALIGNED(src, dest) && !TOO_SMALL(n)) - { - aligned_dst = (FAR long *)dest; - aligned_src = (FAR long *)src; - - /* src and dest are both "long int" aligned, try to do "long int" - * sized copies. - */ - - while (n >= LBLOCKSIZE && !DETECTNULL(*aligned_src)) - { - n -= LBLOCKSIZE; - *aligned_dst++ = *aligned_src++; - } - - dest = (FAR char *)aligned_dst; - src = (FAR char *)aligned_src; - } - - while (n > 0) - { - --n; - if ((*dest++ = *src++) == '\0') - { - ret = dest - 1; - break; - } - } - - while (n-- > 0) - { - *dest++ = '\0'; - } - - return ret ? ret : dest; -#else FAR char *end = dest + n; /* End of dest buffer + 1 byte */ FAR char *ret; /* Value to be returned */ @@ -162,6 +91,5 @@ FAR char *stpncpy(FAR char *dest, FAR const char *src, size_t n) } return ret; -#endif } #endif diff --git a/libs/libc/string/lib_strcat.c b/libs/libc/string/lib_strcat.c index 175ff66776..7dcc5e4ee8 100644 --- a/libs/libc/string/lib_strcat.c +++ b/libs/libc/string/lib_strcat.c @@ -30,67 +30,14 @@ #include "libc.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -#ifdef CONFIG_LIBC_STRING_OPTIMIZE - -#define ALIGNED(x) \ - (((long)(uintptr_t)(x) & (sizeof(long) - 1)) == 0) - -/* Macros for detecting endchar */ - -#if LONG_MAX == 2147483647 -# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080) -#elif LONG_MAX == 9223372036854775807 -/* Nonzero if x (a long int) contains a NULL byte. */ - -# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080) -#endif - -#endif - /**************************************************************************** * Public Functions ****************************************************************************/ #if !defined(CONFIG_LIBC_ARCH_STRCAT) && defined(LIBC_BUILD_STRCAT) #undef strcat /* See mm/README.txt */ -nosanitize_address FAR char *strcat(FAR char *dest, FAR const char *src) { -#ifdef CONFIG_LIBC_STRING_OPTIMIZE - FAR char *ret = dest; - - /* Skip over the data in dest as quickly as possible. */ - - if (ALIGNED(dest)) - { - FAR unsigned long *aligned_s1 = (FAR unsigned long *)dest; - while (!DETECTNULL(*aligned_s1)) - { - aligned_s1++; - } - - dest = (FAR char *)aligned_s1; - } - - while (*dest) - { - dest++; - } - - /* dest now points to the its trailing null character, we can - * just use strcpy to do the work for us now. - * ?!? We might want to just include strcpy here. - * Also, this will cause many more unaligned string copies because - * dest is much less likely to be aligned. I don't know if its worth - * tweaking strcpy to handle this better. - */ - - strcpy(dest, src); -#else FAR char *ret = dest; dest += strlen(dest); @@ -100,7 +47,6 @@ FAR char *strcat(FAR char *dest, FAR const char *src) } *dest = '\0'; -#endif return ret; } diff --git a/libs/libc/string/lib_strchr.c b/libs/libc/string/lib_strchr.c index 750a56f3b7..98538abbb5 100644 --- a/libs/libc/string/lib_strchr.c +++ b/libs/libc/string/lib_strchr.c @@ -30,32 +30,6 @@ #include "libc.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -#ifdef CONFIG_LIBC_STRING_OPTIMIZE - -#define UNALIGNED(x) ((long)(uintptr_t)(x) & (sizeof(long) - 1)) - -/* How many bytes are loaded each iteration of the word copy loop. */ - -#define LBLOCKSIZE (sizeof(long)) - -/* Macros for detecting endchar */ - -#if LONG_MAX == 2147483647 -# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080) -#elif LONG_MAX == 9223372036854775807 -/* Nonzero if x (a long int) contains a NULL byte. */ - -# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080) -#endif - -#define DETECTCHAR(x, mask) (DETECTNULL((x) ^ (mask))) - -#endif - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -76,95 +50,8 @@ #if !defined(CONFIG_LIBC_ARCH_STRCHR) && defined(LIBC_BUILD_STRCHR) #undef strchr /* See mm/README.txt */ -nosanitize_address FAR char *strchr(FAR const char *s, int c) { -#ifdef CONFIG_LIBC_STRING_OPTIMIZE - FAR const unsigned char *s1 = (FAR const unsigned char *)s; - FAR unsigned long *aligned_addr; - unsigned char i = c; - unsigned long mask; - unsigned long j; - - /* Special case for finding 0. */ - - if (!i) - { - while (UNALIGNED(s1)) - { - if (!*s1) - { - return (FAR char *)s1; - } - - s1++; - } - - /* Operate a word at a time. */ - - aligned_addr = (FAR unsigned long *)s1; - while (!DETECTNULL(*aligned_addr)) - { - aligned_addr++; - } - - /* Found the end of string. */ - - s1 = (FAR const unsigned char *)aligned_addr; - while (*s1) - { - s1++; - } - - return (FAR char *)s1; - } - - /* All other bytes. Align the pointer, then search a long at a time. */ - - while (UNALIGNED(s1)) - { - if (!*s1) - { - return NULL; - } - - if (*s1 == i) - { - return (FAR char *)s1; - } - - s1++; - } - - mask = i; - for (j = 8; j < LBLOCKSIZE * 8; j <<= 1) - { - mask = (mask << j) | mask; - } - - aligned_addr = (FAR unsigned long *)s1; - while (!DETECTNULL(*aligned_addr) && !DETECTCHAR(*aligned_addr, mask)) - { - aligned_addr++; - } - - /* The block of bytes currently pointed to by aligned_addr - * contains either a null or the target char, or both. We - * catch it using the bytewise search. - */ - - s1 = (FAR unsigned char *)aligned_addr; - - while (*s1 && *s1 != i) - { - s1++; - } - - if (*s1 == i) - { - return (FAR char *)s1; - } -#else for (; ; s++) { if (*s == c) @@ -177,7 +64,6 @@ FAR char *strchr(FAR const char *s, int c) break; } } -#endif return NULL; } diff --git a/libs/libc/string/lib_strchrnul.c b/libs/libc/string/lib_strchrnul.c index 9cccb44ce9..d8433b695c 100644 --- a/libs/libc/string/lib_strchrnul.c +++ b/libs/libc/string/lib_strchrnul.c @@ -52,11 +52,6 @@ #undef strchrnul /* See mm/README.txt */ FAR char *strchrnul(FAR const char *s, int c) { -#ifdef CONFIG_LIBC_STRING_OPTIMIZE - FAR char *s1 = strchr(s, c); - - return s1 ? s1 : (FAR char *)s + strlen(s); -#else if (s) { while (*s != '\0' && *s != c) @@ -66,6 +61,5 @@ FAR char *strchrnul(FAR const char *s, int c) } return (FAR char *)s; -#endif } #endif diff --git a/libs/libc/string/lib_strcmp.c b/libs/libc/string/lib_strcmp.c index 8be2157859..f445d5f99a 100644 --- a/libs/libc/string/lib_strcmp.c +++ b/libs/libc/string/lib_strcmp.c @@ -30,80 +30,14 @@ #include "libc.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -#ifdef CONFIG_LIBC_STRING_OPTIMIZE -/* Nonzero if either x or y is not aligned on a "long" boundary. */ - -#define UNALIGNED(x, y) \ - (((long)(uintptr_t)(x) & (sizeof(long) - 1)) | ((long)(uintptr_t)(y) & (sizeof(long) - 1))) - -/* Macros for detecting endchar */ - -#if LONG_MAX == 2147483647 -# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080) -#elif LONG_MAX == 9223372036854775807 -/* Nonzero if x (a long int) contains a NULL byte. */ - -# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080) -#endif - -#endif - /**************************************************************************** * Public Functions ****************************************************************************/ #if !defined(CONFIG_LIBC_ARCH_STRCMP) && defined(LIBC_BUILD_STRCMP) #undef strcmp /* See mm/README.txt */ -nosanitize_address int strcmp(FAR const char *cs, FAR const char *ct) { -#ifdef CONFIG_LIBC_STRING_OPTIMIZE - FAR unsigned long *a1; - FAR unsigned long *a2; - - /* If cs or ct are unaligned, then compare bytes. */ - - if (!UNALIGNED(cs, ct)) - { - /* If cs and ct are word-aligned, compare them a word at a time. */ - - a1 = (FAR unsigned long *)cs; - a2 = (FAR unsigned long *)ct; - while (*a1 == *a2) - { - /* To get here, *a1 == *a2, thus if we find a null in *a1, - * then the strings must be equal, so return zero. - */ - - if (DETECTNULL(*a1)) - { - return 0; - } - - a1++; - a2++; - } - - /* A difference was detected in last few bytes of cs, - * so search bytewise. - */ - - cs = (FAR char *)a1; - ct = (FAR char *)a2; - } - - while (*cs != '\0' && *cs == *ct) - { - cs++; - ct++; - } - - return (*(FAR unsigned char *)cs) - (*(FAR unsigned char *)ct); -#else register int result; for (; ; ) { @@ -115,6 +49,5 @@ int strcmp(FAR const char *cs, FAR const char *ct) } return result; -#endif } #endif diff --git a/libs/libc/string/lib_strcpy.c b/libs/libc/string/lib_strcpy.c index d51718d0a6..38c73c3a48 100644 --- a/libs/libc/string/lib_strcpy.c +++ b/libs/libc/string/lib_strcpy.c @@ -30,28 +30,6 @@ #include "libc.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -#ifdef CONFIG_LIBC_STRING_OPTIMIZE -/* Nonzero if either x or y is not aligned on a "long" boundary. */ - -#define UNALIGNED(x, y) \ - (((long)(uintptr_t)(x) & (sizeof(long) - 1)) | ((long)(uintptr_t)(y) & (sizeof(long) - 1))) - -/* Macros for detecting endchar */ - -#if LONG_MAX == 2147483647 -# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080) -#elif LONG_MAX == 9223372036854775807 -/* Nonzero if x (a long int) contains a NULL byte. */ - -# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080) -#endif - -#endif - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -70,42 +48,10 @@ #if !defined(CONFIG_LIBC_ARCH_STRCPY) && defined(LIBC_BUILD_STRCPY) #undef strcpy /* See mm/README.txt */ -nosanitize_address FAR char *strcpy(FAR char *dest, FAR const char *src) { -#ifdef CONFIG_LIBC_STRING_OPTIMIZE - FAR char *dst0 = dest; - FAR const char *src0 = src; - FAR unsigned long *aligned_dst; - FAR const unsigned long *aligned_src; - - /* If SRC or DEST is unaligned, then copy bytes. */ - - if (!UNALIGNED(src0, dst0)) - { - aligned_dst = (FAR unsigned long *)dst0; - aligned_src = (FAR unsigned long *)src0; - - /* SRC and DEST are both "long int" aligned, try to do "long int" - * sized copies. - */ - - while (!DETECTNULL(*aligned_src)) - { - *aligned_dst++ = *aligned_src++; - } - - dst0 = (FAR char *)aligned_dst; - src0 = (FAR char *)aligned_src; - } - - while ((*dst0++ = *src0++) != '\0'); - - return dest; -#else FAR char *tmp = dest; while ((*dest++ = *src++) != '\0'); return tmp; -#endif } #endif diff --git a/libs/libc/string/lib_strlen.c b/libs/libc/string/lib_strlen.c index b465a1dbfb..594f01a481 100644 --- a/libs/libc/string/lib_strlen.c +++ b/libs/libc/string/lib_strlen.c @@ -30,77 +30,16 @@ #include "libc.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -#ifdef CONFIG_LIBC_STRING_OPTIMIZE - -#define LBLOCKSIZE (sizeof(long)) -#define UNALIGNED(x) ((long)(uintptr_t)(x) & (LBLOCKSIZE - 1)) - -/* Macros for detecting endchar */ - -#if LONG_MAX == 2147483647 -# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080) -#elif LONG_MAX == 9223372036854775807 -/* Nonzero if x (a long int) contains a NULL byte. */ - -# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080) -#endif - -#endif - /**************************************************************************** * Public Functions ****************************************************************************/ #if !defined(CONFIG_LIBC_ARCH_STRLEN) && defined(LIBC_BUILD_STRLEN) #undef strlen /* See mm/README.txt */ -nosanitize_address size_t strlen(FAR const char *s) { -#ifdef CONFIG_LIBC_STRING_OPTIMIZE - FAR const char *start = s; - FAR unsigned long *aligned_addr; - - /* Align the pointer, so we can search a word at a time. */ - - while (UNALIGNED(s)) - { - if (!*s) - { - return s - start; - } - - s++; - } - - /* If the string is word-aligned, we can check for the presence of - * a null in each word-sized block. - */ - - aligned_addr = (FAR unsigned long *)s; - while (!DETECTNULL(*aligned_addr)) - { - aligned_addr++; - } - - /* Once a null is detected, we check each byte in that block for a - * precise position of the null. - */ - - s = (FAR char *)aligned_addr; - while (*s) - { - s++; - } - - return s - start; -#else FAR const char *sc; for (sc = s; *sc != '\0'; ++sc); return sc - s; -#endif } #endif diff --git a/libs/libc/string/lib_strncmp.c b/libs/libc/string/lib_strncmp.c index 92f79e957e..e46c7abbce 100644 --- a/libs/libc/string/lib_strncmp.c +++ b/libs/libc/string/lib_strncmp.c @@ -30,99 +30,14 @@ #include "libc.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -#ifdef CONFIG_LIBC_STRING_OPTIMIZE - -#define LBLOCKSIZE (sizeof(long)) - -/* Nonzero if either x or y is not aligned on a "long" boundary. */ - -#define UNALIGNED(x, y) \ - (((long)(uintptr_t)(x) & (sizeof(long) - 1)) | ((long)(uintptr_t)(y) & (sizeof(long) - 1))) - -/* Macros for detecting endchar */ - -#if LONG_MAX == 2147483647 -# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080) -#elif LONG_MAX == 9223372036854775807 -/* Nonzero if x (a long int) contains a NULL byte. */ - -# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080) -#endif - -#endif - /**************************************************************************** * Public Functions ****************************************************************************/ #if !defined(CONFIG_LIBC_ARCH_STRNCMP) && defined(LIBC_BUILD_STRNCMP) #undef strncmp /* See mm/README.txt */ -nosanitize_address int strncmp(FAR const char *cs, FAR const char *ct, size_t nb) { -#ifdef CONFIG_LIBC_STRING_OPTIMIZE - FAR unsigned long *a1; - FAR unsigned long *a2; - - if (nb == 0) - { - return 0; - } - - /* If cs or ct are unaligned, then compare bytes. */ - - if (!UNALIGNED(cs, ct)) - { - /* If cs and ct are word-aligned, compare them a word at a time. */ - - a1 = (FAR unsigned long *)cs; - a2 = (FAR unsigned long *)ct; - while (nb >= LBLOCKSIZE && *a1 == *a2) - { - nb -= LBLOCKSIZE; - - /* If we've run out of bytes or hit a null, return zero - * since we already know *a1 == *a2. - */ - - if (nb == 0 || DETECTNULL(*a1)) - { - return 0; - } - - a1++; - a2++; - } - - /* A difference was detected in last few bytes of cs, so search - * bytewise. - */ - - cs = (FAR char *)a1; - ct = (FAR char *)a2; - } - - while (nb-- > 0 && *cs == *ct) - { - /* If we've run out of bytes or hit a null, return zero - * since we already know *cs == *ct. - */ - - if (nb == 0 || *cs == '\0') - { - return 0; - } - - cs++; - ct++; - } - - return *cs - *ct; -#else register int result = 0; for (; nb > 0; nb--) { @@ -134,6 +49,5 @@ int strncmp(FAR const char *cs, FAR const char *ct, size_t nb) } return result; -#endif } #endif diff --git a/libs/libc/string/lib_strncpy.c b/libs/libc/string/lib_strncpy.c index 29a903e92b..3e36df4ff5 100644 --- a/libs/libc/string/lib_strncpy.c +++ b/libs/libc/string/lib_strncpy.c @@ -30,33 +30,6 @@ #include "libc.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -#ifdef CONFIG_LIBC_STRING_OPTIMIZE - -#define LBLOCKSIZE (sizeof(long)) - -/* Nonzero if either x or y is not aligned on a "long" boundary. */ - -#define UNALIGNED(x, y) \ - (((long)(uintptr_t)(x) & (sizeof(long) - 1)) | ((long)(uintptr_t)(y) & (sizeof(long) - 1))) - -/* Macros for detecting endchar */ - -#if LONG_MAX == 2147483647 -# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080) -#elif LONG_MAX == 9223372036854775807 -/* Nonzero if x (a long int) contains a NULL byte. */ - -# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080) -#endif - -#define TOO_SMALL(len) ((len) < sizeof(long)) - -#endif - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -84,52 +57,8 @@ #if !defined(CONFIG_LIBC_ARCH_STRNCPY) && defined(LIBC_BUILD_STRNCPY) #undef strncpy /* See mm/README.txt */ -nosanitize_address FAR char *strncpy(FAR char *dest, FAR const char *src, size_t n) { -#ifdef CONFIG_LIBC_STRING_OPTIMIZE - FAR char *dst0 = dest; - FAR const char *src0 = src; - FAR long *aligned_dst; - FAR const long *aligned_src; - - /* If src and dest is aligned and n large enough, then copy words. */ - - if (!UNALIGNED(src0, dst0) && !TOO_SMALL(n)) - { - aligned_dst = (FAR long *)dst0; - aligned_src = (FAR long *)src0; - - /* src and dest are both "long int" aligned, try to do "long int" - * sized copies. - */ - - while (n >= LBLOCKSIZE && !DETECTNULL(*aligned_src)) - { - n -= LBLOCKSIZE; - *aligned_dst++ = *aligned_src++; - } - - dst0 = (FAR char *)aligned_dst; - src0 = (FAR char *)aligned_src; - } - - while (n > 0) - { - --n; - if ((*dst0++ = *src0++) == '\0') - { - break; - } - } - - while (n-- > 0) - { - *dst0++ = '\0'; - } - - return dest; -#else FAR char *ret = dest; /* Value to be returned */ FAR char *end = dest + n; /* End of dest buffer + 1 byte */ @@ -151,6 +80,5 @@ FAR char *strncpy(FAR char *dest, FAR const char *src, size_t n) } return ret; -#endif } #endif diff --git a/libs/libc/string/lib_strrchr.c b/libs/libc/string/lib_strrchr.c index a448f27757..d19afc743b 100644 --- a/libs/libc/string/lib_strrchr.c +++ b/libs/libc/string/lib_strrchr.c @@ -42,24 +42,6 @@ #undef strrchr /* See mm/README.txt */ FAR char *strrchr(FAR const char *s, int c) { -#ifdef CONFIG_LIBC_STRING_OPTIMIZE - FAR const char *last = NULL; - - if (c) - { - while ((s = strchr(s, c))) - { - last = s; - s++; - } - } - else - { - last = strchr(s, c); - } - - return (FAR char *)last; -#else FAR const char *r = NULL; do @@ -72,6 +54,5 @@ FAR char *strrchr(FAR const char *s, int c) while (*s++ != '\0'); return (FAR char *)r; -#endif } #endif