]> Savannah Git Hosting - gnulib.git/commitdiff
count-leading-zeros: Fix a link error on 32-bit MSVC and a test failure.
authorBruno Haible <bruno@clisp.org>
Sun, 4 Sep 2022 23:34:36 +0000 (01:34 +0200)
committerBruno Haible <bruno@clisp.org>
Mon, 5 Sep 2022 02:00:31 +0000 (04:00 +0200)
* 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.

ChangeLog
lib/count-leading-zeros.h

index f7ddcc655b23d0b418f5abbbcf7100eb39ed92e0..883cd016a070c6548830be3e4a78758e400bb716 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+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.
index 354641af0a2a91d4ad1810ed86d9e48f2bbe71a0..4b4f5d4f9a1f54de1dc0b6d205368f217c04ab02 100644 (file)
@@ -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