(nw) DRC: Modified branch in delay slot to match non-drc behaviour for non-dynamic branch targets.

This commit is contained in:
Ted Green 2016-06-04 10:46:34 -06:00
parent 2cea059009
commit e022157faa
2 changed files with 15 additions and 6 deletions

View File

@ -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

View File

@ -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();