diff options
author | 2016-12-29 14:34:59 -0800 | |
---|---|---|
committer | 2016-12-29 14:34:59 -0800 | |
commit | 1fafe7706cbfcfc6e39c23c3c713fbb102557cbe (patch) | |
tree | e717407aa8f98f192a2095f28909c89f3af3a8e5 /src/devices/cpu/powerpc/ppcdrc.cpp | |
parent | f7a98c4a969478fca51faf30f588d59631394bd9 (diff) | |
parent | 2b74e4c0be91b86b408fca518af7518c1ea994c9 (diff) |
Merge https://github.com/mamedev/mame
Diffstat (limited to 'src/devices/cpu/powerpc/ppcdrc.cpp')
-rw-r--r-- | src/devices/cpu/powerpc/ppcdrc.cpp | 33 |
1 files changed, 28 insertions, 5 deletions
diff --git a/src/devices/cpu/powerpc/ppcdrc.cpp b/src/devices/cpu/powerpc/ppcdrc.cpp index 6c98830bb96..741e75f9cc2 100644 --- a/src/devices/cpu/powerpc/ppcdrc.cpp +++ b/src/devices/cpu/powerpc/ppcdrc.cpp @@ -642,6 +642,11 @@ static void cfunc_ppccom_execute_mtdcr(void *param) ppc->ppccom_execute_mtdcr(); } +static void cfunc_ppccom_get_dsisr(void *param) +{ + ppc_device *ppc = (ppc_device *)param; + ppc->ppccom_get_dsisr(); +} /*************************************************************************** STATIC CODEGEN @@ -784,7 +789,11 @@ void ppc_device::static_generate_tlb_mismatch() UML_LABEL(block, isi); // isi: if (!(m_cap & PPCCAP_603_MMU)) { - UML_MOV(block, SPR32(SPROEA_DSISR), mem(&m_core->param0)); // mov [dsisr],[param0] + // DAR gets the address, DSISR gets the 'reason' flags + UML_MOV(block, SPR32(SPROEA_DAR), mem(&m_core->param0)); // mov [dar],[param0] + m_core->param1 = 0; // always a read here + UML_CALLC(block, (c_function)cfunc_ppccom_get_dsisr, this); // get DSISR to param1 + UML_MOV(block, SPR32(SPROEA_DSISR), mem(&m_core->param1)); // move [dsisr], [param1] UML_EXH(block, *m_exception[EXCEPTION_ISI], I0); // exh isi,i0 } else @@ -1389,8 +1398,19 @@ void ppc_device::static_generate_memory_accessor(int mode, int size, int iswrite /* general case: DSI exception */ else { - UML_MOV(block, SPR32(SPROEA_DSISR), mem(&m_core->param0)); // mov [dsisr],[param0] - UML_EXH(block, *m_exception[EXCEPTION_DSI], I0); // exh dsi,i0 + UML_MOV(block, SPR32(SPROEA_DAR), mem(&m_core->param0)); // mov [dar],[param0] + // signal read or write to cfunc to get proper reason back + if (iswrite) + { + m_core->param1 = 1; + } + else + { + m_core->param1 = 0; + } + UML_CALLC(block, (c_function)cfunc_ppccom_get_dsisr, this); // get DSISR to param1 + UML_MOV(block, SPR32(SPROEA_DSISR), mem(&m_core->param1)); // move [dsisr], [param1] + UML_EXH(block, *m_exception[EXCEPTION_DSI], I0); // exh dsi,i0 } } @@ -1922,8 +1942,11 @@ void ppc_device::generate_branch(drcuml_block *block, compiler_state *compiler, } else { - generate_update_cycles(block, &compiler_temp, mem(srcptr), true); // <subtract cycles> - UML_HASHJMP(block, m_core->mode, mem(srcptr), *m_nocode); // hashjmp <mode>,<rsreg>,nocode + generate_update_cycles(block, &compiler_temp, mem(srcptr), true); // <subtract cycles> + + /* clear two LSBs of the target address to prevent branching to an invalid address */ + UML_AND(block, I0, mem(srcptr), 0xFFFFFFFC); // and i0, 0xFFFFFFFC + UML_HASHJMP(block, m_core->mode, I0, *m_nocode); // hashjmp <mode>,i0,nocode } /* update the label */ |