Fix conditional ARM instructions at the end of a translation block

This fixes issue #133

The explanation is as follows. Most blocks end on an inconditional
jump/branch, but there's two cases where this doesn't happen:
translation gates and when we hit MAX_EXITS. These are very uncommon
cases and therefore more prone to hidden bugs.

When this happens, the last instruction emits a conditional jump (via
arm_conditional_block_header macro) which is patched by a later
instruction via generate_branch_patch_conditional. Typically the last
unconditional branch will trigger the patching condition (which is
aproximately condition != last_condition), but in these two cases it
might not happen, leaving an unpatched branch. This makes x86 and ARM
dynarecs crash in interesting ways (although it might not crash
depending on $stuff and make the bug even harder to track).
This commit is contained in:
David Guillen Fandos 2021-07-05 18:19:19 +02:00
parent 3d874ec5e3
commit 0ca87a4807
1 changed files with 6 additions and 0 deletions

View File

@ -3115,6 +3115,12 @@ s32 translate_block_arm(u32 pc, translation_region_type
generate_cycle_update();
}
}
/* This can happen if the last instruction is *not* inconditional */
if ((last_condition & 0x0F) != 0x0E) {
generate_branch_patch_conditional(backpatch_address, translation_ptr);
}
for(i = 0; i < translation_gate_targets; i++)
{
if(pc == translation_gate_target_pc[i])