Skip to content

Commit

Permalink
non-BMI pext/pdep
Browse files Browse the repository at this point in the history
  • Loading branch information
primenumber committed Feb 17, 2024
1 parent 60eafa0 commit 5471e15
Showing 1 changed file with 39 additions and 0 deletions.
39 changes: 39 additions & 0 deletions src/engine/bits.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#[cfg(target_feature = "bmi2")]
use core::arch::x86_64::{_pdep_u64, _pext_u64};

pub trait BitManip {
Expand All @@ -6,13 +7,51 @@ pub trait BitManip {
}

impl BitManip for u64 {
#[cfg(target_feature = "avx2")]
fn pext(&self, mask: u64) -> u64 {
unsafe { _pext_u64(*self, mask) }
}

#[cfg(not(target_feature = "avx2"))]
fn pext(&self, mut mask: u64) -> u64 {
let mut x = *self;
x = x & mask;
let mut mk = !mask << 1;
for i in 0..6 {
let mut mp = mk ^ (mk << 1);
mp ^= mp << 2;
mp ^= mp << 4;
mp ^= mp << 8;
mp ^= mp << 16;
mp ^= mp << 32;
let mv = mp & mask;
mask = mask ^ mv | (mv >> (1 << i));
let t = x & mv;
x = x ^ t | (t >> (1 << i));
mk = mk & !mp;
}
x
}

#[cfg(target_feature = "bmi1")]
fn pdep(&self, mask: u64) -> u64 {
unsafe { _pdep_u64(*self, mask) }
}

#[cfg(not(target_feature = "bmi2"))]
fn pdep(&self, mut mask: u64) -> u64 {
let mut x = *self;
let mut res = 0;
while mask != 0 {
let bit = mask & mask.wrapping_neg();
if (x & 1) == 1 {
res |= bit;
}
x >>= 1;
mask ^= bit;
}
res
}
}

pub fn popcnt(x: u64) -> i8 {
Expand Down

0 comments on commit 5471e15

Please sign in to comment.