From 3d304620ec6c95f31db17acc132f42f243369299 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Sat, 7 Jan 2023 18:14:20 +0100 Subject: [PATCH] target/i386: fix operand size of unary SSE operations VRCPSS, VRSQRTSS and VCVTSx2Sx have a 32-bit or 64-bit memory operand, which is represented in the decoding tables by X86_VEX_REPScalar. Add it to the tables, and make validate_vex() handle the case of an instruction that is in exception type 4 without the REP prefix and exception type 5 with it; this is the cas of VRCP and VRSQRT. Reported-by: yongwoo Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1377 Signed-off-by: Paolo Bonzini --- target/i386/tcg/decode-new.c.inc | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/target/i386/tcg/decode-new.c.inc b/target/i386/tcg/decode-new.c.inc index 80c579164f..d5fd8d965c 100644 --- a/target/i386/tcg/decode-new.c.inc +++ b/target/i386/tcg/decode-new.c.inc @@ -105,6 +105,7 @@ #define vex3 .vex_class = 3, #define vex4 .vex_class = 4, #define vex4_unal .vex_class = 4, .vex_special = X86_VEX_SSEUnaligned, +#define vex4_rep5 .vex_class = 4, .vex_special = X86_VEX_REPScalar, #define vex5 .vex_class = 5, #define vex6 .vex_class = 6, #define vex7 .vex_class = 7, @@ -839,8 +840,8 @@ static const X86OpEntry opcodes_0F[256] = { [0x50] = X86_OP_ENTRY3(MOVMSK, G,y, None,None, U,x, vex7 p_00_66), [0x51] = X86_OP_GROUP3(sse_unary, V,x, H,x, W,x, vex2_rep3 p_00_66_f3_f2), - [0x52] = X86_OP_GROUP3(sse_unary, V,x, H,x, W,x, vex5 p_00_f3), - [0x53] = X86_OP_GROUP3(sse_unary, V,x, H,x, W,x, vex5 p_00_f3), + [0x52] = X86_OP_GROUP3(sse_unary, V,x, H,x, W,x, vex4_rep5 p_00_f3), + [0x53] = X86_OP_GROUP3(sse_unary, V,x, H,x, W,x, vex4_rep5 p_00_f3), [0x54] = X86_OP_ENTRY3(PAND, V,x, H,x, W,x, vex4 p_00_66), /* vand */ [0x55] = X86_OP_ENTRY3(PANDN, V,x, H,x, W,x, vex4 p_00_66), /* vandn */ [0x56] = X86_OP_ENTRY3(POR, V,x, H,x, W,x, vex4 p_00_66), /* vor */ @@ -878,7 +879,7 @@ static const X86OpEntry opcodes_0F[256] = { [0x58] = X86_OP_ENTRY3(VADD, V,x, H,x, W,x, vex2_rep3 p_00_66_f3_f2), [0x59] = X86_OP_ENTRY3(VMUL, V,x, H,x, W,x, vex2_rep3 p_00_66_f3_f2), - [0x5a] = X86_OP_GROUP3(sse_unary, V,x, H,x, W,x, vex3 p_00_66_f3_f2), + [0x5a] = X86_OP_GROUP3(sse_unary, V,x, H,x, W,x, vex2_rep3 p_00_66_f3_f2), [0x5b] = X86_OP_GROUP0(0F5B), [0x5c] = X86_OP_ENTRY3(VSUB, V,x, H,x, W,x, vex2_rep3 p_00_66_f3_f2), [0x5d] = X86_OP_ENTRY3(VMIN, V,x, H,x, W,x, vex2_rep3 p_00_66_f3_f2), @@ -1447,9 +1448,9 @@ static bool validate_vex(DisasContext *s, X86DecodedInsn *decode) * Instructions which differ between 00/66 and F2/F3 in the * exception classification and the size of the memory operand. */ - assert(e->vex_class == 1 || e->vex_class == 2); + assert(e->vex_class == 1 || e->vex_class == 2 || e->vex_class == 4); if (s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) { - e->vex_class = 3; + e->vex_class = e->vex_class < 4 ? 3 : 5; if (s->vex_l) { goto illegal; }