mirror of https://github.com/xemu-project/xemu.git
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, ...) \
|
#define X86_OP_ENTRY0(op, ...) \
|
||||||
X86_OP_ENTRY3(op, None, None, None, None, None, None, ## __VA_ARGS__)
|
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 i64 .special = X86_SPECIAL_i64,
|
||||||
#define o64 .special = X86_SPECIAL_o64,
|
#define o64 .special = X86_SPECIAL_o64,
|
||||||
#define xchg .special = X86_SPECIAL_Locked,
|
#define xchg .special = X86_SPECIAL_Locked,
|
||||||
|
@ -513,6 +514,56 @@ static bool decode_insn(DisasContext *s, CPUX86State *env, X86DecodeFunc decode_
|
||||||
return true;
|
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)
|
static void decode_temp_free(X86DecodedOp *op)
|
||||||
{
|
{
|
||||||
if (op->v_ptr) {
|
if (op->v_ptr) {
|
||||||
|
@ -701,6 +752,10 @@ static void disas_insn_new(DisasContext *s, CPUState *cpu, int b)
|
||||||
goto unknown_op;
|
goto unknown_op;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!has_cpuid_feature(s, decode.e.cpuid)) {
|
||||||
|
goto illegal_op;
|
||||||
|
}
|
||||||
|
|
||||||
switch (decode.e.special) {
|
switch (decode.e.special) {
|
||||||
case X86_SPECIAL_None:
|
case X86_SPECIAL_None:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -93,6 +93,25 @@ typedef enum X86OpSize {
|
||||||
X86_SIZE_f64,
|
X86_SIZE_f64,
|
||||||
} X86OpSize;
|
} 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 */
|
/* Execution flags */
|
||||||
|
|
||||||
typedef enum X86OpUnit {
|
typedef enum X86OpUnit {
|
||||||
|
@ -160,6 +179,7 @@ struct X86OpEntry {
|
||||||
X86OpSize s3:8;
|
X86OpSize s3:8;
|
||||||
|
|
||||||
X86InsnSpecial special:8;
|
X86InsnSpecial special:8;
|
||||||
|
X86CPUIDFeature cpuid:8;
|
||||||
bool is_decode:1;
|
bool is_decode:1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue