diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2024-07-10 12:40:24 +0200 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2024-07-16 18:18:24 +0200 |
commit | 3afc6539a84d3d003025c9352a0596dbcb350ff4 (patch) | |
tree | 85141cbe9a687e7a19845a92500b6ceb332f4a92 /target | |
parent | 340627ec14968d64cfa3dd12d0e998639f227c49 (diff) |
target/i386/tcg: fix POP to memory in long mode
In long mode, POP to memory will write a full 64-bit value. However,
the call to gen_writeback() in gen_POP will use MO_32 because the
decoding table is incorrect.
The bug was latent until commit aea49fbb01a ("target/i386: use gen_writeback()
within gen_POP()", 2024-06-08), and then became visible because gen_op_st_v
now receives op->ot instead of the "ot" returned by gen_pop_T0.
Analyzed-by: Clément Chigot <chigot@adacore.com>
Fixes: 5e9e21bcc4d ("target/i386: move 60-BF opcodes to new decoder", 2024-05-07)
Tested-by: Clément Chigot <chigot@adacore.com>
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 | 2 | ||||
-rw-r--r-- | target/i386/tcg/emit.c.inc | 1 |
2 files changed, 2 insertions, 1 deletions
diff --git a/target/i386/tcg/decode-new.c.inc b/target/i386/tcg/decode-new.c.inc index 0d846c32c2..d2da1d396d 100644 --- a/target/i386/tcg/decode-new.c.inc +++ b/target/i386/tcg/decode-new.c.inc @@ -1717,7 +1717,7 @@ static const X86OpEntry opcodes_root[256] = { [0x8C] = X86_OP_ENTRYwr(MOV, E,v, S,w, op0_Mw), [0x8D] = X86_OP_ENTRYwr(LEA, G,v, M,v, nolea), [0x8E] = X86_OP_ENTRYwr(MOV, S,w, E,w), - [0x8F] = X86_OP_GROUPw(group1A, E,v), + [0x8F] = X86_OP_GROUPw(group1A, E,d64), [0x98] = X86_OP_ENTRY1(CBW, 0,v), /* rAX */ [0x99] = X86_OP_ENTRYwr(CWD, 2,v, 0,v), /* rDX, rAX */ diff --git a/target/i386/tcg/emit.c.inc b/target/i386/tcg/emit.c.inc index fc7477833b..016dce8146 100644 --- a/target/i386/tcg/emit.c.inc +++ b/target/i386/tcg/emit.c.inc @@ -2788,6 +2788,7 @@ static void gen_POP(DisasContext *s, X86DecodedInsn *decode) X86DecodedOp *op = &decode->op[0]; MemOp ot = gen_pop_T0(s); + assert(ot >= op->ot); if (op->has_ea || op->unit == X86_OP_SEG) { /* NOTE: order is important for MMU exceptions */ gen_writeback(s, decode, 0, s->T0); |