diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2023-01-07 18:14:20 +0100 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2023-01-11 10:44:35 +0100 |
commit | 3d304620ec6c95f31db17acc132f42f243369299 (patch) | |
tree | 16d0b49a1e975a5874525d7432fc0adda78487b2 | |
parent | 8d5666d76b0a2b0f852e51412c79c3d3d8c90801 (diff) |
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 <https://gitlab.com/yongwoo36>
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1377
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r-- | target/i386/tcg/decode-new.c.inc | 11 |
1 files 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; } |