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