endif()
set(CMAKE_REQUIRED_DEFINITIONS)
+#
+# Check for x86 __cpuid / __cpuid_count support: GNU extensions
+# gcc/clang and MSVC have __cpuid, so check __cpuid_count instead
+check_symbol_exists(__cpuid_count cpuid.h HAVE_CPUID_GNU)
+if(HAVE_CPUID_GNU)
+ add_definitions(-DHAVE_CPUID_GNU)
+endif()
+set(CMAKE_REQUIRED_DEFINITIONS)
+
+#
+# Check for x86 __cpuid / __cpuidex support: MSVC extensions
+# gcc/clang and MSVC have __cpuid, so check __cpuidex instead
+# check_symbol_exists() does not work for intrinsics
+
+check_c_source_compiles(
+"
+#include <intrin.h>
+static inline void cpuid_ms(int info, unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx) {
+ unsigned int registers[4];
+ __cpuid((int *)registers, info);
+ *eax = registers[0];
+ *ebx = registers[1];
+ *ecx = registers[2];
+ *edx = registers[3];
+}
+
+int main(void) {
+ unsigned int eax, ebx, ecx, edx;
+ cpuid_ms(0, &eax, &ebx, &ecx, &edx);
+ return eax;
+}"
+HAVE_CPUID_MS)
+
+if(HAVE_CPUID_MS)
+ add_definitions(-DHAVE_CPUID_MS)
+endif()
+set(CMAKE_REQUIRED_DEFINITIONS)
+
#
# Check whether a sanitizer was requested
#
#include "zbuild.h"
#include "x86_features.h"
-#ifdef _MSC_VER
-# include <intrin.h>
-#else
+
+#if defined(HAVE_CPUID_MS)
+# include <intrin.h>
+#elif defined(HAVE_CPUID_GNU)
// Newer versions of GCC and clang come with cpuid.h
# include <cpuid.h>
# ifdef X86_HAVE_XSAVE_INTRIN
#include <string.h>
static inline void cpuid(int info, unsigned* eax, unsigned* ebx, unsigned* ecx, unsigned* edx) {
-#ifdef _MSC_VER
+#if defined(HAVE_CPUID_MS)
unsigned int registers[4];
__cpuid((int *)registers, info);
*ebx = registers[1];
*ecx = registers[2];
*edx = registers[3];
-#else
+#elif defined(HAVE_CPUID_GNU)
*eax = *ebx = *ecx = *edx = 0;
__cpuid(info, *eax, *ebx, *ecx, *edx);
+#else
+ /* When using this fallback, the faster SSE/AVX code is disabled */
+ *eax = *ebx = *ecx = *edx = 0;
#endif
}
static inline void cpuidex(int info, int subinfo, unsigned* eax, unsigned* ebx, unsigned* ecx, unsigned* edx) {
-#ifdef _MSC_VER
+#if defined(HAVE_CPUID_MS)
unsigned int registers[4];
__cpuidex((int *)registers, info, subinfo);
*ebx = registers[1];
*ecx = registers[2];
*edx = registers[3];
-#else
+#elif defined(HAVE_CPUID_GNU)
*eax = *ebx = *ecx = *edx = 0;
__cpuid_count(info, subinfo, *eax, *ebx, *ecx, *edx);
+#else
+ /* When using this fallback, the faster SSE/AVX code is disabled */
+ *eax = *ebx = *ecx = *edx = 0;
#endif
}
static inline uint64_t xgetbv(unsigned int xcr) {
#if defined(_MSC_VER) || defined(X86_HAVE_XSAVE_INTRIN)
return _xgetbv(xcr);
-#else
+#elif defined(__GNUC__)
uint32_t eax, edx;
__asm__ ( ".byte 0x0f, 0x01, 0xd0" : "=a"(eax), "=d"(edx) : "c"(xcr));
return (uint64_t)(edx) << 32 | eax;
+#else
+ /* When using this fallback, some of the faster code is disabled */
+ return 0;
#endif
}
echo >> configure.log
+# check for cpuid support: GNU extensions
+cat > $test.c <<EOF
+#include <cpuid.h>
+#include <stdio.h>
+static inline void cpuid_gnu(int info, unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx) {
+ *eax = *ebx = *ecx = *edx = 0;
+ __cpuid(info, *eax, *ebx, *ecx, *edx);
+}
+
+int main(void) {
+ unsigned int eax, ebx, ecx, edx;
+ cpuid_gnu(0, &eax, &ebx, &ecx, &edx);
+ printf("%d\n", eax);
+ return eax;
+}
+EOF
+if try $CC $CFLAGS -o $test $test.c $LDSHAREDLIBC; then
+ echo "Checking for GNU style __cpuid... Yes." | tee -a configure.log
+ CFLAGS="${CFLAGS} -DHAVE_CPUID_GNU"
+ SFLAGS="${SFLAGS} -DHAVE_CPUID_GNU"
+else
+ echo "Checking for GNU style __cpuid... No." | tee -a configure.log
+fi
+echo >> configure.log
+
+# check for cpuid support: MSVC extensions
+cat > $test.c <<EOF
+#include <intrin.h>
+#include <stdio.h>
+static inline void cpuid_ms(int info, unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx) {
+ unsigned int registers[4];
+ __cpuid((int *)registers, info);
+ *eax = registers[0];
+ *ebx = registers[1];
+ *ecx = registers[2];
+ *edx = registers[3];
+}
+
+int main(void) {
+ unsigned int eax, ebx, ecx, edx;
+ cpuid_ms(0, &eax, &ebx, &ecx, &edx);
+ printf("%d\n", eax);
+ return 0;
+}
+EOF
+if try $CC $CFLAGS -o $test $test.c $LDSHAREDLIBC; then
+ echo "Checking for MS style __cpuid... Yes." | tee -a configure.log
+ CFLAGS="${CFLAGS} -DHAVE_CPUID_MS"
+ SFLAGS="${SFLAGS} -DHAVE_CPUID_MS"
+else
+ echo "Checking for MS style __cpuid... No." | tee -a configure.log
+fi
+echo >> configure.log
+
+
# check for strerror() for use by gz* functions
cat > $test.c <<EOF
#include <string.h>