target/m68k: Correct instruction emulation

Previously we weren't even initializing the instruction table, so any
attempt at emulation would cause a segmentation fault.

This also moves the end address check after the decoding to correctly
perform exiting behavior with the new translator model.
This commit is contained in:
Lioncash 2019-02-28 19:20:14 -05:00
parent 0868015992
commit 7a6f61057b
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7
2 changed files with 9 additions and 6 deletions

View file

@ -211,8 +211,11 @@ static void any_cpu_initfn(struct uc_struct *uc, Object *obj, void *opaque)
static int m68k_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **errp) static int m68k_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **errp)
{ {
CPUState *cs = CPU(dev); CPUState *cs = CPU(dev);
M68kCPU *cpu = M68K_CPU(uc, dev);
M68kCPUClass *mcc = M68K_CPU_GET_CLASS(uc, dev); M68kCPUClass *mcc = M68K_CPU_GET_CLASS(uc, dev);
register_m68k_insns(&cpu->env);
cpu_reset(cs); cpu_reset(cs);
qemu_init_vcpu(cs); qemu_init_vcpu(cs);

View file

@ -6334,12 +6334,6 @@ static void m68k_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
TCGContext *tcg_ctx = env->uc->tcg_ctx; TCGContext *tcg_ctx = env->uc->tcg_ctx;
uint16_t insn = read_im16(env, dc); uint16_t insn = read_im16(env, dc);
// Unicorn: end address tells us to stop emulation
if (dc->pc == dc->uc->addr_end) {
gen_exception(dc, dc->pc, EXCP_HLT);
return;
}
// Unicorn: trace this instruction on request // Unicorn: trace this instruction on request
if (HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_CODE, dc->pc)) { if (HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_CODE, dc->pc)) {
gen_uc_tracecode(tcg_ctx, 2, UC_HOOK_CODE_IDX, env->uc, dc->pc); gen_uc_tracecode(tcg_ctx, 2, UC_HOOK_CODE_IDX, env->uc, dc->pc);
@ -6353,6 +6347,12 @@ static void m68k_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
dc->base.pc_next = dc->pc; dc->base.pc_next = dc->pc;
// Unicorn: end address tells us to stop emulation
if (dc->pc == dc->uc->addr_end) {
gen_exception(dc, dc->pc, EXCP_HLT);
return;
}
if (dc->base.is_jmp == DISAS_NEXT) { if (dc->base.is_jmp == DISAS_NEXT) {
/* Stop translation when the next insn might touch a new page. /* Stop translation when the next insn might touch a new page.
* This ensures that prefetch aborts at the right place. * This ensures that prefetch aborts at the right place.