mod data_kind;
pub(crate) use data_kind::DataKind;
use crate::simd::{
Simd,
SimdScalar,
Layout,
ValidLayout,
};
#[inline(always)]
#[must_use]
#[track_caller]
pub(crate) unsafe fn exec_binary_native_simd_op<
LhsScalar,
RhsScalar,
ResultScalar,
LhsNative,
RhsNative,
ResultNative,
F,
const N: usize,
>(
lhs: Simd<LhsScalar, N>,
rhs: Simd<RhsScalar, N>,
op: F,
) -> Simd<ResultScalar, N>
where
LhsScalar: SimdScalar,
RhsScalar: SimdScalar,
ResultScalar: SimdScalar,
LhsNative: Copy,
RhsNative: Copy,
ResultNative: Copy,
F: FnOnce(LhsNative, RhsNative) -> ResultNative,
Layout<LhsScalar, N>: ValidLayout,
Layout<RhsScalar, N>: ValidLayout,
Layout<ResultScalar, N>: ValidLayout,
Layout<bool, N>: ValidLayout,
{
let is_same_sizes =
size_of::<Simd<LhsScalar, N>>() == size_of::<LhsNative>()
&& size_of::<Simd<RhsScalar, N>>() == size_of::<RhsNative>()
&& size_of::<Simd<ResultScalar, N>>() == size_of::<ResultNative>();
let is_same_aligns =
align_of::<Simd<LhsScalar, N>>() == align_of::<LhsNative>()
&& align_of::<Simd<RhsScalar, N>>() == align_of::<RhsNative>()
&& align_of::<Simd<ResultScalar, N>>() == align_of::<ResultNative>();
debug_assert!(is_same_sizes);
debug_assert!(is_same_aligns);
if !is_same_sizes || !is_same_aligns {
return Default::default();
}
let lhs = unsafe { *(&raw const lhs as *const LhsNative) };
let rhs = unsafe { *(&raw const rhs as *const RhsNative) };
let result = op(lhs, rhs);
unsafe { *(&raw const result as *const Simd<ResultScalar, N>) }
}