The value that is pushed by PUSHF is the full EFLAGS, while CC_OP_EFLAGS only wants arithmetic flags in CC_SRC. To avoid this, follow what other helpers do and set CC_SRC/CC_OP directly in helper_read_eflags. This is basically free and fixes an issue booting Windows 3.11.
Reported-by: Mark Cave-Ayland <[email protected]> Fixes: e661e2d7a37 ("target/i386/tcg: update cc_op after PUSHF", 2025-12-27) Signed-off-by: Paolo Bonzini <[email protected]> --- target/i386/tcg/cc_helper.c | 4 +++- target/i386/tcg/emit.c.inc | 3 +-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/target/i386/tcg/cc_helper.c b/target/i386/tcg/cc_helper.c index 91e492196af..6ddd64fcb07 100644 --- a/target/i386/tcg/cc_helper.c +++ b/target/i386/tcg/cc_helper.c @@ -414,7 +414,9 @@ target_ulong helper_read_eflags(CPUX86State *env) { uint32_t eflags; - eflags = cpu_cc_compute_all(env); + CC_SRC = eflags = cpu_cc_compute_all(env); + CC_OP = CC_OP_EFLAGS; + eflags |= (env->df & DF_MASK); eflags |= env->eflags & ~(VM_MASK | RF_MASK); return eflags; diff --git a/target/i386/tcg/emit.c.inc b/target/i386/tcg/emit.c.inc index 0fde3d669d9..e55b65176fc 100644 --- a/target/i386/tcg/emit.c.inc +++ b/target/i386/tcg/emit.c.inc @@ -3253,8 +3253,7 @@ static void gen_PUSHF(DisasContext *s, X86DecodedInsn *decode) gen_update_cc_op(s); gen_helper_read_eflags(s->T0, tcg_env); gen_push_v(s, s->T0); - decode->cc_src = s->T0; - decode->cc_op = CC_OP_EFLAGS; + assume_cc_op(s, CC_OP_EFLAGS); } static MemOp gen_shift_count(DisasContext *s, X86DecodedInsn *decode, -- 2.52.0
