aboutsummaryrefslogtreecommitdiff
path: root/target
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2022-10-01 07:09:11 -0700
committerPaolo Bonzini <pbonzini@redhat.com>2022-10-11 09:36:01 +0200
commitf66c8e8cd923a38e454c2d4731bccc0eede1a652 (patch)
tree60160f6d45b6ed4ab156e51989f19599d00c8249 /target
parentddf83b35bde680faecae693c0fa03c18814a7a2e (diff)
downloadqemu-f66c8e8cd923a38e454c2d4731bccc0eede1a652.zip
qemu-f66c8e8cd923a38e454c2d4731bccc0eede1a652.tar.gz
qemu-f66c8e8cd923a38e454c2d4731bccc0eede1a652.tar.bz2
target/i386: Return bool from disas_insn
Instead of returning the new pc, which is present in DisasContext, return true if an insn was translated. This is false when we detect a page crossing and must undo the insn under translation. Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> Message-Id: <20221001140935.465607-3-richard.henderson@linaro.org> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'target')
-rw-r--r--target/i386/tcg/translate.c46
1 files changed, 24 insertions, 22 deletions
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 16bf56d..3f3e79c 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -4707,7 +4707,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b)
/* convert one instruction. s->base.is_jmp is set if the translation must
be stopped. Return the next pc value */
-static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
+static bool disas_insn(DisasContext *s, CPUState *cpu)
{
CPUX86State *env = cpu->env_ptr;
int b, prefixes;
@@ -4734,15 +4734,16 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
break;
case 1:
gen_exception_gpf(s);
- return s->pc;
+ return true;
case 2:
/* Restore state that may affect the next instruction. */
+ s->pc = s->base.pc_next;
s->cc_op_dirty = orig_cc_op_dirty;
s->cc_op = orig_cc_op;
s->base.num_insns--;
tcg_remove_ops_after(s->prev_insn_end);
s->base.is_jmp = DISAS_TOO_MANY;
- return s->base.pc_next;
+ return false;
default:
g_assert_not_reached();
}
@@ -8644,13 +8645,13 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
default:
goto unknown_op;
}
- return s->pc;
+ return true;
illegal_op:
gen_illegal_opcode(s);
- return s->pc;
+ return true;
unknown_op:
gen_unknown_opcode(env, s);
- return s->pc;
+ return true;
}
void tcg_x86_init(void)
@@ -8815,7 +8816,6 @@ static void i386_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
static void i386_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
{
DisasContext *dc = container_of(dcbase, DisasContext, base);
- target_ulong pc_next;
#ifdef TARGET_VSYSCALL_PAGE
/*
@@ -8828,21 +8828,23 @@ static void i386_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
}
#endif
- pc_next = disas_insn(dc, cpu);
- dc->base.pc_next = pc_next;
-
- if (dc->base.is_jmp == DISAS_NEXT) {
- if (dc->flags & (HF_TF_MASK | HF_INHIBIT_IRQ_MASK)) {
- /*
- * If single step mode, we generate only one instruction and
- * generate an exception.
- * If irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
- * the flag and abort the translation to give the irqs a
- * chance to happen.
- */
- dc->base.is_jmp = DISAS_TOO_MANY;
- } else if (!is_same_page(&dc->base, pc_next)) {
- dc->base.is_jmp = DISAS_TOO_MANY;
+ if (disas_insn(dc, cpu)) {
+ target_ulong pc_next = dc->pc;
+ dc->base.pc_next = pc_next;
+
+ if (dc->base.is_jmp == DISAS_NEXT) {
+ if (dc->flags & (HF_TF_MASK | HF_INHIBIT_IRQ_MASK)) {
+ /*
+ * If single step mode, we generate only one instruction and
+ * generate an exception.
+ * If irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
+ * the flag and abort the translation to give the irqs a
+ * chance to happen.
+ */
+ dc->base.is_jmp = DISAS_TOO_MANY;
+ } else if (!is_same_page(&dc->base, pc_next)) {
+ dc->base.is_jmp = DISAS_TOO_MANY;
+ }
}
}
}