pub use super::kernels::Xxh3KernelId as KernelId;
use crate::platform::Caps;
#[derive(Clone, Copy, Debug)]
pub struct DispatchTable {
pub long: KernelId,
}
pub static DEFAULT_TABLE: DispatchTable = DispatchTable {
long: KernelId::Portable,
};
#[cfg(target_arch = "x86_64")]
pub static AVX512_TABLE: DispatchTable = DispatchTable { long: KernelId::Avx512 };
#[cfg(target_arch = "x86_64")]
pub static AVX2_TABLE: DispatchTable = DispatchTable { long: KernelId::Avx2 };
#[cfg(target_arch = "aarch64")]
pub static NEON_TABLE: DispatchTable = DispatchTable { long: KernelId::Neon };
#[cfg(all(target_arch = "powerpc64", target_endian = "little"))]
pub static VSX_TABLE: DispatchTable = DispatchTable { long: KernelId::Vsx };
#[cfg(target_arch = "s390x")]
pub static ZVECTOR_TABLE: DispatchTable = DispatchTable { long: KernelId::Vector };
#[inline]
#[must_use]
pub fn select_runtime_table(caps: Caps) -> &'static DispatchTable {
let _ = caps;
#[cfg(target_arch = "x86_64")]
{
if caps.has(crate::platform::caps::x86::AVX512F) {
return &AVX512_TABLE;
}
if caps.has(crate::platform::caps::x86::AVX2) {
return &AVX2_TABLE;
}
}
#[cfg(target_arch = "aarch64")]
{
if caps.has(crate::platform::caps::aarch64::NEON) {
return &NEON_TABLE;
}
}
#[cfg(all(target_arch = "powerpc64", target_endian = "little"))]
{
if caps.has(super::kernels::required_caps(KernelId::Vsx)) {
return &VSX_TABLE;
}
}
#[cfg(target_arch = "s390x")]
{
if caps.has(crate::platform::caps::s390x::VECTOR) {
return &ZVECTOR_TABLE;
}
}
&DEFAULT_TABLE
}
#[cfg(all(test, target_arch = "powerpc64", target_endian = "little"))]
mod tests {
use super::*;
use crate::platform::caps::power;
#[test]
fn power_table_requires_every_target_feature() {
let required = power::ALTIVEC | power::VSX | power::POWER8_VECTOR;
assert_eq!(select_runtime_table(required).long, KernelId::Vsx);
for missing in [power::ALTIVEC, power::VSX, power::POWER8_VECTOR] {
assert_eq!(
select_runtime_table(required.difference(missing)).long,
KernelId::Portable
);
}
}
}