diff options
Diffstat (limited to 'src/devices/cpu/powerpc/ppcfe.cpp')
-rw-r--r-- | src/devices/cpu/powerpc/ppcfe.cpp | 96 |
1 files changed, 94 insertions, 2 deletions
diff --git a/src/devices/cpu/powerpc/ppcfe.cpp b/src/devices/cpu/powerpc/ppcfe.cpp index fbb6ae3a313..1e8fb105ee1 100644 --- a/src/devices/cpu/powerpc/ppcfe.cpp +++ b/src/devices/cpu/powerpc/ppcfe.cpp @@ -74,7 +74,7 @@ bool ppc_device::frontend::describe(opcode_desc &desc, const opcode_desc *prev) int regnum; // compute the physical PC - if (!m_ppc.memory_translate(AS_PROGRAM, TRANSLATE_FETCH, desc.physpc)) + if (m_ppc.ppccom_translate_address_internal(TR_FETCH, false, desc.physpc) > 1) { // uh-oh: a page fault; leave the description empty and just if this is the first instruction, leave it empty and // mark as needing to validate; otherwise, just end the sequence here @@ -119,6 +119,16 @@ bool ppc_device::frontend::describe(opcode_desc &desc, const opcode_desc *prev) desc.cycles = 2; // ??? return true; + case 0x09: // DOZI (POWER) + if (!(m_ppc.m_cap & PPCCAP_LEGACY_POWER)) + { + return false; + } + + GPR_USED_OR_ZERO(desc, G_RA(op)); + GPR_MODIFIED(desc, G_RD(op)); + return true; + case 0x0e: // ADDI case 0x0f: // ADDIS GPR_USED_OR_ZERO(desc, G_RA(op)); @@ -289,8 +299,12 @@ bool ppc_device::frontend::describe(opcode_desc &desc, const opcode_desc *prev) case 0x2e: // LMW GPR_USED_OR_ZERO(desc, G_RA(op)); + for (regnum = G_RD(op); regnum < 32; regnum++) - 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); return true; @@ -711,6 +725,7 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc case 0x136: // ECIWX if (!(m_ppc.m_cap & PPCCAP_VEA)) return false; + [[fallthrough]]; case 0x014: // LWARX case 0x017: // LWZX case 0x057: // LBZX @@ -920,6 +935,7 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc case 0x1b6: // ECOWX if (!(m_ppc.m_cap & PPCCAP_VEA)) return false; + [[fallthrough]]; case 0x096: // STWCX. case 0x097: // STWX case 0x0d7: // STBX @@ -1150,6 +1166,81 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc return false; desc.flags |= OPFLAG_CAN_CHANGE_MODES | OPFLAG_CAN_CAUSE_EXCEPTION | OPFLAG_END_SEQUENCE; return true; + + case 0x14b: // DIV (POWER) + case 0x16b: // DIVS (POWER) + if (!(m_ppc.m_cap & PPCCAP_LEGACY_POWER)) + { + return false; + } + + GPR_USED(desc, G_RA(op)); + GPR_USED(desc, G_RB(op)); + GPR_MODIFIED(desc, G_RD(op)); + XER_OV_MODIFIED(desc); + XER_SO_MODIFIED(desc); + if (op & M_RC) + CR_MODIFIED(desc, 0); + return true; + + case 0x6b: // MUL (POWER) + if (!(m_ppc.m_cap & PPCCAP_LEGACY_POWER)) + { + return false; + } + + GPR_USED(desc, G_RA(op)); + GPR_USED(desc, G_RB(op)); + GPR_MODIFIED(desc, G_RD(op)); + XER_OV_MODIFIED(desc); + XER_SO_MODIFIED(desc); + if (op & M_RC) + CR_MODIFIED(desc, 0); + return true; + + case 0x108: // DOZ (POWER) + if (!(m_ppc.m_cap & PPCCAP_LEGACY_POWER)) + { + return false; + } + + GPR_USED(desc, G_RA(op)); + GPR_USED(desc, G_RB(op)); + GPR_MODIFIED(desc, G_RD(op)); + XER_OV_MODIFIED(desc); + XER_SO_MODIFIED(desc); + if (op & M_RC) + CR_MODIFIED(desc, 0); + return true; + + case 0x168: // ABS (POWER) + case 0x1e8: // NABS (POWER) + if (!(m_ppc.m_cap & PPCCAP_LEGACY_POWER)) + { + return false; + } + + GPR_USED(desc, G_RA(op)); + GPR_USED(desc, G_RB(op)); + GPR_MODIFIED(desc, G_RD(op)); + XER_OV_MODIFIED(desc); + XER_SO_MODIFIED(desc); + if (op & M_RC) + CR_MODIFIED(desc, 0); + return true; + + case 0x21d: // MASKIR (POWER) + if (!(m_ppc.m_cap & PPCCAP_LEGACY_POWER)) + { + return false; + } + + GPR_USED(desc, G_RS(op)); + GPR_USED(desc, G_RB(op)); + GPR_MODIFIED(desc, G_RA(op)); + if (op & M_RC) + CR_MODIFIED(desc, 0); + return true; } return false; @@ -1339,6 +1430,7 @@ bool ppc_device::frontend::describe_3f(uint32_t op, opcode_desc &desc, const opc case 0x00e: // FCTIWx case 0x00f: // FCTIWZx FPSCR_MODIFIED(desc, 4); + [[fallthrough]]; case 0x028: // FNEGx case 0x048: // FMRx case 0x088: // FNABSx |