#![allow(unsafe_code)]
#![allow(unused_unsafe)]
#![allow(clippy::missing_safety_doc)]
pub mod bmi2 {
use core::arch::x86_64::{_pdep_u32, _pdep_u64, _pext_u32, _pext_u64};
#[target_feature(enable = "bmi2")]
#[inline]
#[must_use]
pub fn pext_u32(x: u32, mask: u32) -> u32 {
unsafe { _pext_u32(x, mask) }
}
#[target_feature(enable = "bmi2")]
#[inline]
#[must_use]
pub fn pext_u64(x: u64, mask: u64) -> u64 {
unsafe { _pext_u64(x, mask) }
}
#[target_feature(enable = "bmi2")]
#[inline]
#[must_use]
pub fn pdep_u32(x: u32, mask: u32) -> u32 {
unsafe { _pdep_u32(x, mask) }
}
#[target_feature(enable = "bmi2")]
#[inline]
#[must_use]
pub fn pdep_u64(x: u64, mask: u64) -> u64 {
unsafe { _pdep_u64(x, mask) }
}
#[target_feature(enable = "bmi2")]
#[inline]
#[must_use]
pub fn select_u64(x: u64, k: u32) -> u32 {
pdep_u64(1u64.checked_shl(k).unwrap_or(0), x).trailing_zeros()
}
}
#[cfg(target_feature = "sse2")]
pub mod pclmulqdq {
use core::arch::x86_64::{
__m128i, _mm_clmulepi64_si128, _mm_cvtsi128_si64, _mm_set_epi64x, _mm_unpackhi_epi64,
};
#[target_feature(enable = "pclmulqdq")]
#[inline]
fn times_ones(x: u64) -> __m128i {
unsafe {
let a = _mm_set_epi64x(0, x.cast_signed());
_mm_clmulepi64_si128(a, _mm_set_epi64x(0, -1), 0)
}
}
#[target_feature(enable = "pclmulqdq")]
#[inline]
#[must_use]
pub fn xor_scan_u64(x: u64) -> u64 {
unsafe { _mm_cvtsi128_si64(times_ones(x)).cast_unsigned() }
}
#[target_feature(enable = "pclmulqdq")]
#[inline]
#[must_use]
pub fn xor_scan_down_u64(x: u64) -> u64 {
let p = times_ones(x);
let exclusive = unsafe { _mm_cvtsi128_si64(_mm_unpackhi_epi64(p, p)) }.cast_unsigned();
exclusive ^ x
}
}