(nw) MIP3 DRC handle branches in delay slot properly.

This commit is contained in:
Ted Green 2016-06-01 08:51:21 -06:00
parent 8a8b3e8b85
commit 130766a55c
3 changed files with 17 additions and 1 deletions

View File

@ -55,7 +55,8 @@ drc_frontend::drc_frontend(device_t &cpu, UINT32 window_start, UINT32 window_end
m_cpudevice(downcast<cpu_device &>(cpu)),
m_program(m_cpudevice.space(AS_PROGRAM)),
m_pageshift(m_cpudevice.space_config(AS_PROGRAM)->m_page_shift),
m_desc_array(window_end + window_start + 2, nullptr)
m_desc_array(window_end + window_start + 2, nullptr),
m_allow_branch_in_delay(false)
{
}
@ -196,6 +197,14 @@ 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 previous instruction is a branch use the target pc. Currently MIP3s only.
if (m_allow_branch_in_delay && prevdesc && (prevdesc->flags & OPFLAG_IS_BRANCH) && prevdesc->targetpc != BRANCH_TARGET_DYNAMIC) {
// We got here because the previous instruction is a branch and this instruction is a branch.
// So the PC of the delay slot for the this branch will be the target address of the previous branch.
delaypc = prevdesc->targetpc;
//printf("drc_frontend::describe_one: branch in delay slot. curpc=0x%08X, delaypc=0x%08X\n", curpc, delaypc);
}
opcode_desc *prev = desc;
for (UINT8 slotnum = 0; slotnum < desc->delayslots; slotnum++)
{

View File

@ -134,6 +134,9 @@ public:
// describe a block
const opcode_desc *describe_code(offs_t startpc);
// Set the allow branches in delay slot flag
void set_allow_branch_in_delay(bool flag) { m_allow_branch_in_delay = flag; }
protected:
// required overrides
virtual bool describe(opcode_desc &desc, const opcode_desc *prev) = 0;
@ -159,6 +162,8 @@ private:
simple_list<opcode_desc> m_desc_live_list; // list of live descriptions
fixed_allocator<opcode_desc> m_desc_allocator; // fixed allocator for descriptions
std::vector<opcode_desc *> m_desc_array; // array of descriptions in PC order
bool m_allow_branch_in_delay; // Allow branches in delay slots
};

View File

@ -386,6 +386,8 @@ void mips3_device::device_start()
/* initialize the front-end helper */
m_drcfe = std::make_unique<mips3_frontend>(this, COMPILE_BACKWARDS_BYTES, COMPILE_FORWARDS_BYTES, SINGLE_INSTRUCTION_MODE ? 1 : COMPILE_MAX_SEQUENCE);
// Allow branches in delay slots
m_drcfe->set_allow_branch_in_delay(true);
/* allocate memory for cache-local state and initialize it */
memcpy(m_fpmode, fpmode_source, sizeof(fpmode_source));