#[cfg_attr(
not(any(target_arch = "aarch64", target_arch = "x86", target_arch = "x86_64")),
allow(dead_code)
)]
#[inline(always)]
pub(crate) fn array_at<T, const N: usize>(s: &[T], i: usize) -> &[T; N] {
s[i..i + N].try_into().unwrap()
}
#[cfg_attr(
not(any(target_arch = "aarch64", target_arch = "x86", target_arch = "x86_64")),
allow(dead_code)
)]
#[inline(always)]
pub(crate) fn array_at_mut<T, const N: usize>(s: &mut [T], i: usize) -> &mut [T; N] {
(&mut s[i..i + N]).try_into().unwrap()
}
#[cfg_attr(not(feature = "dnn"), allow(dead_code))]
#[inline(always)]
pub(crate) unsafe fn array_at_unchecked<T, const N: usize>(s: &[T], i: usize) -> &[T; N] {
unsafe { &*s.as_ptr().add(i).cast::<[T; N]>() }
}
#[cfg(target_arch = "aarch64")]
pub(crate) mod neon {
use crate::kiss_fft::KissCpx;
use core::arch::aarch64::*;
use core::cell::Cell;
use core::mem::MaybeUninit;
#[target_feature(enable = "neon")]
#[inline]
pub(crate) fn load_f32x2(a: &[f32; 2]) -> float32x2_t {
unsafe { vld1_f32(a.as_ptr()) }
}
#[target_feature(enable = "neon")]
#[inline]
pub(crate) fn load_f32x4(a: &[f32; 4]) -> float32x4_t {
unsafe { vld1q_f32(a.as_ptr()) }
}
#[target_feature(enable = "neon")]
#[inline]
pub(crate) fn store_f32x4(a: &mut [f32; 4], v: float32x4_t) {
unsafe { vst1q_f32(a.as_mut_ptr(), v) }
}
#[target_feature(enable = "neon")]
#[inline]
pub(crate) fn store_f32x4_uninit(a: &mut [MaybeUninit<f32>; 4], v: float32x4_t) {
unsafe { vst1q_f32(a.as_mut_ptr().cast(), v) }
}
#[target_feature(enable = "neon")]
#[inline]
pub(crate) fn load_dup_f32x4(a: &f32) -> float32x4_t {
unsafe { vld1q_dup_f32(a) }
}
#[target_feature(enable = "neon")]
#[inline]
pub(crate) fn load_lane_f32x4<const LANE: i32>(a: &f32, v: float32x4_t) -> float32x4_t {
unsafe { vld1q_lane_f32::<LANE>(a, v) }
}
#[target_feature(enable = "neon")]
#[inline]
pub(crate) fn store_lane_f32x4<const LANE: i32>(a: &mut f32, v: float32x4_t) {
unsafe { vst1q_lane_f32::<LANE>(a, v) }
}
#[target_feature(enable = "neon")]
#[inline]
pub(crate) fn load2_f32x4(a: &[f32; 8]) -> float32x4x2_t {
unsafe { vld2q_f32(a.as_ptr()) }
}
#[target_feature(enable = "neon")]
#[inline]
pub(crate) fn store2_f32x4(a: &mut [f32; 8], v: float32x4x2_t) {
unsafe { vst2q_f32(a.as_mut_ptr(), v) }
}
#[target_feature(enable = "neon")]
#[inline]
pub(crate) fn load_f32x4_cells(a: &[Cell<f32>; 4]) -> float32x4_t {
unsafe { vld1q_f32(a.as_ptr().cast()) }
}
#[target_feature(enable = "neon")]
#[inline]
pub(crate) fn store_f32x4_cells(a: &[Cell<f32>; 4], v: float32x4_t) {
unsafe { vst1q_f32(a.as_ptr().cast_mut().cast(), v) }
}
#[target_feature(enable = "neon")]
#[inline]
pub(crate) fn store2_f32x4_cells(a: &[Cell<f32>; 8], v: float32x4x2_t) {
unsafe { vst2q_f32(a.as_ptr().cast_mut().cast(), v) }
}
#[target_feature(enable = "neon")]
#[inline]
pub(crate) fn to_array_f32x4(v: float32x4_t) -> [f32; 4] {
unsafe { core::mem::transmute::<float32x4_t, [f32; 4]>(v) }
}
#[target_feature(enable = "neon")]
#[inline]
pub(crate) fn load_f32x2_cpx(a: &KissCpx) -> float32x2_t {
unsafe { vld1_f32((a as *const KissCpx).cast()) }
}
#[target_feature(enable = "neon")]
#[inline]
pub(crate) fn store_f32x2_cpx(a: &mut KissCpx, v: float32x2_t) {
unsafe { vst1_f32((a as *mut KissCpx).cast(), v) }
}
#[target_feature(enable = "neon")]
#[inline]
pub(crate) fn store_f32x2_cpx_uninit(a: &mut MaybeUninit<KissCpx>, v: float32x2_t) {
unsafe { vst1_f32(a.as_mut_ptr().cast(), v) }
}
#[target_feature(enable = "neon")]
#[inline]
pub(crate) fn load_f32x4_cpx(a: &[KissCpx; 2]) -> float32x4_t {
unsafe { vld1q_f32(a.as_ptr().cast()) }
}
#[target_feature(enable = "neon")]
#[inline]
pub(crate) fn store_f32x4_cpx(a: &mut [KissCpx; 2], v: float32x4_t) {
unsafe { vst1q_f32(a.as_mut_ptr().cast(), v) }
}
#[target_feature(enable = "neon")]
#[inline]
pub(crate) fn load2_f32x4_cpx(a: &[KissCpx; 4]) -> float32x4x2_t {
unsafe { vld2q_f32(a.as_ptr().cast()) }
}
#[target_feature(enable = "neon")]
#[inline]
pub(crate) fn load_i32x2(a: &[i32; 2]) -> int32x2_t {
unsafe { vld1_s32(a.as_ptr()) }
}
#[target_feature(enable = "neon")]
#[inline]
pub(crate) fn store_i32x2(a: &mut [i32; 2], v: int32x2_t) {
unsafe { vst1_s32(a.as_mut_ptr(), v) }
}
#[target_feature(enable = "neon")]
#[inline]
pub(crate) fn load_i32x4(a: &[i32; 4]) -> int32x4_t {
unsafe { vld1q_s32(a.as_ptr()) }
}
#[target_feature(enable = "neon")]
#[inline]
pub(crate) fn store_i32x4(a: &mut [i32; 4], v: int32x4_t) {
unsafe { vst1q_s32(a.as_mut_ptr(), v) }
}
#[target_feature(enable = "neon")]
#[inline]
pub(crate) fn store_lane_i32x4<const LANE: i32>(a: &mut i32, v: int32x4_t) {
unsafe { vst1q_lane_s32::<LANE>(a, v) }
}
#[target_feature(enable = "neon")]
#[inline]
pub(crate) fn load_u32x4(a: &[u32; 4]) -> uint32x4_t {
unsafe { vld1q_u32(a.as_ptr()) }
}
#[target_feature(enable = "neon")]
#[inline]
pub(crate) fn load_i16x4(a: &[i16; 4]) -> int16x4_t {
unsafe { vld1_s16(a.as_ptr()) }
}
#[target_feature(enable = "neon")]
#[inline]
pub(crate) fn store_i16x4(a: &mut [i16; 4], v: int16x4_t) {
unsafe { vst1_s16(a.as_mut_ptr(), v) }
}
#[target_feature(enable = "neon")]
#[inline]
pub(crate) fn store_i16x4_uninit(a: &mut [MaybeUninit<i16>; 4], v: int16x4_t) {
unsafe { vst1_s16(a.as_mut_ptr().cast(), v) }
}
#[target_feature(enable = "neon")]
#[inline]
pub(crate) fn load_i16x8(a: &[i16; 8]) -> int16x8_t {
unsafe { vld1q_s16(a.as_ptr()) }
}
#[target_feature(enable = "neon")]
#[inline]
pub(crate) fn store_i16x8(a: &mut [i16; 8], v: int16x8_t) {
unsafe { vst1q_s16(a.as_mut_ptr(), v) }
}
#[cfg_attr(not(feature = "analysis"), allow(dead_code))]
#[target_feature(enable = "neon")]
#[inline]
pub(crate) fn load2_i16x8(a: &[i16; 16]) -> int16x8x2_t {
unsafe { vld2q_s16(a.as_ptr()) }
}
#[target_feature(enable = "neon")]
#[inline]
pub(crate) fn load_u8x8(a: &[u8; 8]) -> uint8x8_t {
unsafe { vld1_u8(a.as_ptr()) }
}
#[target_feature(enable = "neon")]
#[inline]
pub(crate) fn load_u8x16(a: &[u8; 16]) -> uint8x16_t {
unsafe { vld1q_u8(a.as_ptr()) }
}
#[cfg_attr(not(feature = "dnn"), allow(dead_code))]
#[target_feature(enable = "neon")]
#[inline]
pub(crate) fn load_i8x16(a: &[i8; 16]) -> int8x16_t {
unsafe { vld1q_s8(a.as_ptr()) }
}
#[cfg_attr(not(feature = "dnn"), allow(dead_code))]
#[target_feature(enable = "neon")]
#[inline]
pub(crate) fn load_i8x16x4(a: &[i8; 64]) -> int8x16x4_t {
unsafe { vld1q_s8_x4(a.as_ptr()) }
}
#[cfg_attr(not(feature = "dnn"), allow(dead_code))]
#[target_feature(enable = "neon")]
#[inline]
pub(crate) fn store_i8x4_uninit(a: &mut [MaybeUninit<i8>; 4], v: int8x8_t) {
let x = vget_lane_s32::<0>(vreinterpret_s32_s8(v));
unsafe { a.as_mut_ptr().cast::<i32>().write_unaligned(x) }
}
#[cfg_attr(not(feature = "dnn"), allow(dead_code))]
#[target_feature(enable = "neon")]
#[inline]
pub(crate) fn store_i8x16_uninit(a: &mut [MaybeUninit<i8>; 16], v: int8x16_t) {
unsafe { vst1q_s8(a.as_mut_ptr().cast(), v) }
}
}
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
pub(crate) mod x86 {
use crate::kiss_fft::KissCpx;
#[cfg(target_arch = "x86")]
use core::arch::x86::*;
#[cfg(target_arch = "x86_64")]
use core::arch::x86_64::*;
use core::cell::Cell;
use core::mem::MaybeUninit;
#[target_feature(enable = "sse")]
#[inline]
pub(crate) fn load_f32x4(a: &[f32; 4]) -> __m128 {
unsafe { _mm_loadu_ps(a.as_ptr()) }
}
#[target_feature(enable = "sse")]
#[inline]
pub(crate) fn store_f32x4(a: &mut [f32; 4], v: __m128) {
unsafe { _mm_storeu_ps(a.as_mut_ptr(), v) }
}
#[target_feature(enable = "sse")]
#[inline]
pub(crate) fn load_f32x4_cells(a: &[Cell<f32>; 4]) -> __m128 {
unsafe { _mm_loadu_ps(a.as_ptr().cast()) }
}
#[target_feature(enable = "sse")]
#[inline]
pub(crate) fn store_f32x4_cells(a: &[Cell<f32>; 4], v: __m128) {
unsafe { _mm_storeu_ps(a.as_ptr().cast_mut().cast(), v) }
}
#[target_feature(enable = "sse")]
#[inline]
pub(crate) fn to_array_f32x4(v: __m128) -> [f32; 4] {
unsafe { core::mem::transmute::<__m128, [f32; 4]>(v) }
}
#[target_feature(enable = "avx")]
#[inline]
pub(crate) fn load_f32x8(a: &[f32; 8]) -> __m256 {
unsafe { _mm256_loadu_ps(a.as_ptr()) }
}
#[target_feature(enable = "avx")]
#[inline]
pub(crate) fn store_f32x8(a: &mut [f32; 8], v: __m256) {
unsafe { _mm256_storeu_ps(a.as_mut_ptr(), v) }
}
#[cfg_attr(not(feature = "analysis"), allow(dead_code))]
#[target_feature(enable = "sse2")]
#[inline]
pub(crate) fn store_f32x2_cpx(a: &mut KissCpx, v: __m128) {
unsafe { _mm_storel_epi64((a as *mut KissCpx).cast(), _mm_castps_si128(v)) }
}
#[cfg_attr(not(feature = "analysis"), allow(dead_code))]
#[target_feature(enable = "sse")]
#[inline]
pub(crate) fn load_f32x4_cpx(a: &[KissCpx; 2]) -> __m128 {
unsafe { _mm_loadu_ps(a.as_ptr().cast()) }
}
#[target_feature(enable = "sse2")]
#[inline]
pub(crate) fn load_i32x4(a: &[i32; 4]) -> __m128i {
unsafe { _mm_loadu_si128(a.as_ptr().cast()) }
}
#[target_feature(enable = "sse2")]
#[inline]
pub(crate) fn store_i32x4(a: &mut [i32; 4], v: __m128i) {
unsafe { _mm_storeu_si128(a.as_mut_ptr().cast(), v) }
}
#[target_feature(enable = "sse2")]
#[inline]
pub(crate) fn store_i32x4_uninit(a: &mut [MaybeUninit<i32>; 4], v: __m128i) {
unsafe { _mm_storeu_si128(a.as_mut_ptr().cast(), v) }
}
#[target_feature(enable = "avx")]
#[inline]
pub(crate) fn load_i32x8(a: &[i32; 8]) -> __m256i {
unsafe { _mm256_loadu_si256(a.as_ptr().cast()) }
}
#[target_feature(enable = "avx")]
#[inline]
pub(crate) fn store_i32x8(a: &mut [i32; 8], v: __m256i) {
unsafe { _mm256_storeu_si256(a.as_mut_ptr().cast(), v) }
}
#[target_feature(enable = "sse2")]
#[inline]
pub(crate) fn load_i16x4(a: &[i16; 4]) -> __m128i {
unsafe { _mm_loadl_epi64(a.as_ptr().cast()) }
}
#[target_feature(enable = "sse2")]
#[inline]
pub(crate) fn store_i16x4(a: &mut [i16; 4], v: __m128i) {
unsafe { _mm_storel_epi64(a.as_mut_ptr().cast(), v) }
}
#[target_feature(enable = "sse2")]
#[inline]
pub(crate) fn store_i16x4_uninit(a: &mut [MaybeUninit<i16>; 4], v: __m128i) {
unsafe { _mm_storel_epi64(a.as_mut_ptr().cast(), v) }
}
#[target_feature(enable = "sse2")]
#[inline]
pub(crate) fn load_i16x8(a: &[i16; 8]) -> __m128i {
unsafe { _mm_loadu_si128(a.as_ptr().cast()) }
}
#[target_feature(enable = "sse2")]
#[inline]
pub(crate) fn store_i16x8(a: &mut [i16; 8], v: __m128i) {
unsafe { _mm_storeu_si128(a.as_mut_ptr().cast(), v) }
}
#[target_feature(enable = "avx")]
#[inline]
pub(crate) fn load_i16x16(a: &[i16; 16]) -> __m256i {
unsafe { _mm256_loadu_si256(a.as_ptr().cast()) }
}
#[target_feature(enable = "sse2")]
#[inline]
pub(crate) fn load_u8x16(a: &[u8; 16]) -> __m128i {
unsafe { _mm_loadu_si128(a.as_ptr().cast()) }
}
#[cfg_attr(not(feature = "dnn"), allow(dead_code))]
#[target_feature(enable = "avx")]
#[inline]
pub(crate) fn load_i8x32(a: &[i8; 32]) -> __m256i {
unsafe { _mm256_loadu_si256(a.as_ptr().cast()) }
}
#[cfg_attr(not(feature = "dnn"), allow(dead_code))]
#[target_feature(enable = "avx512f")]
#[inline]
pub(crate) fn load_i8x64(a: &[i8; 64]) -> __m512i {
unsafe { _mm512_loadu_si512(a.as_ptr().cast()) }
}
}