# define CPUID1C_PCLMUL (1u << 1)
# define CPUID1C_SSSE3 (1u << 9)
# define CPUID1C_AESNI (1u << 25)
# define CPUID1C_PCLMUL (1u << 1)
# define CPUID1C_SSSE3 (1u << 9)
# define CPUID1C_AESNI (1u << 25)
};
struct cpuid { unsigned a, b, c, d; };
};
struct cpuid { unsigned a, b, c, d; };
extern int dispatch_x86ish_cpuid(struct cpuid *, unsigned a, unsigned c);
extern int dispatch_x86ish_xmmregisters_p(void);
extern int dispatch_x86ish_cpuid(struct cpuid *, unsigned a, unsigned c);
extern int dispatch_x86ish_xmmregisters_p(void);
if (cpuid_maxleaf() < 1) return (0);
cpuid(&c, 1, 0); r = c.c;
break;
if (cpuid_maxleaf() < 1) return (0);
cpuid(&c, 1, 0); r = c.c;
break;
+static int ymm_registers_available_p(void)
+{
+ struct xcr xcr0;
+ int f;
+
+ f = cpuid_feature_p(CPUID_1_C, CPUID1C_OSXSAVE);
+ dispatch_debug("XGETBV %savailable", f ? "" : "not ");
+ if (!f) return (0);
+
+ dispatch_x86ish_xgetbv(&xcr0, 0); f = (xcr0.lo&0x06) == 0x06;
+ dispatch_debug("YMM state %senabled", f ? "" : "not ");
+ if (!f) return (0);
+
+ return (1);
+}
+
/* Check that it doesn't always give the same answer. Try four times: this
* will fail with probability %$2^{-128}$% with a truly random generator,
* which seems fair enough.
*/
/* Check that it doesn't always give the same answer. Try four times: this
* will fail with probability %$2^{-128}$% with a truly random generator,
* which seems fair enough.
*/
cpuid_feature_p(CPUID_1_D, CPUID1D_SSE2) &&
xmm_registers_available_p());
CASE_CPUFEAT(X86_AESNI, "x86:aesni",
cpuid_feature_p(CPUID_1_D, CPUID1D_SSE2) &&
xmm_registers_available_p());
CASE_CPUFEAT(X86_AESNI, "x86:aesni",
xmm_registers_available_p());
CASE_CPUFEAT(X86_RDRAND, "x86:rdrand",
cpuid_feature_p(CPUID_1_C, CPUID1C_RDRAND) &&
xmm_registers_available_p());
CASE_CPUFEAT(X86_RDRAND, "x86:rdrand",
cpuid_feature_p(CPUID_1_C, CPUID1C_RDRAND) &&
CASE_CPUFEAT(X86_AVX, "x86:avx",
cpuid_feature_p(CPUID_1_C, CPUID1C_AVX) &&
CASE_CPUFEAT(X86_AVX, "x86:avx",
cpuid_feature_p(CPUID_1_C, CPUID1C_AVX) &&
- xmm_registers_available_p());
+ ymm_registers_available_p());
+ CASE_CPUFEAT(X86_AVX2, "x86:avx2",
+ cpuid_feature_p(CPUID_1_C, CPUID1C_AVX) &&
+ cpuid_feature_p(CPUID_7_0_B, CPUID70B_AVX2) &&
+ ymm_registers_available_p());
CASE_CPUFEAT(X86_SSSE3, "x86:ssse3",
cpuid_feature_p(CPUID_1_C, CPUID1C_SSSE3) &&
xmm_registers_available_p());
CASE_CPUFEAT(X86_PCLMUL, "x86:pclmul",
cpuid_feature_p(CPUID_1_C, CPUID1C_PCLMUL) &&
xmm_registers_available_p());
CASE_CPUFEAT(X86_SSSE3, "x86:ssse3",
cpuid_feature_p(CPUID_1_C, CPUID1C_SSSE3) &&
xmm_registers_available_p());
CASE_CPUFEAT(X86_PCLMUL, "x86:pclmul",
cpuid_feature_p(CPUID_1_C, CPUID1C_PCLMUL) &&
xmm_registers_available_p());
+ CASE_CPUFEAT(X86_RDSEED, "x86:rdseed",
+ cpuid_feature_p(CPUID_7_0_B, CPUID70B_RDSEED) &&
+ rdrand_works_p(OP_RDSEED));