Skip to content

Commit 192acfa

Browse files
committed
port: Use __cpuid only, when available.
Add a fallback, when __cpuid is not available
1 parent fd0d263 commit 192acfa

3 files changed

Lines changed: 98 additions & 8 deletions

File tree

CMakeLists.txt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,24 @@ if(HAVE__ALIGNED_MALLOC)
490490
endif()
491491
set(CMAKE_REQUIRED_DEFINITIONS)
492492

493+
#
494+
# Check for x86 __cpuid / __cpuid_count support: GNU extensions
495+
# gcc/clang and MSVC have __cpuid, so check __cpuid_count instead
496+
check_symbol_exists(__cpuid_count cpuid.h HAVE_CPUID_GNU)
497+
if(HAVE_CPUID_GNU)
498+
add_definitions(-DHAVE_CPUID_GNU)
499+
endif()
500+
set(CMAKE_REQUIRED_DEFINITIONS)
501+
502+
#
503+
# Check for x86 __cpuid / __cpuidex support: MSVC extensions
504+
# gcc/clang and MSVC have __cpuid, so check __cpuidex instead
505+
check_symbol_exists(__cpuidex intrin.h HAVE_CPUID_MS)
506+
if(HAVE_CPUID_MS)
507+
add_definitions(-DHAVE_CPUID_MS)
508+
endif()
509+
set(CMAKE_REQUIRED_DEFINITIONS)
510+
493511
#
494512
# Check whether a sanitizer was requested
495513
#

arch/x86/x86_features.c

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@
1010
#include "zbuild.h"
1111
#include "x86_features.h"
1212

13-
#ifdef _MSC_VER
14-
# include <intrin.h>
15-
#else
13+
14+
#if defined(HAVE_CPUID_MS)
15+
# include <intrin.h>
16+
#elif defined(HAVE_CPUID_GNU)
1617
// Newer versions of GCC and clang come with cpuid.h
1718
# include <cpuid.h>
1819
# ifdef X86_HAVE_XSAVE_INTRIN
@@ -27,42 +28,51 @@
2728
#include <string.h>
2829

2930
static inline void cpuid(int info, unsigned* eax, unsigned* ebx, unsigned* ecx, unsigned* edx) {
30-
#ifdef _MSC_VER
31+
#if defined(HAVE_CPUID_MS)
3132
unsigned int registers[4];
3233
__cpuid((int *)registers, info);
3334

3435
*eax = registers[0];
3536
*ebx = registers[1];
3637
*ecx = registers[2];
3738
*edx = registers[3];
38-
#else
39+
#elif defined(HAVE_CPUID_GNU)
3940
*eax = *ebx = *ecx = *edx = 0;
4041
__cpuid(info, *eax, *ebx, *ecx, *edx);
42+
#else
43+
/* When using this fallback, the faster SSE/AVX code is disabled */
44+
*eax = *ebx = *ecx = *edx = 0;
4145
#endif
4246
}
4347

4448
static inline void cpuidex(int info, int subinfo, unsigned* eax, unsigned* ebx, unsigned* ecx, unsigned* edx) {
45-
#ifdef _MSC_VER
49+
#if defined(HAVE_CPUID_MS)
4650
unsigned int registers[4];
4751
__cpuidex((int *)registers, info, subinfo);
4852

4953
*eax = registers[0];
5054
*ebx = registers[1];
5155
*ecx = registers[2];
5256
*edx = registers[3];
53-
#else
57+
#elif defined(HAVE_CPUID_GNU)
5458
*eax = *ebx = *ecx = *edx = 0;
5559
__cpuid_count(info, subinfo, *eax, *ebx, *ecx, *edx);
60+
#else
61+
/* When using this fallback, the faster SSE/AVX code is disabled */
62+
*eax = *ebx = *ecx = *edx = 0;
5663
#endif
5764
}
5865

5966
static inline uint64_t xgetbv(unsigned int xcr) {
6067
#if defined(_MSC_VER) || defined(X86_HAVE_XSAVE_INTRIN)
6168
return _xgetbv(xcr);
62-
#else
69+
#elif defined(__GNUC__)
6370
uint32_t eax, edx;
6471
__asm__ ( ".byte 0x0f, 0x01, 0xd0" : "=a"(eax), "=d"(edx) : "c"(xcr));
6572
return (uint64_t)(edx) << 32 | eax;
73+
#else
74+
/* When using this fallback, some of the faster code is disabled */
75+
return 0;
6676
#endif
6777
}
6878

configure

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -807,6 +807,68 @@ fi
807807
echo >> configure.log
808808

809809

810+
# #####################################################
811+
812+
813+
# check for cpuid support: GNU extensions
814+
cat > $test.c <<EOF
815+
#include <cpuid.h>
816+
#include <stdio.h>
817+
static inline void cpuid_gnu(int info, unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx) {
818+
*eax = *ebx = *ecx = *edx = 0;
819+
__cpuid(info, *eax, *ebx, *ecx, *edx);
820+
}
821+
822+
int main(void) {
823+
unsigned int eax, ebx, ecx, edx;
824+
cpuid_gnu(0, &eax, &ebx, &ecx, &edx);
825+
printf("%d\n", eax);
826+
return eax;
827+
}
828+
EOF
829+
if try $CC $CFLAGS -o $test $test.c $LDSHAREDLIBC; then
830+
echo "Checking for GNU style __cpuid... Yes." | tee -a configure.log
831+
CFLAGS="${CFLAGS} -DHAVE_CPUID_GNU"
832+
SFLAGS="${SFLAGS} -DHAVE_CPUID_GNU"
833+
else
834+
echo "Checking for GNU style __cpuid... No." | tee -a configure.log
835+
fi
836+
echo >> configure.log
837+
838+
# check for cpuid support: MSVC extensions
839+
cat > $test.c <<EOF
840+
#include <intrin.h>
841+
#include <stdio.h>
842+
static inline void cpuid_ms(int info, unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx) {
843+
unsigned int registers[4];
844+
__cpuid((int *)registers, info);
845+
*eax = registers[0];
846+
*ebx = registers[1];
847+
*ecx = registers[2];
848+
*edx = registers[3];
849+
}
850+
851+
int main(void) {
852+
unsigned int eax, ebx, ecx, edx;
853+
cpuid_ms(0, &eax, &ebx, &ecx, &edx);
854+
printf("%d\n", eax);
855+
return 0;
856+
}
857+
EOF
858+
if try $CC $CFLAGS -o $test $test.c $LDSHAREDLIBC; then
859+
echo "Checking for MS style __cpuid... Yes." | tee -a configure.log
860+
CFLAGS="${CFLAGS} -DHAVE_CPUID_MS"
861+
SFLAGS="${SFLAGS} -DHAVE_CPUID_MS"
862+
else
863+
echo "Checking for MS style __cpuid... No." | tee -a configure.log
864+
fi
865+
echo >> configure.log
866+
867+
868+
869+
# #####################################################
870+
871+
810872
# check for strerror() for use by gz* functions
811873
cat > $test.c <<EOF
812874
#include <string.h>

0 commit comments

Comments
 (0)