/// lsb() and msb() return the least/most significant bit in a non-zero bitboard
-#if defined(__GNUC__)
+#if defined(__GNUC__) // GCC, Clang, ICC
inline Square lsb(Bitboard b) {
assert(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);
return (Square) idx;
}
-#else
+#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."
#endif