#[rustfmt::skip]
macro_rules! reduce_32x4 {
($prefix:ident $value:expr; $op:ident $last:ident) => {{paste::paste! {
let v0 = $value;
let v1 = arch::u8x16_swizzle(v0, const { arch::x4indices(2, 3, 2, 3) });
let v0 = arch::$op(v0, v1);
let v1 = arch::u8x16_swizzle(v0, const { arch::x4indices(1, 1, 3, 3) });
arch::[<$prefix 32x4_extract_lane>]::<0>(arch::$last(v0, v1))
}}};
}
#[rustfmt::skip]
macro_rules! reduce_64x2 {
($prefix:ident $value:expr; $op:ident $last:ident) => {{paste::paste! {
let v0 = $value;
let v1 = arch::u8x16_swizzle(v0, const { arch::x2indices(1, 1) });
arch::[<$prefix 64x2_extract_lane>]::<0>(arch::$last(v0, v1))
}}};
}
#[rustfmt::skip]
macro_rules! impl_wasm_align_shuffle {
() => {
const HAS_NATIVE_ALIGN: bool = true;
fn align<const OFFSET: usize>(a: Storage<Self>, b: Storage<Self>) -> Storage<Self> {
match const { OFFSET * core::mem::size_of::<Self::Element>() } {
0 => a,
1 => arch::i8x16_shuffle::<1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16>(a, b),
2 => arch::i8x16_shuffle::<2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17>(a, b),
3 => arch::i8x16_shuffle::<3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18>(a, b),
4 => arch::i8x16_shuffle::<4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19>(a, b),
5 => arch::i8x16_shuffle::<5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20>(a, b),
6 => arch::i8x16_shuffle::<6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21>(a, b),
7 => arch::i8x16_shuffle::<7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22>(a, b),
8 => arch::i8x16_shuffle::<8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23>(a, b),
9 => arch::i8x16_shuffle::<9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24>(a, b),
10 => arch::i8x16_shuffle::<10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25>(a, b),
11 => arch::i8x16_shuffle::<11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26>(a, b),
12 => arch::i8x16_shuffle::<12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27>(a, b),
13 => arch::i8x16_shuffle::<13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28>(a, b),
14 => arch::i8x16_shuffle::<14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29>(a, b),
15 => arch::i8x16_shuffle::<15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30>(a, b),
16 => b,
_ => Self::swizzle_const::<$crate::swizzle::AlignIndices<OFFSET, Self::Lanes>>(a, b),
}
}
};
}
#[rustfmt::skip]
macro_rules! impl_widen_indices_wasm {
($($reg:ty => $shape:ident),* $(,)?) => {
$(
#[thermite_macros::inline_always]
impl $crate::register::WidenIndexRegister for $reg {
fn widen_indices(
idxs: &generic_array::GenericArray<u8, generic_array::typenum::U8>,
) -> generic_array::GenericArray<u32, <Self as $crate::register::CoreRegister>::Lanes> {
unsafe { impl_widen_indices_wasm!(@body idxs, $shape) }
}
fn permutev_row(
value: $crate::register::Storage<Self>,
row: &generic_array::GenericArray<u8, generic_array::typenum::U8>,
) -> $crate::register::Storage<Self> {
arch::u8x16_relaxed_swizzle(value, unsafe { impl_widen_indices_wasm!(@row row, $shape) })
}
}
)*
};
(@row $row:ident, x2) => { arch::wasm_lane_table_row::<2>($row.as_ptr()) };
(@row $row:ident, x4) => { arch::wasm_lane_table_row::<4>($row.as_ptr()) };
(@row $row:ident, x8) => { arch::wasm_lane_table_row::<8>($row.as_ptr()) };
(@body $idxs:ident, x2) => {{ impl_widen_indices_wasm!(@low $idxs) }};
(@body $idxs:ident, x4) => {{ impl_widen_indices_wasm!(@low $idxs) }};
(@body $idxs:ident, x8) => {{
let w16 = arch::u16x8_extend_low_u8x16(arch::v128_load64_zero($idxs.as_ptr() as *const u64));
let lo = arch::u32x4_extend_low_u16x8(w16);
let hi = arch::u32x4_extend_high_u16x8(w16);
core::mem::transmute_copy(&[lo, hi])
}};
(@low $idxs:ident) => {{
let w16 = arch::u16x8_extend_low_u8x16(arch::v128_load64_zero($idxs.as_ptr() as *const u64));
core::mem::transmute_copy(&arch::u32x4_extend_low_u16x8(w16))
}};
}