]> Savannah Git Hosting - gnulib.git/commitdiff
count-trailing-zeros: Fix a link error on 32-bit MSVC.
authorBruno Haible <bruno@clisp.org>
Sun, 4 Sep 2022 23:29:26 +0000 (01:29 +0200)
committerBruno Haible <bruno@clisp.org>
Mon, 5 Sep 2022 02:00:26 +0000 (04:00 +0200)
* lib/count-trailing-zeros.h: Correct syntax for #pragma intrinsic.
(count_trailing_zeros_ll): Use two _BitScanForward invocations instead
of a _BitScanForward64 invocation.

ChangeLog
lib/count-trailing-zeros.h

index cf6006cb514d317cb224701297c0414061554741..f7ddcc655b23d0b418f5abbbcf7100eb39ed92e0 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+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
+       of a _BitScanForward64 invocation.
+
 2022-09-04  Bruno Haible  <bruno@clisp.org>
 
        unictype/category-none tests: Fix a link error on MSVC.
index 9a989a432453987c889b923cd823e29aa28886d4..61fbdf29801c207fbe99cce1a46912bb41ef230f 100644 (file)
@@ -43,8 +43,10 @@ extern "C" {
 # define COUNT_TRAILING_ZEROS(BUILTIN, MSC_BUILTIN, TYPE)               \
   return x ? BUILTIN (x) : CHAR_BIT * sizeof x;
 #elif _MSC_VER
-# pragma intrinsic _BitScanForward
-# pragma intrinsic _BitScanForward64
+# pragma intrinsic (_BitScanForward)
+# if defined _M_X64
+#  pragma intrinsic (_BitScanForward64)
+# endif
 # define COUNT_TRAILING_ZEROS(BUILTIN, MSC_BUILTIN, TYPE)               \
     do                                                                  \
       {                                                                 \
@@ -101,8 +103,18 @@ count_trailing_zeros_l (unsigned long int x)
 COUNT_TRAILING_ZEROS_INLINE int
 count_trailing_zeros_ll (unsigned long long int x)
 {
+#if (defined _MSC_VER && !defined __clang__) && !defined _M_X64
+  /* 32-bit MSVC does not have _BitScanForward64, only _BitScanForward.  */
+  unsigned long result;
+  if (_BitScanForward (&result, (unsigned long) x))
+    return result;
+  if (_BitScanForward (&result, (unsigned long) (x >> 32)))
+    return result + 32;
+  return CHAR_BIT * sizeof x;
+#else
   COUNT_TRAILING_ZEROS (__builtin_ctzll, _BitScanForward64,
                         unsigned long long int);
+#endif
 }
 
 #ifdef __cplusplus