#if defined(__i386__) || defined(_M_IX86) || \
defined(__x86_64__) || defined(_M_X64)
-enum VendorSignatures {
- SIG_INTEL = 0x756e6547 /* Genu */,
- SIG_AMD = 0x68747541 /* Auth */
-};
-
// 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
#endif
}
+namespace llvm {
+namespace sys {
+namespace detail {
+namespace x86 {
+
+VendorSignatures getVendorSignature(unsigned *MaxLeaf) {
+ unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
+ if (MaxLeaf == nullptr)
+ MaxLeaf = &EAX;
+ else
+ *MaxLeaf = 0;
+
+ if (!isCpuIdSupported())
+ return VendorSignatures::UNKNOWN;
+
+ if (getX86CpuIDAndInfo(0, MaxLeaf, &EBX, &ECX, &EDX) || *MaxLeaf < 1)
+ return VendorSignatures::UNKNOWN;
+
+ // "Genu ineI ntel"
+ if (EBX == 0x756e6547 && ECX == 0x6c65746e && EDX == 0x49656e69)
+ return VendorSignatures::GENUINE_INTEL;
+
+ // "Auth enti cAMD"
+ if (EBX == 0x68747541 && ECX == 0x69746e65 && EDX == 0x444d4163)
+ return VendorSignatures::AUTHENTIC_AMD;
+
+ return VendorSignatures::UNKNOWN;
+}
+
+} // namespace x86
+} // namespace detail
+} // namespace sys
+} // namespace llvm
+
+using namespace llvm::sys::detail::x86;
+
/// getX86CpuIDAndInfoEx - Execute the specified cpuid with subleaf and return
/// the 4 values in the specified arguments. If we can't run cpuid on the host,
/// return true.
}
StringRef sys::getHostCPUName() {
- unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
- unsigned MaxLeaf, Vendor;
-
- if (!isCpuIdSupported())
+ unsigned MaxLeaf = 0;
+ const VendorSignatures Vendor = getVendorSignature(&MaxLeaf);
+ if (Vendor == VendorSignatures::UNKNOWN)
return "generic";
- if (getX86CpuIDAndInfo(0, &MaxLeaf, &Vendor, &ECX, &EDX) || MaxLeaf < 1)
- return "generic";
+ unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
getX86CpuIDAndInfo(0x1, &EAX, &EBX, &ECX, &EDX);
unsigned Family = 0, Model = 0;
StringRef CPU;
- if (Vendor == SIG_INTEL) {
+ if (Vendor == VendorSignatures::GENUINE_INTEL) {
CPU = getIntelProcessorTypeAndSubtype(Family, Model, Features, &Type,
&Subtype);
- } else if (Vendor == SIG_AMD) {
+ } else if (Vendor == VendorSignatures::AUTHENTIC_AMD) {
CPU = getAMDProcessorTypeAndSubtype(Family, Model, Features, &Type,
&Subtype);
}
}
#else
StringRef sys::getHostCPUName() { return "generic"; }
+namespace llvm {
+namespace sys {
+namespace detail {
+namespace x86 {
+
+VendorSignatures getVendorSignature(unsigned *MaxLeaf) {
+ return VendorSignatures::UNKNOWN;
+}
+
+} // namespace x86
+} // namespace detail
+} // namespace sys
+} // namespace llvm
#endif
#if defined(__linux__) && (defined(__i386__) || defined(__x86_64__))
#include "llvm/Support/Errc.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/FormatVariadic.h"
+#include "llvm/Support/Host.h"
#include <memory>
#include <string>
#if defined(__linux__) && defined(HAVE_LIBPFM) && \
defined(LIBPFM_HAS_FIELD_CYCLES)
- // If the kernel supports it, the hardware still may not have it.
- return X86LbrCounter::checkLbrSupport();
+ // FIXME: Fix this.
+ // https://bugs.llvm.org/show_bug.cgi?id=48918
+ // For now, only do the check if we see an Intel machine because
+ // the counter uses some intel-specific magic and it could
+ // be confuse and think an AMD machine actually has LBR support.
+#if defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || \
+ defined(_M_X64)
+ using namespace sys::detail::x86;
+
+ if (getVendorSignature() == VendorSignatures::GENUINE_INTEL)
+ // If the kernel supports it, the hardware still may not have it.
+ return X86LbrCounter::checkLbrSupport();
#else
+ llvm_unreachable("Running X86 exegesis on non-X86 target");
+#endif
+#endif
return llvm::make_error<llvm::StringError>(
"LBR not supported on this kernel and/or platform",
llvm::errc::not_supported);
-#endif
}
std::unique_ptr<SavedState> withSavedState() const override {