mod elementwise;
mod gather;
mod matrix;
mod rows;
mod scatter;
mod single;
#[cfg(feature = "simd512")]
pub(super) use elementwise::ISO_11D_TO_11B;
pub use elementwise::{
mul_elementwise_assign_gfni, mul_elementwise_assign_gfni_8d, mul_elementwise_gfni,
mul_elementwise_gfni_8d,
};
pub use gather::{mul_add_gather_gfni, mul_add_gather_gfni_8d};
pub use matrix::{
mul_add_matrix_at_gfni, mul_add_matrix_at_gfni_8d, mul_add_matrix_gfni, mul_add_matrix_gfni_8d,
mul_add_matrix_gfni_8d_with, mul_add_matrix_gfni_with, mul_into_matrix_gfni,
mul_into_matrix_gfni_8d, mul_into_matrix_gfni_8d_with, mul_into_matrix_gfni_with,
};
pub use scatter::{mul_add_scatter_gfni, mul_add_scatter_gfni_8d};
pub use single::{
mul_add_gfni, mul_add_gfni_8d, mul_assign_gfni, mul_assign_gfni_8d, mul_into_gfni,
mul_into_gfni_8d,
};
#[cfg(feature = "simd512")]
pub(super) use single::{mul_add_gfni_8d_impl, mul_assign_gfni_8d_impl, mul_into_gfni_8d_impl};
use crate::field::gf8b::Elem;
use crate::field::gf8d;
use crate::kernel::tables::{ScaleTable, affine_8d, scale_table, scale_table_8d};
#[cfg(target_arch = "x86")]
use core::arch::x86::*;
#[cfg(target_arch = "x86_64")]
use core::arch::x86_64::*;
pub(super) trait Blocked {
type Coeff: Copy;
fn zero() -> Self::Coeff;
const AFFINE: bool;
fn byte(coeff: Self::Coeff) -> u8;
fn map(coeff: Self::Coeff) -> u64;
fn table(coeff: Self::Coeff) -> &'static ScaleTable;
}
pub(super) enum Gfni {}
impl Blocked for Gfni {
type Coeff = Elem;
const AFFINE: bool = false;
#[inline]
fn zero() -> Elem {
Elem(0)
}
#[inline]
fn byte(coeff: Elem) -> u8 {
coeff.0
}
#[inline]
fn map(_coeff: Elem) -> u64 {
0
}
#[inline]
fn table(coeff: Elem) -> &'static ScaleTable {
scale_table(coeff)
}
}
pub(super) enum Affine8D {}
impl Blocked for Affine8D {
type Coeff = gf8d::Elem;
const AFFINE: bool = true;
#[inline]
fn zero() -> gf8d::Elem {
gf8d::Elem(0)
}
#[inline]
fn byte(coeff: gf8d::Elem) -> u8 {
coeff.0
}
#[inline]
fn map(coeff: gf8d::Elem) -> u64 {
affine_8d(coeff)
}
#[inline]
fn table(coeff: gf8d::Elem) -> &'static ScaleTable {
scale_table_8d(coeff)
}
}
#[inline]
#[archmage::rite(v3_gfni_crypto)]
pub(super) fn bfactor_gfni<S: Blocked>(coeff: S::Coeff) -> __m256i {
if S::AFFINE {
_mm256_set1_epi64x(S::map(coeff).cast_signed())
} else {
_mm256_set1_epi8(S::byte(coeff).cast_signed())
}
}
#[inline]
#[archmage::rite(v3_gfni_crypto)]
pub(super) fn bfactor_half_gfni<S: Blocked>(coeff: S::Coeff) -> __m128i {
if S::AFFINE {
_mm_set1_epi64x(S::map(coeff).cast_signed())
} else {
_mm_set1_epi8(S::byte(coeff).cast_signed())
}
}
#[inline]
#[archmage::rite(v3_gfni_crypto)]
pub(super) fn bmul_gfni<S: Blocked>(x: __m256i, factor: __m256i) -> __m256i {
if S::AFFINE {
_mm256_gf2p8affine_epi64_epi8::<0>(x, factor)
} else {
_mm256_gf2p8mul_epi8(x, factor)
}
}
#[inline]
#[archmage::rite(v3_gfni_crypto)]
pub(super) fn bmul_half_gfni<S: Blocked>(x: __m128i, factor: __m128i) -> __m128i {
if S::AFFINE {
_mm_gf2p8affine_epi64_epi8::<0>(x, factor)
} else {
_mm_gf2p8mul_epi8(x, factor)
}
}
#[archmage::rite(v3_gfni_crypto)]
pub(super) fn brem_gfni<S: Blocked>(dst: &mut [u8], coeff: S::Coeff, src: &[u8]) {
if S::AFFINE {
single::mul_add_gfni_8d_impl(dst, S::map(coeff), S::table(coeff), src);
} else {
single::mul_add_gfni_impl(dst, Elem(S::byte(coeff)), src);
}
}
#[inline]
fn factor_word_gfni<S: Blocked>(coeff: S::Coeff) -> u64 {
if S::AFFINE {
S::map(coeff)
} else {
u64::from(S::byte(coeff))
}
}
#[inline]
#[archmage::rite(v3_gfni_crypto)]
pub(super) fn wfactor_gfni<S: Blocked>(word: u64) -> __m256i {
if S::AFFINE {
_mm256_set1_epi64x(word.cast_signed())
} else {
_mm256_set1_epi8(word.to_le_bytes()[0].cast_signed())
}
}