Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add fallback for BMI or BMI2 instructions #4

Merged
merged 4 commits into from
Aug 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
13 changes: 13 additions & 0 deletions .github/workflows/ci-mac
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
name: CI-Mac
on: [push]
jobs:
build-and-test:
runs-on: macos-latest
steps:
- name: install compilers etc
run: sudo apt install g++
- name: Check out repository code
uses: actions/checkout@v3
- run: make -j$(nproc) test no-BMI2=1
- run: make -j$(nproc) release no-BMI2=1
- run: make -j$(nproc) perft no-BMI2=1
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: CI
name: CI-Ubuntu
on: [push]
jobs:
build-and-test:
Expand Down
8 changes: 8 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@ ifneq ($(LIBS),)
LINK_FLAGS += $(shell pkg-config --libs $(LIBS))
endif

# BMI and BMI2 instruction set
ifeq ($(no-BMI),)
COMPILE_FLAGS += -mbmi
ifeq ($(no-BMI2),)
COMPILE_FLAGS += -mbmi2
endif
endif

# Verbose option, to output compile and link commands
export V := false
export CMD_PREFIX := @
Expand Down
2 changes: 1 addition & 1 deletion config.mk
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ MAINS_PATH = mains
# Space-separated pkg-config libraries used by this project
LIBS =
# General compiler flags
COMPILE_FLAGS = -std=c++17 -Wall -Wextra -g -mbmi -mbmi2 -O3
COMPILE_FLAGS = -std=c++17 -Wall -Wextra -g -O3
# Additional release-specific flags
RCOMPILE_FLAGS = -D NDEBUG -DDOCTEST_CONFIG_DISABLE
# Additional debug-specific flags
Expand Down
17 changes: 9 additions & 8 deletions includes/attacks.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

# include "bitboard.hpp"
# include "lookup.hpp"
# include "bmi2_fallback.hpp"

# include <tuple>

Expand Down Expand Up @@ -150,14 +151,14 @@ constexpr BitMask compute_file_blocker(const size_t square){
const auto file_blocker_lookup = lookup_table<BitMask, 64>(compute_file_blocker);

inline BitMask rook_seen_rank(const Square square, const BitMask occ){
const BitMask ext_block_mask = _pext_u64(occ, rank_blocker_lookup[square]);
const BitMask ext_block_mask = PEXT(occ, rank_blocker_lookup[square]);
const BitMask ext_seen_mask = slider_attack_table[square % 8][ext_block_mask];
return _pdep_u64(ext_seen_mask, rank_lookup[square]);
return PDEP(ext_seen_mask, rank_lookup[square]);
}
inline BitMask rook_seen_file(const Square square, const BitMask occ){
const BitMask ext_block_mask = _pext_u64(occ, file_blocker_lookup[square]);
const BitMask ext_block_mask = PEXT(occ, file_blocker_lookup[square]);
const BitMask ext_seen_mask = slider_attack_table[square / 8][ext_block_mask];
return _pdep_u64(ext_seen_mask, file_lookup[square]);
return PDEP(ext_seen_mask, file_lookup[square]);
}
inline BitMask rook_seen(const Square square, const BitMask occ){
return rook_seen_rank(square, occ) | rook_seen_file(square, occ);
Expand Down Expand Up @@ -198,15 +199,15 @@ constexpr auto index_on_lower(Square square){
}

inline BitMask bishop_seen_upper(const Square square, const BitMask occ){
const BitMask ext_block_mask = _pext_u64(occ, upper_blocker_lookup[square]);
const BitMask ext_block_mask = PEXT(occ, upper_blocker_lookup[square]);
const BitMask ext_seen_mask = slider_attack_table[index_on_upper(square)][ext_block_mask];
return _pdep_u64(ext_seen_mask, upper_diag_lookup[square]);
return PDEP(ext_seen_mask, upper_diag_lookup[square]);
}

inline BitMask bishop_seen_lower(const Square square, const BitMask occ){
const BitMask ext_block_mask = _pext_u64(occ, lower_blocker_lookup[square]);
const BitMask ext_block_mask = PEXT(occ, lower_blocker_lookup[square]);
const BitMask ext_seen_mask = slider_attack_table[index_on_lower(square)][ext_block_mask];
return _pdep_u64(ext_seen_mask, lower_diag_lookup[square]);
return PDEP(ext_seen_mask, lower_diag_lookup[square]);
}

inline BitMask bishop_seen(const Square square, const BitMask occ){
Expand Down
3 changes: 2 additions & 1 deletion includes/bitboard.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@

# include <cstdint>
# include <x86intrin.h>
# include "bmi_fallback.hpp"

#define SquareOf(X) _tzcnt_u64(X)
#define ToMask(X) (1ull << (X))
#define Bitloop(X, var) for(auto var = X; var; var = __blsr_u64(var))
#define Bitloop(X, var) for(auto var = X; var; var = BLSR(var))
#define Flip(X) ((X) ^ 56)
#define FlipIf(cond, X) ((cond) ? ((X) ^ 56) : (X))

Expand Down
33 changes: 33 additions & 0 deletions includes/bmi2_fallback.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# pragma once

# ifdef __BMI2__

# include <x86intrin.h>
# define PEXT _pext_u64
# define PDEP _pdep_u64

# else

# include <cstdint>

constexpr uint64_t PEXT(const uint64_t val, uint64_t mask) {
uint64_t res = 0;
for (uint64_t bb = 1; mask; bb += bb) {
if ( val & mask & -mask )
res |= bb;
mask &= mask - 1;
}
return res;
}

constexpr uint64_t PDEP(const uint64_t val, uint64_t mask) {
uint64_t res = 0;
for (uint64_t bb = 1; mask; bb += bb) {
if (val & bb)
res |= mask & -mask;
mask &= mask - 1;
}
return res;
}

# endif
13 changes: 13 additions & 0 deletions includes/bmi_fallback.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# pragma once

# ifdef __BMI__

# include <x86intrin.h>
# define BLSR __blsr_u64

# else

# include <cstdint>
constexpr uint64_t BLSR(const uint64_t x){ return x & (x-1); }

# endif
25 changes: 13 additions & 12 deletions src/movegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
# include "movegen.hpp"
# include "parse_format.hpp"
# include "attacks.hpp"
# include "bmi2_fallback.hpp"

/* KNIGHTS */

Expand Down Expand Up @@ -85,21 +86,21 @@ std::tuple<BitMask, BitMask> rook_checks_and_pins(
const BitMask rank = rank_lookup[king];
Bitloop(rank & rooks, loop_var){
const Square rook = SquareOf(loop_var);
const BitMask ext_block_mask = _pext_u64(occ, rank_blocker_lookup[king]);
const BitMask ext_block_mask = PEXT(occ, rank_blocker_lookup[king]);
BitMask check, pin;
std::tie(check, pin) = slider_cnp_table[rook % 8][king % 8][ext_block_mask];
h_check_mask |= _pdep_u64(check, rank);
hv_pin |= _pdep_u64(pin, rank);
h_check_mask |= PDEP(check, rank);
hv_pin |= PDEP(pin, rank);
}

const BitMask file = file_lookup[king];
Bitloop(file & rooks, loop_var){
const Square rook = SquareOf(loop_var);
const BitMask ext_block_mask = _pext_u64(occ, file_blocker_lookup[king]);
const BitMask ext_block_mask = PEXT(occ, file_blocker_lookup[king]);
BitMask check, pin;
std::tie(check, pin) = slider_cnp_table[rook / 8][king / 8][ext_block_mask];
v_check_mask |= _pdep_u64(check, file);
hv_pin |= _pdep_u64(pin, file);
v_check_mask |= PDEP(check, file);
hv_pin |= PDEP(pin, file);
}

BitMask check_mask = (h_check_mask ? h_check_mask : FULL_BOARD) &
Expand Down Expand Up @@ -142,25 +143,25 @@ std::tuple<BitMask, BitMask> bishop_checks_and_pins(
const BitMask upper_diag = upper_diag_lookup[king];
Bitloop(upper_diag & bishops, loop_var){
const Square bishop = SquareOf(loop_var);
const BitMask ext_block_mask = _pext_u64(occ, upper_blocker_lookup[king]);
const BitMask ext_block_mask = PEXT(occ, upper_blocker_lookup[king]);
const auto k_index = index_on_upper(king);
const auto b_index = index_on_upper(bishop);
BitMask check, pin;
std::tie(check, pin) = slider_cnp_table[b_index][k_index][ext_block_mask];
check_mask |= _pdep_u64(check, upper_diag);
diag_pin |= _pdep_u64(pin, upper_diag);
check_mask |= PDEP(check, upper_diag);
diag_pin |= PDEP(pin, upper_diag);
}

const BitMask lower_diag = lower_diag_lookup[king];
Bitloop(lower_diag & bishops, loop_var){
const Square bishop = SquareOf(loop_var);
const BitMask ext_block_mask = _pext_u64(occ, lower_blocker_lookup[king]);
const BitMask ext_block_mask = PEXT(occ, lower_blocker_lookup[king]);
const auto k_index = index_on_lower(king);
const auto b_index = index_on_lower(bishop);
BitMask check, pin;
std::tie(check, pin) = slider_cnp_table[b_index][k_index][ext_block_mask];
check_mask |= _pdep_u64(check, lower_diag);
diag_pin |= _pdep_u64(pin, lower_diag);
check_mask |= PDEP(check, lower_diag);
diag_pin |= PDEP(pin, lower_diag);
}

return std::make_tuple(check_mask ? check_mask : FULL_BOARD, diag_pin);
Expand Down