8#include <botan/internal/cpuid.h>
10#if defined(BOTAN_HAS_OS_UTILS)
11 #include <botan/internal/os_utils.h>
16#if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)
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, CPUID::CPUID_ALTIVEC_BIT, allowed);
34 #if defined(BOTAN_TARGET_ARCH_IS_PPC64)
35 if(feat & CPUID::CPUID_ALTIVEC_BIT) {
36 feat |=
if_set(hwcap_crypto, PPC_hwcap_bit::CRYPTO_bit, CPUID::CPUID_POWER_CRYPTO_BIT, allowed);
37 feat |=
if_set(hwcap_crypto, PPC_hwcap_bit::DARN_bit, CPUID::CPUID_DARN_BIT, allowed);
45 #if defined(BOTAN_USE_GCC_INLINE_ASM) && defined(BOTAN_HAS_OS_UTILS)
46 auto vmx_probe = []()
noexcept ->
int {
51 if(allowed & CPUID::CPUID_ALTIVEC_BIT) {
53 feat |= CPUID::CPUID_ALTIVEC_BIT;
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 & CPUID::CPUID_ALTIVEC_BIT) {
70 feat |= CPUID::CPUID_POWER_CRYPTO_BIT & allowed;
74 feat |= CPUID::CPUID_DARN_BIT & allowed;
static uint32_t if_set(uint64_t cpuid, T flag, CPUID::CPUID_bits 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)