Support non-GCC and 32bit for large-board version
authorFabian Fichter <ianfab@users.noreply.github.com>
Tue, 29 Jan 2019 22:14:58 +0000 (23:14 +0100)
committerFabian Fichter <ianfab@users.noreply.github.com>
Tue, 30 Apr 2019 21:05:18 +0000 (23:05 +0200)
.travis.yml
src/bitboard.cpp
src/bitboard.h
src/evaluate.cpp
src/movegen.cpp
src/pawns.cpp
src/position.cpp
src/types.h

index aa4c2e0..db1385c 100644 (file)
@@ -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
index 40c038f..4e0194f 100644 (file)
@@ -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 } };
index 87db5dc..06cdaad 100644 (file)
@@ -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);
 }
 
 
index 0409ad5..7bda6e5 100644 (file)
@@ -252,7 +252,7 @@ namespace {
         mobilityArea[Us] = ~(b | pos.pieces(Us, KING, QUEEN) | pe->pawn_attacks(Them) | shift<Down>(pos.pieces(Them, SHOGI_PAWN)));
 
     // Initialize attackedBy[] for king and pawns
-    attackedBy[Us][KING] = pos.count<KING>(Us) ? pos.attacks_from<KING>(Us, ksq) : 0;
+    attackedBy[Us][KING] = pos.count<KING>(Us) ? pos.attacks_from<KING>(Us, ksq) : Bitboard(0);
     attackedBy[Us][PAWN] = pe->pawn_attacks(Us);
     attackedBy[Us][SHOGI_PAWN] = shift<Up>(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<BISHOP>(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
 
     std::function <Bitboard (Color, PieceType)> 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())
     {
index e1f74f6..b326233 100644 (file)
@@ -91,7 +91,7 @@ namespace {
         emptySquares = (Type == QUIETS || Type == QUIET_CHECKS ? target : ~pos.pieces());
 
         Bitboard b1 = shift<Up>(pawnsNotOn7)   & emptySquares;
-        Bitboard b2 = pos.double_step_enabled() ? shift<Up>(b1 & TRank3BB) & emptySquares : 0;
+        Bitboard b2 = pos.double_step_enabled() ? shift<Up>(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<WHITE, Type>(pos, moveList, target)
index 0a493fd..cd4c92d 100644 (file)
@@ -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.
index 9c1cefd..12ee530 100644 (file)
@@ -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<KING>(sideToMove) ? attackers_to(square<KING>(sideToMove), ~sideToMove) : 0;
+  si->checkersBB = count<KING>(sideToMove) ? attackers_to(square<KING>(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<KING>(them), us) & pieces(us) : 0;
+  st->checkersBB = givesCheck ? attackers_to(square<KING>(them), us) & pieces(us) : Bitboard(0);
 
   // Update information about promoted pieces
   if (type_of(m) != DROP && is_promoted(from))
index 41de7f6..ac250ac 100644 (file)
@@ -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;