5050#if defined(__sun__) && defined(__svr4__)
5151#include < kstat.h>
5252#endif
53+ #if defined(__GNUC__) || defined(__clang__)
54+ #include < cpuid.h>
55+ #endif
5356
5457#define DEBUG_TYPE " host-detection"
5558
@@ -521,68 +524,15 @@ StringRef sys::detail::getHostCPUNameForBPF() {
521524#endif
522525}
523526
524- #if defined(__i386__) || defined(_M_IX86) || \
525- defined (__x86_64__) || defined(_M_X64)
526-
527- // The check below for i386 was copied from clang's cpuid.h (__get_cpuid_max).
528- // Check motivated by bug reports for OpenSSL crashing on CPUs without CPUID
529- // support. Consequently, for i386, the presence of CPUID is checked first
530- // via the corresponding eflags bit.
531- // Removal of cpuid.h header motivated by PR30384
532- // Header cpuid.h and method __get_cpuid_max are not used in llvm, clang, openmp
533- // or test-suite, but are used in external projects e.g. libstdcxx
534- static bool isCpuIdSupported() {
535- #if defined(__GNUC__) || defined(__clang__)
536- #if defined(__i386__)
537- int __cpuid_supported;
538- __asm__ (" pushfl\n "
539- " popl %%eax\n "
540- " movl %%eax,%%ecx\n "
541- " xorl $0x00200000,%%eax\n "
542- " pushl %%eax\n "
543- " popfl\n "
544- " pushfl\n "
545- " popl %%eax\n "
546- " movl $0,%0\n "
547- " cmpl %%eax,%%ecx\n "
548- " je 1f\n "
549- " movl $1,%0\n "
550- " 1:"
551- : " =r" (__cpuid_supported)
552- :
553- : " eax" , " ecx" );
554- if (!__cpuid_supported)
555- return false ;
556- #endif
557- return true ;
558- #endif
559- return true ;
560- }
527+ #if defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || \
528+ defined (_M_X64)
561529
562530// / getX86CpuIDAndInfo - Execute the specified cpuid and return the 4 values in
563531// / the specified arguments. If we can't run cpuid on the host, return true.
564532static bool getX86CpuIDAndInfo(unsigned value, unsigned *rEAX, unsigned *rEBX,
565533 unsigned *rECX, unsigned *rEDX) {
566534#if defined(__GNUC__) || defined(__clang__)
567- #if defined(__x86_64__)
568- // gcc doesn't know cpuid would clobber ebx/rbx. Preserve it manually.
569- // FIXME: should we save this for Clang?
570- __asm__ (" movq\t %%rbx, %%rsi\n\t "
571- " cpuid\n\t "
572- " xchgq\t %%rbx, %%rsi\n\t "
573- : " =a" (*rEAX), " =S" (*rEBX), " =c" (*rECX), " =d" (*rEDX)
574- : " a" (value));
575- return false ;
576- #elif defined(__i386__)
577- __asm__ (" movl\t %%ebx, %%esi\n\t "
578- " cpuid\n\t "
579- " xchgl\t %%ebx, %%esi\n\t "
580- : " =a" (*rEAX), " =S" (*rEBX), " =c" (*rECX), " =d" (*rEDX)
581- : " a" (value));
582- return false ;
583- #else
584- return true ;
585- #endif
535+ return !__get_cpuid (value, rEAX, rEBX, rECX, rEDX);
586536#elif defined(_MSC_VER)
587537 // The MSVC intrinsic is portable across x86 and x64.
588538 int registers[4 ];
@@ -609,9 +559,6 @@ VendorSignatures getVendorSignature(unsigned *MaxLeaf) {
609559 else
610560 *MaxLeaf = 0 ;
611561
612- if (!isCpuIdSupported ())
613- return VendorSignatures::UNKNOWN;
614-
615562 if (getX86CpuIDAndInfo (0 , MaxLeaf, &EBX, &ECX, &EDX) || *MaxLeaf < 1 )
616563 return VendorSignatures::UNKNOWN;
617564
@@ -639,26 +586,12 @@ using namespace llvm::sys::detail::x86;
639586static bool getX86CpuIDAndInfoEx (unsigned value, unsigned subleaf,
640587 unsigned *rEAX, unsigned *rEBX, unsigned *rECX,
641588 unsigned *rEDX) {
589+ // TODO(boomanaiden154): When the minimum toolchain versions for gcc and clang
590+ // are such that __cpuidex is defined within cpuid.h for both, we can remove
591+ // the __get_cpuid_count function and share the MSVC implementation between
592+ // all three.
642593#if defined(__GNUC__) || defined(__clang__)
643- #if defined(__x86_64__)
644- // gcc doesn't know cpuid would clobber ebx/rbx. Preserve it manually.
645- // FIXME: should we save this for Clang?
646- __asm__ (" movq\t %%rbx, %%rsi\n\t "
647- " cpuid\n\t "
648- " xchgq\t %%rbx, %%rsi\n\t "
649- : " =a" (*rEAX), " =S" (*rEBX), " =c" (*rECX), " =d" (*rEDX)
650- : " a" (value), " c" (subleaf));
651- return false ;
652- #elif defined(__i386__)
653- __asm__ (" movl\t %%ebx, %%esi\n\t "
654- " cpuid\n\t "
655- " xchgl\t %%ebx, %%esi\n\t "
656- : " =a" (*rEAX), " =S" (*rEBX), " =c" (*rECX), " =d" (*rEDX)
657- : " a" (value), " c" (subleaf));
658- return false ;
659- #else
660- return true ;
661- #endif
594+ return !__get_cpuid_count (value, subleaf, rEAX, rEBX, rECX, rEDX);
662595#elif defined(_MSC_VER)
663596 int registers[4 ];
664597 __cpuidex (registers, value, subleaf);
@@ -674,6 +607,9 @@ static bool getX86CpuIDAndInfoEx(unsigned value, unsigned subleaf,
674607
675608// Read control register 0 (XCR0). Used to detect features such as AVX.
676609static bool getX86XCR0 (unsigned *rEAX, unsigned *rEDX) {
610+ // TODO(boomanaiden154): When the minimum toolchain versions for gcc and clang
611+ // are such that _xgetbv is supported by both, we can unify the implementation
612+ // with MSVC and remove all inline assembly.
677613#if defined(__GNUC__) || defined(__clang__)
678614 // Check xgetbv; this uses a .byte sequence instead of the instruction
679615 // directly because older assemblers do not include support for xgetbv and
0 commit comments