diff options
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 |
commit | e022157faa3eafc7a2d889b5e721c790b0979c36 (patch) | |
tree | eb1beb7ae2d8e121217ef123a69193aae00c58fc /src/devices | |
parent | 2cea059009134005f2f930176c9cad1c13b5ba8b (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.cpp | 19 | ||||
-rw-r--r-- | src/devices/cpu/drcfe.h | 2 |
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(); |