X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fbitboard.h;h=390966e3494273969bdb53a50c6953a6c9782611;hp=b38fa55b224a47c4b09be0d6e7c7315761080df7;hb=7c5d724724e826ff1fd9a97c8812d5a4bffaaa84;hpb=3fda064a669c2bcecfa31d66c661efa7408499de diff --git a/src/bitboard.h b/src/bitboard.h index b38fa55b..390966e3 100644 --- a/src/bitboard.h +++ b/src/bitboard.h @@ -1,14 +1,14 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 Copyright (C) 2004-2008 Tord Romstad (Glaurung author) - Copyright (C) 2008-2014 Marco Costalba, Joona Kiiski, Tord Romstad + Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad + Copyright (C) 2015-2016 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the @@ -61,16 +61,6 @@ const Bitboard Rank8BB = Rank1BB << (8 * 7); extern int SquareDistance[SQUARE_NB][SQUARE_NB]; -extern Bitboard RookMasks [SQUARE_NB]; -extern Bitboard RookMagics [SQUARE_NB]; -extern Bitboard* RookAttacks[SQUARE_NB]; -extern unsigned RookShifts [SQUARE_NB]; - -extern Bitboard BishopMasks [SQUARE_NB]; -extern Bitboard BishopMagics [SQUARE_NB]; -extern Bitboard* BishopAttacks[SQUARE_NB]; -extern unsigned BishopShifts [SQUARE_NB]; - extern Bitboard SquareBB[SQUARE_NB]; extern Bitboard FileBB[FILE_NB]; extern Bitboard RankBB[RANK_NB]; @@ -200,14 +190,6 @@ inline Bitboard passed_pawn_mask(Color c, Square s) { } -/// squares_of_color() returns a bitboard representing all the squares of the -/// same color of the given one. - -inline Bitboard squares_of_color(Square s) { - return DarkSquares & s ? DarkSquares : ~DarkSquares; -} - - /// aligned() returns true if the squares s1, s2 and s3 are aligned either on a /// straight or on a diagonal line. @@ -231,14 +213,21 @@ template<> inline int distance(Square x, Square y) { return distance(rank_ /// piece of type Pt (bishop or rook) placed on 's'. The helper magic_index() /// looks up the index using the 'magic bitboards' approach. template -FORCE_INLINE unsigned magic_index(Square s, Bitboard occupied) { +inline unsigned magic_index(Square s, Bitboard occupied) { + + extern Bitboard RookMasks[SQUARE_NB]; + extern Bitboard RookMagics[SQUARE_NB]; + extern unsigned RookShifts[SQUARE_NB]; + extern Bitboard BishopMasks[SQUARE_NB]; + extern Bitboard BishopMagics[SQUARE_NB]; + extern unsigned BishopShifts[SQUARE_NB]; Bitboard* const Masks = Pt == ROOK ? RookMasks : BishopMasks; Bitboard* const Magics = Pt == ROOK ? RookMagics : BishopMagics; unsigned* const Shifts = Pt == ROOK ? RookShifts : BishopShifts; if (HasPext) - return unsigned(_pext_u64(occupied, Masks[s])); + return unsigned(pext(occupied, Masks[s])); if (Is64Bit) return unsigned(((occupied & Masks[s]) * Magics[s]) >> Shifts[s]); @@ -250,6 +239,10 @@ FORCE_INLINE unsigned magic_index(Square s, Bitboard occupied) { template inline Bitboard attacks_bb(Square s, Bitboard occupied) { + + extern Bitboard* RookAttacks[SQUARE_NB]; + extern Bitboard* BishopAttacks[SQUARE_NB]; + return (Pt == ROOK ? RookAttacks : BishopAttacks)[s][magic_index(s, occupied)]; } @@ -265,56 +258,61 @@ inline Bitboard attacks_bb(Piece pc, Square s, Bitboard occupied) { } -/// lsb() and msb() return the least/most significant bit in a non-zero bitboard +/// popcount() counts the number of non-zero bits in a bitboard -#ifdef USE_BSFQ +inline int popcount(Bitboard b) { -# if defined(_MSC_VER) && !defined(__INTEL_COMPILER) +#ifndef USE_POPCNT -FORCE_INLINE Square lsb(Bitboard b) { - unsigned long idx; - _BitScanForward64(&idx, b); - return (Square) idx; -} + extern uint8_t PopCnt16[1 << 16]; + union { Bitboard bb; uint16_t u[4]; } v = { b }; + return PopCnt16[v.u[0]] + PopCnt16[v.u[1]] + PopCnt16[v.u[2]] + PopCnt16[v.u[3]]; -FORCE_INLINE Square msb(Bitboard b) { - unsigned long idx; - _BitScanReverse64(&idx, b); - return (Square) idx; -} +#elif defined(_MSC_VER) || defined(__INTEL_COMPILER) -# elif defined(__arm__) + return (int)_mm_popcnt_u64(b); -FORCE_INLINE int lsb32(uint32_t v) { - __asm__("rbit %0, %1" : "=r"(v) : "r"(v)); - return __builtin_clz(v); +#else // Assumed gcc or compatible compiler + + return __builtin_popcountll(b); + +#endif } -FORCE_INLINE Square msb(Bitboard b) { - return (Square) (63 - __builtin_clzll(b)); + +/// lsb() and msb() return the least/most significant bit in a non-zero bitboard + +#if defined(__GNUC__) + +inline Square lsb(Bitboard b) { + assert(b); + return Square(__builtin_ctzll(b)); } -FORCE_INLINE Square lsb(Bitboard b) { - return (Square) (uint32_t(b) ? lsb32(uint32_t(b)) : 32 + lsb32(uint32_t(b >> 32))); +inline Square msb(Bitboard b) { + assert(b); + return Square(63 - __builtin_clzll(b)); } -# else // Assumed gcc or compatible compiler +#elif defined(_WIN64) && defined(_MSC_VER) -FORCE_INLINE Square lsb(Bitboard b) { // Assembly code by Heinz van Saanen - Bitboard idx; - __asm__("bsfq %1, %0": "=r"(idx): "rm"(b) ); +inline Square lsb(Bitboard b) { + assert(b); + unsigned long idx; + _BitScanForward64(&idx, b); return (Square) idx; } -FORCE_INLINE Square msb(Bitboard b) { - Bitboard idx; - __asm__("bsrq %1, %0": "=r"(idx): "rm"(b) ); +inline Square msb(Bitboard b) { + assert(b); + unsigned long idx; + _BitScanReverse64(&idx, b); return (Square) idx; } -# endif +#else -#else // ifdef(USE_BSFQ) +#define NO_BSF // Fallback on software implementation for other cases Square lsb(Bitboard b); Square msb(Bitboard b); @@ -324,7 +322,7 @@ Square msb(Bitboard b); /// pop_lsb() finds and clears the least significant bit in a non-zero bitboard -FORCE_INLINE Square pop_lsb(Bitboard* b) { +inline Square pop_lsb(Bitboard* b) { const Square s = lsb(*b); *b &= *b - 1; return s;