diff --git a/libs/libc/string/CMakeLists.txt b/libs/libc/string/CMakeLists.txt index a862919faa5..eb1f5494ee3 100644 --- a/libs/libc/string/CMakeLists.txt +++ b/libs/libc/string/CMakeLists.txt @@ -59,7 +59,6 @@ set(SRCS lib_mempcpy.c lib_rawmemchr.c lib_memmove.c - lib_memset.c lib_strlcat.c lib_strlcpy.c lib_strnlen.c) @@ -83,6 +82,7 @@ if(CONFIG_LIBC_NEWLIB_OPTSPEED) lib_bsdmemccpy.c lib_bsdmemcmp.c lib_bsdmemrchr.c + lib_bsdmemset.c lib_bsdstpncpy.c lib_bsdstrchr.c lib_bsdstrcmp.c @@ -102,6 +102,7 @@ else() lib_memccpy.c lib_memcmp.c lib_memrchr.c + lib_memset.c lib_stpncpy.c lib_strchr.c lib_strcmp.c diff --git a/libs/libc/string/Make.defs b/libs/libc/string/Make.defs index 4d909c51bb4..d0c90d88d1b 100644 --- a/libs/libc/string/Make.defs +++ b/libs/libc/string/Make.defs @@ -34,7 +34,7 @@ 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 -CSRCS += lib_memmove.c lib_memset.c +CSRCS += lib_memmove.c CSRCS += lib_strlcat.c CSRCS += lib_strlcpy.c lib_strnlen.c @@ -54,12 +54,12 @@ ifeq ($(CONFIG_LIBC_NEWLIB_OPTSPEED),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 +CSRCS += lib_bsdstrcpy.c lib_bsdstrncmp.c lib_bsdstrrchr.c lib_memset.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 +CSRCS += lib_strcpy.c lib_strncmp.c lib_strrchr.c lib_memset.c endif # Add the string directory to the build diff --git a/libs/libc/string/lib_bsdmemset.c b/libs/libc/string/lib_bsdmemset.c new file mode 100644 index 00000000000..21ca7d6b058 --- /dev/null +++ b/libs/libc/string/lib_bsdmemset.c @@ -0,0 +1,113 @@ +/**************************************************************************** + * libs/libc/string/lib_bsdmemset.c + * + * SPDX-License-Identifier: BSD + * SPDX-FileCopyrightText: 1994-2009 Red Hat, Inc. All rights reserved + * + * 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)(x) & (LBLOCKSIZE - 1)) +#define TOO_SMALL(len) ((len) < LBLOCKSIZE) + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: memset + ****************************************************************************/ + +#if !defined(CONFIG_LIBC_ARCH_MEMSET) && defined(LIBC_BUILD_MEMSET) +#undef memset +no_builtin("memset") +FAR void *memset(FAR void *m, int c, size_t n) +{ + FAR unsigned long *aligned_addr; + FAR char *s = (FAR char *)m; + unsigned long buffer; + int i; + + /* To avoid sign extension, copy C to an unsigned variable. */ + + while (UNALIGNED(s)) + { + if (n--) + { + *s++ = c; + } + else + { + return m; + } + } + + if (!TOO_SMALL(n)) + { + /* If we get this far, we know that n is large and s is word-aligned. */ + + aligned_addr = (FAR unsigned long *)s; + buffer = ((unsigned int)c << 8) | c; + buffer |= (buffer << 16); + for (i = 32; i < LBLOCKSIZE * 8; i <<= 1) + { + buffer = (buffer << i) | buffer; + } + + /* Unroll the loop. */ + + while (n >= LBLOCKSIZE * 4) + { + *aligned_addr++ = buffer; + *aligned_addr++ = buffer; + *aligned_addr++ = buffer; + *aligned_addr++ = buffer; + n -= 4 * LBLOCKSIZE; + } + + while (n >= LBLOCKSIZE) + { + *aligned_addr++ = buffer; + n -= LBLOCKSIZE; + } + + /* Pick up the remainder with a bytewise loop. */ + + s = (FAR char *)aligned_addr; + } + + while (n--) + { + *s++ = c; + } + + return m; +} +#endif