target-arm: Fix and improve AA32 singlestep translation completion code

This commit is contained in:
Sergey Fedorov 2018-02-17 19:32:24 -05:00 committed by Lioncash
parent e1701b069f
commit 587c9f0570
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7

View file

@ -11691,49 +11691,46 @@ tb_end:
instruction was a conditional branch or trap, and the PC has instruction was a conditional branch or trap, and the PC has
already been written. */ already been written. */
if (unlikely(cs->singlestep_enabled || dc->ss_active)) { if (unlikely(cs->singlestep_enabled || dc->ss_active)) {
/* Make sure the pc is updated, and raise a debug exception. */ /* Unconditional and "condition passed" instruction codepath. */
if (dc->condjmp) {
gen_set_condexec(dc); gen_set_condexec(dc);
if (dc->is_jmp == DISAS_SWI) { switch (dc->is_jmp) {
case DISAS_SWI:
gen_ss_advance(dc); gen_ss_advance(dc);
gen_exception(dc, EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb), gen_exception(dc, EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
default_exception_el(dc)); default_exception_el(dc));
} else if (dc->is_jmp == DISAS_HVC) { break;
case DISAS_HVC:
gen_ss_advance(dc); gen_ss_advance(dc);
gen_exception(dc, EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2); gen_exception(dc, EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
} else if (dc->is_jmp == DISAS_SMC) { break;
case DISAS_SMC:
gen_ss_advance(dc); gen_ss_advance(dc);
gen_exception(dc, EXCP_SMC, syn_aa32_smc(), 3); gen_exception(dc, EXCP_SMC, syn_aa32_smc(), 3);
} else if (dc->ss_active) { break;
gen_step_complete_exception(dc); case DISAS_NEXT:
} else { case DISAS_UPDATE:
gen_exception_internal(dc, EXCP_DEBUG);
}
gen_set_label(tcg_ctx, dc->condlabel);
}
if (dc->condjmp || dc->is_jmp == DISAS_NEXT ||
dc->is_jmp == DISAS_UPDATE) {
gen_set_pc_im(dc, dc->pc); gen_set_pc_im(dc, dc->pc);
dc->condjmp = 0; /* fall through */
} default:
gen_set_condexec(dc); if (dc->ss_active) {
if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
gen_ss_advance(dc);
gen_exception(dc, EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
default_exception_el(dc));
} else if (dc->is_jmp == DISAS_HVC && !dc->condjmp) {
gen_ss_advance(dc);
gen_exception(dc, EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
} else if (dc->is_jmp == DISAS_SMC && !dc->condjmp) {
gen_ss_advance(dc);
gen_exception(dc, EXCP_SMC, syn_aa32_smc(), 3);
} else if (dc->ss_active) {
gen_step_complete_exception(dc); gen_step_complete_exception(dc);
} else { } else {
/* FIXME: Single stepping a WFI insn will not halt /* FIXME: Single stepping a WFI insn will not halt
the CPU. */ the CPU. */
gen_exception_internal(dc, EXCP_DEBUG); gen_exception_internal(dc, EXCP_DEBUG);
} }
}
if (dc->condjmp) {
/* "Condition failed" instruction codepath. */
gen_set_label(tcg_ctx, dc->condlabel);
gen_set_condexec(dc);
gen_set_pc_im(dc, dc->pc);
if (dc->ss_active) {
gen_step_complete_exception(dc);
} else {
gen_exception_internal(dc, EXCP_DEBUG);
}
}
} else { } else {
/* While branches must always occur at the end of an IT block, /* While branches must always occur at the end of an IT block,
there are a few other things that can cause us to terminate there are a few other things that can cause us to terminate