diff --git a/src/emu/cpu/mips/mips3drc.c b/src/emu/cpu/mips/mips3drc.c index eac56eb258f..667833a7719 100644 --- a/src/emu/cpu/mips/mips3drc.c +++ b/src/emu/cpu/mips/mips3drc.c @@ -169,6 +169,7 @@ struct _mips3imp_state /* internal stuff */ UINT8 cache_dirty; /* true if we need to flush the cache */ + UINT32 jmpdest; /* destination jump target */ /* parameters for subroutines */ UINT64 numcycles; /* return value from gettotalcycles */ @@ -1633,15 +1634,19 @@ static void generate_delay_slot_and_branch(drcuml_block *block, compiler_state * { compiler_state compiler_temp = *compiler; UINT32 op = *desc->opptr.l; - - /* set the link if needed */ - if (linkreg != 0) - UML_DMOV(block, R64(linkreg), IMM((INT32)(desc->pc + 8))); // dmov ,desc->pc + 8 + + /* fetch the target register if dynamic, in case it is modified by the delay slot */ + if (desc->targetpc == BRANCH_TARGET_DYNAMIC) + UML_MOV(block, MEM(&mips3->impstate->jmpdest), R32(RSREG)); // mov [jmpdest], /* compile the delay slot using temporary compiler state */ assert(desc->delay != NULL); generate_sequence_instruction(block, &compiler_temp, desc->delay); // + /* set the link if needed -- after the delay slot */ + if (linkreg != 0) + UML_DMOV(block, R64(linkreg), IMM((INT32)(desc->pc + 8))); // dmov ,desc->pc + 8 + /* update the cycles and jump through the hash table to the target */ if (desc->targetpc != BRANCH_TARGET_DYNAMIC) { @@ -1654,9 +1659,9 @@ static void generate_delay_slot_and_branch(drcuml_block *block, compiler_state * } else { - generate_update_cycles(block, &compiler_temp, R32(RSREG), TRUE); + generate_update_cycles(block, &compiler_temp, MEM(&mips3->impstate->jmpdest), TRUE); // - UML_HASHJMP(block, IMM(mips3->impstate->mode), R32(RSREG), mips3->impstate->nocode); + UML_HASHJMP(block, IMM(mips3->impstate->mode), MEM(&mips3->impstate->jmpdest), mips3->impstate->nocode); // hashjmp ,,nocode }