summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Aaron Giles <aaron@aarongiles.com>2008-06-29 06:19:59 +0000
committer Aaron Giles <aaron@aarongiles.com>2008-06-29 06:19:59 +0000
commitbc5eecc7a2f9e70820bb67df4b17038e6f26a2b9 (patch)
treee4239fe84a9f05b6d6fcda8c9205eefd6718d6ca
parentacaabbe09d66ad71cc956286512ca05107b235f6 (diff)
Stash jump target address before executing delay slot.
Also, don't update link register until delay slot has finished executing. Fixes hang in gauntleg, though there are math problems lurking still.
-rw-r--r--src/emu/cpu/mips/mips3drc.c17
1 files changed, 11 insertions, 6 deletions
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 <linkreg>,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],<rsreg>
/* compile the delay slot using temporary compiler state */
assert(desc->delay != NULL);
generate_sequence_instruction(block, &compiler_temp, desc->delay); // <next instruction>
+ /* set the link if needed -- after the delay slot */
+ if (linkreg != 0)
+ UML_DMOV(block, R64(linkreg), IMM((INT32)(desc->pc + 8))); // dmov <linkreg>,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);
// <subtract cycles>
- 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 <mode>,<rsreg>,nocode
}