50
50
#if defined(__sun__) && defined(__svr4__)
51
51
#include < kstat.h>
52
52
#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
53
58
54
59
#define DEBUG_TYPE " host-detection"
55
60
@@ -522,68 +527,15 @@ StringRef sys::detail::getHostCPUNameForBPF() {
522
527
#endif
523
528
}
524
529
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)
562
532
563
533
// / getX86CpuIDAndInfo - Execute the specified cpuid and return the 4 values in
564
534
// / the specified arguments. If we can't run cpuid on the host, return true.
565
535
static bool getX86CpuIDAndInfo(unsigned value, unsigned *rEAX, unsigned *rEBX,
566
536
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);
587
539
#elif defined(_MSC_VER)
588
540
// The MSVC intrinsic is portable across x86 and x64.
589
541
int registers[4 ];
@@ -610,9 +562,6 @@ VendorSignatures getVendorSignature(unsigned *MaxLeaf) {
610
562
else
611
563
*MaxLeaf = 0 ;
612
564
613
- if (!isCpuIdSupported ())
614
- return VendorSignatures::UNKNOWN;
615
-
616
565
if (getX86CpuIDAndInfo (0 , MaxLeaf, &EBX, &ECX, &EDX) || *MaxLeaf < 1 )
617
566
return VendorSignatures::UNKNOWN;
618
567
@@ -640,26 +589,12 @@ using namespace llvm::sys::detail::x86;
640
589
static bool getX86CpuIDAndInfoEx (unsigned value, unsigned subleaf,
641
590
unsigned *rEAX, unsigned *rEBX, unsigned *rECX,
642
591
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);
663
598
#elif defined(_MSC_VER)
664
599
int registers[4 ];
665
600
__cpuidex (registers, value, subleaf);
@@ -675,6 +610,9 @@ static bool getX86CpuIDAndInfoEx(unsigned value, unsigned subleaf,
675
610
676
611
// Read control register 0 (XCR0). Used to detect features such as AVX.
677
612
static 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.
678
616
#if defined(__GNUC__) || defined(__clang__)
679
617
// Check xgetbv; this uses a .byte sequence instead of the instruction
680
618
// directly because older assemblers do not include support for xgetbv and
0 commit comments