summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices
diff options
context:
space:
mode:
author Ted Green <tedgreen99@inbox.com>2016-06-04 10:46:34 -0600
committer Ted Green <tedgreen99@inbox.com>2016-06-04 10:47:22 -0600
commite022157faa3eafc7a2d889b5e721c790b0979c36 (patch)
treeeb1beb7ae2d8e121217ef123a69193aae00c58fc /src/devices
parent2cea059009134005f2f930176c9cad1c13b5ba8b (diff)
(nw) DRC: Modified branch in delay slot to match non-drc behaviour for non-dynamic branch targets.
Diffstat (limited to 'src/devices')
-rw-r--r--src/devices/cpu/drcfe.cpp19
-rw-r--r--src/devices/cpu/drcfe.h2
2 files changed, 15 insertions, 6 deletions
diff --git a/src/devices/cpu/drcfe.cpp b/src/devices/cpu/drcfe.cpp
index 87478de59e6..104c774ac3e 100644
--- a/src/devices/cpu/drcfe.cpp
+++ b/src/devices/cpu/drcfe.cpp
@@ -156,7 +156,7 @@ const opcode_desc *drc_frontend::describe_code(offs_t startpc)
// slots of branches as well
//-------------------------------------------------
-opcode_desc *drc_frontend::describe_one(offs_t curpc, const opcode_desc *prevdesc)
+opcode_desc *drc_frontend::describe_one(offs_t curpc, const opcode_desc *prevdesc, bool in_delay_slot)
{
// initialize the description
opcode_desc *desc = m_desc_allocator.alloc();
@@ -170,7 +170,8 @@ opcode_desc *drc_frontend::describe_one(offs_t curpc, const opcode_desc *prevdes
desc->length = 0;
desc->delayslots = 0;
desc->skipslots = 0;
- desc->flags = 0;
+ // set the delay slot flag
+ desc->flags = in_delay_slot ? OPFLAG_IN_DELAY_SLOT : 0;
desc->userflags = 0;
desc->cycles = 0;
memset(desc->regin, 0x00, sizeof(desc->regin));
@@ -196,18 +197,26 @@ opcode_desc *drc_frontend::describe_one(offs_t curpc, const opcode_desc *prevdes
{
// iterate over slots and describe them
offs_t delaypc = curpc + desc->length;
+ // If this is a delay slot it is the true branch fork and the pc should be the previous branch target
+ if (desc->flags & OPFLAG_IN_DELAY_SLOT) {
+ if (prevdesc->targetpc != BRANCH_TARGET_DYNAMIC) {
+ delaypc = prevdesc->targetpc;
+ //printf("drc_frontend::describe_one Branch in delay slot. curpc=%08X delaypc=%08X\n", curpc, delaypc);
+ } else {
+ //printf("drc_frontend::describe_one Warning! Branch in delay slot of dynamic target. curpc=%08X\n", curpc);
+ }
+ }
opcode_desc *prev = desc;
for (UINT8 slotnum = 0; slotnum < desc->delayslots; slotnum++)
{
// recursively describe the next instruction
- opcode_desc *delaydesc = describe_one(delaypc, prev);
+ opcode_desc *delaydesc = describe_one(delaypc, prev, true);
if (delaydesc == nullptr)
break;
desc->delay.append(*delaydesc);
prev = desc;
- // set the delay slot flag and a pointer back to the original branch
- delaydesc->flags |= OPFLAG_IN_DELAY_SLOT;
+ // set a pointer back to the original branch
delaydesc->branch = desc;
// stop if we hit a page fault
diff --git a/src/devices/cpu/drcfe.h b/src/devices/cpu/drcfe.h
index 09d86b2bd99..59efb405a23 100644
--- a/src/devices/cpu/drcfe.h
+++ b/src/devices/cpu/drcfe.h
@@ -140,7 +140,7 @@ protected:
private:
// internal helpers
- opcode_desc *describe_one(offs_t curpc, const opcode_desc *prevdesc);
+ opcode_desc *describe_one(offs_t curpc, const opcode_desc *prevdesc, bool in_delay_slot = false);
void build_sequence(int start, int end, UINT32 endflag);
void accumulate_required_backwards(opcode_desc &desc, UINT32 *reqmask);
void release_descriptions();