MMX instructions do not have a VEX encoding, so reject VEX instructions with no prefix for instructions that use X86_SPECIAL_MMX.
Cc: [email protected] Signed-off-by: Paolo Bonzini <[email protected]> --- target/i386/tcg/decode-new.c.inc | 33 +++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/target/i386/tcg/decode-new.c.inc b/target/i386/tcg/decode-new.c.inc index 2756953c744..65fd402c17f 100644 --- a/target/i386/tcg/decode-new.c.inc +++ b/target/i386/tcg/decode-new.c.inc @@ -2425,6 +2425,12 @@ static void decode_modrm(DisasContext *s, CPUX86State *env, decode->mem = (AddressParts){ def_seg, base, index, scale, disp }; } +static bool is_mmx(const DisasContext *s, const X86OpEntry *e) +{ + return (e->special == X86_SPECIAL_MMX && + !(s->prefix & (PREFIX_REPZ | PREFIX_REPNZ | PREFIX_DATA))); +} + static bool decode_op_size(DisasContext *s, X86OpEntry *e, X86OpSize size, MemOp *ot) { switch (size) { @@ -2470,8 +2476,7 @@ static bool decode_op_size(DisasContext *s, X86OpEntry *e, X86OpSize size, MemOp return true; case X86_SIZE_dq: /* SSE/AVX 128-bit */ - if (e->special == X86_SPECIAL_MMX && - !(s->prefix & (PREFIX_DATA | PREFIX_REPZ | PREFIX_REPNZ))) { + if (is_mmx(s, e)) { *ot = MO_64; return true; } @@ -2489,8 +2494,7 @@ static bool decode_op_size(DisasContext *s, X86OpEntry *e, X86OpSize size, MemOp return true; case X86_SIZE_x: /* 128/256-bit, based on operand size */ - if (e->special == X86_SPECIAL_MMX && - !(s->prefix & (PREFIX_DATA | PREFIX_REPZ | PREFIX_REPNZ))) { + if (is_mmx(s, e)) { *ot = MO_64; return true; } @@ -2605,8 +2609,7 @@ static bool decode_op(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode, goto get_reg; case X86_TYPE_V: /* reg in the modrm byte selects an XMM/YMM register */ - if (decode->e.special == X86_SPECIAL_MMX && - !(s->prefix & (PREFIX_DATA | PREFIX_REPZ | PREFIX_REPNZ))) { + if (is_mmx(s, &decode->e)) { op->unit = X86_OP_MMX; } else { op->unit = X86_OP_SSE; @@ -2625,8 +2628,7 @@ static bool decode_op(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode, goto get_modrm; case X86_TYPE_W: /* XMM/YMM modrm operand */ - if (decode->e.special == X86_SPECIAL_MMX && - !(s->prefix & (PREFIX_DATA | PREFIX_REPZ | PREFIX_REPNZ))) { + if (is_mmx(s, &decode->e)) { op->unit = X86_OP_MMX; } else { op->unit = X86_OP_SSE; @@ -2638,8 +2640,7 @@ static bool decode_op(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode, goto get_modrm_reg; case X86_TYPE_U: /* R/M in the modrm byte selects an XMM/YMM register */ - if (decode->e.special == X86_SPECIAL_MMX && - !(s->prefix & (PREFIX_DATA | PREFIX_REPZ | PREFIX_REPNZ))) { + if (is_mmx(s, &decode->e)) { op->unit = X86_OP_MMX; } else { op->unit = X86_OP_SSE; @@ -3135,12 +3136,15 @@ static bool validate_vex(DisasContext *s, X86DecodedInsn *decode) case 4: case 5: case 7: - if (s->prefix & PREFIX_VEX) { + if (is_mmx(s, e)) { + if (s->prefix & PREFIX_VEX) { + goto illegal; + } + } else if (s->prefix & PREFIX_VEX) { if (!(s->flags & HF_AVX_EN_MASK)) { goto illegal; } - } else if (e->special != X86_SPECIAL_MMX || - (s->prefix & (PREFIX_REPZ | PREFIX_REPNZ | PREFIX_DATA))) { + } else { if (!(s->flags & HF_OSFXSR_MASK)) { goto illegal; } @@ -3694,8 +3698,7 @@ static void disas_insn(DisasContext *s, CPUState *cpu) } } - if (decode.e.special == X86_SPECIAL_MMX && - !(s->prefix & (PREFIX_REPZ | PREFIX_REPNZ | PREFIX_DATA))) { + if (is_mmx(s, &decode.e)) { gen_helper_enter_mmx(tcg_env); } -- 2.56.0
