Skip to content

Commit 702bda5

Browse files
authored
cpu/powerpc: Don't generalte illegal instruction exception for lmw invalid forms (fixes MT08791). (#11775)
1 parent 2dbabc2 commit 702bda5

File tree

2 files changed

+9
-30
lines changed

2 files changed

+9
-30
lines changed

src/devices/cpu/powerpc/ppcdrc.cpp

+6-18
Original file line numberDiff line numberDiff line change
@@ -2257,26 +2257,14 @@ bool ppc_device::generate_opcode(drcuml_block &block, compiler_state *compiler,
22572257
UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IMMU(op)); // mapvar dsisr,DSISR_IMMU(op)
22582258
UML_MOV(block, mem(&m_core->tempaddr), R32Z(G_RA(op))); // mov [tempaddr],ra
22592259

2260-
if (G_RD(op) <= G_RA(op) && !(m_cap & PPCCAP_4XX) && m_flavor != PPC_MODEL_601)
2260+
for (int regnum = G_RD(op); regnum < 32; regnum++)
22612261
{
2262-
// RA being in the range is an invalid form
2263-
// 403 and 405 manual allows writes where regnum != RA || regnum == 31, regnum == RA is skipped
2264-
// 601 user manual lists no special rules for R31 being valid but regnum == RA is skipped
2265-
// 603 and above just says it's an invalid form
2266-
// tropchnc (403GA) is known to use this behavior
2267-
UML_EXH(block, *m_exception[EXCEPTION_PROGRAM], 0x80000); // exh exception_program,0x80000
2268-
}
2269-
else
2270-
{
2271-
for (int regnum = G_RD(op); regnum < 32; regnum++)
2272-
{
2273-
UML_ADD(block, I0, mem(&m_core->tempaddr), (int16_t)G_SIMM(op) + 4 * (regnum - G_RD(op)));
2274-
// add i0,[tempaddr],simm + 4*(regnum-rd)
2275-
UML_CALLH(block, *m_read32align[m_core->mode]); // callh read32align
2262+
UML_ADD(block, I0, mem(&m_core->tempaddr), (int16_t)G_SIMM(op) + 4 * (regnum - G_RD(op)));
2263+
// add i0,[tempaddr],simm + 4*(regnum-rd)
2264+
UML_CALLH(block, *m_read32align[m_core->mode]); // callh read32align
22762265

2277-
if (regnum != G_RA(op) || ((m_cap & PPCCAP_4XX) && regnum == 31))
2278-
UML_MOV(block, R32(regnum), I0); // mov regnum,i0
2279-
}
2266+
if (regnum != G_RA(op) || ((m_cap & PPCCAP_4XX) && regnum == 31))
2267+
UML_MOV(block, R32(regnum), I0); // mov regnum,i0
22802268
}
22812269
generate_update_cycles(block, compiler, desc->pc + 4, true); // <update cycles>
22822270
return true;

src/devices/cpu/powerpc/ppcfe.cpp

+3-12
Original file line numberDiff line numberDiff line change
@@ -290,19 +290,10 @@ bool ppc_device::frontend::describe(opcode_desc &desc, const opcode_desc *prev)
290290
case 0x2e: // LMW
291291
GPR_USED_OR_ZERO(desc, G_RA(op));
292292

293-
if (G_RD(op) <= G_RA(op) && !(m_ppc.m_cap & PPCCAP_4XX) && !is_601_class())
293+
for (regnum = G_RD(op); regnum < 32; regnum++)
294294
{
295-
// Undefined invalid form that has different behavior between CPUs
296-
// See ppcdrc.cpp for a more detailed explanation
297-
desc.flags |= OPFLAG_INVALID_OPCODE;
298-
}
299-
else
300-
{
301-
for (regnum = G_RD(op); regnum < 32; regnum++)
302-
{
303-
if (regnum != G_RA(op) || ((m_ppc.m_cap & PPCCAP_4XX) && regnum == 31))
304-
GPR_MODIFIED(desc, regnum);
305-
}
295+
if (regnum != G_RA(op) || ((m_ppc.m_cap & PPCCAP_4XX) && regnum == 31))
296+
GPR_MODIFIED(desc, regnum);
306297
}
307298
desc.flags |= OPFLAG_READS_MEMORY;
308299
desc.cycles = 32 - G_RD(op);

0 commit comments

Comments
 (0)