[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 03/13] target/i386: unify REP and REPZ/REPNZ generation
From: |
Paolo Bonzini |
Subject: |
[PATCH 03/13] target/i386: unify REP and REPZ/REPNZ generation |
Date: |
Sun, 15 Dec 2024 10:06:02 +0100 |
It only differs in a single call to gen_jcc, so use a "bool" argument
to distinguish the two cases; do not duplicate code.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/tcg/translate.c | 39 +++++++++++++++++++------------------
1 file changed, 20 insertions(+), 19 deletions(-)
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 99e989d4b22..8bf6aa1fcf6 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -1309,14 +1309,18 @@ static void gen_outs(DisasContext *s, MemOp ot)
gen_bpt_io(s, s->tmp2_i32, ot);
}
-/* Generate jumps to current or next instruction */
-static void gen_repz(DisasContext *s, MemOp ot,
- void (*fn)(DisasContext *s, MemOp ot))
+static void do_gen_rep(DisasContext *s, MemOp ot,
+ void (*fn)(DisasContext *s, MemOp ot),
+ bool is_repz_nz)
{
TCGLabel *l2;
l2 = gen_jz_ecx_string(s);
fn(s, ot);
gen_op_add_reg_im(s, s->aflag, R_ECX, -1);
+ if (is_repz_nz) {
+ int nz = (s->prefix & PREFIX_REPNZ) ? 1 : 0;
+ gen_jcc(s, (JCC_Z << 1) | (nz ^ 1), l2);
+ }
/*
* A loop would cause two single step exceptions if ECX = 1
* before rep string_insn
@@ -1324,28 +1328,25 @@ static void gen_repz(DisasContext *s, MemOp ot,
if (s->repz_opt) {
gen_op_jz_ecx(s, l2);
}
+ /*
+ * For CMPS/SCAS there is no need to set CC_OP_DYNAMIC: only one iteration
+ * is done at a time, so the translation block ends unconditionally after
+ * this instruction and there is no control flow junction.
+ */
gen_jmp_rel_csize(s, -cur_insn_len(s), 0);
}
+static void gen_repz(DisasContext *s, MemOp ot,
+ void (*fn)(DisasContext *s, MemOp ot))
+
+{
+ do_gen_rep(s, ot, fn, false);
+}
+
static void gen_repz_nz(DisasContext *s, MemOp ot,
void (*fn)(DisasContext *s, MemOp ot))
{
- TCGLabel *l2;
- int nz = (s->prefix & PREFIX_REPNZ) ? 1 : 0;
-
- l2 = gen_jz_ecx_string(s);
- fn(s, ot);
- gen_op_add_reg_im(s, s->aflag, R_ECX, -1);
- gen_jcc(s, (JCC_Z << 1) | (nz ^ 1), l2);
- if (s->repz_opt) {
- gen_op_jz_ecx(s, l2);
- }
- /*
- * Only one iteration is done at a time, so the translation
- * block ends unconditionally after this instruction and there
- * is no control flow junction - no need to set CC_OP_DYNAMIC.
- */
- gen_jmp_rel_csize(s, -cur_insn_len(s), 0);
+ do_gen_rep(s, ot, fn, true);
}
static void gen_helper_fp_arith_ST0_FT0(int op)
--
2.47.1
- [PATCH 00/13] target/i386: optimize string operations, Paolo Bonzini, 2024/12/15
- [PATCH 01/13] target/i386: inline gen_jcc into sole caller, Paolo Bonzini, 2024/12/15
- [PATCH 03/13] target/i386: unify REP and REPZ/REPNZ generation,
Paolo Bonzini <=
- [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, 2024/12/15