use crate::Architecture;
#[doc(hidden)]
pub enum SimdTypeImpl {
Float32,
Float64,
Other,
}
pub trait SimdType {
#[doc(hidden)]
const IMPL: SimdTypeImpl;
}
impl SimdType for u8 {
const IMPL: SimdTypeImpl = SimdTypeImpl::Other;
}
impl SimdType for u16 {
const IMPL: SimdTypeImpl = SimdTypeImpl::Other;
}
impl SimdType for u32 {
const IMPL: SimdTypeImpl = SimdTypeImpl::Other;
}
impl SimdType for u64 {
const IMPL: SimdTypeImpl = SimdTypeImpl::Other;
}
impl SimdType for usize {
const IMPL: SimdTypeImpl = SimdTypeImpl::Other;
}
impl SimdType for i8 {
const IMPL: SimdTypeImpl = SimdTypeImpl::Other;
}
impl SimdType for i16 {
const IMPL: SimdTypeImpl = SimdTypeImpl::Other;
}
impl SimdType for i32 {
const IMPL: SimdTypeImpl = SimdTypeImpl::Other;
}
impl SimdType for i64 {
const IMPL: SimdTypeImpl = SimdTypeImpl::Other;
}
impl SimdType for isize {
const IMPL: SimdTypeImpl = SimdTypeImpl::Other;
}
impl SimdType for f32 {
const IMPL: SimdTypeImpl = SimdTypeImpl::Float32;
}
impl SimdType for f64 {
const IMPL: SimdTypeImpl = SimdTypeImpl::Float64;
}
impl<T> SimdType for *const T {
const IMPL: SimdTypeImpl = SimdTypeImpl::Other;
}
impl<T> SimdType for *mut T {
const IMPL: SimdTypeImpl = SimdTypeImpl::Other;
}
impl crate::Target {
pub const fn suggested_simd_width<T: SimdType>(&self) -> Option<usize> {
let is_f32 = T::IMPL as u8 == SimdTypeImpl::Float32 as u8;
let is_f64 = T::IMPL as u8 == SimdTypeImpl::Float64 as u8;
let v128 = 16 / core::mem::size_of::<T>();
let v256 = 32 / core::mem::size_of::<T>();
let v512 = 64 / core::mem::size_of::<T>();
let v1024 = 128 / core::mem::size_of::<T>();
if let Architecture::Arm = self.architecture() {
if self.supports_feature_str("neon") && !is_f64 {
Some(v128)
} else {
None
}
} else if let Architecture::AArch64 = self.architecture() {
if self.supports_feature_str("neon") {
Some(v128)
} else {
None
}
} else if let Architecture::Hexagon = self.architecture() {
if is_f32 || is_f64 {
None
} else if self.supports_feature_str("hvx-length128b") {
Some(v1024)
} else if self.supports_feature_str("hvx") {
Some(v512)
} else {
None
}
} else if let Architecture::Mips = self.architecture() {
if self.supports_feature_str("msa") {
Some(v128)
} else {
None
}
} else if let Architecture::PowerPC = self.architecture() {
if self.supports_feature_str("vsx") || (self.supports_feature_str("altivec") && !is_f64)
{
Some(v128)
} else {
None
}
} else if let Architecture::RiscV = self.architecture() {
if self.supports_feature_str("v") {
Some(v128)
} else {
None
}
} else if let Architecture::Wasm = self.architecture() {
if self.supports_feature_str("simd128") {
Some(v128)
} else {
None
}
} else if let Architecture::X86 = self.architecture() {
if self.supports_feature_str("avx512f") {
Some(v512)
} else if self.supports_feature_str("avx2")
|| (is_f32 || is_f64) && self.supports_feature_str("avx")
{
Some(v256)
} else if self.supports_feature_str("sse2")
|| is_f32 && self.supports_feature_str("sse")
{
Some(v128)
} else {
None
}
} else {
None
}
}
}