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:
parent
ddf83b35bd
commit
f66c8e8cd9
@ -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)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user