[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 07/13] target/i386: fix RF handling for string instructions
From: |
Paolo Bonzini |
Subject: |
[PATCH 07/13] target/i386: fix RF handling for string instructions |
Date: |
Sun, 15 Dec 2024 10:06:06 +0100 |
RF must be set on traps and interrupts from a string instruction,
except if they occur after the last iteration. Ensure it is set
before giving the main loop a chance to execute.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/tcg/translate.c | 22 +++++++++++++++++++++-
1 file changed, 21 insertions(+), 1 deletion(-)
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 0fe7ed4ec8d..4ff0ccf71cb 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -1336,6 +1336,14 @@ static void do_gen_rep(DisasContext *s, MemOp ot,
bool is_repz_nz)
{
TCGLabel *done = gen_new_label();
+ bool had_rf = s->flags & HF_RF_MASK;
+
+ /*
+ * Even if EFLAGS.RF was set on entry (such as if we're on the second or
+ * later iteration and an exception or interrupt happened), force gen_eob()
+ * not to clear the flag. We do that ourselves after the last iteration.
+ */
+ s->flags &= ~HF_RF_MASK;
gen_update_cc_op(s);
gen_op_jz_ecx(s, done);
@@ -1347,12 +1355,24 @@ static void do_gen_rep(DisasContext *s, MemOp ot,
gen_jcc(s, (JCC_Z << 1) | (nz ^ 1), done);
}
+ /*
+ * Traps or interrupts set RF_MASK if they happen after any iteration
+ * but the last. Set it here before giving the main loop a chance to
+ * execute. (For faults, seg_helper.c sets the flag as usual).
+ */
+ if (!had_rf) {
+ gen_set_eflags(s, RF_MASK);
+ }
+
/* Go to the main loop but reenter the same instruction. */
gen_jmp_rel_csize(s, -cur_insn_len(s), 0);
/* CX/ECX/RCX is zero, or REPZ/REPNZ broke the repetition. */
gen_set_label(done);
set_cc_op(s, CC_OP_DYNAMIC);
+ if (had_rf) {
+ gen_reset_eflags(s, RF_MASK);
+ }
gen_jmp_rel_csize(s, 0, 1);
}
@@ -2157,7 +2177,7 @@ gen_eob(DisasContext *s, int mode)
gen_set_hflag(s, HF_INHIBIT_IRQ_MASK);
}
- if (s->base.tb->flags & HF_RF_MASK) {
+ if (s->flags & HF_RF_MASK) {
gen_reset_eflags(s, RF_MASK);
}
if (mode == DISAS_EOB_RECHECK_TF) {
--
2.47.1
- Re: [PATCH 01/13] target/i386: inline gen_jcc into sole caller, (continued)
- [PATCH 03/13] target/i386: unify REP and REPZ/REPNZ generation, Paolo Bonzini, 2024/12/15
- [PATCH 04/13] target/i386: unify choice between single and repeated string instructions, Paolo Bonzini, 2024/12/15
- [PATCH 02/13] target/i386: remove trailing 1 from gen_{j, cmov, set}cc1, Paolo Bonzini, 2024/12/15
- [PATCH 05/13] target/i386: reorganize ops emitted by do_gen_rep, drop repz_opt, Paolo Bonzini, 2024/12/15
- [PATCH 07/13] target/i386: fix RF handling for string instructions,
Paolo Bonzini <=
- [PATCH 06/13] target/i386: tcg: move gen_set/reset_* earlier in the file, Paolo Bonzini, 2024/12/15
- [PATCH 08/13] target/i386: make cc_op handling more explicit for repeated string instructions., Paolo Bonzini, 2024/12/15
- [PATCH 09/13] target/i386: do not use gen_op_jz_ecx for repeated string operations, Paolo Bonzini, 2024/12/15