diff --git a/include/nuttx/compiler.h b/include/nuttx/compiler.h index 5c5c25be295..15a0f059a9a 100644 --- a/include/nuttx/compiler.h +++ b/include/nuttx/compiler.h @@ -64,6 +64,18 @@ # define UNUSED(a) ((void)(a)) +/* Built-in functions */ + +/* GCC 4.x have __builtin_ctz(|l|ll) and __builtin_clz(|l|ll). These count + * trailing/leading zeros of input number and typically will generate few + * fast bit-counting instructions. Inputting zero to these functions is + * undefined and needs to be taken care of by the caller. */ + +#if __GNUC__ >= 4 +# define CONFIG_HAVE_BUILTIN_CTZ 1 +# define CONFIG_HAVE_BUILTIN_CLZ 1 +#endif + /* Attributes * * GCC supports weak symbols which can be used to reduce code size because diff --git a/include/strings.h b/include/strings.h index 4b7fc439da4..54be5dd380e 100644 --- a/include/strings.h +++ b/include/strings.h @@ -114,6 +114,17 @@ static inline FAR char *rindex(FAR const char *s, int c) ****************************************************************************/ int ffs(int j); +int ffsl(long j); +#ifdef CONFIG_HAVE_LONG_LONG +int ffsll(long long j); +#endif + +int fls(int j); +int flsl(long j); +#ifdef CONFIG_HAVE_LONG_LONG +int flsll(long long j); +#endif + int strcasecmp(FAR const char *, FAR const char *); int strncasecmp(FAR const char *, FAR const char *, size_t); diff --git a/libc/string/Make.defs b/libc/string/Make.defs index defedcfb60a..72cb8354d53 100644 --- a/libc/string/Make.defs +++ b/libc/string/Make.defs @@ -35,7 +35,8 @@ # Add the string C files to the build -CSRCS += lib_ffs.c lib_isbasedigit.c lib_memset.c lib_memchr.c +CSRCS += lib_ffs.c lib_ffsl.c lib_ffsll.c lib_fls.c lib_flsl.c +CSRCS += lib_flsll.c lib_isbasedigit.c lib_memset.c lib_memchr.c CSRCS += lib_memccpy.c lib_memcmp.c lib_memmove.c lib_skipspace.c CSRCS += lib_stpcpy.c lib_strcasecmp.c lib_strcat.c lib_strchr.c CSRCS += lib_strcpy.c lib_strcmp.c lib_strcspn.c lib_strdup.c diff --git a/libc/string/lib_ffs.c b/libc/string/lib_ffs.c index c52a9c43b23..885718ba49e 100644 --- a/libc/string/lib_ffs.c +++ b/libc/string/lib_ffs.c @@ -33,11 +33,11 @@ * ****************************************************************************/ - /**************************************************************************** * Included Files ****************************************************************************/ +#include #include /**************************************************************************** @@ -55,11 +55,11 @@ * * Description: * The ffs() function will find the first bit set (beginning with the least - * significant bit) in i, and return the index of that bit. Bits are + * significant bit) in j, and return the index of that bit. Bits are * numbered starting at one (the least significant bit). * * Returned Value: - * The ffs() function will return the index of the first bit set. If i is + * The ffs() function will return the index of the first bit set. If j is * 0, then ffs() will return 0. * ****************************************************************************/ @@ -70,6 +70,11 @@ int ffs(int j) if (j != 0) { +#ifdef CONFIG_HAVE_BUILTIN_CTZ + /* Count trailing zeros function can be used to implement ffs. */ + + ret = __builtin_ctz(j) + 1; +#else unsigned int value = (unsigned int)j; int bitno; @@ -81,6 +86,7 @@ int ffs(int j) break; } } +#endif } return ret; diff --git a/libc/string/lib_ffsl.c b/libc/string/lib_ffsl.c new file mode 100644 index 00000000000..4d5739cc03b --- /dev/null +++ b/libc/string/lib_ffsl.c @@ -0,0 +1,93 @@ +/**************************************************************************** + * libc/string/lib_ffsl.c + * + * Copyright (C) 2017 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define NBITS (8 * sizeof(unsigned long)) + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: ffsl + * + * Description: + * The ffsl() function will find the first bit set (beginning with the least + * significant bit) in j, and return the index of that bit. Bits are + * numbered starting at one (the least significant bit). + * + * Returned Value: + * The ffsl() function will return the index of the first bit set. If j is + * 0, then ffsl() will return 0. + * + ****************************************************************************/ + +int ffsl(long j) +{ + int ret = 0; + + if (j != 0) + { +#ifdef CONFIG_HAVE_BUILTIN_CTZ + /* Count trailing zeros function can be used to implement ffs. */ + + ret = __builtin_ctzl(j) + 1; +#else + unsigned long value = (unsigned long)j; + int bitno; + + for (bitno = 1; bitno <= NBITS; bitno++, value >>= 1) + { + if ((value & 1) != 0) + { + ret = bitno; + break; + } + } +#endif + } + + return ret; +} diff --git a/libc/string/lib_ffsll.c b/libc/string/lib_ffsll.c new file mode 100644 index 00000000000..111e664d422 --- /dev/null +++ b/libc/string/lib_ffsll.c @@ -0,0 +1,97 @@ +/**************************************************************************** + * libc/string/lib_ffsll.c + * + * Copyright (C) 2017 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define NBITS (8 * sizeof(unsigned long long)) + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifdef CONFIG_HAVE_LONG_LONG + +/**************************************************************************** + * Name: ffsll + * + * Description: + * The ffsll() function will find the first bit set (beginning with the least + * significant bit) in i, and return the index of that bit. Bits are + * numbered starting at one (the least significant bit). + * + * Returned Value: + * The ffsll() function will return the index of the first bit set. If j is + * 0, then ffsll() will return 0. + * + ****************************************************************************/ + +int ffsll(long long j) +{ + int ret = 0; + + if (j != 0) + { +#ifdef CONFIG_HAVE_BUILTIN_CTZ + /* Count trailing zeros function can be used to implement ffs. */ + + ret = __builtin_ctzll(j) + 1; +#else + unsigned long long value = (unsigned long long)j; + int bitno; + + for (bitno = 1; bitno <= NBITS; bitno++, value >>= 1) + { + if ((value & 1) != 0) + { + ret = bitno; + break; + } + } +#endif + } + + return ret; +} + +#endif diff --git a/libc/string/lib_fls.c b/libc/string/lib_fls.c new file mode 100644 index 00000000000..5894fb1953a --- /dev/null +++ b/libc/string/lib_fls.c @@ -0,0 +1,93 @@ +/**************************************************************************** + * libc/string/lib_fls.c + * + * Copyright (C) 2017 Haltian Ltd. All rights reserved. + * Author: Jussi Kivilinna + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define NBITS (8 * sizeof(unsigned int)) + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: fls + * + * Description: + * The fls() function will find the last bit set in value and return + * the index of that bit. Bits are numbered starting at one (the least + * significant bit). + * + * Returned Value: + * The fls() function will return the index of the last bit set. If j is + * 0, then fls() will return 0. + * + ****************************************************************************/ + +int fls(int j) +{ + int ret = 0; + + if (j != 0) + { +#ifdef CONFIG_HAVE_BUILTIN_CLZ + /* Count leading zeros function can be used to implement fls. */ + + ret = NBITS - __builtin_clz(j); +#else + unsigned int value = (unsigned int)j; + int bitno; + + for (bitno = 1; bitno <= NBITS; bitno++, value >>= 1) + { + if (value == 1) + { + ret = bitno; + break; + } + } +#endif + } + + return ret; +} diff --git a/libc/string/lib_flsl.c b/libc/string/lib_flsl.c new file mode 100644 index 00000000000..2a3837ddc7e --- /dev/null +++ b/libc/string/lib_flsl.c @@ -0,0 +1,93 @@ +/**************************************************************************** + * libc/string/lib_fls.c + * + * Copyright (C) 2017 Haltian Ltd. All rights reserved. + * Author: Jussi Kivilinna + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define NBITS (8 * sizeof(unsigned long)) + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: flsl + * + * Description: + * The flsl() function will find the last bit set in value and return + * the index of that bit. Bits are numbered starting at one (the least + * significant bit). + * + * Returned Value: + * The flsl() function will return the index of the last bit set. If j is + * 0, then flsl() will return 0. + * + ****************************************************************************/ + +int flsl(long j) +{ + int ret = 0; + + if (j != 0) + { +#ifdef CONFIG_HAVE_BUILTIN_CLZ + /* Count leading zeros function can be used to implement fls. */ + + ret = NBITS - __builtin_clzl(j); +#else + unsigned long value = (unsigned long)j; + int bitno; + + for (bitno = 1; bitno <= NBITS; bitno++, value >>= 1) + { + if (value == 1) + { + ret = bitno; + break; + } + } +#endif + } + + return ret; +} diff --git a/libc/string/lib_flsll.c b/libc/string/lib_flsll.c new file mode 100644 index 00000000000..2f30f8142e1 --- /dev/null +++ b/libc/string/lib_flsll.c @@ -0,0 +1,98 @@ +/**************************************************************************** + * libc/string/lib_fls.c + * + * Copyright (C) 2017 Haltian Ltd. All rights reserved. + * Author: Jussi Kivilinna + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define NBITS (8 * sizeof(unsigned long long)) + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifdef CONFIG_HAVE_LONG_LONG + +/**************************************************************************** + * Name: flsll + * + * Description: + * The flsll() function will find the last bit set in value and return + * the index of that bit. Bits are numbered starting at one (the least + * significant bit). + * + * Returned Value: + * The flsll() function will return the index of the last bit set. If j is + * 0, then flsll() will return 0. + * + ****************************************************************************/ + +int flsll(long long j) +{ + int ret = 0; + + if (j != 0) + { +#ifdef CONFIG_HAVE_BUILTIN_CLZ + /* Count leading zeros function can be used to implement fls. */ + + ret = NBITS - __builtin_clzll(j); +#else + unsigned long long value = (unsigned long long)j; + int bitno; + + for (bitno = 1; bitno <= NBITS; bitno++, value >>= 1) + { + if (value == 1) + { + ret = bitno; + break; + } + } +#endif + } + + return ret; +} + +#endif +