aboutsummaryrefslogtreecommitdiffstats
path: root/src/libs/3rdparty/botan/src/lib/utils/cpuid/cpuid_ppc.cpp
diff options
context:
space:
mode:
authorEike Ziller <eike.ziller@qt.io>2018-08-15 13:53:28 +0200
committerEike Ziller <eike.ziller@qt.io>2018-08-15 13:53:28 +0200
commitdb9837fa6c9401e898ac8e7492081a6e21c71790 (patch)
treed542a089711257402ac4fe70813fa0e7de825f2e /src/libs/3rdparty/botan/src/lib/utils/cpuid/cpuid_ppc.cpp
parent7bc14bf3498ea6b1c19abacf85a5103772da26bc (diff)
parent58747b2de107e8f6ac00daeb431ecbf3e603fd34 (diff)
Merge remote-tracking branch 'origin/4.7'
Conflicts: src/plugins/clangtools/clangtoolruncontrol.cpp src/plugins/cpptools/compileroptionsbuilder.cpp Change-Id: Ib1e8abf066898b50c90fc1ccba4697fe983e8a8f
Diffstat (limited to 'src/libs/3rdparty/botan/src/lib/utils/cpuid/cpuid_ppc.cpp')
-rw-r--r--src/libs/3rdparty/botan/src/lib/utils/cpuid/cpuid_ppc.cpp129
1 files changed, 129 insertions, 0 deletions
diff --git a/src/libs/3rdparty/botan/src/lib/utils/cpuid/cpuid_ppc.cpp b/src/libs/3rdparty/botan/src/lib/utils/cpuid/cpuid_ppc.cpp
new file mode 100644
index 00000000000..43b68478524
--- /dev/null
+++ b/src/libs/3rdparty/botan/src/lib/utils/cpuid/cpuid_ppc.cpp
@@ -0,0 +1,129 @@
+/*
+* Runtime CPU detection for POWER/PowerPC
+* (C) 2009,2010,2013,2017 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include <botan/cpuid.h>
+#include <botan/internal/os_utils.h>
+
+#if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)
+
+/*
+* On Darwin and OpenBSD ppc, use sysctl to detect AltiVec
+*/
+#if defined(BOTAN_TARGET_OS_IS_DARWIN)
+ #include <sys/sysctl.h>
+#elif defined(BOTAN_TARGET_OS_IS_OPENBSD)
+ #include <sys/param.h>
+ #include <sys/sysctl.h>
+ #include <machine/cpu.h>
+#elif defined(BOTAN_TARGET_OS_HAS_GETAUXVAL)
+ #include <sys/auxv.h>
+#endif
+
+#endif
+
+namespace Botan {
+
+#if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)
+
+/*
+* PowerPC specific block: check for AltiVec using either
+* sysctl or by reading processor version number register.
+*/
+uint64_t CPUID::detect_cpu_features(size_t* cache_line_size)
+ {
+ BOTAN_UNUSED(cache_line_size);
+
+#if defined(BOTAN_TARGET_OS_IS_DARWIN) || defined(BOTAN_TARGET_OS_IS_OPENBSD)
+ // On Darwin/OS X and OpenBSD, use sysctl
+
+ int sels[2] = {
+#if defined(BOTAN_TARGET_OS_IS_OPENBSD)
+ CTL_MACHDEP, CPU_ALTIVEC
+#else
+ CTL_HW, HW_VECTORUNIT
+#endif
+ };
+
+ int vector_type = 0;
+ size_t length = sizeof(vector_type);
+ int error = ::sysctl(sels, 2, &vector_type, &length, NULL, 0);
+
+ if(error == 0 && vector_type > 0)
+ return CPUID::CPUID_ALTIVEC_BIT;
+
+#elif defined(BOTAN_TARGET_OS_HAS_GETAUXVAL) && defined(BOTAN_TARGET_ARCH_IS_PPC64)
+
+ enum PPC_hwcap_bit {
+ ALTIVEC_bit = (1 << 28),
+ CRYPTO_bit = (1 << 25),
+
+ ARCH_hwcap_altivec = 16, // AT_HWCAP
+ ARCH_hwcap_crypto = 26, // AT_HWCAP2
+ };
+
+ uint64_t detected_features = 0;
+
+ const unsigned long hwcap_altivec = ::getauxval(PPC_hwcap_bit::ARCH_hwcap_altivec);
+ if(hwcap_altivec & PPC_hwcap_bit::ALTIVEC_bit)
+ detected_features |= CPUID::CPUID_ALTIVEC_BIT;
+
+ const unsigned long hwcap_crypto = ::getauxval(PPC_hwcap_bit::ARCH_hwcap_crypto);
+ if(hwcap_crypto & PPC_hwcap_bit::CRYPTO_bit)
+ detected_features |= CPUID::CPUID_PPC_CRYPTO_BIT;
+
+ return detected_features;
+
+#else
+
+ /*
+ On PowerPC, MSR 287 is PVR, the Processor Version Number
+ Normally it is only accessible to ring 0, but Linux and NetBSD
+ (others, too, maybe?) will trap and emulate it for us.
+ */
+
+ int pvr = OS::run_cpu_instruction_probe([]() -> int {
+ uint32_t pvr = 0;
+ asm volatile("mfspr %0, 287" : "=r" (pvr));
+ // Top 16 bits suffice to identify the model
+ return static_cast<int>(pvr >> 16);
+ });
+
+ if(pvr > 0)
+ {
+ const uint16_t ALTIVEC_PVR[] = {
+ 0x003E, // IBM POWER6
+ 0x003F, // IBM POWER7
+ 0x004A, // IBM POWER7p
+ 0x004D, // IBM POWER8
+ 0x004B, // IBM POWER8E
+ 0x000C, // G4-7400
+ 0x0039, // G5 970
+ 0x003C, // G5 970FX
+ 0x0044, // G5 970MP
+ 0x0070, // Cell PPU
+ 0, // end
+ };
+
+ for(size_t i = 0; ALTIVEC_PVR[i]; ++i)
+ {
+ if(pvr == ALTIVEC_PVR[i])
+ return CPUID::CPUID_ALTIVEC_BIT;
+ }
+
+ return 0;
+ }
+
+ // TODO try direct instruction probing
+
+#endif
+
+ return 0;
+ }
+
+#endif
+
+}