summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Support/Host.cpp
diff options
context:
space:
mode:
authorAlina Sbirlea <asbirlea@google.com>2016-10-04 22:39:53 +0000
committerAlina Sbirlea <asbirlea@google.com>2016-10-04 22:39:53 +0000
commit9a78ebd6d8aa24d0352d5a3640711aa5155dec80 (patch)
treefb1777a6c8d8761931ae510b5e90587f0e885048 /llvm/lib/Support/Host.cpp
parentf3a0bce1557f2c070518875122a8eb648f971211 (diff)
downloadbcm5719-llvm-9a78ebd6d8aa24d0352d5a3640711aa5155dec80.tar.gz
bcm5719-llvm-9a78ebd6d8aa24d0352d5a3640711aa5155dec80.zip
[cpu-detection] Copy simplified version of get_cpuid_max to remove dependency to clang's implementation
Summary: Attempting to fix PR30384. Take the same approach as in compiler_rt and add a simplified version of __get_cpuid_max. Including cpuid.h is no longer needed. Reviewers: echristo, joerg Subscribers: mehdi_amini, llvm-commits Differential Revision: https://reviews.llvm.org/D24597 llvm-svn: 283265
Diffstat (limited to 'llvm/lib/Support/Host.cpp')
-rw-r--r--llvm/lib/Support/Host.cpp42
1 files changed, 37 insertions, 5 deletions
diff --git a/llvm/lib/Support/Host.cpp b/llvm/lib/Support/Host.cpp
index 689e05093fe..cf61e0487a5 100644
--- a/llvm/lib/Support/Host.cpp
+++ b/llvm/lib/Support/Host.cpp
@@ -73,10 +73,6 @@ static ssize_t LLVM_ATTRIBUTE_UNUSED readCpuInfo(void *Buf, size_t Size) {
#if defined(__i386__) || defined(_M_IX86) || \
defined(__x86_64__) || defined(_M_X64)
-#if defined(__GNUC__) || defined(__clang__)
-#include <cpuid.h>
-#endif
-
enum VendorSignatures {
SIG_INTEL = 0x756e6547 /* Genu */,
SIG_AMD = 0x68747541 /* Auth */
@@ -173,6 +169,41 @@ enum ProcessorFeatures {
FEATURE_EM64T
};
+// The check below for i386 was copied from clang's cpuid.h (__get_cpuid_max).
+// Check motivated by bug reports for OpenSSL crashing on CPUs without CPUID
+// support. Consequently, for i386, the presence of CPUID is checked first
+// via the corresponding eflags bit.
+// Removal of cpuid.h header motivated by PR30384
+// Header cpuid.h and method __get_cpuid_max are not used in llvm, clang, openmp
+// or test-suite, but are used in external projects e.g. libstdcxx
+static bool isCpuIdSupported() {
+#if defined(__GNUC__) || defined(__clang__)
+#if defined(__i386__)
+ int __cpuid_supported;
+ __asm__(" pushfl\n"
+ " popl %%eax\n"
+ " movl %%eax,%%ecx\n"
+ " xorl $0x00200000,%%eax\n"
+ " pushl %%eax\n"
+ " popfl\n"
+ " pushfl\n"
+ " popl %%eax\n"
+ " movl $0,%0\n"
+ " cmpl %%eax,%%ecx\n"
+ " je 1f\n"
+ " movl $1,%0\n"
+ "1:"
+ : "=r"(__cpuid_supported)
+ :
+ : "eax", "ecx");
+ if (!__cpuid_supported)
+ return false;
+#endif
+ return true;
+#endif
+ return true;
+}
+
/// getX86CpuIDAndInfo - Execute the specified cpuid and return the 4 values in
/// the specified arguments. If we can't run cpuid on the host, return true.
static bool getX86CpuIDAndInfo(unsigned value, unsigned *rEAX, unsigned *rEBX,
@@ -748,7 +779,8 @@ StringRef sys::getHostCPUName() {
//FIXME: include cpuid.h from clang or copy __get_cpuid_max here
// and simplify it to not invoke __cpuid (like cpu_model.c in
// compiler-rt/lib/builtins/cpu_model.c?
- if(!__get_cpuid_max(0, &Vendor))
+ // Opting for the second option.
+ if(!isCpuIdSupported())
return "generic";
#endif
if (getX86CpuIDAndInfo(0, &MaxLeaf, &Vendor, &ECX, &EDX))
OpenPOWER on IntegriCloud