From db4b0d8b7db8db15c16a71212990354094f00b0d Mon Sep 17 00:00:00 2001 From: Marco Costalba Date: Mon, 28 Mar 2016 10:08:06 +0200 Subject: [PATCH] Rewrite bsfq management 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 | 18 ++---------------- src/bitboard.cpp | 4 ++-- src/bitboard.h | 40 +++++++--------------------------------- src/types.h | 1 - 4 files changed, 11 insertions(+), 52 deletions(-) diff --git a/src/Makefile b/src/Makefile index 358788bd..0824072d 100644 --- a/src/Makefile +++ b/src/Makefile @@ -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" diff --git a/src/bitboard.cpp b/src/bitboard.cpp index 47dce42e..4ea69ebc 100644 --- a/src/bitboard.cpp +++ b/src/bitboard.cpp @@ -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 diff --git a/src/bitboard.h b/src/bitboard.h index 967a68f5..2ad87736 100644 --- a/src/bitboard.h +++ b/src/bitboard.h @@ -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); diff --git a/src/types.h b/src/types.h index c43eee3d..6f62c776 100644 --- a/src/types.h +++ b/src/types.h @@ -62,7 +62,6 @@ #if defined(_WIN64) && defined(_MSC_VER) // No Makefile used # include // MSVC popcnt and bsfq instrinsics # define IS_64BIT -# define USE_BSFQ #endif #if defined(USE_POPCNT) && defined(__INTEL_COMPILER) && defined(_MSC_VER) -- 2.39.2