From 702bda5d6514f0e23c84ee8cb36c61467e09d7f7 Mon Sep 17 00:00:00 2001 From: 987123879113 <63495610+987123879113@users.noreply.github.com> Date: Thu, 23 Nov 2023 02:40:54 +0900 Subject: cpu/powerpc: Don't generalte illegal instruction exception for lmw invalid forms (fixes MT08791). (#11775) --- src/devices/cpu/powerpc/ppcdrc.cpp | 24 ++++++------------------ src/devices/cpu/powerpc/ppcfe.cpp | 15 +++------------ 2 files changed, 9 insertions(+), 30 deletions(-) diff --git a/src/devices/cpu/powerpc/ppcdrc.cpp b/src/devices/cpu/powerpc/ppcdrc.cpp index 1905e1eb1d6..0c62dec346a 100644 --- a/src/devices/cpu/powerpc/ppcdrc.cpp +++ b/src/devices/cpu/powerpc/ppcdrc.cpp @@ -2257,26 +2257,14 @@ bool ppc_device::generate_opcode(drcuml_block &block, compiler_state *compiler, UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IMMU(op)); // mapvar dsisr,DSISR_IMMU(op) UML_MOV(block, mem(&m_core->tempaddr), R32Z(G_RA(op))); // mov [tempaddr],ra - if (G_RD(op) <= G_RA(op) && !(m_cap & PPCCAP_4XX) && m_flavor != PPC_MODEL_601) + for (int regnum = G_RD(op); regnum < 32; regnum++) { - // RA being in the range is an invalid form - // 403 and 405 manual allows writes where regnum != RA || regnum == 31, regnum == RA is skipped - // 601 user manual lists no special rules for R31 being valid but regnum == RA is skipped - // 603 and above just says it's an invalid form - // tropchnc (403GA) is known to use this behavior - UML_EXH(block, *m_exception[EXCEPTION_PROGRAM], 0x80000); // exh exception_program,0x80000 - } - else - { - for (int regnum = G_RD(op); regnum < 32; regnum++) - { - UML_ADD(block, I0, mem(&m_core->tempaddr), (int16_t)G_SIMM(op) + 4 * (regnum - G_RD(op))); - // add i0,[tempaddr],simm + 4*(regnum-rd) - UML_CALLH(block, *m_read32align[m_core->mode]); // callh read32align + UML_ADD(block, I0, mem(&m_core->tempaddr), (int16_t)G_SIMM(op) + 4 * (regnum - G_RD(op))); + // add i0,[tempaddr],simm + 4*(regnum-rd) + UML_CALLH(block, *m_read32align[m_core->mode]); // callh read32align - if (regnum != G_RA(op) || ((m_cap & PPCCAP_4XX) && regnum == 31)) - UML_MOV(block, R32(regnum), I0); // mov regnum,i0 - } + if (regnum != G_RA(op) || ((m_cap & PPCCAP_4XX) && regnum == 31)) + UML_MOV(block, R32(regnum), I0); // mov regnum,i0 } generate_update_cycles(block, compiler, desc->pc + 4, true); // return true; diff --git a/src/devices/cpu/powerpc/ppcfe.cpp b/src/devices/cpu/powerpc/ppcfe.cpp index f4abd4a9004..57ec36cd317 100644 --- a/src/devices/cpu/powerpc/ppcfe.cpp +++ b/src/devices/cpu/powerpc/ppcfe.cpp @@ -290,19 +290,10 @@ bool ppc_device::frontend::describe(opcode_desc &desc, const opcode_desc *prev) case 0x2e: // LMW GPR_USED_OR_ZERO(desc, G_RA(op)); - if (G_RD(op) <= G_RA(op) && !(m_ppc.m_cap & PPCCAP_4XX) && !is_601_class()) + for (regnum = G_RD(op); regnum < 32; regnum++) { - // Undefined invalid form that has different behavior between CPUs - // See ppcdrc.cpp for a more detailed explanation - desc.flags |= OPFLAG_INVALID_OPCODE; - } - else - { - for (regnum = G_RD(op); regnum < 32; regnum++) - { - if (regnum != G_RA(op) || ((m_ppc.m_cap & PPCCAP_4XX) && regnum == 31)) - GPR_MODIFIED(desc, regnum); - } + if (regnum != G_RA(op) || ((m_ppc.m_cap & PPCCAP_4XX) && regnum == 31)) + GPR_MODIFIED(desc, regnum); } desc.flags |= OPFLAG_READS_MEMORY; desc.cycles = 32 - G_RD(op); -- cgit v1.2.3