use crate::field::FieldBuffer;
use crate::field::finite_field::{FiniteField, Residue};
use crate::kernel::residue::PreparedResidue;
mod u32;
mod u64;
mod u8;
pub use u8::{mul_add_u8_avx512, mul_assign_u8_avx512, mul_into_u8_avx512};
pub use u32::{
mul_add_u32_avx512, mul_assign_u32_avx512, mul_elementwise_assign_u32_avx512,
mul_elementwise_u32_avx512, mul_into_u32_avx512,
};
pub use u64::{mul_add_u64_avx512, mul_assign_u64_avx512, mul_into_u64_avx512};
#[inline]
#[allow(clippy::cast_possible_truncation)]
pub(crate) fn mul_into_with<const P: u64>(dst: &mut [u8], coeff: PreparedResidue, src: &[u8]) {
let token = crate::kernel::x86_v4_token();
match <FiniteField<P, 1, Residue> as FieldBuffer>::BYTES {
1 => mul_into_u8_avx512(token, dst, src, coeff.word as u8, P as u8),
4 => mul_into_u32_avx512(
token,
dst,
src,
coeff.word as u32,
(coeff.word >> 32) as u32,
P as u32,
),
8 => mul_into_u64_avx512(token, dst, src, coeff.word, P),
_ => unreachable!("selected residue lane width"),
}
}
#[inline]
#[allow(clippy::cast_possible_truncation)]
pub(crate) fn mul_add_with<const P: u64>(dst: &mut [u8], coeff: PreparedResidue, src: &[u8]) {
let token = crate::kernel::x86_v4_token();
match <FiniteField<P, 1, Residue> as FieldBuffer>::BYTES {
1 => mul_add_u8_avx512(token, dst, src, coeff.word as u8, P as u8),
4 => mul_add_u32_avx512(
token,
dst,
src,
coeff.word as u32,
(coeff.word >> 32) as u32,
P as u32,
),
8 => mul_add_u64_avx512(token, dst, src, coeff.word, P),
_ => unreachable!("selected residue lane width"),
}
}
#[inline]
#[allow(clippy::cast_possible_truncation)]
pub(crate) fn mul_assign_with<const P: u64>(dst: &mut [u8], coeff: PreparedResidue) {
let token = crate::kernel::x86_v4_token();
match <FiniteField<P, 1, Residue> as FieldBuffer>::BYTES {
1 => mul_assign_u8_avx512(token, dst, coeff.word as u8, P as u8),
4 => mul_assign_u32_avx512(
token,
dst,
coeff.word as u32,
(coeff.word >> 32) as u32,
P as u32,
),
8 => mul_assign_u64_avx512(token, dst, coeff.word, P),
_ => unreachable!("selected residue lane width"),
}
}
#[inline]
pub(crate) fn mul_elementwise<const P: u64>(dst: &mut [u8], a: &[u8], b: &[u8]) {
mul_elementwise_u32_avx512(
crate::kernel::x86_v4_token(),
dst,
a,
b,
FiniteField::<P, 1, Residue>::U32_PARAMS,
);
}
#[inline]
pub(crate) fn mul_elementwise_assign<const P: u64>(dst: &mut [u8], src: &[u8]) {
mul_elementwise_assign_u32_avx512(
crate::kernel::x86_v4_token(),
dst,
src,
FiniteField::<P, 1, Residue>::U32_PARAMS,
);
}
pub(super) fn src_tail_avx512(src: &[u8]) -> &[u8] {
let (_, tail) = src.as_chunks::<64>();
tail
}