macro_rules! impl_packed_fp8 {
($($u8:ty => $f32:ty),* $(,)?) => {$(
impl $crate::register::PackedFloatRegister<$crate::element::float::spec::Fp8E4M3, $f32> for $u8 {}
impl $crate::register::PackedFloatRegister<$crate::element::float::spec::Fp8E5M2, $f32> for $u8 {}
)*};
}
macro_rules! impl_byte_align_alignr {
() => {
fn align<const OFFSET: usize>(a: Storage<Self>, b: Storage<Self>) -> Storage<Self> {
match OFFSET {
0 => unsafe { arch::_mm_alignr_epi8::<0>(b, a) },
1 => unsafe { arch::_mm_alignr_epi8::<1>(b, a) },
2 => unsafe { arch::_mm_alignr_epi8::<2>(b, a) },
3 => unsafe { arch::_mm_alignr_epi8::<3>(b, a) },
4 => unsafe { arch::_mm_alignr_epi8::<4>(b, a) },
5 => unsafe { arch::_mm_alignr_epi8::<5>(b, a) },
6 => unsafe { arch::_mm_alignr_epi8::<6>(b, a) },
7 => unsafe { arch::_mm_alignr_epi8::<7>(b, a) },
8 => unsafe { arch::_mm_alignr_epi8::<8>(b, a) },
9 => unsafe { arch::_mm_alignr_epi8::<9>(b, a) },
10 => unsafe { arch::_mm_alignr_epi8::<10>(b, a) },
11 => unsafe { arch::_mm_alignr_epi8::<11>(b, a) },
12 => unsafe { arch::_mm_alignr_epi8::<12>(b, a) },
13 => unsafe { arch::_mm_alignr_epi8::<13>(b, a) },
14 => unsafe { arch::_mm_alignr_epi8::<14>(b, a) },
15 => unsafe { arch::_mm_alignr_epi8::<15>(b, a) },
16 => unsafe { arch::_mm_alignr_epi8::<16>(b, a) },
_ => Self::swizzle_const::<$crate::swizzle::AlignIndices<OFFSET, Self::Lanes>>(a, b),
}
}
};
}
macro_rules! impl_byte_align_alignr256 {
() => {
fn align<const OFFSET: usize>(a: Storage<Self>, b: Storage<Self>) -> Storage<Self> {
let mid = unsafe { arch::_mm256_permute2x128_si256::<0x21>(a, b) };
match OFFSET * core::mem::size_of::<Self::Element>() {
0 => unsafe { arch::_mm256_alignr_epi8::<0>(mid, a) },
1 => unsafe { arch::_mm256_alignr_epi8::<1>(mid, a) },
2 => unsafe { arch::_mm256_alignr_epi8::<2>(mid, a) },
3 => unsafe { arch::_mm256_alignr_epi8::<3>(mid, a) },
4 => unsafe { arch::_mm256_alignr_epi8::<4>(mid, a) },
5 => unsafe { arch::_mm256_alignr_epi8::<5>(mid, a) },
6 => unsafe { arch::_mm256_alignr_epi8::<6>(mid, a) },
7 => unsafe { arch::_mm256_alignr_epi8::<7>(mid, a) },
8 => unsafe { arch::_mm256_alignr_epi8::<8>(mid, a) },
9 => unsafe { arch::_mm256_alignr_epi8::<9>(mid, a) },
10 => unsafe { arch::_mm256_alignr_epi8::<10>(mid, a) },
11 => unsafe { arch::_mm256_alignr_epi8::<11>(mid, a) },
12 => unsafe { arch::_mm256_alignr_epi8::<12>(mid, a) },
13 => unsafe { arch::_mm256_alignr_epi8::<13>(mid, a) },
14 => unsafe { arch::_mm256_alignr_epi8::<14>(mid, a) },
15 => unsafe { arch::_mm256_alignr_epi8::<15>(mid, a) },
16 => unsafe { arch::_mm256_alignr_epi8::<16>(mid, a) },
17 => unsafe { arch::_mm256_alignr_epi8::<1>(b, mid) },
18 => unsafe { arch::_mm256_alignr_epi8::<2>(b, mid) },
19 => unsafe { arch::_mm256_alignr_epi8::<3>(b, mid) },
20 => unsafe { arch::_mm256_alignr_epi8::<4>(b, mid) },
21 => unsafe { arch::_mm256_alignr_epi8::<5>(b, mid) },
22 => unsafe { arch::_mm256_alignr_epi8::<6>(b, mid) },
23 => unsafe { arch::_mm256_alignr_epi8::<7>(b, mid) },
24 => unsafe { arch::_mm256_alignr_epi8::<8>(b, mid) },
25 => unsafe { arch::_mm256_alignr_epi8::<9>(b, mid) },
26 => unsafe { arch::_mm256_alignr_epi8::<10>(b, mid) },
27 => unsafe { arch::_mm256_alignr_epi8::<11>(b, mid) },
28 => unsafe { arch::_mm256_alignr_epi8::<12>(b, mid) },
29 => unsafe { arch::_mm256_alignr_epi8::<13>(b, mid) },
30 => unsafe { arch::_mm256_alignr_epi8::<14>(b, mid) },
31 => unsafe { arch::_mm256_alignr_epi8::<15>(b, mid) },
32 => unsafe { arch::_mm256_alignr_epi8::<16>(b, mid) },
_ => Self::swizzle_const::<$crate::swizzle::AlignIndices<OFFSET, Self::Lanes>>(a, b),
}
}
};
}
macro_rules! impl_byteshift_align {
() => {
fn align<const OFFSET: usize>(a: Storage<Self>, b: Storage<Self>) -> Storage<Self> {
match const { OFFSET * core::mem::size_of::<Self::Element>() } {
0 => Self::bitor(Self::bshri::<0>(a), Self::bshli::<16>(b)),
1 => Self::bitor(Self::bshri::<1>(a), Self::bshli::<15>(b)),
2 => Self::bitor(Self::bshri::<2>(a), Self::bshli::<14>(b)),
3 => Self::bitor(Self::bshri::<3>(a), Self::bshli::<13>(b)),
4 => Self::bitor(Self::bshri::<4>(a), Self::bshli::<12>(b)),
5 => Self::bitor(Self::bshri::<5>(a), Self::bshli::<11>(b)),
6 => Self::bitor(Self::bshri::<6>(a), Self::bshli::<10>(b)),
7 => Self::bitor(Self::bshri::<7>(a), Self::bshli::<9>(b)),
8 => Self::bitor(Self::bshri::<8>(a), Self::bshli::<8>(b)),
9 => Self::bitor(Self::bshri::<9>(a), Self::bshli::<7>(b)),
10 => Self::bitor(Self::bshri::<10>(a), Self::bshli::<6>(b)),
11 => Self::bitor(Self::bshri::<11>(a), Self::bshli::<5>(b)),
12 => Self::bitor(Self::bshri::<12>(a), Self::bshli::<4>(b)),
13 => Self::bitor(Self::bshri::<13>(a), Self::bshli::<3>(b)),
14 => Self::bitor(Self::bshri::<14>(a), Self::bshli::<2>(b)),
15 => Self::bitor(Self::bshri::<15>(a), Self::bshli::<1>(b)),
16 => Self::bitor(Self::bshri::<16>(a), Self::bshli::<0>(b)),
_ => Self::swizzle_const::<$crate::swizzle::AlignIndices<OFFSET, Self::Lanes>>(a, b),
}
}
};
}
macro_rules! impl_bit_casts {
($($from:ty as $to:ty => $conv:ident),* $(,)?) => {
const _: () = {$(
#[thermite_macros::inline_always]
impl $crate::register::BitCastRegister<$from> for $to {
fn from_bits(value: Storage<$from>) -> Storage<Self> {
unsafe { arch::$conv(value) }
}
}
)*};
};
}
macro_rules! impl_type_casts {
($($from:ty as $to:ty => $conv:ident $(| $fast_conv:ident)?),* $(,)?) => {
const _: () = {$(
#[thermite_macros::inline_always]
impl $crate::register::CastRegister<$from> for $to {
fn cast_from(value: Storage<$from>) -> Storage<Self> {
unsafe { arch::$conv(value) }
}
$(
fn fast_cast_from(value: Storage<$from>) -> Storage<Self> {
unsafe { arch::$fast_conv(value) }
}
)?
}
)*};
};
}
macro_rules! impl_mask_casts {
($($from:ty as $to:ty => $conv:ident),* $(,)?) => {
const _: () = {$(
#[thermite_macros::inline_always]
impl $crate::register::CastMaskRegister<$from> for $to {
fn mask_from(value: Storage<$from>) -> Storage<Self> {
unsafe { arch::$conv(value) }
}
}
)*};
};
}
macro_rules! impl_concat_bool_register2 {
($e:ty, $r:ty) => {
const _: () = {
use $crate::element::MaskElement;
#[thermite_macros::inline_always]
impl $crate::register::ConcatRegister<bool> for $r {
fn concat(lo: Storage<bool>, hi: Storage<bool>) -> Storage<Self> {
<Self as $crate::register::ConcatRegister<$e>>::concat(<$e>::from_bool(lo), <$e>::from_bool(hi))
}
fn split(value: Storage<Self>) -> (Storage<bool>, Storage<bool>) {
let (lo, hi) = <Self as $crate::register::ConcatRegister<$e>>::split(value);
(lo.to_bool(), hi.to_bool())
}
}
#[thermite_macros::inline_always]
impl $crate::register::ExtendRegister<bool> for $r {
fn extend(value: Storage<bool>) -> Storage<Self> {
<Self as $crate::register::ExtendRegister<$e>>::extend(<$e>::from_bool(value))
}
fn narrow(value: Storage<Self>) -> Storage<bool> {
<Self as $crate::register::ExtendRegister<$e>>::narrow(value).to_bool()
}
}
};
};
}
macro_rules! impl_newregister {
($($r:ty),*) => {$(
impl $crate::register::NewRegister<
<$r as $crate::register::Register>::Element,
<$r as $crate::register::CoreRegister>::Lanes,
<$r as $crate::register::CoreRegister>::Storage
> for $r {
type New<T: $crate::vector::splat::NewConst<
<$r as $crate::register::Register>::Element,
<$r as $crate::register::CoreRegister>::Lanes>
> = Self;
}
impl<T> $crate::vector::splat::VectorValue<T, Storage<Self>> for $r
where
T: $crate::vector::splat::NewConst<
<$r as $crate::register::Register>::Element,
<$r as $crate::register::CoreRegister>::Lanes
>,
{
const VALUE: Storage<Self> = const { unsafe { $crate::generic_array::const_transmute(T::VALUES) } };
}
)*};
}
macro_rules! compress_via_table {
() => {
#[inline(always)]
fn compress(
value: $crate::register::Storage<Self>,
mask: $crate::register::Storage<<Self as $crate::register::CoreRegister>::Mask>,
) -> $crate::register::Storage<Self> {
$crate::backend::generic::polyfills::compress_permute::<Self>(value, mask)
}
#[inline(always)]
fn compress_z(
value: $crate::register::Storage<Self>,
mask: $crate::register::Storage<<Self as $crate::register::CoreRegister>::Mask>,
) -> $crate::register::Storage<Self> {
$crate::backend::generic::polyfills::compress_permute::<Self>(
<Self as $crate::register::CoreRegister>::zz(mask, value),
mask,
)
}
};
}
macro_rules! compress_via_wide {
() => {
#[inline(always)]
fn compress(
value: $crate::register::Storage<Self>,
mask: $crate::register::Storage<<Self as $crate::register::CoreRegister>::Mask>,
) -> $crate::register::Storage<Self> {
$crate::backend::generic::polyfills::compress_permute_wide::<Self>(value, mask)
}
#[inline(always)]
fn compress_z(
value: $crate::register::Storage<Self>,
mask: $crate::register::Storage<<Self as $crate::register::CoreRegister>::Mask>,
) -> $crate::register::Storage<Self> {
$crate::backend::generic::polyfills::compress_permute_wide::<Self>(
<Self as $crate::register::CoreRegister>::zz(mask, value),
mask,
)
}
};
}