use core::arch::aarch64::{
uint64x2_t, uint64x2x3_t, vextq_u64, vld1q_u64, vst3q_u64, vzip1q_u64, vzip2q_u64,
};
pub(crate) type Reg = uint64x2_t;
pub(crate) const WIDTH_64: usize = 2;
#[inline(always)]
pub(crate) fn interleave_64(a: Reg, b: Reg, block_len: usize) -> (Reg, Reg) {
match block_len {
1 => unsafe { (vzip1q_u64(a, b), vzip2q_u64(a, b)) },
WIDTH_64 => (a, b),
_ => panic!("unsupported block_len"),
}
}
#[inline(always)]
pub(crate) unsafe fn gather_3(from: *const u64) -> [Reg; 3] {
unsafe {
let low = vld1q_u64(from);
let middle = vld1q_u64(from.add(2));
let high = vld1q_u64(from.add(4));
let crossed = vextq_u64::<1>(middle, middle);
[
vzip1q_u64(low, crossed),
vextq_u64::<1>(low, high),
vzip2q_u64(crossed, high),
]
}
}
#[inline(always)]
pub(crate) unsafe fn scatter_3(to: *mut u64, [c0, c1, c2]: [Reg; 3]) {
unsafe { vst3q_u64(to, uint64x2x3_t(c0, c1, c2)) }
}