X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fbitboard.cpp;h=e329ab52a79439710ef1771ecc4ac3be08442c0b;hp=7a4d73c9cb6b2adbbbd8204777327d5311201375;hb=e0504ab876a997321102f040ab88203cb893db12;hpb=84a641b8bb849a1951c60f92dc97619237fb2d09 diff --git a/src/bitboard.cpp b/src/bitboard.cpp index 7a4d73c9..e329ab52 100644 --- a/src/bitboard.cpp +++ b/src/bitboard.cpp @@ -2,6 +2,7 @@ Stockfish, a UCI chess playing engine derived from Glaurung 2.1 Copyright (C) 2004-2008 Tord Romstad (Glaurung author) 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 @@ -20,9 +21,9 @@ #include #include "bitboard.h" -#include "bitcount.h" #include "misc.h" +uint8_t PopCnt16[1 << 16]; int SquareDistance[SQUARE_NB][SQUARE_NB]; Bitboard RookMasks [SQUARE_NB]; @@ -73,18 +74,30 @@ namespace { return Is64Bit ? (b * DeBruijn64) >> 58 : ((unsigned(b) ^ unsigned(b >> 32)) * DeBruijn32) >> 26; } + + + // popcount16() counts the non-zero bits using SWAR-Popcount algorithm + + unsigned popcount16(unsigned u) { + u -= (u >> 1) & 0x5555U; + u = ((u >> 2) & 0x3333U) + (u & 0x3333U); + u = ((u >> 4) + u) & 0x0F0FU; + return (u * 0x0101U) >> 8; + } } -#ifndef USE_BSFQ +#ifdef NO_BSF /// Software fall-back of lsb() and msb() for CPU lacking hardware support Square lsb(Bitboard b) { + assert(b); return BSFTable[bsf_index(b)]; } Square msb(Bitboard b) { + assert(b); unsigned b32; int result = 0; @@ -111,7 +124,7 @@ Square msb(Bitboard b) { return Square(result + MSBTable[b32]); } -#endif // ifndef USE_BSFQ +#endif // ifdef NO_BSF /// Bitboards::pretty() returns an ASCII representation of a bitboard suitable @@ -138,6 +151,9 @@ const std::string Bitboards::pretty(Bitboard b) { void Bitboards::init() { + for (unsigned i = 0; i < (1 << 16); ++i) + PopCnt16[i] = (uint8_t) popcount16(i); + for (Square s = SQ_A1; s <= SQ_H8; ++s) { SquareBB[s] = 1ULL << s; @@ -189,8 +205,8 @@ void Bitboards::init() { StepAttacksBB[make_piece(c, pt)][s] |= to; } - Square RookDeltas[] = { DELTA_N, DELTA_E, DELTA_S, DELTA_W }; - Square BishopDeltas[] = { DELTA_NE, DELTA_SE, DELTA_SW, DELTA_NW }; + Square RookDeltas[] = { NORTH, EAST, SOUTH, WEST }; + Square BishopDeltas[] = { NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST }; init_magics(RookTable, RookAttacks, RookMagics, RookMasks, RookShifts, RookDeltas, magic_index); init_magics(BishopTable, BishopAttacks, BishopMagics, BishopMasks, BishopShifts, BishopDeltas, magic_index); @@ -262,7 +278,7 @@ namespace { // the number of 1s of the mask. Hence we deduce the size of the shift to // apply to the 64 or 32 bits word to get the index. masks[s] = sliding_attack(deltas, s, 0) & ~edges; - shifts[s] = (Is64Bit ? 64 : 32) - popcount(masks[s]); + shifts[s] = (Is64Bit ? 64 : 32) - popcount(masks[s]); // Use Carry-Rippler trick to enumerate all subsets of masks[s] and // store the corresponding sliding attack bitboard in reference[]. @@ -293,7 +309,7 @@ namespace { do { do magics[s] = rng.sparse_rand(); - while (popcount((magics[s] * masks[s]) >> 56) < 6); + while (popcount((magics[s] * masks[s]) >> 56) < 6); // A good magic must map every possible occupancy to an index that // looks up the correct sliding attack in the attacks[s] database.