Rewrite bsfq management
authorMarco Costalba <mcostalba@gmail.com>
Mon, 28 Mar 2016 08:08:06 +0000 (10:08 +0200)
committerJoona Kiiski <joona@zoox.com>
Mon, 28 Mar 2016 14:46:55 +0000 (15:46 +0100)
Use compiler intrinsics when possible to
avoid writing platform specific asm code.

Tested on Windows 7 with MSVC 2013 and mingw 4.8.3 (32 and 64 bit)
and on Linux Mint with g++ 4.8.4 and clang 3.4 (32 and 64 bit).

No functional change

Resolves #609

src/Makefile
src/bitboard.cpp
src/bitboard.h
src/types.h

index 358788bd7f2d7262740e3e686be0180b005e4a02..0824072de8e95654f3b303a1dc4695103e1ed8b3 100644 (file)
@@ -50,10 +50,8 @@ OBJS = benchmark.o bitbase.o bitboard.o endgame.o evaluate.o main.o \
 # optimize = yes/no   --- (-O3/-fast etc.) --- Enable/Disable optimizations
 # arch = (name)       --- (-arch)          --- Target architecture
 # bits = 64/32        --- -DIS_64BIT       --- 64-/32-bit operating system
-# prefetch = yes/no   --- -DUSE_PREFETCH   --- Use prefetch x86 asm-instruction
-# bsfq = yes/no       --- -DUSE_BSFQ       --- Use bsfq x86_64 asm-instruction (only
-#                                              with GCC and ICC 64-bit)
-# popcnt = yes/no     --- -DUSE_POPCNT     --- Use popcnt x86_64 asm-instruction
+# prefetch = yes/no   --- -DUSE_PREFETCH   --- Use prefetch asm-instruction
+# popcnt = yes/no     --- -DUSE_POPCNT     --- Use popcnt asm-instruction
 # sse = yes/no        --- -msse            --- Use Intel Streaming SIMD Extensions
 # pext = yes/no       --- -DUSE_PEXT       --- Use pext x86_64 asm-instruction
 #
@@ -66,7 +64,6 @@ optimize = yes
 debug = no
 bits = 32
 prefetch = no
-bsfq = no
 popcnt = no
 sse = no
 pext = no
@@ -96,7 +93,6 @@ ifeq ($(ARCH),x86-64)
        arch = x86_64
        bits = 64
        prefetch = yes
-       bsfq = yes
        sse = yes
 endif
 
@@ -104,7 +100,6 @@ ifeq ($(ARCH),x86-64-modern)
        arch = x86_64
        bits = 64
        prefetch = yes
-       bsfq = yes
        popcnt = yes
        sse = yes
 endif
@@ -113,7 +108,6 @@ ifeq ($(ARCH),x86-64-bmi2)
        arch = x86_64
        bits = 64
        prefetch = yes
-       bsfq = yes
        popcnt = yes
        sse = yes
        pext = yes
@@ -122,7 +116,6 @@ endif
 ifeq ($(ARCH),armv7)
        arch = armv7
        prefetch = yes
-       bsfq = yes
 endif
 
 ifeq ($(ARCH),ppc-32)
@@ -309,11 +302,6 @@ else
        CXXFLAGS += -DNO_PREFETCH
 endif
 
-### 3.8 bsfq
-ifeq ($(bsfq),yes)
-       CXXFLAGS += -DUSE_BSFQ
-endif
-
 ### 3.9 popcnt
 ifeq ($(popcnt),yes)
        ifeq ($(comp),icc)
@@ -465,7 +453,6 @@ config-sanity:
        @echo "arch: '$(arch)'"
        @echo "bits: '$(bits)'"
        @echo "prefetch: '$(prefetch)'"
-       @echo "bsfq: '$(bsfq)'"
        @echo "popcnt: '$(popcnt)'"
        @echo "sse: '$(sse)'"
        @echo "pext: '$(pext)'"
@@ -483,7 +470,6 @@ config-sanity:
         test "$(arch)" = "ppc64" || test "$(arch)" = "ppc" || test "$(arch)" = "armv7"
        @test "$(bits)" = "32" || test "$(bits)" = "64"
        @test "$(prefetch)" = "yes" || test "$(prefetch)" = "no"
-       @test "$(bsfq)" = "yes" || test "$(bsfq)" = "no"
        @test "$(popcnt)" = "yes" || test "$(popcnt)" = "no"
        @test "$(sse)" = "yes" || test "$(sse)" = "no"
        @test "$(pext)" = "yes" || test "$(pext)" = "no"
index 47dce42eabb55315ff36bf325f90f28e53fc10e3..4ea69ebc757df81fbea8f70d79e1d54c7d568446 100644 (file)
@@ -76,7 +76,7 @@ namespace {
   }
 }
 
-#ifndef USE_BSFQ
+#ifdef NO_BSF
 
 /// Software fall-back of lsb() and msb() for CPU lacking hardware support
 
@@ -112,7 +112,7 @@ Square msb(Bitboard b) {
   return Square(result + MSBTable[b32]);
 }
 
-#endif // ifndef USE_BSFQ
+#endif // ifdef NO_BSF
 
 
 /// Bitboards::pretty() returns an ASCII representation of a bitboard suitable
index 967a68f59f8f8247397bb62e24eb8a7a3a569b7a..2ad8773634dce967e6cc6b223e68eeb3d4d66f05 100644 (file)
@@ -259,9 +259,12 @@ inline Bitboard attacks_bb(Piece pc, Square s, Bitboard occupied) {
 
 /// lsb() and msb() return the least/most significant bit in a non-zero bitboard
 
-#ifdef USE_BSFQ
+#if defined(__GNUC__)
 
-#  if defined(_MSC_VER) && !defined(__INTEL_COMPILER)
+inline Square lsb(Bitboard b) { return Square(__builtin_ctzll(b)); }
+inline Square msb(Bitboard b) { return Square(63 - __builtin_clzll(b)); }
+
+#elif defined(_WIN64) && defined(_MSC_VER)
 
 inline Square lsb(Bitboard b) {
   unsigned long idx;
@@ -275,38 +278,9 @@ inline Square msb(Bitboard b) {
   return (Square) idx;
 }
 
-#  elif defined(__arm__)
-
-inline int lsb32(uint32_t v) {
-  __asm__("rbit %0, %1" : "=r"(v) : "r"(v));
-  return __builtin_clz(v);
-}
-
-inline Square msb(Bitboard b) {
-  return (Square) (63 - __builtin_clzll(b));
-}
-
-inline Square lsb(Bitboard b) {
-  return (Square) (uint32_t(b) ? lsb32(uint32_t(b)) : 32 + lsb32(uint32_t(b >> 32)));
-}
-
-#  else // Assumed gcc or compatible compiler
-
-inline Square lsb(Bitboard b) { // Assembly code by Heinz van Saanen
-  Bitboard idx;
-  __asm__("bsfq %1, %0": "=r"(idx): "rm"(b) );
-  return (Square) idx;
-}
-
-inline Square msb(Bitboard b) {
-  Bitboard idx;
-  __asm__("bsrq %1, %0": "=r"(idx): "rm"(b) );
-  return (Square) idx;
-}
-
-#  endif
+#else
 
-#else // ifdef(USE_BSFQ)
+#define NO_BSF // Fallback on software implementation for other cases
 
 Square lsb(Bitboard b);
 Square msb(Bitboard b);
index c43eee3df14ed3bea9692b44fad299d40bde1f71..6f62c776f6dae20e0a343613cef46ba54befc6bc 100644 (file)
@@ -62,7 +62,6 @@
 #if defined(_WIN64) && defined(_MSC_VER) // No Makefile used
 #  include <intrin.h> // MSVC popcnt and bsfq instrinsics
 #  define IS_64BIT
-#  define USE_BSFQ
 #endif
 
 #if defined(USE_POPCNT) && defined(__INTEL_COMPILER) && defined(_MSC_VER)