diff --git a/src/bitboard.cpp b/src/bitboard.cpp index 94f667b2a..4e24456a5 100644 --- a/src/bitboard.cpp +++ b/src/bitboard.cpp @@ -18,12 +18,8 @@ #include "bitboard.h" -#include - namespace Stockfish { -u8 PopCnt16[1 << 16]; - // Returns an ASCII representation of a bitboard suitable // to be printed to standard output. Useful for debugging. std::string Bitboards::pretty(Bitboard b) { @@ -45,10 +41,4 @@ std::string Bitboards::pretty(Bitboard b) { return s; } -// Initializes the popcount table at startup. -void Bitboards::init() { - for (unsigned i = 0; i < (1 << 16); ++i) - PopCnt16[i] = u8(std::bitset<16>(i).count()); -} - } // namespace Stockfish diff --git a/src/bitboard.h b/src/bitboard.h index 836035b33..49989d2e3 100644 --- a/src/bitboard.h +++ b/src/bitboard.h @@ -21,8 +21,8 @@ #include #include -#include #include +#include #include "types.h" #include "misc.h" @@ -31,7 +31,6 @@ namespace Stockfish { namespace Bitboards { -void init(); std::string pretty(Bitboard b); } // namespace Stockfish::Bitboards @@ -63,8 +62,6 @@ constexpr Bitboard Rank6BB = Rank1BB << (8 * 5); constexpr Bitboard Rank7BB = Rank1BB << (8 * 6); constexpr Bitboard Rank8BB = Rank1BB << (8 * 7); -extern u8 PopCnt16[1 << 16]; - constexpr Bitboard square_bb(Square s) { assert(is_ok(s)); return 1ULL << s; @@ -130,26 +127,39 @@ constexpr Bitboard pawn_single_push_bb(Color c, Bitboard b) { return c == WHITE ? shift(b) : shift(b); } -inline int edge_distance(File f) { return std::min(f, File(FILE_H - f)); } +constexpr int edge_distance(File f) { return std::min(f, File(FILE_H - f)); } -constexpr int constexpr_popcount(Bitboard b) { - b = b - ((b >> 1) & 0x5555555555555555ULL); - b = (b & 0x3333333333333333ULL) + ((b >> 2) & 0x3333333333333333ULL); - b = (b + (b >> 4)) & 0x0F0F0F0F0F0F0F0FULL; - return static_cast((b * 0x0101010101010101ULL) >> 56); + +template +constexpr int constexpr_popcount(T v) { + static_assert(std::is_integral_v, "constexpr_popcount is undefined for non-integral types"); + + if constexpr (sizeof(T) <= 8) + { + u64 b = static_cast>(v); + + b = b - ((b >> 1) & 0x5555555555555555ULL); + b = (b & 0x3333333333333333ULL) + ((b >> 2) & 0x3333333333333333ULL); + b = (b + (b >> 4)) & 0x0F0F0F0F0F0F0F0FULL; + + return static_cast((b * 0x0101010101010101ULL) >> 56); + } + else + { + int result = 0; + + for (; v; v >>= static_cast(1)) + if (v & static_cast(1)) + ++result; + + return result; + } } // Counts the number of non-zero bits in a bitboard. inline int popcount(Bitboard b) { -#ifndef USE_POPCNT - - u16 indices[4]; - std::memcpy(indices, &b, sizeof(b)); - return PopCnt16[indices[0]] + PopCnt16[indices[1]] + PopCnt16[indices[2]] - + PopCnt16[indices[3]]; - -#elif defined(_MSC_VER) +#ifdef _MSC_VER return int(_mm_popcnt_u64(b)); diff --git a/src/main.cpp b/src/main.cpp index 7e36b23dc..304b2be06 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -21,7 +21,6 @@ #include #include "attacks.h" -#include "bitboard.h" #include "misc.h" #include "position.h" #include "tune.h" @@ -40,7 +39,6 @@ __attribute__((used)) // keep main alive int main(int argc, char* argv[]) { std::cout << engine_info() << std::endl; - Bitboards::init(); Attacks::init(); Position::init(); diff --git a/src/types.h b/src/types.h index c4eb1f8c1..71bc90812 100644 --- a/src/types.h +++ b/src/types.h @@ -76,7 +76,7 @@ #define IS_64BIT #endif - #if defined(USE_POPCNT) && defined(_MSC_VER) + #if defined(_MSC_VER) #include // Microsoft header for _mm_popcnt_u64() #endif