diff --git a/src/uucore/src/lib/features/hardware.rs b/src/uucore/src/lib/features/hardware.rs index e1ff494f4c..df36d15bc8 100644 --- a/src/uucore/src/lib/features/hardware.rs +++ b/src/uucore/src/lib/features/hardware.rs @@ -145,17 +145,10 @@ impl CpuFeatures { } fn detect_impl() -> Self { - let set = [ - (HardwareFeature::Avx512, detect_avx512 as fn() -> bool), - (HardwareFeature::Avx2, detect_avx2), - (HardwareFeature::Pclmulqdq, detect_pclmulqdq), - (HardwareFeature::Pmull, detect_pmull), - (HardwareFeature::Sse2, detect_sse2), - (HardwareFeature::Asimd, detect_asimd), - ] - .into_iter() - .filter_map(|(feat, detect)| detect().then_some(feat)) - .collect(); + let set = FEATURE_DETECTORS + .iter() + .filter_map(|(feat, detect)| detect().then_some(*feat)) + .collect(); Self { set } } @@ -241,6 +234,33 @@ impl HasHardwareFeatures for SimdPolicy { // Platform-specific feature detection +/// A feature this architecture can have, with its detector. +type FeatureDetector = (HardwareFeature, fn() -> bool); + +#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] +const FEATURE_DETECTORS: &[FeatureDetector] = &[ + (HardwareFeature::Avx512, detect_avx512), + (HardwareFeature::Avx2, detect_avx2), + (HardwareFeature::PclMul, detect_pclmul), + (HardwareFeature::Sse2, detect_sse2), +]; + +// bytecount's aarch64 SIMD code, used by wc, is only built for little-endian +// targets, so skip these detectors on big-endian targets. +#[cfg(all(target_arch = "aarch64", target_endian = "little"))] +const FEATURE_DETECTORS: &[FeatureDetector] = &[ + (HardwareFeature::Pmull, detect_pmull), + (HardwareFeature::Asimd, detect_asimd), +]; + +// No hardware feature detectors are currently supported on this target. +#[cfg(not(any( + target_arch = "x86", + target_arch = "x86_64", + all(target_arch = "aarch64", target_endian = "little") +)))] +const FEATURE_DETECTORS: &[FeatureDetector] = &[]; + #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] fn detect_avx512() -> bool { if cfg!(target_os = "android") { @@ -251,11 +271,6 @@ fn detect_avx512() -> bool { } } -#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))] -fn detect_avx512() -> bool { - false -} - #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] fn detect_avx2() -> bool { if cfg!(target_os = "android") { @@ -265,11 +280,6 @@ fn detect_avx2() -> bool { } } -#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))] -fn detect_avx2() -> bool { - false -} - #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] fn detect_pclmulqdq() -> bool { if cfg!(target_os = "android") { @@ -279,11 +289,6 @@ fn detect_pclmulqdq() -> bool { } } -#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))] -fn detect_pclmulqdq() -> bool { - false -} - #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] fn detect_sse2() -> bool { if cfg!(target_os = "android") { @@ -293,12 +298,7 @@ fn detect_sse2() -> bool { } } -#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))] -fn detect_sse2() -> bool { - false -} - -#[cfg(all(target_arch = "aarch64", target_endian = "little"))] +#[cfg(target_arch = "aarch64")] fn detect_asimd() -> bool { if cfg!(target_os = "android") { false @@ -307,11 +307,6 @@ fn detect_asimd() -> bool { } } -#[cfg(not(all(target_arch = "aarch64", target_endian = "little")))] -fn detect_asimd() -> bool { - false -} - #[cfg(target_arch = "aarch64")] fn detect_pmull() -> bool { // PMULL is an optional extension. ASIMD alone is not enough. @@ -322,11 +317,6 @@ fn detect_pmull() -> bool { } } -#[cfg(not(target_arch = "aarch64"))] -fn detect_pmull() -> bool { - false -} - // GLIBC_TUNABLES parsing /// Parse the `glibc.cpu.hwcaps` setting of `GLIBC_TUNABLES` into the set of