tcg/i386: Detect AVX512
There are some operation sizes in some subsets of AVX512 that are missing from previous iterations of AVX. Detect them. Tested-by: Alex Bennée <alex.bennee@linaro.org> Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
21eab5bfae
commit
ba597b66d9
@ -45,12 +45,26 @@
|
||||
#ifndef bit_AVX2
|
||||
#define bit_AVX2 (1 << 5)
|
||||
#endif
|
||||
#ifndef bit_AVX512F
|
||||
#define bit_AVX512F (1 << 16)
|
||||
#endif
|
||||
#ifndef bit_BMI2
|
||||
#define bit_BMI2 (1 << 8)
|
||||
#endif
|
||||
#ifndef bit_AVX512F
|
||||
#define bit_AVX512F (1 << 16)
|
||||
#endif
|
||||
#ifndef bit_AVX512DQ
|
||||
#define bit_AVX512DQ (1 << 17)
|
||||
#endif
|
||||
#ifndef bit_AVX512BW
|
||||
#define bit_AVX512BW (1 << 30)
|
||||
#endif
|
||||
#ifndef bit_AVX512VL
|
||||
#define bit_AVX512VL (1u << 31)
|
||||
#endif
|
||||
|
||||
/* Leaf 7, %ecx */
|
||||
#ifndef bit_AVX512VBMI2
|
||||
#define bit_AVX512VBMI2 (1 << 6)
|
||||
#endif
|
||||
|
||||
/* Leaf 0x80000001, %ecx */
|
||||
#ifndef bit_LZCNT
|
||||
|
@ -171,6 +171,10 @@ bool have_bmi1;
|
||||
bool have_popcnt;
|
||||
bool have_avx1;
|
||||
bool have_avx2;
|
||||
bool have_avx512bw;
|
||||
bool have_avx512dq;
|
||||
bool have_avx512vbmi2;
|
||||
bool have_avx512vl;
|
||||
bool have_movbe;
|
||||
|
||||
#ifdef CONFIG_CPUID_H
|
||||
@ -3839,12 +3843,12 @@ static void tcg_out_nop_fill(tcg_insn_unit *p, int count)
|
||||
static void tcg_target_init(TCGContext *s)
|
||||
{
|
||||
#ifdef CONFIG_CPUID_H
|
||||
unsigned a, b, c, d, b7 = 0;
|
||||
unsigned a, b, c, d, b7 = 0, c7 = 0;
|
||||
unsigned max = __get_cpuid_max(0, 0);
|
||||
|
||||
if (max >= 7) {
|
||||
/* BMI1 is available on AMD Piledriver and Intel Haswell CPUs. */
|
||||
__cpuid_count(7, 0, a, b7, c, d);
|
||||
__cpuid_count(7, 0, a, b7, c7, d);
|
||||
have_bmi1 = (b7 & bit_BMI) != 0;
|
||||
have_bmi2 = (b7 & bit_BMI2) != 0;
|
||||
}
|
||||
@ -3874,6 +3878,22 @@ static void tcg_target_init(TCGContext *s)
|
||||
if ((xcrl & 6) == 6) {
|
||||
have_avx1 = (c & bit_AVX) != 0;
|
||||
have_avx2 = (b7 & bit_AVX2) != 0;
|
||||
|
||||
/*
|
||||
* There are interesting instructions in AVX512, so long
|
||||
* as we have AVX512VL, which indicates support for EVEX
|
||||
* on sizes smaller than 512 bits. We are required to
|
||||
* check that OPMASK and all extended ZMM state are enabled
|
||||
* even if we're not using them -- the insns will fault.
|
||||
*/
|
||||
if ((xcrl & 0xe0) == 0xe0
|
||||
&& (b7 & bit_AVX512F)
|
||||
&& (b7 & bit_AVX512VL)) {
|
||||
have_avx512vl = true;
|
||||
have_avx512bw = (b7 & bit_AVX512BW) != 0;
|
||||
have_avx512dq = (b7 & bit_AVX512DQ) != 0;
|
||||
have_avx512vbmi2 = (c7 & bit_AVX512VBMI2) != 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -103,6 +103,10 @@ extern bool have_bmi1;
|
||||
extern bool have_popcnt;
|
||||
extern bool have_avx1;
|
||||
extern bool have_avx2;
|
||||
extern bool have_avx512bw;
|
||||
extern bool have_avx512dq;
|
||||
extern bool have_avx512vbmi2;
|
||||
extern bool have_avx512vl;
|
||||
extern bool have_movbe;
|
||||
|
||||
/* optional instructions */
|
||||
|
Loading…
Reference in New Issue
Block a user