diff options
author | Bruno Haible <bruno@clisp.org> | 2022-09-05 01:34:36 +0200 |
---|---|---|
committer | Bruno Haible <bruno@clisp.org> | 2022-09-05 01:34:36 +0200 |
commit | 6689528e4b24e199b3feba2381cafc6905f249c5 (patch) | |
tree | 23b6eb90c42b06ba1b28f41118336df7f221a66d | |
parent | 3730c889a4b671ea4513374a6977b941494a29bd (diff) | |
download | gnulib-6689528e4b24e199b3feba2381cafc6905f249c5.tar.gz |
count-leading-zeros: Fix a link error on 32-bit MSVC and a test failure.
* lib/count-leading-zeros.h: Correct syntax for #pragma intrinsic.
(COUNT_LEADING_ZEROS): Fix the return value.
(count_leading_zeros_ll): Use two _BitScanReverse invocations instead
of a _BitScanReverse64 invocation.
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | lib/count-leading-zeros.h | 20 |
2 files changed, 25 insertions, 3 deletions
@@ -1,5 +1,13 @@ 2022-09-04 Bruno Haible <bruno@clisp.org> + count-leading-zeros: Fix a link error on 32-bit MSVC and a test failure. + * lib/count-leading-zeros.h: Correct syntax for #pragma intrinsic. + (COUNT_LEADING_ZEROS): Fix the return value. + (count_leading_zeros_ll): Use two _BitScanReverse invocations instead + of a _BitScanReverse64 invocation. + +2022-09-04 Bruno Haible <bruno@clisp.org> + count-trailing-zeros: Fix a link error on 32-bit MSVC. * lib/count-trailing-zeros.h: Correct syntax for #pragma intrinsic. (count_trailing_zeros_ll): Use two _BitScanForward invocations instead diff --git a/lib/count-leading-zeros.h b/lib/count-leading-zeros.h index 354641af0a..4b4f5d4f9a 100644 --- a/lib/count-leading-zeros.h +++ b/lib/count-leading-zeros.h @@ -43,13 +43,17 @@ extern "C" { # define COUNT_LEADING_ZEROS(BUILTIN, MSC_BUILTIN, TYPE) \ return x ? BUILTIN (x) : CHAR_BIT * sizeof x; #elif _MSC_VER -# pragma intrinsic _BitScanReverse -# pragma intrinsic _BitScanReverse64 +# pragma intrinsic (_BitScanReverse) +# if defined _M_X64 +# pragma intrinsic (_BitScanReverse64) +# endif # define COUNT_LEADING_ZEROS(BUILTIN, MSC_BUILTIN, TYPE) \ do \ { \ unsigned long result; \ - return MSC_BUILTIN (&result, x) ? result : CHAR_BIT * sizeof x; \ + if (MSC_BUILTIN (&result, x)) \ + return CHAR_BIT * sizeof x - 1 - result; \ + return CHAR_BIT * sizeof x; \ } \ while (0) #else @@ -109,8 +113,18 @@ count_leading_zeros_l (unsigned long int x) COUNT_LEADING_ZEROS_INLINE int count_leading_zeros_ll (unsigned long long int x) { +#if (defined _MSC_VER && !defined __clang__) && !defined _M_X64 + /* 32-bit MSVC does not have _BitScanReverse64, only _BitScanReverse. */ + unsigned long result; + if (_BitScanReverse (&result, (unsigned long) (x >> 32))) + return CHAR_BIT * sizeof x - 1 - 32 - result; + if (_BitScanReverse (&result, (unsigned long) x)) + return CHAR_BIT * sizeof x - 1 - result; + return CHAR_BIT * sizeof x; +#else COUNT_LEADING_ZEROS (__builtin_clzll, _BitScanReverse64, unsigned long long int); +#endif } #ifdef __cplusplus |