target/i386: add CPUID feature checks to new decoder
Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
268dc4648f
commit
caa01fadbe
@ -85,6 +85,7 @@
|
||||
#define X86_OP_ENTRY0(op, ...) \
|
||||
X86_OP_ENTRY3(op, None, None, None, None, None, None, ## __VA_ARGS__)
|
||||
|
||||
#define cpuid(feat) .cpuid = X86_FEAT_##feat,
|
||||
#define i64 .special = X86_SPECIAL_i64,
|
||||
#define o64 .special = X86_SPECIAL_o64,
|
||||
#define xchg .special = X86_SPECIAL_Locked,
|
||||
@ -513,6 +514,56 @@ static bool decode_insn(DisasContext *s, CPUX86State *env, X86DecodeFunc decode_
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool has_cpuid_feature(DisasContext *s, X86CPUIDFeature cpuid)
|
||||
{
|
||||
switch (cpuid) {
|
||||
case X86_FEAT_None:
|
||||
return true;
|
||||
case X86_FEAT_MOVBE:
|
||||
return (s->cpuid_ext_features & CPUID_EXT_MOVBE);
|
||||
case X86_FEAT_PCLMULQDQ:
|
||||
return (s->cpuid_ext_features & CPUID_EXT_PCLMULQDQ);
|
||||
case X86_FEAT_SSE:
|
||||
return (s->cpuid_ext_features & CPUID_SSE);
|
||||
case X86_FEAT_SSE2:
|
||||
return (s->cpuid_ext_features & CPUID_SSE2);
|
||||
case X86_FEAT_SSE3:
|
||||
return (s->cpuid_ext_features & CPUID_EXT_SSE3);
|
||||
case X86_FEAT_SSSE3:
|
||||
return (s->cpuid_ext_features & CPUID_EXT_SSSE3);
|
||||
case X86_FEAT_SSE41:
|
||||
return (s->cpuid_ext_features & CPUID_EXT_SSE41);
|
||||
case X86_FEAT_SSE42:
|
||||
return (s->cpuid_ext_features & CPUID_EXT_SSE42);
|
||||
case X86_FEAT_AES:
|
||||
if (!(s->cpuid_ext_features & CPUID_EXT_AES)) {
|
||||
return false;
|
||||
} else if (!(s->prefix & PREFIX_VEX)) {
|
||||
return true;
|
||||
} else if (!(s->cpuid_ext_features & CPUID_EXT_AVX)) {
|
||||
return false;
|
||||
} else {
|
||||
return !s->vex_l || (s->cpuid_7_0_ecx_features & CPUID_7_0_ECX_VAES);
|
||||
}
|
||||
|
||||
case X86_FEAT_AVX:
|
||||
return (s->cpuid_ext_features & CPUID_EXT_AVX);
|
||||
|
||||
case X86_FEAT_SSE4A:
|
||||
return (s->cpuid_ext3_features & CPUID_EXT3_SSE4A);
|
||||
|
||||
case X86_FEAT_ADX:
|
||||
return (s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_ADX);
|
||||
case X86_FEAT_BMI1:
|
||||
return (s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1);
|
||||
case X86_FEAT_BMI2:
|
||||
return (s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2);
|
||||
case X86_FEAT_AVX2:
|
||||
return (s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_AVX2);
|
||||
}
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
static void decode_temp_free(X86DecodedOp *op)
|
||||
{
|
||||
if (op->v_ptr) {
|
||||
@ -701,6 +752,10 @@ static void disas_insn_new(DisasContext *s, CPUState *cpu, int b)
|
||||
goto unknown_op;
|
||||
}
|
||||
|
||||
if (!has_cpuid_feature(s, decode.e.cpuid)) {
|
||||
goto illegal_op;
|
||||
}
|
||||
|
||||
switch (decode.e.special) {
|
||||
case X86_SPECIAL_None:
|
||||
break;
|
||||
|
@ -93,6 +93,25 @@ typedef enum X86OpSize {
|
||||
X86_SIZE_f64,
|
||||
} X86OpSize;
|
||||
|
||||
typedef enum X86CPUIDFeature {
|
||||
X86_FEAT_None,
|
||||
X86_FEAT_ADX,
|
||||
X86_FEAT_AES,
|
||||
X86_FEAT_AVX,
|
||||
X86_FEAT_AVX2,
|
||||
X86_FEAT_BMI1,
|
||||
X86_FEAT_BMI2,
|
||||
X86_FEAT_MOVBE,
|
||||
X86_FEAT_PCLMULQDQ,
|
||||
X86_FEAT_SSE,
|
||||
X86_FEAT_SSE2,
|
||||
X86_FEAT_SSE3,
|
||||
X86_FEAT_SSSE3,
|
||||
X86_FEAT_SSE41,
|
||||
X86_FEAT_SSE42,
|
||||
X86_FEAT_SSE4A,
|
||||
} X86CPUIDFeature;
|
||||
|
||||
/* Execution flags */
|
||||
|
||||
typedef enum X86OpUnit {
|
||||
@ -160,6 +179,7 @@ struct X86OpEntry {
|
||||
X86OpSize s3:8;
|
||||
|
||||
X86InsnSpecial special:8;
|
||||
X86CPUIDFeature cpuid:8;
|
||||
bool is_decode:1;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user