Browse Source
The Blackfin sim uses this function, but Windows/mingw doesn't provide it.binutils-2_37-branch
13 changed files with 580 additions and 22 deletions
@ -0,0 +1,68 @@ |
|||
/* ffs.c -- find the first set bit in a word.
|
|||
Copyright (C) 2011-2021 Free Software Foundation, Inc. |
|||
|
|||
This program is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation; either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
This program is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
|||
|
|||
/* Written by Eric Blake. */ |
|||
|
|||
#include <config.h> |
|||
|
|||
/* Specification. */ |
|||
#include <strings.h> |
|||
|
|||
#include <limits.h> |
|||
|
|||
#if defined _MSC_VER && !(__clang_major__ >= 4) |
|||
# include <intrin.h> |
|||
#endif |
|||
|
|||
int |
|||
ffs (int i) |
|||
{ |
|||
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__clang_major__ >= 4) |
|||
return __builtin_ffs (i); |
|||
#elif defined _MSC_VER |
|||
/* _BitScanForward
|
|||
<https://docs.microsoft.com/en-us/cpp/intrinsics/bitscanforward-bitscanforward64> */
|
|||
unsigned long bit; |
|||
if (_BitScanForward (&bit, i)) |
|||
return bit + 1; |
|||
else |
|||
return 0; |
|||
#else |
|||
/* <https://github.com/gibsjose/BitHacks>
|
|||
gives this deBruijn constant for a branch-less computation, although |
|||
that table counted trailing zeros rather than bit position. This |
|||
requires 32-bit int, we fall back to a naive algorithm on the rare |
|||
platforms where that assumption is not true. */ |
|||
if (CHAR_BIT * sizeof i == 32) |
|||
{ |
|||
static unsigned int table[] = { |
|||
1, 2, 29, 3, 30, 15, 25, 4, 31, 23, 21, 16, 26, 18, 5, 9, |
|||
32, 28, 14, 24, 22, 20, 17, 8, 27, 13, 19, 7, 12, 6, 11, 10 |
|||
}; |
|||
unsigned int u = i; |
|||
unsigned int bit = u & -u; |
|||
return table[(bit * 0x077cb531U) >> 27] - !i; |
|||
} |
|||
else |
|||
{ |
|||
unsigned int j; |
|||
for (j = 0; j < CHAR_BIT * sizeof i; j++) |
|||
if (i & (1U << j)) |
|||
return j + 1; |
|||
return 0; |
|||
} |
|||
#endif |
|||
} |
|||
@ -0,0 +1,32 @@ |
|||
# ffs.m4 serial 4 |
|||
dnl Copyright (C) 2011-2021 Free Software Foundation, Inc. |
|||
dnl This file is free software; the Free Software Foundation |
|||
dnl gives unlimited permission to copy and/or distribute it, |
|||
dnl with or without modifications, as long as this notice is preserved. |
|||
|
|||
AC_DEFUN([gl_FUNC_FFS], |
|||
[ |
|||
AC_REQUIRE([gl_HEADER_STRINGS_H_DEFAULTS]) |
|||
|
|||
dnl We can't use AC_CHECK_FUNC here, because ffs() is defined as a |
|||
dnl static inline function when compiling for Android 4.2 or older. |
|||
dnl But require that ffs() is declared; otherwise we may be using |
|||
dnl the GCC built-in function, which leads to warnings |
|||
dnl "warning: implicit declaration of function 'ffs'". |
|||
AC_CACHE_CHECK([for ffs], [gl_cv_func_ffs], |
|||
[AC_LINK_IFELSE( |
|||
[AC_LANG_PROGRAM( |
|||
[[#include <strings.h> |
|||
int x; |
|||
]], |
|||
[[int (*func) (int) = ffs; |
|||
return func (x); |
|||
]]) |
|||
], |
|||
[gl_cv_func_ffs=yes], |
|||
[gl_cv_func_ffs=no]) |
|||
]) |
|||
if test $gl_cv_func_ffs = no; then |
|||
HAVE_FFS=0 |
|||
fi |
|||
]) |
|||
@ -0,0 +1,52 @@ |
|||
# Configure a replacement for <strings.h>. |
|||
# serial 6 |
|||
|
|||
# Copyright (C) 2007, 2009-2021 Free Software Foundation, Inc. |
|||
# This file is free software; the Free Software Foundation |
|||
# gives unlimited permission to copy and/or distribute it, |
|||
# with or without modifications, as long as this notice is preserved. |
|||
|
|||
AC_DEFUN([gl_HEADER_STRINGS_H], |
|||
[ |
|||
dnl Use AC_REQUIRE here, so that the default behavior below is expanded |
|||
dnl once only, before all statements that occur in other macros. |
|||
AC_REQUIRE([gl_HEADER_STRINGS_H_BODY]) |
|||
]) |
|||
|
|||
AC_DEFUN([gl_HEADER_STRINGS_H_BODY], |
|||
[ |
|||
AC_REQUIRE([gl_HEADER_STRINGS_H_DEFAULTS]) |
|||
|
|||
gl_CHECK_NEXT_HEADERS([strings.h]) |
|||
if test $ac_cv_header_strings_h = yes; then |
|||
HAVE_STRINGS_H=1 |
|||
else |
|||
HAVE_STRINGS_H=0 |
|||
fi |
|||
AC_SUBST([HAVE_STRINGS_H]) |
|||
|
|||
dnl Check for declarations of anything we want to poison if the |
|||
dnl corresponding gnulib module is not in use. |
|||
gl_WARN_ON_USE_PREPARE([[ |
|||
/* Minix 3.1.8 has a bug: <sys/types.h> must be included before |
|||
<strings.h>. */ |
|||
#include <sys/types.h> |
|||
#include <strings.h> |
|||
]], [ffs strcasecmp strncasecmp]) |
|||
]) |
|||
|
|||
AC_DEFUN([gl_STRINGS_MODULE_INDICATOR], |
|||
[ |
|||
dnl Use AC_REQUIRE here, so that the default settings are expanded once only. |
|||
AC_REQUIRE([gl_HEADER_STRINGS_H_DEFAULTS]) |
|||
gl_MODULE_INDICATOR_SET_VARIABLE([$1]) |
|||
]) |
|||
|
|||
AC_DEFUN([gl_HEADER_STRINGS_H_DEFAULTS], |
|||
[ |
|||
GNULIB_FFS=0; AC_SUBST([GNULIB_FFS]) |
|||
dnl Assume proper GNU behavior unless another module says otherwise. |
|||
HAVE_FFS=1; AC_SUBST([HAVE_FFS]) |
|||
HAVE_STRCASECMP=1; AC_SUBST([HAVE_STRCASECMP]) |
|||
HAVE_DECL_STRNCASECMP=1; AC_SUBST([HAVE_DECL_STRNCASECMP]) |
|||
]) |
|||
@ -0,0 +1,122 @@ |
|||
/* A substitute <strings.h>.
|
|||
|
|||
Copyright (C) 2007-2021 Free Software Foundation, Inc. |
|||
|
|||
This program is free software; you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation; either version 3, or (at your option) |
|||
any later version. |
|||
|
|||
This program is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with this program; if not, see <https://www.gnu.org/licenses/>. */
|
|||
|
|||
#ifndef _@GUARD_PREFIX@_STRINGS_H |
|||
|
|||
#if __GNUC__ >= 3 |
|||
@PRAGMA_SYSTEM_HEADER@ |
|||
#endif |
|||
@PRAGMA_COLUMNS@ |
|||
|
|||
/* Minix 3.1.8 has a bug: <sys/types.h> must be included before <strings.h>.
|
|||
But avoid namespace pollution on glibc systems. */ |
|||
#if defined __minix && !defined __GLIBC__ |
|||
# include <sys/types.h> |
|||
#endif |
|||
|
|||
/* The include_next requires a split double-inclusion guard. */ |
|||
#if @HAVE_STRINGS_H@ |
|||
# @INCLUDE_NEXT@ @NEXT_STRINGS_H@ |
|||
#endif |
|||
|
|||
#ifndef _@GUARD_PREFIX@_STRINGS_H |
|||
#define _@GUARD_PREFIX@_STRINGS_H |
|||
|
|||
#if ! @HAVE_DECL_STRNCASECMP@ |
|||
/* Get size_t. */ |
|||
# include <stddef.h> |
|||
#endif |
|||
|
|||
|
|||
/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ |
|||
|
|||
/* The definition of _GL_ARG_NONNULL is copied here. */ |
|||
|
|||
/* The definition of _GL_WARN_ON_USE is copied here. */ |
|||
|
|||
#ifdef __cplusplus |
|||
extern "C" { |
|||
#endif |
|||
|
|||
|
|||
/* Find the index of the least-significant set bit. */ |
|||
#if @GNULIB_FFS@ |
|||
# if !@HAVE_FFS@ |
|||
_GL_FUNCDECL_SYS (ffs, int, (int i)); |
|||
# endif |
|||
_GL_CXXALIAS_SYS (ffs, int, (int i)); |
|||
_GL_CXXALIASWARN (ffs); |
|||
#elif defined GNULIB_POSIXCHECK |
|||
# undef ffs |
|||
# if HAVE_RAW_DECL_FFS |
|||
_GL_WARN_ON_USE (ffs, "ffs is not portable - use the ffs module"); |
|||
# endif |
|||
#endif |
|||
|
|||
/* Compare strings S1 and S2, ignoring case, returning less than, equal to or
|
|||
greater than zero if S1 is lexicographically less than, equal to or greater |
|||
than S2. |
|||
Note: This function does not work in multibyte locales. */ |
|||
#if ! @HAVE_STRCASECMP@ |
|||
extern int strcasecmp (char const *s1, char const *s2) |
|||
_GL_ARG_NONNULL ((1, 2)); |
|||
#endif |
|||
#if defined GNULIB_POSIXCHECK |
|||
/* strcasecmp() does not work with multibyte strings:
|
|||
POSIX says that it operates on "strings", and "string" in POSIX is defined |
|||
as a sequence of bytes, not of characters. */ |
|||
# undef strcasecmp |
|||
# if HAVE_RAW_DECL_STRCASECMP |
|||
_GL_WARN_ON_USE (strcasecmp, "strcasecmp cannot work correctly on character " |
|||
"strings in multibyte locales - " |
|||
"use mbscasecmp if you care about " |
|||
"internationalization, or use c_strcasecmp , " |
|||
"gnulib module c-strcase) if you want a locale " |
|||
"independent function"); |
|||
# endif |
|||
#endif |
|||
|
|||
/* Compare no more than N bytes of strings S1 and S2, ignoring case,
|
|||
returning less than, equal to or greater than zero if S1 is |
|||
lexicographically less than, equal to or greater than S2. |
|||
Note: This function cannot work correctly in multibyte locales. */ |
|||
#if ! @HAVE_DECL_STRNCASECMP@ |
|||
extern int strncasecmp (char const *s1, char const *s2, size_t n) |
|||
_GL_ARG_NONNULL ((1, 2)); |
|||
#endif |
|||
#if defined GNULIB_POSIXCHECK |
|||
/* strncasecmp() does not work with multibyte strings:
|
|||
POSIX says that it operates on "strings", and "string" in POSIX is defined |
|||
as a sequence of bytes, not of characters. */ |
|||
# undef strncasecmp |
|||
# if HAVE_RAW_DECL_STRNCASECMP |
|||
_GL_WARN_ON_USE (strncasecmp, "strncasecmp cannot work correctly on character " |
|||
"strings in multibyte locales - " |
|||
"use mbsncasecmp or mbspcasecmp if you care about " |
|||
"internationalization, or use c_strncasecmp , " |
|||
"gnulib module c-strcase) if you want a locale " |
|||
"independent function"); |
|||
# endif |
|||
#endif |
|||
|
|||
|
|||
#ifdef __cplusplus |
|||
} |
|||
#endif |
|||
|
|||
#endif /* _@GUARD_PREFIX@_STRING_H */ |
|||
#endif /* _@GUARD_PREFIX@_STRING_H */ |
|||
Loading…
Reference in new issue