aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorlloyd <[email protected]>2011-11-18 20:46:16 +0000
committerlloyd <[email protected]>2011-11-18 20:46:16 +0000
commit02f5422ba1908639b5949d5e228863a73e0c7520 (patch)
tree0f310a6d85d7f3b7b29b25061010c6325ef090d4 /src
parent4ba7731b856442a7bb6e595c6dda2696abc0415d (diff)
Call cpuid via inline asm on x86-64, so we can use it with Clang (no
cpuid intrinsic) and older GCC (no cpuid.h before 4.3)
Diffstat (limited to 'src')
-rw-r--r--src/utils/cpuid.cpp18
1 files changed, 16 insertions, 2 deletions
diff --git a/src/utils/cpuid.cpp b/src/utils/cpuid.cpp
index 917789f65..c5710d689 100644
--- a/src/utils/cpuid.cpp
+++ b/src/utils/cpuid.cpp
@@ -24,9 +24,9 @@
#elif defined(BOTAN_BUILD_COMPILER_IS_INTEL)
#include <ia32intrin.h>
- #define CALL_CPUID(type, out) do { __cpuid(out, type); } while(0);
+ #define CALL_CPUID(type, out) do { __cpuid(out, type); } while(0)
-#elif (BOTAN_GCC_VERSION >= 430)
+#elif defined(BOTAN_BUILD_COMPILER_IS_GCC) && (BOTAN_GCC_VERSION >= 430)
// Only available starting in GCC 4.3
#include <cpuid.h>
@@ -46,6 +46,20 @@ namespace {
}
+#elif defined(BOTAN_TARGET_ARCH_IS_X86_64) && \
+ (defined(BOTAN_BUILD_COMPILER_IS_CLANG) || defined(BOTAN_BUILD_COMPILER_IS_GCC))
+
+ /*
+ * We can't safely use this on x86-32 as some 32-bit ABIs use ebx as
+ * a PIC register, and in theory there are some x86-32s still out
+ * there that don't support cpuid at all; it requires strange
+ * contortions to detect them.
+ */
+
+ #define CALL_CPUID(type, out) \
+ asm("cpuid\n\t" : "=a" (out[0]), "=b" (out[1]), "=c" (out[2]), "=d" (out[3]) \
+ : "0" (type))
+
#else
#warning "No method of calling CPUID for this compiler"
#endif