pub(crate) fn get_or_init() -> Dispatch {
use core::sync::atomic::{AtomicU8, Ordering::Relaxed};
static LAZY: AtomicU8 = AtomicU8::new(to_u8(None));
const fn to_u8(val: Option<Dispatch>) -> u8 {
unsafe { core::mem::transmute(val) }
}
const unsafe fn from_u8(val: u8) -> Option<Dispatch> {
unsafe { core::mem::transmute(val) }
}
#[cold]
fn init() -> Dispatch {
let val = {
use Dispatch::*;
#[cfg(target_arch = "aarch64")]
{
if std::arch::is_aarch64_feature_detected!("neon") {
Neon
} else {
Plain
}
}
#[cfg(target_arch = "arm")]
{
if std::arch::is_arm_feature_detected!("neon") {
Neon
} else {
Plain
}
}
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
{
if std::arch::is_x86_feature_detected!("avx512f") {
Avx512
} else if std::arch::is_x86_feature_detected!("avx2") {
Avx2
} else if std::arch::is_x86_feature_detected!("sse4.2") {
Sse4
} else {
Plain
}
}
#[cfg(target_arch = "mips")]
{
if std::arch::is_mips_feature_detected!("msa") {
Msa
} else {
Plain
}
}
#[cfg(target_arch = "mips64")]
{
if std::arch::is_mips64_feature_detected!("msa") {
Msa
} else {
Plain
}
}
#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
{
if std::arch::is_riscv_feature_detected!("v") {
V
} else {
Plain
}
}
#[cfg(all(target_arch = "wasm32", target_feature = "simd128"))]
{
Simd128
}
#[cfg(all(target_arch = "wasm32", not(target_feature = "simd128")))]
{
Plain
}
};
LAZY.store(to_u8(Some(val)), Relaxed);
val
}
if let Some(val) = unsafe { from_u8(LAZY.load(Relaxed)) } {
val
} else {
init()
}
}
#[derive(Clone, Copy)]
pub(crate) enum Dispatch {
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
Avx512,
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
Avx2,
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
Sse4,
#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
Neon,
#[cfg(any(target_arch = "mips", target_arch = "mips64"))]
Msa,
#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
V,
#[cfg(all(target_arch = "wasm32", target_feature = "simd128"))]
Simd128,
#[cfg(not(all(target_arch = "wasm32", target_feature = "simd128")))]
Plain,
}