5050#if defined(__sun__) && defined(__svr4__)
5151#include < kstat.h>
5252#endif
53+ #if defined(__GNUC__) || defined(__clang__)
54+ #if (defined(__i386__) || defined(__x86_64__)) && !defined(_MSC_VER)
55+ #include < cpuid.h>
56+ #endif
57+ #endif
5358
5459#define DEBUG_TYPE " host-detection"
5560
@@ -522,68 +527,15 @@ StringRef sys::detail::getHostCPUNameForBPF() {
522527#endif
523528}
524529
525- #if defined(__i386__) || defined(_M_IX86) || \
526- defined (__x86_64__) || defined(_M_X64)
527-
528- // The check below for i386 was copied from clang's cpuid.h (__get_cpuid_max).
529- // Check motivated by bug reports for OpenSSL crashing on CPUs without CPUID
530- // support. Consequently, for i386, the presence of CPUID is checked first
531- // via the corresponding eflags bit.
532- // Removal of cpuid.h header motivated by PR30384
533- // Header cpuid.h and method __get_cpuid_max are not used in llvm, clang, openmp
534- // or test-suite, but are used in external projects e.g. libstdcxx
535- static bool isCpuIdSupported() {
536- #if defined(__GNUC__) || defined(__clang__)
537- #if defined(__i386__)
538- int __cpuid_supported;
539- __asm__ (" pushfl\n "
540- " popl %%eax\n "
541- " movl %%eax,%%ecx\n "
542- " xorl $0x00200000,%%eax\n "
543- " pushl %%eax\n "
544- " popfl\n "
545- " pushfl\n "
546- " popl %%eax\n "
547- " movl $0,%0\n "
548- " cmpl %%eax,%%ecx\n "
549- " je 1f\n "
550- " movl $1,%0\n "
551- " 1:"
552- : " =r" (__cpuid_supported)
553- :
554- : " eax" , " ecx" );
555- if (!__cpuid_supported)
556- return false ;
557- #endif
558- return true ;
559- #endif
560- return true ;
561- }
530+ #if defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || \
531+ defined (_M_X64)
562532
563533// / getX86CpuIDAndInfo - Execute the specified cpuid and return the 4 values in
564534// / the specified arguments. If we can't run cpuid on the host, return true.
565535static bool getX86CpuIDAndInfo(unsigned value, unsigned *rEAX, unsigned *rEBX,
566536 unsigned *rECX, unsigned *rEDX) {
567- #if defined(__GNUC__) || defined(__clang__)
568- #if defined(__x86_64__)
569- // gcc doesn't know cpuid would clobber ebx/rbx. Preserve it manually.
570- // FIXME: should we save this for Clang?
571- __asm__ (" movq\t %%rbx, %%rsi\n\t "
572- " cpuid\n\t "
573- " xchgq\t %%rbx, %%rsi\n\t "
574- : " =a" (*rEAX), " =S" (*rEBX), " =c" (*rECX), " =d" (*rEDX)
575- : " a" (value));
576- return false ;
577- #elif defined(__i386__)
578- __asm__ (" movl\t %%ebx, %%esi\n\t "
579- " cpuid\n\t "
580- " xchgl\t %%ebx, %%esi\n\t "
581- : " =a" (*rEAX), " =S" (*rEBX), " =c" (*rECX), " =d" (*rEDX)
582- : " a" (value));
583- return false ;
584- #else
585- return true ;
586- #endif
537+ #if (defined(__i386__) || defined(__x86_64__)) && !defined(_MSC_VER)
538+ return !__get_cpuid (value, rEAX, rEBX, rECX, rEDX);
587539#elif defined(_MSC_VER)
588540 // The MSVC intrinsic is portable across x86 and x64.
589541 int registers[4 ];
@@ -610,9 +562,6 @@ VendorSignatures getVendorSignature(unsigned *MaxLeaf) {
610562 else
611563 *MaxLeaf = 0 ;
612564
613- if (!isCpuIdSupported ())
614- return VendorSignatures::UNKNOWN;
615-
616565 if (getX86CpuIDAndInfo (0 , MaxLeaf, &EBX, &ECX, &EDX) || *MaxLeaf < 1 )
617566 return VendorSignatures::UNKNOWN;
618567
@@ -640,26 +589,12 @@ using namespace llvm::sys::detail::x86;
640589static bool getX86CpuIDAndInfoEx (unsigned value, unsigned subleaf,
641590 unsigned *rEAX, unsigned *rEBX, unsigned *rECX,
642591 unsigned *rEDX) {
643- #if defined(__GNUC__) || defined(__clang__)
644- #if defined(__x86_64__)
645- // gcc doesn't know cpuid would clobber ebx/rbx. Preserve it manually.
646- // FIXME: should we save this for Clang?
647- __asm__ (" movq\t %%rbx, %%rsi\n\t "
648- " cpuid\n\t "
649- " xchgq\t %%rbx, %%rsi\n\t "
650- : " =a" (*rEAX), " =S" (*rEBX), " =c" (*rECX), " =d" (*rEDX)
651- : " a" (value), " c" (subleaf));
652- return false ;
653- #elif defined(__i386__)
654- __asm__ (" movl\t %%ebx, %%esi\n\t "
655- " cpuid\n\t "
656- " xchgl\t %%ebx, %%esi\n\t "
657- : " =a" (*rEAX), " =S" (*rEBX), " =c" (*rECX), " =d" (*rEDX)
658- : " a" (value), " c" (subleaf));
659- return false ;
660- #else
661- return true ;
662- #endif
592+ // TODO(boomanaiden154): When the minimum toolchain versions for gcc and clang
593+ // are such that __cpuidex is defined within cpuid.h for both, we can remove
594+ // the __get_cpuid_count function and share the MSVC implementation between
595+ // all three.
596+ #if (defined(__i386__) || defined(__x86_64__)) && !defined(_MSC_VER)
597+ return !__get_cpuid_count (value, subleaf, rEAX, rEBX, rECX, rEDX);
663598#elif defined(_MSC_VER)
664599 int registers[4 ];
665600 __cpuidex (registers, value, subleaf);
@@ -675,6 +610,9 @@ static bool getX86CpuIDAndInfoEx(unsigned value, unsigned subleaf,
675610
676611// Read control register 0 (XCR0). Used to detect features such as AVX.
677612static bool getX86XCR0 (unsigned *rEAX, unsigned *rEDX) {
613+ // TODO(boomanaiden154): When the minimum toolchain versions for gcc and clang
614+ // are such that _xgetbv is supported by both, we can unify the implementation
615+ // with MSVC and remove all inline assembly.
678616#if defined(__GNUC__) || defined(__clang__)
679617 // Check xgetbv; this uses a .byte sequence instead of the instruction
680618 // directly because older assemblers do not include support for xgetbv and
0 commit comments