diff --git a/src/uucore/src/lib/features/hardware.rs b/src/uucore/src/lib/features/hardware.rs index 0d1e3f7e4de..fbc097c75d8 100644 --- a/src/uucore/src/lib/features/hardware.rs +++ b/src/uucore/src/lib/features/hardware.rs @@ -143,17 +143,10 @@ impl CpuFeatures { } fn detect_impl() -> Self { - let set = [ - (HardwareFeature::Avx512, detect_avx512 as fn() -> bool), - (HardwareFeature::Avx2, detect_avx2), - (HardwareFeature::PclMul, detect_pclmul), - (HardwareFeature::Vmull, detect_vmull), - (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 } } @@ -239,6 +232,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::Vmull, detect_vmull), + (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") { @@ -249,11 +269,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") { @@ -263,11 +278,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_pclmul() -> bool { if cfg!(target_os = "android") { @@ -277,11 +287,6 @@ fn detect_pclmul() -> bool { } } -#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))] -fn detect_pclmul() -> bool { - false -} - #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] fn detect_sse2() -> bool { if cfg!(target_os = "android") { @@ -291,12 +296,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 @@ -305,11 +305,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_vmull() -> bool { // VMULL on 64-bit lanes needs PMULL, an optional extension. @@ -321,11 +316,6 @@ fn detect_vmull() -> bool { } } -#[cfg(not(target_arch = "aarch64"))] -fn detect_vmull() -> bool { - false -} - // GLIBC_TUNABLES parsing /// Parse the `glibc.cpu.hwcaps` setting of `GLIBC_TUNABLES` into the set of