]>
Commit | Line | Data |
---|---|---|
f20569fa XL |
1 | //! Run-time feature detection for PowerPC on Linux. |
2 | ||
3 | use super::{auxvec, cpuinfo}; | |
4 | use crate::detect::{cache, Feature}; | |
5 | ||
6 | /// Performs run-time feature detection. | |
7 | #[inline] | |
8 | pub fn check_for(x: Feature) -> bool { | |
9 | cache::test(x as u32, detect_features) | |
10 | } | |
11 | ||
12 | /// Try to read the features from the auxiliary vector, and if that fails, try | |
13 | /// to read them from /proc/cpuinfo. | |
14 | fn detect_features() -> cache::Initializer { | |
15 | let mut value = cache::Initializer::default(); | |
16 | let enable_feature = |value: &mut cache::Initializer, f, enable| { | |
17 | if enable { | |
18 | value.set(f as u32); | |
19 | } | |
20 | }; | |
21 | ||
22 | // The values are part of the platform-specific [asm/cputable.h][cputable] | |
23 | // | |
24 | // [cputable]: https://github.com/torvalds/linux/blob/master/arch/powerpc/include/uapi/asm/cputable.h | |
25 | if let Ok(auxv) = auxvec::auxv() { | |
26 | // note: the PowerPC values are the mask to do the test (instead of the | |
27 | // index of the bit to test like in ARM and Aarch64) | |
28 | enable_feature(&mut value, Feature::altivec, auxv.hwcap & 0x10000000 != 0); | |
29 | enable_feature(&mut value, Feature::vsx, auxv.hwcap & 0x00000080 != 0); | |
30 | enable_feature(&mut value, Feature::power8, auxv.hwcap2 & 0x80000000 != 0); | |
31 | return value; | |
32 | } | |
33 | ||
34 | // PowerPC's /proc/cpuinfo lacks a proper Feature field, | |
35 | // but `altivec` support is indicated in the `cpu` field. | |
36 | if let Ok(c) = cpuinfo::CpuInfo::new() { | |
37 | enable_feature(&mut value, Feature::altivec, c.field("cpu").has("altivec")); | |
38 | return value; | |
39 | } | |
40 | value | |
41 | } |