use crate::row::arch::neon::endian::*;
unsafe fn u16x8_to_arr(v: core::arch::aarch64::uint16x8_t) -> [u16; 8] {
let mut out = [0u16; 8];
unsafe { core::arch::aarch64::vst1q_u16(out.as_mut_ptr(), v) };
out
}
unsafe fn u32x4_to_arr(v: core::arch::aarch64::uint32x4_t) -> [u32; 4] {
let mut out = [0u32; 4];
unsafe { core::arch::aarch64::vst1q_u32(out.as_mut_ptr(), v) };
out
}
#[test]
#[cfg_attr(miri, ignore = "NEON SIMD intrinsics unsupported by Miri")]
#[cfg(target_endian = "little")]
fn neon_load_le_u16x8_noop_on_le_host() {
let input: [u8; 16] = [
0x02, 0x01, 0x04, 0x03, 0x06, 0x05, 0x08, 0x07, 0x0a, 0x09, 0x0c, 0x0b, 0x0e, 0x0d, 0x10, 0x0f, ];
let v = unsafe { load_le_u16x8(input.as_ptr()) };
let got = unsafe { u16x8_to_arr(v) };
assert_eq!(
got,
[
0x0102, 0x0304, 0x0506, 0x0708, 0x090a, 0x0b0c, 0x0d0e, 0x0f10
],
"load_le_u16x8 must not swap on LE host"
);
}
#[test]
#[cfg_attr(miri, ignore = "NEON SIMD intrinsics unsupported by Miri")]
#[cfg(target_endian = "big")]
fn neon_load_le_u16x8_swaps_on_be_host() {
let input: [u8; 16] = [
0x02, 0x01, 0x04, 0x03, 0x06, 0x05, 0x08, 0x07, 0x0a, 0x09, 0x0c, 0x0b, 0x0e, 0x0d, 0x10, 0x0f,
];
let v = unsafe { load_le_u16x8(input.as_ptr()) };
let got = unsafe { u16x8_to_arr(v) };
assert_eq!(
got,
[
0x0102, 0x0304, 0x0506, 0x0708, 0x090a, 0x0b0c, 0x0d0e, 0x0f10
],
"load_le_u16x8 must swap bytes on BE host to restore LE value"
);
}
#[test]
#[cfg_attr(miri, ignore = "NEON SIMD intrinsics unsupported by Miri")]
#[cfg(target_endian = "little")]
fn neon_load_be_u16x8_swaps_on_le_host() {
let input: [u8; 16] = [
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, ];
let v = unsafe { load_be_u16x8(input.as_ptr()) };
let got = unsafe { u16x8_to_arr(v) };
assert_eq!(
got,
[
0x0102, 0x0304, 0x0506, 0x0708, 0x090a, 0x0b0c, 0x0d0e, 0x0f10
],
"load_be_u16x8 must swap on LE host to convert BE→LE-native"
);
}
#[test]
#[cfg_attr(miri, ignore = "NEON SIMD intrinsics unsupported by Miri")]
#[cfg(target_endian = "big")]
fn neon_load_be_u16x8_noop_on_be_host() {
let input: [u8; 16] = [
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
];
let v = unsafe { load_be_u16x8(input.as_ptr()) };
let got = unsafe { u16x8_to_arr(v) };
assert_eq!(
got,
[
0x0102, 0x0304, 0x0506, 0x0708, 0x090a, 0x0b0c, 0x0d0e, 0x0f10
],
"load_be_u16x8 must not swap on BE host"
);
}
#[test]
#[cfg_attr(miri, ignore = "NEON SIMD intrinsics unsupported by Miri")]
#[cfg(target_endian = "little")]
fn neon_load_le_u32x4_noop_on_le_host() {
let input: [u8; 16] = [
0x04, 0x03, 0x02, 0x01, 0x08, 0x07, 0x06, 0x05, 0x0c, 0x0b, 0x0a, 0x09, 0x10, 0x0f, 0x0e, 0x0d, ];
let v = unsafe { load_le_u32x4(input.as_ptr()) };
let got = unsafe { u32x4_to_arr(v) };
assert_eq!(
got,
[0x01020304, 0x05060708, 0x090a0b0c, 0x0d0e0f10],
"load_le_u32x4 must not swap on LE host"
);
}
#[test]
#[cfg_attr(miri, ignore = "NEON SIMD intrinsics unsupported by Miri")]
#[cfg(target_endian = "little")]
fn neon_load_be_u32x4_swaps_on_le_host() {
let input: [u8; 16] = [
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, ];
let v = unsafe { load_be_u32x4(input.as_ptr()) };
let got = unsafe { u32x4_to_arr(v) };
assert_eq!(
got,
[0x01020304, 0x05060708, 0x090a0b0c, 0x0d0e0f10],
"load_be_u32x4 must swap on LE host"
);
}
#[test]
#[cfg_attr(miri, ignore = "NEON SIMD intrinsics unsupported by Miri")]
#[cfg(target_endian = "little")]
fn neon_load_endian_u16x8_le_dispatcher() {
let input: [u8; 16] = [
0x02, 0x01, 0x04, 0x03, 0x06, 0x05, 0x08, 0x07, 0x0a, 0x09, 0x0c, 0x0b, 0x0e, 0x0d, 0x10, 0x0f,
];
let direct = unsafe { load_le_u16x8(input.as_ptr()) };
let via_dispatch = unsafe { load_endian_u16x8::<false>(input.as_ptr()) };
let d = unsafe { u16x8_to_arr(direct) };
let g = unsafe { u16x8_to_arr(via_dispatch) };
assert_eq!(d, g, "load_endian_u16x8::<false> must match load_le_u16x8");
}
#[test]
#[cfg_attr(miri, ignore = "NEON SIMD intrinsics unsupported by Miri")]
#[cfg(target_endian = "little")]
fn neon_load_endian_u16x8_be_dispatcher() {
let input: [u8; 16] = [
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
];
let direct = unsafe { load_be_u16x8(input.as_ptr()) };
let via_dispatch = unsafe { load_endian_u16x8::<true>(input.as_ptr()) };
let d = unsafe { u16x8_to_arr(direct) };
let g = unsafe { u16x8_to_arr(via_dispatch) };
assert_eq!(d, g, "load_endian_u16x8::<true> must match load_be_u16x8");
}