use core::arch::x86_64::{
_mm_clmulepi64_si128, _mm_cvtsi128_si64, _mm_set_epi64x, _mm_unpackhi_epi64,
};
mod ghash;
mod lanes;
#[cfg(all(
target_feature = "gfni",
target_feature = "avx512f",
target_feature = "avx512bw",
target_feature = "avx512vbmi"
))]
mod gfni;
#[cfg(all(
target_feature = "gfni",
target_feature = "avx512f",
target_feature = "avx512bw",
target_feature = "avx512vbmi"
))]
pub(crate) use gfni::square_times;
pub(crate) use ghash::{poly_dot_128, poly_mul_128, poly_mul_128_by_64, poly_square_128};
#[inline]
pub(super) fn clmul_64x64(a: u64, b: u64) -> u128 {
unsafe {
let a = _mm_set_epi64x(0, a as i64);
let b = _mm_set_epi64x(0, b as i64);
let product = _mm_clmulepi64_si128::<0x00>(a, b);
let low = _mm_cvtsi128_si64(product) as u64;
let high = _mm_cvtsi128_si64(_mm_unpackhi_epi64(product, product)) as u64;
u128::from(low) | (u128::from(high) << 64)
}
}