summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--lib/ffsl.c1
-rw-r--r--lib/ffsl.h8
-rw-r--r--lib/ffsll.c3
4 files changed, 19 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 0a336bf367..51b2be7bca 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
2020-08-03 Bruno Haible <bruno@clisp.org>
+ ffsll: Optimize for MSVC in 64-bit mode.
+ * lib/ffsl.h (FUNC): On MSVC, use MSVC_BUILTIN if defined.
+ * lib/ffsll.c (MSVC_BUILTIN): Define for MSVC in 64-bit mode.
+ * lib/ffsl.c (MSVC_BUILTIN): Define for MSVC.
+
+2020-08-03 Bruno Haible <bruno@clisp.org>
+
ffsll: Optimize for MSVC in 32-bit mode.
* lib/ffsl.h: Include <intrin.h>.
(ffs): Define as inline function, like in lib/ffs.c.
diff --git a/lib/ffsl.c b/lib/ffsl.c
index ee99ba7e01..198cacbd88 100644
--- a/lib/ffsl.c
+++ b/lib/ffsl.c
@@ -1,4 +1,5 @@
#define FUNC ffsl
#define TYPE long int
#define GCC_BUILTIN __builtin_ffsl
+#define MSVC_BUILTIN _BitScanForward
#include "ffsl.h"
diff --git a/lib/ffsl.h b/lib/ffsl.h
index d5c5a97509..fa5c0935a3 100644
--- a/lib/ffsl.h
+++ b/lib/ffsl.h
@@ -52,6 +52,14 @@ FUNC (TYPE i)
{
#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) && defined GCC_BUILTIN
return GCC_BUILTIN (i);
+#elif defined _MSC_VER && defined MSVC_BUILTIN
+ /* _BitScanForward, _BitScanForward64
+ <https://docs.microsoft.com/en-us/cpp/intrinsics/bitscanforward-bitscanforward64> */
+ unsigned long bit;
+ if (MSVC_BUILTIN (&bit, i))
+ return bit + 1;
+ else
+ return 0;
#else
unsigned TYPE j = i;
/* Split j into chunks, and look at one chunk after the other. */
diff --git a/lib/ffsll.c b/lib/ffsll.c
index f0e9425eed..80a273c3b3 100644
--- a/lib/ffsll.c
+++ b/lib/ffsll.c
@@ -1,4 +1,7 @@
#define FUNC ffsll
#define TYPE long long int
#define GCC_BUILTIN __builtin_ffsll
+#ifdef _WIN64
+# define MSVC_BUILTIN _BitScanForward64
+#endif
#include "ffsl.h"