The NO_BSF does not cover any real life use-case today. The only compilers that
can compile SF today, with the current Makefile and no source code changes, are
either GCC compatible (define __GNUC__) or MSVC compatible (define _MSC_VER). So
they all support LSB/MSB intrinsics.
This patch simplifies away the software fall-backs of LSB/MSB that were still
in Stockfish code, but unused in any of the officially supported compilers.
Note the (legacy) MSVC/WIN32 case, where we use a 32-bit BSF/BSR solution, as
64-bit intrinsics aren't available there.
Discussed in: https://github.com/official-stockfish/Stockfish/pull/1447
and: https://github.com/official-stockfish/Stockfish/pull/1479
No functional change.
- // De Bruijn sequences. See chessprogramming.wikispaces.com/BitScan
- const uint64_t DeBruijn64 = 0x3F79D71B4CB0A89ULL;
- const uint32_t DeBruijn32 = 0x783A9B23;
-
- int MSBTable[256]; // To implement software msb()
- Square BSFTable[SQUARE_NB]; // To implement software bitscan
Bitboard RookTable[0x19000]; // To store rook attacks
Bitboard BishopTable[0x1480]; // To store bishop attacks
void init_magics(Bitboard table[], Magic magics[], Direction directions[]);
Bitboard RookTable[0x19000]; // To store rook attacks
Bitboard BishopTable[0x1480]; // To store bishop attacks
void init_magics(Bitboard table[], Magic magics[], Direction directions[]);
- // bsf_index() returns the index into BSFTable[] to look up the bitscan. Uses
- // Matt Taylor's folding for 32 bit case, extended to 64 bit by Kim Walisch.
-
- unsigned bsf_index(Bitboard b) {
- b ^= b - 1;
- return Is64Bit ? (b * DeBruijn64) >> 58
- : ((unsigned(b) ^ unsigned(b >> 32)) * DeBruijn32) >> 26;
- }
-
-
// popcount16() counts the non-zero bits using SWAR-Popcount algorithm
unsigned popcount16(unsigned u) {
// popcount16() counts the non-zero bits using SWAR-Popcount algorithm
unsigned popcount16(unsigned u) {
-#ifdef NO_BSF
-
-/// Software fall-back of lsb() and msb() for CPU lacking hardware support
-
-Square lsb(Bitboard b) {
- assert(b);
- return BSFTable[bsf_index(b)];
-}
-
-Square msb(Bitboard b) {
-
- assert(b);
- unsigned b32;
- int result = 0;
-
- if (b > 0xFFFFFFFF)
- {
- b >>= 32;
- result = 32;
- }
-
- b32 = unsigned(b);
-
- if (b32 > 0xFFFF)
- {
- b32 >>= 16;
- result += 16;
- }
-
- if (b32 > 0xFF)
- {
- b32 >>= 8;
- result += 8;
- }
-
- return Square(result + MSBTable[b32]);
-}
-
-#endif // ifdef NO_BSF
-
/// Bitboards::pretty() returns an ASCII representation of a bitboard suitable
/// to be printed to standard output. Useful for debugging.
/// Bitboards::pretty() returns an ASCII representation of a bitboard suitable
/// to be printed to standard output. Useful for debugging.
PopCnt16[i] = (uint8_t) popcount16(i);
for (Square s = SQ_A1; s <= SQ_H8; ++s)
PopCnt16[i] = (uint8_t) popcount16(i);
for (Square s = SQ_A1; s <= SQ_H8; ++s)
- BSFTable[bsf_index(SquareBB[s])] = s;
- }
-
- for (Bitboard b = 2; b < 256; ++b)
- MSBTable[b] = MSBTable[b - 1] + !more_than_one(b);
for (File f = FILE_A; f <= FILE_H; ++f)
FileBB[f] = f > FILE_A ? FileBB[f - 1] << 1 : FileABB;
for (File f = FILE_A; f <= FILE_H; ++f)
FileBB[f] = f > FILE_A ? FileBB[f - 1] << 1 : FileABB;
/// lsb() and msb() return the least/most significant bit in a non-zero bitboard
/// lsb() and msb() return the least/most significant bit in a non-zero bitboard
+#if defined(__GNUC__) // GCC, Clang, ICC
inline Square lsb(Bitboard b) {
assert(b);
inline Square lsb(Bitboard b) {
assert(b);
return Square(63 ^ __builtin_clzll(b));
}
return Square(63 ^ __builtin_clzll(b));
}
-#elif defined(_WIN64) && defined(_MSC_VER)
+#elif defined(_MSC_VER) // MSVC
+
+#ifdef _WIN64 // MSVC, WIN64
inline Square lsb(Bitboard b) {
assert(b);
inline Square lsb(Bitboard b) {
assert(b);
+#else // MSVC, WIN32
+
+inline Square lsb(Bitboard b) {
+ assert(b);
+ unsigned long idx;
+
+ if (b & 0xffffffff) {
+ _BitScanForward(&idx, int32_t(b));
+ return Square(idx);
+ } else {
+ _BitScanForward(&idx, int32_t(b >> 32));
+ return Square(idx + 32);
+ }
+}
+
+inline Square msb(Bitboard b) {
+ assert(b);
+ unsigned long idx;
+
+ if (b >> 32) {
+ _BitScanReverse(&idx, int32_t(b >> 32));
+ return Square(idx + 32);
+ } else {
+ _BitScanReverse(&idx, int32_t(b));
+ return Square(idx);
+ }
+}
+
+#endif
-#define NO_BSF // Fallback on software implementation for other cases
+#else // Compiler is neither GCC nor MSVC compatible
-Square lsb(Bitboard b);
-Square msb(Bitboard b);
+#error "Compiler not supported."