#[cfg(target_arch = "x86_64")]
use core::arch::x86_64::*;
#[target_feature(enable = "bmi2")]
#[inline]
#[allow(unused_unsafe)]
pub unsafe fn bzhi(val: u64, n: u32) -> u64 {
debug_assert!(n <= 64);
unsafe { _bzhi_u64(val, n) }
}
#[target_feature(enable = "bmi2")]
#[inline]
#[allow(unused_unsafe)]
pub unsafe fn pext(val: u64, mask: u64) -> u64 {
unsafe { _pext_u64(val, mask) }
}
#[target_feature(enable = "bmi2")]
#[inline]
#[allow(unused_unsafe)]
pub unsafe fn pdep(val: u64, mask: u64) -> u64 {
unsafe { _pdep_u64(val, mask) }
}
#[cfg(all(test, feature = "std"))]
mod tests {
use super::*;
#[test]
fn bzhi_basic() {
if !std::arch::is_x86_feature_detected!("bmi2") {
return;
}
unsafe {
assert_eq!(bzhi(0xFF, 4), 0x0F);
assert_eq!(bzhi(0xFFFF_FFFF_FFFF_FFFF, 1), 1);
assert_eq!(bzhi(0xFFFF_FFFF_FFFF_FFFF, 0), 0);
assert_eq!(bzhi(0xDEAD_BEEF, 16), 0xBEEF);
}
}
#[test]
fn pext_basic() {
if !std::arch::is_x86_feature_detected!("bmi2") {
return;
}
unsafe {
assert_eq!(pext(0b1010_1010, 0b1111_0000), 0b1010);
assert_eq!(pext(0b1100_0011, 0b1001_0110), 0b1001);
}
}
#[test]
fn pdep_basic() {
if !std::arch::is_x86_feature_detected!("bmi2") {
return;
}
unsafe {
assert_eq!(pdep(0b1010, 0b1111_0000), 0b1010_0000);
}
}
}