diff --git a/src/Makefile b/src/Makefile index 4f9a27ab4..65f1ff027 100644 --- a/src/Makefile +++ b/src/Makefile @@ -903,7 +903,7 @@ endif ifeq ($(pext),yes) CXXFLAGS += -DUSE_PEXT ifeq ($(comp),$(filter $(comp),gcc clang mingw icx)) - CXXFLAGS += -mbmi2 -DUSE_COMPTIME_ATTACKS + CXXFLAGS += -mbmi2 endif endif diff --git a/src/attacks.cpp b/src/attacks.cpp index 4da27ce90..db8bea488 100644 --- a/src/attacks.cpp +++ b/src/attacks.cpp @@ -24,15 +24,17 @@ namespace Stockfish::Attacks { -namespace { +#ifdef USE_DUAL_HYPERBOLA_QUINT +alignas(64) DualMagic DualMagics[SQUARE_NB]; +#endif Bitboard LineBB[SQUARE_NB][SQUARE_NB]; Bitboard BetweenBB[SQUARE_NB][SQUARE_NB]; Bitboard RayPassBB[SQUARE_NB][SQUARE_NB]; -#ifdef USE_DUAL_HYPERBOLA_QUINT -alignas(64) DualMagic DualMagics[SQUARE_NB]; -#else +namespace { + +#ifndef USE_DUAL_HYPERBOLA_QUINT alignas(64) Magic Magics[SQUARE_NB][2]; #endif @@ -187,28 +189,11 @@ void init() { } } -#ifdef USE_DUAL_HYPERBOLA_QUINT -const DualMagic& dual_magic(Square s) { return DualMagics[s]; } -#else +#ifndef USE_DUAL_HYPERBOLA_QUINT const Magic& magic(Square s, PieceType pt) { assert((pt == BISHOP || pt == ROOK) && is_ok(s)); return Magics[s][pt - BISHOP]; } #endif -Bitboard line_bb(Square s1, Square s2) { - assert(is_ok(s1) && is_ok(s2)); - return LineBB[s1][s2]; -} - -Bitboard between_bb(Square s1, Square s2) { - assert(is_ok(s1) && is_ok(s2)); - return BetweenBB[s1][s2]; -} - -Bitboard ray_pass_bb(Square s1, Square s2) { - assert(is_ok(s1) && is_ok(s2)); - return RayPassBB[s1][s2]; -} - } // namespace Stockfish::Attacks diff --git a/src/attacks.h b/src/attacks.h index 63e6902f2..5961e04d0 100644 --- a/src/attacks.h +++ b/src/attacks.h @@ -22,6 +22,7 @@ #include #include #include +#include #include "types.h" #include "bitboard.h" @@ -135,7 +136,9 @@ struct alignas(32) DualMagic { } }; -const DualMagic& dual_magic(Square s); +extern DualMagic DualMagics[SQUARE_NB]; + +inline const DualMagic& dual_magic(Square s) { return DualMagics[s]; } #else // Magic holds all magic bitboards relevant data for a single square @@ -164,9 +167,24 @@ const Magic& magic(Square s, PieceType pt); #endif -Bitboard line_bb(Square s1, Square s2); -Bitboard between_bb(Square s1, Square s2); -Bitboard ray_pass_bb(Square s1, Square s2); +extern Bitboard LineBB[SQUARE_NB][SQUARE_NB]; +extern Bitboard BetweenBB[SQUARE_NB][SQUARE_NB]; +extern Bitboard RayPassBB[SQUARE_NB][SQUARE_NB]; + +inline Bitboard line_bb(Square s1, Square s2) { + assert(is_ok(s1) && is_ok(s2)); + return LineBB[s1][s2]; +} + +inline Bitboard between_bb(Square s1, Square s2) { + assert(is_ok(s1) && is_ok(s2)); + return BetweenBB[s1][s2]; +} + +inline Bitboard ray_pass_bb(Square s1, Square s2) { + assert(is_ok(s1) && is_ok(s2)); + return RayPassBB[s1][s2]; +} // Returns the bitboard of target square for the given step // from the given square. If the step is off the board, returns empty bitboard. @@ -304,6 +322,14 @@ inline Bitboard attacks_bb(Square s, Bitboard occupied) { #endif } +inline std::pair both_attacks_bb(Square s, Bitboard occupied) { +#ifdef USE_DUAL_HYPERBOLA_QUINT + return dual_magic(s).both_attacks_bb(occupied); +#else + return {attacks_bb(s, occupied), attacks_bb(s, occupied)}; +#endif +} + // Returns the attacks by the given piece // assuming the board is occupied according to the passed Bitboard. // Sliding piece attacks do not continue past an occupied square. diff --git a/src/position.cpp b/src/position.cpp index 42bb871a4..69de6267e 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -469,12 +469,13 @@ void Position::set_check_info() const { update_slider_blockers(WHITE); update_slider_blockers(BLACK); - Square ksq = square(~sideToMove); + Square ksq = square(~sideToMove); + const auto [bishopAttacks, rookAttacks] = both_attacks_bb(ksq, pieces()); st->checkSquares[PAWN] = attacks_bb(ksq, ~sideToMove); st->checkSquares[KNIGHT] = attacks_bb(ksq); - st->checkSquares[BISHOP] = attacks_bb(ksq, pieces()); - st->checkSquares[ROOK] = attacks_bb(ksq, pieces()); + st->checkSquares[BISHOP] = bishopAttacks; + st->checkSquares[ROOK] = rookAttacks; st->checkSquares[QUEEN] = st->checkSquares[BISHOP] | st->checkSquares[ROOK]; st->checkSquares[KING] = 0; } @@ -641,8 +642,9 @@ void Position::update_slider_blockers(Color c) const { // Slider attacks use the occupied bitboard to indicate occupancy. Bitboard Position::attackers_to(Square s, Bitboard occupied) const { - return (attacks_bb(s, occupied) & pieces(ROOK, QUEEN)) - | (attacks_bb(s, occupied) & pieces(BISHOP, QUEEN)) + const auto [bishopAttacks, rookAttacks] = both_attacks_bb(s, occupied); + + return (rookAttacks & pieces(ROOK, QUEEN)) | (bishopAttacks & pieces(BISHOP, QUEEN)) | (attacks_bb(s, BLACK) & pieces(WHITE, PAWN)) | (attacks_bb(s, WHITE) & pieces(BLACK, PAWN)) | (attacks_bb(s) & pieces(KNIGHT)) | (attacks_bb(s) & pieces(KING)); @@ -789,12 +791,12 @@ bool Position::gives_check(Move m) const { // checks and ordinary discovered check, so the only case we need to handle // is the unusual case of a discovered check through the captured pawn. case EN_PASSANT : { - Square capsq = make_square(file_of(to), rank_of(from)); - Bitboard b = (pieces() ^ from ^ capsq) | to; + Square capsq = make_square(file_of(to), rank_of(from)); + Bitboard b = (pieces() ^ from ^ capsq) | to; + const auto [bishopAttacks, rookAttacks] = both_attacks_bb(square(~sideToMove), b); - return (attacks_bb(square(~sideToMove), b) & pieces(sideToMove, QUEEN, ROOK)) - | (attacks_bb(square(~sideToMove), b) - & pieces(sideToMove, QUEEN, BISHOP)); + return (rookAttacks & pieces(sideToMove, QUEEN, ROOK)) + | (bishopAttacks & pieces(sideToMove, QUEEN, BISHOP)); } default : //CASTLING { @@ -1189,8 +1191,9 @@ void Position::update_piece_threats(Piece pc, const Bitboard occupied = pieces(); const Bitboard rookQueens = pieces(ROOK, QUEEN); const Bitboard bishopQueens = pieces(BISHOP, QUEEN); - const Bitboard rAttacks = attacks_bb(s, occupied); - const Bitboard bAttacks = attacks_bb(s, occupied); + const auto attacks = both_attacks_bb(s, occupied); + const Bitboard bAttacks = attacks.first; + const Bitboard rAttacks = attacks.second; const Bitboard occupiedNoK = occupied ^ pieces(KING); Bitboard sliders = (rookQueens & rAttacks) | (bishopQueens & bAttacks); @@ -1508,8 +1511,9 @@ bool Position::see_ge(Move m, int threshold) const { assert(swap >= res); occupied ^= least_significant_square_bb(bb); - attackers |= (attacks_bb(to, occupied) & pieces(BISHOP, QUEEN)) - | (attacks_bb(to, occupied) & pieces(ROOK, QUEEN)); + const auto [bishopAttacks, rookAttacks] = both_attacks_bb(to, occupied); + attackers |= + (bishopAttacks & pieces(BISHOP, QUEEN)) | (rookAttacks & pieces(ROOK, QUEEN)); } else // KING