From c33fc5df179f65cbf34872b6ff968126eaf59002 Mon Sep 17 00:00:00 2001 From: Fabian Fichter Date: Tue, 29 Jan 2019 23:14:58 +0100 Subject: [PATCH] Support non-GCC and 32bit for large-board version --- .travis.yml | 1 + src/bitboard.cpp | 6 ++-- src/bitboard.h | 6 ++- src/evaluate.cpp | 4 +- src/movegen.cpp | 10 +++--- src/pawns.cpp | 6 ++-- src/position.cpp | 6 ++-- src/types.h | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 126 insertions(+), 18 deletions(-) diff --git a/.travis.yml b/.travis.yml index aa4c2e0..db1385c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -45,6 +45,7 @@ script: - make clean && make -j2 ARCH=x86-64 largeboards=yes build && ../tests/perft.sh largeboard - ./stockfish bench shogi > /dev/null 2>&1 - ./stockfish bench capablanca > /dev/null 2>&1 + - make clean && make -j2 ARCH=x86-32 largeboards=yes build && ../tests/perft.sh largeboard # # Obtain bench reference from git log - git log HEAD | grep "\b[Bb]ench[ :]\+[0-9]\{7\}" | head -n 1 | sed "s/[^0-9]*\([0-9]*\).*/\1/g" > git_sig diff --git a/src/bitboard.cpp b/src/bitboard.cpp index 40c038f..4e0194f 100644 --- a/src/bitboard.cpp +++ b/src/bitboard.cpp @@ -364,7 +364,7 @@ void Bitboards::init() { for (File f = FILE_A; f <= FILE_MAX; ++f) for (Rank r = RANK_1; r <= RANK_MAX; ++r) - BoardSizeBB[f][r] = forward_file_bb(BLACK, make_square(f, r)) | SquareBB[make_square(f, r)] | (f > FILE_A ? BoardSizeBB[f - 1][r] : 0); + BoardSizeBB[f][r] = forward_file_bb(BLACK, make_square(f, r)) | SquareBB[make_square(f, r)] | (f > FILE_A ? BoardSizeBB[f - 1][r] : Bitboard(0)); for (Square s1 = SQ_A1; s1 <= SQ_MAX; ++s1) for (Square s2 = SQ_A1; s2 <= SQ_MAX; ++s2) @@ -440,8 +440,8 @@ namespace { // Optimal PRNG seeds to pick the correct magics in the shortest time #ifndef PRECOMPUTED_MAGICS #ifdef LARGEBOARDS - int seeds[][RANK_NB] = { {}, - { 734, 10316, 55013, 32803, 12281, 15100, 16645, 255, 346, 89123} }; + int seeds[][RANK_NB] = { { 734, 10316, 55013, 32803, 12281, 15100, 16645, 255, 346, 89123 }, + { 734, 10316, 55013, 32803, 12281, 15100, 16645, 255, 346, 89123 } }; #else int seeds[][RANK_NB] = { { 8977, 44560, 54343, 38998, 5731, 95205, 104912, 17020 }, { 728, 10316, 55013, 32803, 12281, 15100, 16645, 255 } }; diff --git a/src/bitboard.h b/src/bitboard.h index 87db5dc..06cdaad 100644 --- a/src/bitboard.h +++ b/src/bitboard.h @@ -121,7 +121,9 @@ struct Magic { if (HasPext) return unsigned(pext(occupied, mask)); +#ifndef LARGEBOARDS if (Is64Bit) +#endif return unsigned(((occupied & mask) * magic) >> shift); unsigned lo = unsigned(occupied) & unsigned(mask); @@ -204,7 +206,7 @@ constexpr Bitboard shift(Bitboard b) { : D == EAST ? (b & ~file_bb(FILE_MAX)) << EAST : D == WEST ? (b & ~FileABB) >> EAST : D == NORTH_EAST ? (b & ~file_bb(FILE_MAX)) << NORTH_EAST : D == NORTH_WEST ? (b & ~FileABB) << NORTH_WEST : D == SOUTH_EAST ? (b & ~file_bb(FILE_MAX)) >> NORTH_WEST : D == SOUTH_WEST ? (b & ~FileABB) >> NORTH_EAST - : 0; + : Bitboard(0); } @@ -215,7 +217,7 @@ constexpr Bitboard shift(Direction D, Bitboard b) { : D == EAST ? (b & ~file_bb(FILE_MAX)) << EAST : D == WEST ? (b & ~FileABB) >> EAST : D == NORTH_EAST ? (b & ~file_bb(FILE_MAX)) << NORTH_EAST : D == NORTH_WEST ? (b & ~FileABB) << NORTH_WEST : D == SOUTH_EAST ? (b & ~file_bb(FILE_MAX)) >> NORTH_WEST : D == SOUTH_WEST ? (b & ~FileABB) >> NORTH_EAST - : 0; + : Bitboard(0); } diff --git a/src/evaluate.cpp b/src/evaluate.cpp index 0409ad5..7bda6e5 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -252,7 +252,7 @@ namespace { mobilityArea[Us] = ~(b | pos.pieces(Us, KING, QUEEN) | pe->pawn_attacks(Them) | shift(pos.pieces(Them, SHOGI_PAWN))); // Initialize attackedBy[] for king and pawns - attackedBy[Us][KING] = pos.count(Us) ? pos.attacks_from(Us, ksq) : 0; + attackedBy[Us][KING] = pos.count(Us) ? pos.attacks_from(Us, ksq) : Bitboard(0); attackedBy[Us][PAWN] = pe->pawn_attacks(Us); attackedBy[Us][SHOGI_PAWN] = shift(pos.pieces(Us, SHOGI_PAWN)); attackedBy[Us][ALL_PIECES] = attackedBy[Us][KING] | attackedBy[Us][PAWN] | attackedBy[Us][SHOGI_PAWN]; @@ -482,7 +482,7 @@ namespace { b2 = attacks_bb(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN)); std::function get_attacks = [this](Color c, PieceType pt) { - return attackedBy[c][pt] | (pos.captures_to_hand() && pos.count_in_hand(c, pt) ? ~pos.pieces() : 0); + return attackedBy[c][pt] | (pos.captures_to_hand() && pos.count_in_hand(c, pt) ? ~pos.pieces() : Bitboard(0)); }; for (PieceType pt : pos.piece_types()) { diff --git a/src/movegen.cpp b/src/movegen.cpp index e1f74f6..b326233 100644 --- a/src/movegen.cpp +++ b/src/movegen.cpp @@ -91,7 +91,7 @@ namespace { emptySquares = (Type == QUIETS || Type == QUIET_CHECKS ? target : ~pos.pieces()); Bitboard b1 = shift(pawnsNotOn7) & emptySquares; - Bitboard b2 = pos.double_step_enabled() ? shift(b1 & TRank3BB) & emptySquares : 0; + Bitboard b2 = pos.double_step_enabled() ? shift(b1 & TRank3BB) & emptySquares : Bitboard(0); if (Type == EVASIONS) // Consider only blocking squares { @@ -240,8 +240,8 @@ namespace { Bitboard b1 = ( (pos.attacks_from(us, pt, from) & pos.pieces()) | (pos.moves_from(us, pt, from) & ~pos.pieces())) & target; - Bitboard b2 = pos.promoted_piece_type(pt) ? b1 : 0; - Bitboard b3 = pos.piece_demotion() && pos.is_promoted(from) ? b1 : 0; + Bitboard b2 = pos.promoted_piece_type(pt) ? b1 : Bitboard(0); + Bitboard b3 = pos.piece_demotion() && pos.is_promoted(from) ? b1 : Bitboard(0); if (Checks) { @@ -257,7 +257,7 @@ namespace { { Bitboard promotion_zone = promotion_zone_bb(us, pos.promotion_rank(), pos.max_rank()); if (pos.mandatory_piece_promotion()) - b1 &= (promotion_zone & from ? 0 : ~promotion_zone) | (pos.piece_promotion_on_capture() ? ~pos.pieces() : 0); + b1 &= (promotion_zone & from ? Bitboard(0) : ~promotion_zone) | (pos.piece_promotion_on_capture() ? ~pos.pieces() : Bitboard(0)); // Exclude quiet promotions/demotions if (pos.piece_promotion_on_capture()) { @@ -353,7 +353,7 @@ ExtMove* generate(const Position& pos, ExtMove* moveList) { Bitboard target = Type == CAPTURES ? pos.pieces(~us) : Type == QUIETS ? ~pos.pieces() - : Type == NON_EVASIONS ? ~pos.pieces(us) : 0; + : Type == NON_EVASIONS ? ~pos.pieces(us) : Bitboard(0); target &= pos.board_bb(); return us == WHITE ? generate_all(pos, moveList, target) diff --git a/src/pawns.cpp b/src/pawns.cpp index 0a493fd..cd4c92d 100644 --- a/src/pawns.cpp +++ b/src/pawns.cpp @@ -94,11 +94,11 @@ namespace { opposed = theirPawns & forward_file_bb(Us, s); stoppers = theirPawns & passed_pawn_span(Us, s); lever = theirPawns & PseudoAttacks[Us][PAWN][s]; - leverPush = relative_rank(Them, s, pos.max_rank()) > RANK_1 ? theirPawns & PseudoAttacks[Us][PAWN][s + Up] : 0; - doubled = r > RANK_1 ? ourPawns & (s - Up) : 0; + leverPush = relative_rank(Them, s, pos.max_rank()) > RANK_1 ? theirPawns & PseudoAttacks[Us][PAWN][s + Up] : Bitboard(0); + doubled = r > RANK_1 ? ourPawns & (s - Up) : Bitboard(0); neighbours = ourPawns & adjacent_files_bb(f); phalanx = neighbours & rank_bb(s); - support = r > RANK_1 ? neighbours & rank_bb(s - Up) : 0; + support = r > RANK_1 ? neighbours & rank_bb(s - Up) : Bitboard(0); // A pawn is backward when it is behind all pawns of the same color // on the adjacent files and cannot be safely advanced. diff --git a/src/position.cpp b/src/position.cpp index 9c1cefd..12ee530 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -476,7 +476,7 @@ void Position::set_check_info(StateInfo* si) const { // For unused piece types, the check squares are left uninitialized for (PieceType pt : piece_types()) - si->checkSquares[pt] = ksq != SQ_NONE ? attacks_from(~sideToMove, pt, ksq) : 0; + si->checkSquares[pt] = ksq != SQ_NONE ? attacks_from(~sideToMove, pt, ksq) : Bitboard(0); si->checkSquares[KING] = 0; si->shak = si->checkersBB & (byTypeBB[KNIGHT] | byTypeBB[ROOK] | byTypeBB[BERS]); } @@ -492,7 +492,7 @@ void Position::set_state(StateInfo* si) const { si->key = si->materialKey = 0; si->pawnKey = Zobrist::noPawns; si->nonPawnMaterial[WHITE] = si->nonPawnMaterial[BLACK] = VALUE_ZERO; - si->checkersBB = count(sideToMove) ? attackers_to(square(sideToMove), ~sideToMove) : 0; + si->checkersBB = count(sideToMove) ? attackers_to(square(sideToMove), ~sideToMove) : Bitboard(0); set_check_info(si); @@ -1245,7 +1245,7 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) { st->key = k; // Calculate checkers bitboard (if move gives check) - st->checkersBB = givesCheck ? attackers_to(square(them), us) & pieces(us) : 0; + st->checkersBB = givesCheck ? attackers_to(square(them), us) & pieces(us) : Bitboard(0); // Update information about promoted pieces if (type_of(m) != DROP && is_promoted(from)) diff --git a/src/types.h b/src/types.h index 41de7f6..ac250ac 100644 --- a/src/types.h +++ b/src/types.h @@ -104,7 +104,112 @@ constexpr bool Is64Bit = false; typedef uint64_t Key; #ifdef LARGEBOARDS +#if defined(__GNUC__) && defined(IS_64BIT) typedef unsigned __int128 Bitboard; +#else +struct Bitboard { + uint64_t b64[2]; + + constexpr Bitboard() : b64 {0, 0} {} + constexpr Bitboard(uint64_t i) : b64 {0, i} {} + constexpr Bitboard(uint64_t hi, uint64_t lo) : b64 {hi, lo} {}; + + constexpr operator bool() const { + return b64[0] || b64[1]; + } + + constexpr operator long long unsigned () const { + return b64[1]; + } + + constexpr operator unsigned() const { + return b64[1]; + } + + constexpr Bitboard operator << (const unsigned int bits) const { + return Bitboard( bits >= 64 ? b64[1] << (bits - 64) + : bits == 0 ? b64[0] + : ((b64[0] << bits) | (b64[1] >> (64 - bits))), + bits >= 64 ? 0 : b64[1] << bits); + } + + constexpr Bitboard operator >> (const unsigned int bits) const { + return Bitboard(bits >= 64 ? 0 : b64[0] >> bits, + bits >= 64 ? b64[0] >> (bits - 64) + : bits == 0 ? b64[1] + : ((b64[1] >> bits) | (b64[0] << (64 - bits)))); + } + + constexpr Bitboard operator << (const int bits) const { + return *this << unsigned(bits); + } + + constexpr Bitboard operator >> (const int bits) const { + return *this >> unsigned(bits); + } + + constexpr bool operator == (const Bitboard y) const { + return (b64[0] == y.b64[0]) && (b64[1] == y.b64[1]); + } + + constexpr bool operator != (const Bitboard y) const { + return !(*this == y); + } + + inline Bitboard& operator |=(const Bitboard x) { + b64[0] |= x.b64[0]; + b64[1] |= x.b64[1]; + return *this; + } + inline Bitboard& operator &=(const Bitboard x) { + b64[0] &= x.b64[0]; + b64[1] &= x.b64[1]; + return *this; + } + inline Bitboard& operator ^=(const Bitboard x) { + b64[0] ^= x.b64[0]; + b64[1] ^= x.b64[1]; + return *this; + } + + constexpr Bitboard operator ~ () const { + return Bitboard(~b64[0], ~b64[1]); + } + + constexpr Bitboard operator | (const Bitboard x) const { + return Bitboard(b64[0] | x.b64[0], b64[1] | x.b64[1]); + } + + constexpr Bitboard operator & (const Bitboard x) const { + return Bitboard(b64[0] & x.b64[0], b64[1] & x.b64[1]); + } + + constexpr Bitboard operator ^ (const Bitboard x) const { + return Bitboard(b64[0] ^ x.b64[0], b64[1] ^ x.b64[1]); + } + + constexpr Bitboard operator - (const Bitboard x) const { + return Bitboard(b64[0] - x.b64[0] - (b64[1] < x.b64[1]), b64[1] - x.b64[1]); + } + + constexpr Bitboard operator - (const int x) const { + return *this - Bitboard(x); + } + + inline Bitboard operator * (const Bitboard x) const { + uint64_t a_lo = (uint32_t)b64[1]; + uint64_t a_hi = b64[1] >> 32; + uint64_t b_lo = (uint32_t)x.b64[1]; + uint64_t b_hi = x.b64[1] >> 32; + + uint64_t t1 = (a_hi * b_lo) + ((a_lo * b_lo) >> 32); + uint64_t t2 = (a_lo * b_hi) + (t1 & 0xFFFFFFFF); + + return Bitboard(b64[0] * x.b64[1] + b64[1] * x.b64[0] + (a_hi * b_hi) + (t1 >> 32) + (t2 >> 32), + (t2 << 32) + (a_lo * b_lo & 0xFFFFFFFF)); + } +}; +#endif constexpr int SQUARE_BITS = 7; #else typedef uint64_t Bitboard; -- 1.7.0.4