1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
|
AC_DEFUN([AX_CPUID_NON_INTEL],
[AC_REQUIRE([AC_PROG_CC])
AC_LANG_PUSH([C])
# Test for SSE2 support
AC_MSG_CHECKING(for sse2 support)
AC_RUN_IFELSE(
[AC_LANG_PROGRAM([[#include <stdint.h>
static void run_cpuid (uint32_t eax, uint32_t ecx, uint32_t *abcd) {
uint32_t ebx, edx;
__asm__ ("cpuid" : "+b" (ebx), "+a" (eax), "+c" (ecx), "=d" (edx));
abcd[0] = eax; abcd[1] = ebx; abcd[2] = ecx; abcd[3] = edx;}]],
[[uint32_t abcd[4];
uint32_t sse2_mask = (1 << 26);
run_cpuid(1, 0, abcd);
return ((abcd[/*EDX*/3] & sse2_mask) == sse2_mask) ? 0 : 9;]])],
[AC_MSG_RESULT(yes)
ax_cv_cpu_has_sse2_ext=yes],
[AC_MSG_RESULT(no)])
# Test for SSSE3 support
AC_MSG_CHECKING(for ssse3 support)
AC_RUN_IFELSE(
[AC_LANG_PROGRAM([[#include <stdint.h>
static void run_cpuid (uint32_t eax, uint32_t ecx, uint32_t *abcd) {
uint32_t ebx, edx;
__asm__ ("cpuid" : "+b" (ebx), "+a" (eax), "+c" (ecx), "=d" (edx));
abcd[0] = eax; abcd[1] = ebx; abcd[2] = ecx; abcd[3] = edx;}]],
[[uint32_t abcd[4];
uint32_t ssse3_mask = (1 << 9);
run_cpuid(1, 0, abcd);
return ((abcd[/*ECX*/2] & ssse3_mask) == ssse3_mask) ? 0 : 9;]])],
[AC_MSG_RESULT(yes)
ax_cv_cpu_has_ssse3_ext=yes],
[AC_MSG_RESULT(no)])
# Test for SSE4.1 support
AC_MSG_CHECKING(for sse4.1 support)
AC_RUN_IFELSE(
[AC_LANG_PROGRAM([[#include <stdint.h>
static void run_cpuid (uint32_t eax, uint32_t ecx, uint32_t *abcd) {
uint32_t ebx, edx;
__asm__ ("cpuid" : "+b" (ebx), "+a" (eax), "+c" (ecx), "=d" (edx));
abcd[0] = eax; abcd[1] = ebx; abcd[2] = ecx; abcd[3] = edx;}]],
[[uint32_t abcd[4];
uint32_t sse4_1_mask = (1 << 19);
run_cpuid(1, 0, abcd);
return ((abcd[/*ECX*/2] & sse4_1_mask) == sse4_1_mask) ? 0 : 9;]])],
[AC_MSG_RESULT(yes)
ax_cv_cpu_has_sse41_ext=yes],
[AC_MSG_RESULT(no)])
# Test for SSE4.2 support
AC_MSG_CHECKING(for sse4.2 support)
AC_RUN_IFELSE(
[AC_LANG_PROGRAM([[#include <stdint.h>
static void run_cpuid (uint32_t eax, uint32_t ecx, uint32_t *abcd) {
uint32_t ebx, edx;
__asm__ ("cpuid" : "+b" (ebx), "+a" (eax), "+c" (ecx), "=d" (edx));
abcd[0] = eax; abcd[1] = ebx; abcd[2] = ecx; abcd[3] = edx;}]],
[[uint32_t abcd[4];
uint32_t sse4_2_mask = (1 << 20);
run_cpuid(1, 0, abcd);
return ((abcd[/*ECX*/2] & sse4_2_mask) == sse4_2_mask) ? 0 : 9;]])],
[AC_MSG_RESULT(yes)
ax_cv_cpu_has_sse42_ext=yes],
[AC_MSG_RESULT(no)])
# Test for popcnt support
AC_MSG_CHECKING(for popcnt support)
AC_RUN_IFELSE(
[AC_LANG_PROGRAM([[#include <stdint.h>
static void run_cpuid (uint32_t eax, uint32_t ecx, uint32_t *abcd) {
uint32_t ebx, edx;
__asm__ ("cpuid" : "+b" (ebx), "+a" (eax), "+c" (ecx), "=d" (edx));
abcd[0] = eax; abcd[1] = ebx; abcd[2] = ecx; abcd[3] = edx;}]],
[[uint32_t abcd[4];
uint32_t popcnt_mask = (1 << 23);
run_cpuid(1, 0, abcd);
return ((abcd[/*ECX*/2] & popcnt_mask) == popcnt_mask) ? 0 : 9;]])],
[AC_MSG_RESULT(yes)
ax_cv_cpu_has_popcnt_ext=yes],
[AC_MSG_RESULT(no)])
# Test for bmi1 support
AC_MSG_CHECKING(for bmi1 support)
AC_RUN_IFELSE(
[AC_LANG_PROGRAM([[#include <stdint.h>
static void run_cpuid (uint32_t eax, uint32_t ecx, uint32_t *abcd) {
uint32_t ebx, edx;
__asm__ ("cpuid" : "+b" (ebx), "+a" (eax), "+c" (ecx), "=d" (edx));
abcd[0] = eax; abcd[1] = ebx; abcd[2] = ecx; abcd[3] = edx;}]],
[[uint32_t abcd[4];
uint32_t bmi1_mask = (1 << 3);
run_cpuid(1, 0, abcd);
return ((abcd[/*EBX*/1] & bmi1_mask) == bmi1_mask) ? 0 : 9;]])],
[AC_MSG_RESULT(yes)
ax_cv_cpu_has_bmi1_ext=yes],
[AC_MSG_RESULT(no)])
# Test for AVX2 support
AC_MSG_CHECKING(for avx2 support)
AC_RUN_IFELSE(
[AC_LANG_PROGRAM([[#include <stdint.h>
static void run_cpuid (uint32_t eax, uint32_t ecx, uint32_t *abcd) {
uint32_t ebx, edx;
__asm__ ("cpuid" : "+b" (ebx), "+a" (eax), "+c" (ecx), "=d" (edx));
abcd[0] = eax; abcd[1] = ebx; abcd[2] = ecx; abcd[3] = edx;}
static int check_xcr0_ymm () {
uint32_t xcr0;
__asm__ ("xgetbv" : "=a" (xcr0) : "c" (0) : "%edx");
return ((xcr0 & 6) == 6);}]],
[[uint32_t abcd[4];
uint32_t fma_movbe_osxsave_mask = ((1 << 12) | (1 << 22) | (1 << 27));
uint32_t avx2_bmi12_mask = ((1 << 5) | (1 << 3) | (1 << 8));
uint32_t lzcnt_mask = (1 << 5);
run_cpuid(1, 0, abcd);
if ((abcd[/*ECX*/2] & fma_movbe_osxsave_mask) != fma_movbe_osxsave_mask) {
return 9;
} else if (!check_xcr0_ymm()) {
return 8;
} else {
run_cpuid(7, 0, abcd);
if ((abcd[/*EBX*/1] & avx2_bmi12_mask) != avx2_bmi12_mask) {
return 7;
} else {
run_cpuid(0x80000001, 0, abcd);
if ((abcd[/*ECX*/2] & lzcnt_mask) != lzcnt_mask) {
return 6;
} else {
return 0;
}
}
}]])],
[AC_MSG_RESULT(yes)
ax_cv_cpu_has_avx2_ext=yes],
[AC_MSG_RESULT(no)])
# Test for bmi2 support
AC_MSG_CHECKING(for bmi2 support)
AC_RUN_IFELSE(
[AC_LANG_PROGRAM([[#include <stdint.h>
static void run_cpuid (uint32_t eax, uint32_t ecx, uint32_t *abcd) {
uint32_t ebx, edx;
__asm__ ("cpuid" : "+b" (ebx), "+a" (eax), "+c" (ecx), "=d" (edx));
abcd[0] = eax; abcd[1] = ebx; abcd[2] = ecx; abcd[3] = edx;}]],
[[uint32_t abcd[4];
uint32_t bmi2_mask = (1 << 8);
run_cpuid(1, 0, abcd);
return ((abcd[/*EBX*/1] & bmi2_mask) == bmi2_mask) ? 0 : 9;]])],
[AC_MSG_RESULT(yes)
ax_cv_cpu_has_bmi2_ext=yes],
[AC_MSG_RESULT(no)])
# Test for AVX512 support
AC_MSG_CHECKING(for avx512 support)
AC_RUN_IFELSE(
[AC_LANG_PROGRAM([[#include <stdint.h>
static void run_cpuid (uint32_t eax, uint32_t ecx, uint32_t *abcd) {
uint32_t ebx, edx;
__asm__ ("cpuid" : "+b" (ebx), "+a" (eax), "+c" (ecx), "=d" (edx));
abcd[0] = eax; abcd[1] = ebx; abcd[2] = ecx; abcd[3] = edx;}
static int check_xcr0_zmm () {
uint32_t xcr0;
uint32_t zmm_ymm_xmm = ((7 << 5) | (1 << 2) | (1 << 1));
__asm__ ("xgetbv" : "=a" (xcr0) : "c" (0) : "%edx");
return ((xcr0 & zmm_ymm_xmm) == zmm_ymm_xmm);}]],
[[uint32_t abcd[4];
uint32_t osxsave_mask = (1 << 27);
uint32_t avx512_mask = (/*512F*/(1 << 16) | /*512CD*/(1 << 28));
run_cpuid(1, 0, abcd);
if ((abcd[/*ECX*/2] & osxsave_mask) != osxsave_mask) {
return 9;
} else if (!check_xcr0_zmm()) {
return 8;
} else if ((abcd[/*EBX*/1] & avx512_mask) != avx512_mask) {
return 0; /* Should fail here, but book/Web examples skip */
} else {
return 0;
}]])],
[AC_MSG_RESULT(yes)
ax_cv_cpu_has_avx512_ext=yes],
[AC_MSG_RESULT(no)])
AC_LANG_POP([C])
])
|