#[cfg(target_arch = "powerpc64")]
fn detect_power() -> Detected {
#[cfg(feature = "std")]
let caps = caps_static() | runtime_power();
#[cfg(not(feature = "std"))]
let caps = caps_static();
Detected {
caps,
arch: Arch::Power,
}
}
#[cfg(all(
target_arch = "powerpc64",
feature = "std",
any(target_os = "linux", target_os = "android")
))]
fn runtime_power() -> Caps {
use std::{fs::File, io::Read};
use crate::platform::caps::power;
const AT_HWCAP: u64 = 16;
const AT_HWCAP2: u64 = 26;
const PPC_FEATURE_HAS_ALTIVEC: u64 = 0x1000_0000;
const PPC_FEATURE_HAS_VSX: u64 = 0x0000_0080;
const PPC_FEATURE2_ARCH_2_07: u64 = 0x8000_0000; const PPC_FEATURE2_ARCH_3_00: u64 = 0x0080_0000; const PPC_FEATURE2_ARCH_3_1: u64 = 0x0004_0000;
let (hwcap, hwcap2) = (|| -> Option<(u64, u64)> {
let mut file = File::open("/proc/self/auxv").ok()?;
let mut buf = [0u8; 4096];
let n = file.read(&mut buf).ok()?;
let mut hwcap = 0u64;
let mut hwcap2 = 0u64;
for chunk in buf.get(..n)?.chunks_exact(16) {
let a_type = u64::from_ne_bytes(chunk.get(0..8)?.try_into().ok()?);
let a_val = u64::from_ne_bytes(chunk.get(8..16)?.try_into().ok()?);
if a_type == AT_HWCAP {
hwcap = a_val;
} else if a_type == AT_HWCAP2 {
hwcap2 = a_val;
} else if a_type == 0 {
break;
}
}
Some((hwcap, hwcap2))
})()
.unwrap_or((0, 0));
let mut caps = Caps::NONE;
if hwcap & PPC_FEATURE_HAS_ALTIVEC != 0 {
caps |= power::ALTIVEC;
}
if hwcap & PPC_FEATURE_HAS_VSX != 0 {
caps |= power::VSX;
}
if hwcap2 & PPC_FEATURE2_ARCH_3_1 != 0 {
caps |= power::POWER10_VECTOR | power::POWER9_VECTOR | power::POWER8_VECTOR | power::POWER8_CRYPTO;
} else if hwcap2 & PPC_FEATURE2_ARCH_3_00 != 0 {
caps |= power::POWER9_VECTOR | power::POWER8_VECTOR | power::POWER8_CRYPTO;
} else if hwcap2 & PPC_FEATURE2_ARCH_2_07 != 0 {
caps |= power::POWER8_VECTOR | power::POWER8_CRYPTO;
}
caps
}
#[cfg(all(
target_arch = "powerpc64",
feature = "std",
not(any(target_os = "linux", target_os = "android"))
))]
fn runtime_power() -> Caps {
Caps::NONE
}