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>
This commit is contained in:
Richard Henderson 2022-10-01 07:09:11 -07:00 committed by Paolo Bonzini
parent ddf83b35bd
commit f66c8e8cd9

View File

@ -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 /* convert one instruction. s->base.is_jmp is set if the translation must
be stopped. Return the next pc value */ 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; CPUX86State *env = cpu->env_ptr;
int b, prefixes; int b, prefixes;
@ -4734,15 +4734,16 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
break; break;
case 1: case 1:
gen_exception_gpf(s); gen_exception_gpf(s);
return s->pc; return true;
case 2: case 2:
/* Restore state that may affect the next instruction. */ /* 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_dirty = orig_cc_op_dirty;
s->cc_op = orig_cc_op; s->cc_op = orig_cc_op;
s->base.num_insns--; s->base.num_insns--;
tcg_remove_ops_after(s->prev_insn_end); tcg_remove_ops_after(s->prev_insn_end);
s->base.is_jmp = DISAS_TOO_MANY; s->base.is_jmp = DISAS_TOO_MANY;
return s->base.pc_next; return false;
default: default:
g_assert_not_reached(); g_assert_not_reached();
} }
@ -8644,13 +8645,13 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
default: default:
goto unknown_op; goto unknown_op;
} }
return s->pc; return true;
illegal_op: illegal_op:
gen_illegal_opcode(s); gen_illegal_opcode(s);
return s->pc; return true;
unknown_op: unknown_op:
gen_unknown_opcode(env, s); gen_unknown_opcode(env, s);
return s->pc; return true;
} }
void tcg_x86_init(void) 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) static void i386_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
{ {
DisasContext *dc = container_of(dcbase, DisasContext, base); DisasContext *dc = container_of(dcbase, DisasContext, base);
target_ulong pc_next;
#ifdef TARGET_VSYSCALL_PAGE #ifdef TARGET_VSYSCALL_PAGE
/* /*
@ -8828,7 +8828,8 @@ static void i386_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
} }
#endif #endif
pc_next = disas_insn(dc, cpu); if (disas_insn(dc, cpu)) {
target_ulong pc_next = dc->pc;
dc->base.pc_next = pc_next; dc->base.pc_next = pc_next;
if (dc->base.is_jmp == DISAS_NEXT) { if (dc->base.is_jmp == DISAS_NEXT) {
@ -8846,6 +8847,7 @@ static void i386_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
} }
} }
} }
}
static void i386_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) static void i386_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
{ {