diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2022-09-01 14:51:35 +0200 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2022-10-18 13:58:04 +0200 |
commit | caa01fadbef15f0e2a5ac7bfc7372a4b4244687f (patch) | |
tree | be229fa1bc223fbe59a28547250700893fccdb3d /target | |
parent | 268dc4648fd7b3e48de93d43397dd8478ebbd02d (diff) | |
download | qemu-caa01fadbef15f0e2a5ac7bfc7372a4b4244687f.zip qemu-caa01fadbef15f0e2a5ac7bfc7372a4b4244687f.tar.gz qemu-caa01fadbef15f0e2a5ac7bfc7372a4b4244687f.tar.bz2 |
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>
Diffstat (limited to 'target')
-rw-r--r-- | target/i386/tcg/decode-new.c.inc | 55 | ||||
-rw-r--r-- | target/i386/tcg/decode-new.h | 20 |
2 files changed, 75 insertions, 0 deletions
diff --git a/target/i386/tcg/decode-new.c.inc b/target/i386/tcg/decode-new.c.inc index 37e7669..9afc26b 100644 --- a/target/i386/tcg/decode-new.c.inc +++ b/target/i386/tcg/decode-new.c.inc @@ -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; diff --git a/target/i386/tcg/decode-new.h b/target/i386/tcg/decode-new.h index 3a856b4..e62e9c9 100644 --- a/target/i386/tcg/decode-new.h +++ b/target/i386/tcg/decode-new.h @@ -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; }; |