44namespace chess {
55
66namespace _chess {
7- #if defined(__AVX512BW__)
7+
8+ #if defined(USE_AVX512ICL)
9+
10+ // clang-format off
11+ const __m512i AllSquares = _mm512_set_epi8(
12+ 63 , 62 , 61 , 60 , 59 , 58 , 57 , 56 , 55 , 54 , 53 , 52 , 51 , 50 , 49 , 48 , 47 , 46 , 45 , 44 , 43 , 42 , 41 ,
13+ 40 , 39 , 38 , 37 , 36 , 35 , 34 , 33 , 32 , 31 , 30 , 29 , 28 , 27 , 26 , 25 , 24 , 23 , 22 , 21 , 20 , 19 , 18 ,
14+ 17 , 16 , 15 , 14 , 13 , 12 , 11 , 10 , 9 , 8 , 7 , 6 , 5 , 4 , 3 , 2 , 1 , 0 );
15+ // clang-format on
16+
17+ template <Direction offset> inline Move *splat_pawn_moves (Move *moveList, Bitboard to_bb) {
18+ assert (popcount (to_bb) <= 8 ); // <= 8 pawns per side
19+
20+ const __m128i toSquares = _mm_cvtepi8_epi16 (_mm512_castsi512_si128 (_mm512_maskz_compress_epi8 (to_bb, AllSquares)));
21+ const __m128i fromSquares = _mm_subs_epi16 (toSquares, _mm_set1_epi16 (offset));
22+ const __m128i moves = _mm_or_si128 (_mm_slli_epi16 (fromSquares, 6 ), _mm_slli_epi16 (toSquares, 0 ));
23+
24+ _mm_storeu_si128 (reinterpret_cast <__m128i *>(moveList), moves);
25+ return moveList + popcount (to_bb);
26+ }
27+
28+ inline Move *splat_moves (Move *moveList, Square from, Bitboard to_bb) {
29+ assert (popcount (to_bb) <= 32 ); // Q can attack up to 27 squares
30+
31+ const __m512i fromVec = _mm512_set1_epi16 (Move (from, SQUARE_ZERO).raw ());
32+ const __m512i toSquares = _mm512_cvtepi8_epi16 (_mm512_castsi512_si256 (_mm512_maskz_compress_epi8 (to_bb, AllSquares)));
33+ const __m512i moves = _mm512_or_si512 (fromVec, _mm512_slli_epi16 (toSquares, Move::ToSqShift));
34+
35+ _mm512_storeu_si512 (moveList, moves);
36+ return moveList + popcount (to_bb);
37+ }
38+
39+ #elif defined(__AVX512BW__)
840template <int Offset = 0 > struct alignas (64 ) SplatTable {
941 std::array<uint16_t , 64 > data;
1042 constexpr int clamp64 (int x) { return (x < 0 ) ? 0 : (x > 63 ? 63 : x); }
@@ -213,7 +245,7 @@ void movegen::genPawnSingleMoves(
213245}
214246template <typename T, Color c, bool capturesOnly>
215247void movegen::genKnightMoves (const _Position<T, void > &pos, Movelist &list, Bitboard _pin_mask, Bitboard _check_mask) {
216- Bitboard knights = pos.template pieces <KNIGHT, c>() & ~_pin_mask; // yes, unconditionally.
248+ Bitboard knights = pos.template pieces <KNIGHT, c>() & ~_pin_mask;
217249 while (knights) {
218250 Square x = static_cast <Square>(pop_lsb (knights));
219251 Bitboard moves = attacks::knight (x) & ~pos.occ (c);
@@ -253,7 +285,6 @@ void movegen::genKingMoves(const _Position<T, void> &pos, Movelist &out, Bitboar
253285 // Enemy king (adjacent control squares)
254286 enemyAttacks |= attacks::king (pos.kingSq (them));
255287
256- // Candidate king moves = legal squares not attacked by enemy
257288 Bitboard moves = attacks::king (kingSq) & ~myOcc & ~enemyAttacks;
258289 if constexpr (capturesOnly)
259290 moves &= pos.occ (~c);
@@ -289,8 +320,7 @@ void movegen::genSlidingMoves(
289320 static_assert (pt == BISHOP || pt == ROOK || pt == QUEEN, " Sliding pieces only." );
290321 Bitboard sliders = pos.template pieces <pt, c>();
291322 Bitboard occ_all = pos.occ ();
292- // Square king_sq = current_state.kings[c];
293- Bitboard rook_pinners = _rook_pin; // bitboard of enemy rooks/queens pinning
323+ Bitboard rook_pinners = _rook_pin;
294324 Bitboard bishop_pinners = _bishop_pin;
295325 if constexpr (pt == BISHOP)
296326 sliders &= ~rook_pinners;
@@ -305,7 +335,6 @@ void movegen::genSlidingMoves(
305335 Bitboard bishop_hit = bishop_pinners & from_bb;
306336 Bitboard pin_mask = rook_hit ? rook_pinners : bishop_hit ? bishop_pinners : ~0ULL ;
307337
308- // Bitboard blockers = occ() ^ from_bb; // remove piece temporarily
309338 auto func = attacks::queen;
310339 if constexpr (pt == BISHOP)
311340 func = attacks::bishop;
0 commit comments