8#include <botan/internal/cpuid.h>
10#include <botan/internal/target_info.h>
12#if defined(BOTAN_HAS_OS_UTILS)
13 #include <botan/internal/os_utils.h>
18uint32_t CPUID::CPUID_Data::detect_cpu_features(uint32_t allowed) {
21#if defined(BOTAN_HAS_OS_UTILS)
24 const auto [hwcap_altivec, hwcap_crypto] = *auxval;
26 enum class PPC_hwcap_bit : uint64_t {
27 ALTIVEC_bit = (1 << 28),
28 CRYPTO_bit = (1 << 25),
32 feat |=
if_set(hwcap_altivec, PPC_hwcap_bit::ALTIVEC_bit, CPUFeature::Bit::ALTIVEC, allowed);
34 #if defined(BOTAN_TARGET_ARCH_IS_PPC64)
35 if(feat & CPUFeature::Bit::ALTIVEC) {
36 feat |=
if_set(hwcap_crypto, PPC_hwcap_bit::CRYPTO_bit, CPUFeature::Bit::POWER_CRYPTO, allowed);
37 feat |=
if_set(hwcap_crypto, PPC_hwcap_bit::DARN_bit, CPUFeature::Bit::DARN, allowed);
45#if defined(BOTAN_USE_GCC_INLINE_ASM) && defined(BOTAN_HAS_OS_UTILS)
46 auto vmx_probe = []()
noexcept ->
int {
51 if(allowed & CPUFeature::Bit::ALTIVEC) {
53 feat |= CPUFeature::Bit::ALTIVEC;
56 #if defined(BOTAN_TARGET_CPU_IS_PPC64)
57 auto vcipher_probe = []()
noexcept ->
int {
58 asm(
"vcipher 0, 0, 0");
62 auto darn_probe = []()
noexcept ->
int {
64 asm volatile(
"darn %0, 1" :
"=r"(output));
65 return (~output) != 0;
68 if(feat & CPUFeature::Bit::ALTIVEC) {
70 feat |= CPUFeature::Bit::POWER_CRYPTO & allowed;
74 feat |= CPUFeature::Bit::DARN & allowed;
static uint32_t if_set(uint64_t cpuid, T flag, CPUID::Feature bit, uint32_t allowed)
std::optional< std::pair< unsigned long, unsigned long > > get_auxval_hwcap()
int BOTAN_TEST_API run_cpu_instruction_probe(const std::function< int()> &probe_fn)