use core::arch::x86_64::{
__m128i, _mm_gf2p8affine_epi64_epi8, _mm_gf2p8affineinv_epi64_epi8, _mm_gf2p8mul_epi8,
_mm_loadu_si128, _mm_set1_epi64x, _mm_storeu_si128,
};
use super::ByteLanes;
pub(super) type Narrow = __m128i;
unsafe impl ByteLanes for __m128i {
const WIDTH: usize = 16;
type Matrix = Self;
#[inline(always)]
fn matrix(quadword: u64) -> Self::Matrix {
unsafe { _mm_set1_epi64x(quadword as i64) }
}
#[inline(always)]
unsafe fn load(from: *const u8) -> Self {
unsafe { _mm_loadu_si128(from.cast()) }
}
#[inline(always)]
unsafe fn store(to: *mut u8, value: Self) {
unsafe { _mm_storeu_si128(to.cast(), value) }
}
#[inline(always)]
fn mul(self, other: Self) -> Self {
unsafe { _mm_gf2p8mul_epi8(self, other) }
}
#[inline(always)]
fn affine(self, matrix: Self::Matrix) -> Self {
unsafe { _mm_gf2p8affine_epi64_epi8::<0>(self, matrix) }
}
#[inline(always)]
fn inverse_then_affine(self, matrix: Self::Matrix) -> Self {
unsafe { _mm_gf2p8affineinv_epi64_epi8::<0>(self, matrix) }
}
}
#[cfg(not(all(target_feature = "avx512f", target_feature = "avx512bw")))]
pub(super) type Wide = __m128i;
#[cfg(all(target_feature = "avx512f", target_feature = "avx512bw"))]
pub(super) type Wide = core::arch::x86_64::__m512i;
#[cfg(all(target_feature = "avx512f", target_feature = "avx512bw"))]
mod wide {
use core::arch::x86_64::{
__m512i, _mm512_gf2p8affine_epi64_epi8, _mm512_gf2p8affineinv_epi64_epi8,
_mm512_gf2p8mul_epi8, _mm512_loadu_si512, _mm512_set1_epi64, _mm512_storeu_si512,
};
use super::ByteLanes;
unsafe impl ByteLanes for __m512i {
const WIDTH: usize = 64;
type Matrix = Self;
#[inline(always)]
fn matrix(quadword: u64) -> Self::Matrix {
unsafe { _mm512_set1_epi64(quadword as i64) }
}
#[inline(always)]
unsafe fn load(from: *const u8) -> Self {
unsafe { _mm512_loadu_si512(from.cast()) }
}
#[inline(always)]
unsafe fn store(to: *mut u8, value: Self) {
unsafe { _mm512_storeu_si512(to.cast(), value) }
}
#[inline(always)]
fn mul(self, other: Self) -> Self {
unsafe { _mm512_gf2p8mul_epi8(self, other) }
}
#[inline(always)]
fn affine(self, matrix: Self::Matrix) -> Self {
unsafe { _mm512_gf2p8affine_epi64_epi8::<0>(self, matrix) }
}
#[inline(always)]
fn inverse_then_affine(self, matrix: Self::Matrix) -> Self {
unsafe { _mm512_gf2p8affineinv_epi64_epi8::<0>(self, matrix) }
}
}
}