diff options
author | 2015-09-13 08:41:44 +0200 | |
---|---|---|
committer | 2015-09-13 08:41:44 +0200 | |
commit | f88cefad27a1737c76e09d99c9fb43e173506081 (patch) | |
tree | 2d8167d03579c46e226471747eb4407bd00ed6fa /src/emu/cpu/mips/mips3fe.c | |
parent | e92ac9e0fa8e99869894bea00589bbb526be30aa (diff) |
Move all devices into separate part of src tree (nw)
Diffstat (limited to 'src/emu/cpu/mips/mips3fe.c')
-rw-r--r-- | src/emu/cpu/mips/mips3fe.c | 741 |
1 files changed, 0 insertions, 741 deletions
diff --git a/src/emu/cpu/mips/mips3fe.c b/src/emu/cpu/mips/mips3fe.c deleted file mode 100644 index 42055c39e24..00000000000 --- a/src/emu/cpu/mips/mips3fe.c +++ /dev/null @@ -1,741 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Aaron Giles -/*************************************************************************** - - mips3fe.c - - Front-end for MIPS3 recompiler - -***************************************************************************/ - -#include "emu.h" -#include "mips3fe.h" -#include "mips3com.h" - - -//************************************************************************** -// MIPS3 FRONTEND -//************************************************************************** - -//------------------------------------------------- -// mips3_frontend - constructor -//------------------------------------------------- - -mips3_frontend::mips3_frontend(mips3_device *mips3, UINT32 window_start, UINT32 window_end, UINT32 max_sequence) - : drc_frontend(*mips3, window_start, window_end, max_sequence), - m_mips3(mips3) -{ -} - - -//------------------------------------------------- -// describe - build a description of a single -// instruction -//------------------------------------------------- - -bool mips3_frontend::describe(opcode_desc &desc, const opcode_desc *prev) -{ - UINT32 op, opswitch; - - // compute the physical PC - assert((desc.physpc & 3) == 0); - if (!m_mips3->memory_translate(AS_PROGRAM, TRANSLATE_FETCH, desc.physpc)) - { - // 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 - desc.flags |= OPFLAG_VALIDATE_TLB | OPFLAG_CAN_CAUSE_EXCEPTION | OPFLAG_COMPILER_PAGE_FAULT | OPFLAG_VIRTUAL_NOOP | OPFLAG_END_SEQUENCE; - return true; - } - - // fetch the opcode - assert((desc.physpc & 3) == 0); - op = desc.opptr.l[0] = m_mips3->m_direct->read_dword(desc.physpc); - - // all instructions are 4 bytes and default to a single cycle each - desc.length = 4; - desc.cycles = 1; - - // parse the instruction - opswitch = op >> 26; - switch (opswitch) - { - case 0x00: // SPECIAL - return describe_special(op, desc); - - case 0x01: // REGIMM - return describe_regimm(op, desc); - - case 0x10: // COP0 - return describe_cop0(op, desc); - - case 0x11: // COP1 - return describe_cop1(op, desc); - - case 0x12: // COP2 - return describe_cop2(op, desc); - - case 0x13: // COP1X - MIPS IV - if (m_mips3->m_flavor < mips3_device::MIPS3_TYPE_MIPS_IV) - return false; - return describe_cop1x(op, desc); - - case 0x1c: // IDT-specific opcodes: mad/madu/mul on R4640/4650, msub on RC32364 - return describe_idt(op, desc); - - case 0x02: // J - desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; - desc.targetpc = (desc.pc & 0xf0000000) | (LIMMVAL << 2); - desc.delayslots = 1; - return true; - - case 0x03: // JAL - desc.regout[0] |= REGFLAG_R(31); - desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; - desc.targetpc = (desc.pc & 0xf0000000) | (LIMMVAL << 2); - desc.delayslots = 1; - return true; - - case 0x04: // BEQ - case 0x05: // BNE - case 0x14: // BEQL - case 0x15: // BNEL - if ((opswitch == 0x04 || opswitch == 0x14) && RSREG == RTREG) - desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; - else - { - desc.regin[0] |= REGFLAG_R(RSREG) | REGFLAG_R(RTREG); - desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH; - } - desc.targetpc = desc.pc + 4 + SIMMVAL * 4; - desc.delayslots = 1; - desc.skipslots = (opswitch & 0x10) ? 1 : 0; - return true; - - case 0x06: // BLEZ - case 0x07: // BGTZ - case 0x16: // BLEZL - case 0x17: // BGTZL - if ((opswitch == 0x06 || opswitch == 0x16) && RSREG == 0) - desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; - else - { - desc.regin[0] |= REGFLAG_R(RSREG); - desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH; - } - desc.targetpc = desc.pc + 4 + SIMMVAL * 4; - desc.delayslots = 1; - desc.skipslots = (opswitch & 0x10) ? 1 : 0; - return true; - - case 0x08: // ADDI - case 0x18: // DADDI - desc.regin[0] |= REGFLAG_R(RSREG); - desc.regout[0] |= REGFLAG_R(RTREG); - desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; - return true; - - case 0x09: // ADDIU - case 0x0a: // SLTI - case 0x0b: // SLTIU - case 0x0c: // ANDI - case 0x0d: // ORI - case 0x0e: // XORI - case 0x19: // DADDIU - desc.regin[0] |= REGFLAG_R(RSREG); - desc.regout[0] |= REGFLAG_R(RTREG); - return true; - - case 0x0f: // LUI - desc.regout[0] |= REGFLAG_R(RTREG); - return true; - - case 0x1a: // LDL - case 0x1b: // LDR - case 0x22: // LWL - case 0x26: // LWR - desc.regin[0] |= REGFLAG_R(RTREG); - case 0x20: // LB - case 0x21: // LH - case 0x23: // LW - case 0x24: // LBU - case 0x25: // LHU - case 0x27: // LWU - case 0x30: // LL - case 0x34: // LLD - case 0x37: // LD - desc.regin[0] |= REGFLAG_R(RSREG); - desc.regout[0] |= REGFLAG_R(RTREG); - desc.flags |= OPFLAG_READS_MEMORY | OPFLAG_CAN_CAUSE_EXCEPTION; - return true; - - case 0x28: // SB - case 0x29: // SH - case 0x2a: // SWL - case 0x2b: // SW - case 0x2c: // SDL - case 0x2d: // SDR - case 0x2e: // SWR - case 0x3f: // SD - desc.regin[0] |= REGFLAG_R(RSREG) | REGFLAG_R(RTREG); - desc.flags |= OPFLAG_WRITES_MEMORY | OPFLAG_CAN_CAUSE_EXCEPTION; - return true; - - case 0x38: // SC - case 0x3c: // SCD - desc.regin[0] |= REGFLAG_R(RSREG) | REGFLAG_R(RTREG); - desc.regout[0] |= REGFLAG_R(RTREG); - desc.flags |= OPFLAG_WRITES_MEMORY | OPFLAG_CAN_CAUSE_EXCEPTION; - return true; - - case 0x31: // LWC1 - case 0x35: // LDC1 - desc.regin[0] |= REGFLAG_R(RSREG); - desc.regout[1] |= REGFLAG_CPR1(RTREG); - desc.flags |= OPFLAG_READS_MEMORY | OPFLAG_CAN_CAUSE_EXCEPTION; - return true; - - case 0x39: // SWC1 - case 0x3d: // SDC1 - desc.regin[0] |= REGFLAG_R(RSREG); - desc.regin[1] |= REGFLAG_CPR1(RTREG); - desc.flags |= OPFLAG_WRITES_MEMORY | OPFLAG_CAN_CAUSE_EXCEPTION; - return true; - - case 0x32: // LWC2 - case 0x36: // LDC2 - desc.regin[0] |= REGFLAG_R(RSREG); - desc.flags |= OPFLAG_READS_MEMORY | OPFLAG_CAN_CAUSE_EXCEPTION; - return true; - - case 0x3a: // SWC2 - case 0x3e: // SDC2 - desc.regin[0] |= REGFLAG_R(RSREG); - desc.flags |= OPFLAG_WRITES_MEMORY | OPFLAG_CAN_CAUSE_EXCEPTION; - return true; - - case 0x33: // PREF - if (m_mips3->m_flavor < mips3_device::MIPS3_TYPE_MIPS_IV) - return false; - case 0x2f: // CACHE - // effective no-op - return true; - } - - return false; -} - - -//------------------------------------------------- -// describe_special - build a description of a -// single instruction in the 'special' group -//------------------------------------------------- - -bool mips3_frontend::describe_special(UINT32 op, opcode_desc &desc) -{ - switch (op & 63) - { - case 0x00: // SLL - case 0x02: // SRL - case 0x03: // SRA - case 0x38: // DSLL - case 0x3a: // DSRL - case 0x3b: // DSRA - case 0x3c: // DSLL32 - case 0x3e: // DSRL32 - case 0x3f: // DSRA32 - desc.regin[0] |= REGFLAG_R(RTREG); - desc.regout[0] |= REGFLAG_R(RDREG); - return true; - - case 0x0a: // MOVZ - MIPS IV - case 0x0b: // MOVN - MIPS IV - if (m_mips3->m_flavor < mips3_device::MIPS3_TYPE_MIPS_IV) - return false; - desc.regin[0] |= REGFLAG_R(RDREG); - case 0x04: // SLLV - case 0x06: // SRLV - case 0x07: // SRAV - case 0x14: // DSLLV - case 0x16: // DSRLV - case 0x17: // DSRAV - case 0x21: // ADDU - case 0x23: // SUBU - case 0x24: // AND - case 0x25: // OR - case 0x26: // XOR - case 0x27: // NOR - case 0x2a: // SLT - case 0x2b: // SLTU - case 0x2d: // DADDU - case 0x2f: // DSUBU - desc.regin[0] |= REGFLAG_R(RSREG) | REGFLAG_R(RTREG); - desc.regout[0] |= REGFLAG_R(RDREG); - return true; - - case 0x20: // ADD - case 0x22: // SUB - case 0x2c: // DADD - case 0x2e: // DSUB - desc.regin[0] |= REGFLAG_R(RSREG) | REGFLAG_R(RTREG); - desc.regout[0] |= REGFLAG_R(RDREG); - desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; - return true; - - case 0x30: // TGE - case 0x31: // TGEU - case 0x32: // TLT - case 0x33: // TLTU - case 0x34: // TEQ - case 0x36: // TNE - desc.regin[0] |= REGFLAG_R(RSREG) | REGFLAG_R(RTREG); - desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; - return true; - - case 0x01: // MOVF - MIPS IV - if (m_mips3->m_flavor < mips3_device::MIPS3_TYPE_MIPS_IV) - return false; - desc.regin[0] |= REGFLAG_R(RSREG); - desc.regin[2] |= REGFLAG_FCC; - desc.regout[0] |= REGFLAG_R(RDREG); - return true; - - case 0x08: // JR - desc.regin[0] |= REGFLAG_R(RSREG); - desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; - desc.targetpc = BRANCH_TARGET_DYNAMIC; - desc.delayslots = 1; - return true; - - case 0x09: // JALR - desc.regin[0] |= REGFLAG_R(RSREG); - desc.regout[0] |= REGFLAG_R(RDREG); - desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; - desc.targetpc = BRANCH_TARGET_DYNAMIC; - desc.delayslots = 1; - return true; - - case 0x10: // MFHI - desc.regin[0] |= REGFLAG_HI; - desc.regout[0] |= REGFLAG_R(RDREG); - return true; - - case 0x11: // MTHI - desc.regin[0] |= REGFLAG_R(RSREG); - desc.regout[0] |= REGFLAG_HI; - return true; - - case 0x12: // MFLO - desc.regin[2] |= REGFLAG_LO; - desc.regout[0] |= REGFLAG_R(RDREG); - return true; - - case 0x13: // MTLO - desc.regin[0] |= REGFLAG_R(RSREG); - desc.regout[2] |= REGFLAG_LO; - return true; - - case 0x18: // MULT - case 0x19: // MULTU - desc.regin[0] |= REGFLAG_R(RSREG) | REGFLAG_R(RTREG); - desc.regout[2] |= REGFLAG_LO | REGFLAG_HI; - desc.cycles = 3; - return true; - - case 0x1a: // DIV - case 0x1b: // DIVU - desc.regin[0] |= REGFLAG_R(RSREG) | REGFLAG_R(RTREG); - desc.regout[2] |= REGFLAG_LO | REGFLAG_HI; - desc.cycles = 35; - return true; - - case 0x1c: // DMULT - case 0x1d: // DMULTU - desc.regin[0] |= REGFLAG_R(RSREG) | REGFLAG_R(RTREG); - desc.regout[2] |= REGFLAG_LO | REGFLAG_HI; - desc.cycles = 7; - return true; - - case 0x1e: // DDIV - case 0x1f: // DDIVU - desc.regin[0] |= REGFLAG_R(RSREG) | REGFLAG_R(RTREG); - desc.regout[2] |= REGFLAG_LO | REGFLAG_HI; - desc.cycles = 67; - return true; - - case 0x0c: // SYSCALL - case 0x0d: // BREAK - desc.flags |= OPFLAG_WILL_CAUSE_EXCEPTION | OPFLAG_END_SEQUENCE; - return true; - - case 0x0f: // SYNC - // effective no-op - return true; - } - - return false; -} - - -//------------------------------------------------- -// describe_regimm - build a description of a -// single instruction in the 'regimm' group -//------------------------------------------------- - -bool mips3_frontend::describe_regimm(UINT32 op, opcode_desc &desc) -{ - switch (RTREG) - { - case 0x00: // BLTZ - case 0x01: // BGEZ - case 0x02: // BLTZL - case 0x03: // BGEZL - if (RTREG == 0x01 && RSREG == 0) - desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; - else - { - desc.regin[0] |= REGFLAG_R(RSREG); - desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH; - } - desc.targetpc = desc.pc + 4 + SIMMVAL * 4; - desc.delayslots = 1; - desc.skipslots = (RTREG & 0x02) ? 1 : 0; - return true; - - case 0x08: // TGEI - case 0x09: // TGEIU - case 0x0a: // TLTI - case 0x0b: // TLTIU - case 0x0c: // TEQI - case 0x0e: // TNEI - desc.regin[0] |= REGFLAG_R(RSREG); - desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; - return true; - - case 0x10: // BLTZAL - case 0x11: // BGEZAL - case 0x12: // BLTZALL - case 0x13: // BGEZALL - if (RTREG == 0x11 && RSREG == 0) - desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; - else - { - desc.regin[0] |= REGFLAG_R(RSREG); - desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH; - } - desc.regout[0] |= REGFLAG_R(31); - desc.targetpc = desc.pc + 4 + SIMMVAL * 4; - desc.delayslots = 1; - desc.skipslots = (RTREG & 0x02) ? 1 : 0; - return true; - } - - return false; -} - - -//------------------------------------------------- -// describe_idt - build a description of a single -// instruction in the IDT-specific group -//------------------------------------------------- - -bool mips3_frontend::describe_idt(UINT32 op, opcode_desc &desc) -{ - // only on the R4650 - if (m_mips3->m_flavor != mips3_device::MIPS3_TYPE_R4650) - return false; - - switch (op & 0x1f) - { - case 0: // MAD - case 1: // MADU - desc.regin[0] |= REGFLAG_R(RSREG) | REGFLAG_R(RTREG); - desc.regin[2] |= REGFLAG_LO | REGFLAG_HI; - desc.regout[2] |= REGFLAG_LO | REGFLAG_HI; - return true; - - case 2: // MUL - desc.regin[0] |= REGFLAG_R(RSREG) | REGFLAG_R(RTREG); - desc.regout[0] |= REGFLAG_R(RDREG); - desc.cycles = 3; - return true; - } - - return false; -} - - -//------------------------------------------------- -// describe_cop0 - build a description of a -// single instruction in the COP0 group -//------------------------------------------------- - -bool mips3_frontend::describe_cop0(UINT32 op, opcode_desc &desc) -{ - // any COP0 instruction can potentially cause an exception - desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; - - switch (RSREG) - { - case 0x00: // MFCz - case 0x01: // DMFCz - if (RDREG == COP0_Count) - desc.cycles += MIPS3_COUNT_READ_CYCLES; - if (RDREG == COP0_Cause) - desc.cycles += MIPS3_CAUSE_READ_CYCLES; - desc.regout[0] |= REGFLAG_R(RTREG); - return true; - - case 0x02: // CFCz - desc.regout[0] |= REGFLAG_R(RTREG); - return true; - - case 0x04: // MTCz - case 0x05: // DMTCz - case 0x06: // CTCz - desc.regin[0] |= REGFLAG_R(RTREG); - if (RSREG == 0x04 || RSREG == 0x05) - { - if (RDREG == COP0_Cause) - desc.flags |= OPFLAG_CAN_TRIGGER_SW_INT; - if (RDREG == COP0_Status) - desc.flags |= OPFLAG_CAN_EXPOSE_EXTERNAL_INT | OPFLAG_CAN_CHANGE_MODES | OPFLAG_END_SEQUENCE; - } - return true; - - case 0x08: // BC - switch (RTREG) - { - case 0x00: // BCzF - case 0x01: // BCzT - desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH; - desc.targetpc = desc.pc + 4 + SIMMVAL * 4; - desc.delayslots = 1; - return true; - } - return false; - - case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17: - case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f: // COP - switch (op & 0x01ffffff) - { - case 0x01: // TLBR - case 0x08: // TLBP - case 0x20: // WAIT - return true; - - case 0x02: // TLBWI - case 0x06: // TLBWR - desc.flags |= OPFLAG_MODIFIES_TRANSLATION; - return true; - - case 0x18: // ERET - desc.flags |= OPFLAG_CAN_CHANGE_MODES | OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; - return true; - } - return false; - } - - return false; -} - - -//------------------------------------------------- -// describe_cop1 - build a description of a -// single instruction in the COP1 group -//------------------------------------------------- - -bool mips3_frontend::describe_cop1(UINT32 op, opcode_desc &desc) -{ - // any COP1 instruction can potentially cause an exception -// desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; - - switch (RSREG) - { - case 0x00: // MFCz - case 0x01: // DMFCz - desc.regin[1] |= REGFLAG_CPR1(RDREG); - desc.regout[0] |= REGFLAG_R(RTREG); - return true; - - case 0x02: // CFCz - desc.regout[0] |= REGFLAG_R(RTREG); - return true; - - case 0x04: // MTCz - case 0x05: // DMTCz - desc.regin[0] |= REGFLAG_R(RTREG); - desc.regout[1] |= REGFLAG_CPR1(RDREG); - return true; - - case 0x06: // CTCz - desc.regin[0] |= REGFLAG_R(RTREG); - return true; - - case 0x08: // BC - switch (RTREG & 3) - { - case 0x00: // BCzF - case 0x01: // BCzT - case 0x02: // BCzFL - case 0x03: // BCzTL - desc.regin[2] |= REGFLAG_FCC; - desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH; - desc.targetpc = desc.pc + 4 + SIMMVAL * 4; - desc.delayslots = 1; - desc.skipslots = (RTREG & 0x02) ? 1 : 0; - return true; - } - return false; - - case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17: - case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f: // COP - switch (op & 0x3f) - { - case 0x12: // MOVZ - MIPS IV - case 0x13: // MOVN - MIPS IV - if (m_mips3->m_flavor < mips3_device::MIPS3_TYPE_MIPS_IV) - return false; - case 0x00: // ADD - case 0x01: // SUB - case 0x02: // MUL - case 0x03: // DIV - desc.regin[1] |= REGFLAG_CPR1(FSREG) | REGFLAG_CPR1(FTREG); - desc.regout[1] |= REGFLAG_CPR1(FDREG); - return true; - - case 0x15: // RECIP - MIPS IV - case 0x16: // RSQRT - MIPS IV - if (m_mips3->m_flavor < mips3_device::MIPS3_TYPE_MIPS_IV) - return false; - case 0x04: // SQRT - case 0x05: // ABS - case 0x06: // MOV - case 0x07: // NEG - case 0x08: // ROUND.L - case 0x09: // TRUNC.L - case 0x0a: // CEIL.L - case 0x0b: // FLOOR.L - case 0x0c: // ROUND.W - case 0x0d: // TRUNC.W - case 0x0e: // CEIL.W - case 0x0f: // FLOOR.W - case 0x20: // CVT.S - case 0x21: // CVT.D - case 0x24: // CVT.W - case 0x25: // CVT.L - desc.regin[1] |= REGFLAG_CPR1(FSREG); - desc.regout[1] |= REGFLAG_CPR1(FDREG); - return true; - - case 0x11: // MOVT/F - MIPS IV - if (m_mips3->m_flavor < mips3_device::MIPS3_TYPE_MIPS_IV) - return false; - desc.regin[1] |= REGFLAG_CPR1(FSREG); - desc.regin[2] |= REGFLAG_FCC; - desc.regout[1] |= REGFLAG_CPR1(FDREG); - return true; - - case 0x30: case 0x38: // C.F - case 0x31: case 0x39: // C.UN - desc.regout[2] |= REGFLAG_FCC; - return true; - - case 0x32: case 0x3a: // C.EQ - case 0x33: case 0x3b: // C.UEQ - case 0x34: case 0x3c: // C.OLT - case 0x35: case 0x3d: // C.ULT - case 0x36: case 0x3e: // C.OLE - case 0x37: case 0x3f: // C.ULE - desc.regin[1] |= REGFLAG_CPR1(FSREG) | REGFLAG_CPR1(FTREG); - desc.regout[2] |= REGFLAG_FCC; - return true; - } - return false; - } - - return false; -} - - -//------------------------------------------------- -// describe_cop1x - build a description of a -// single instruction in the COP1X group -//------------------------------------------------- - -bool mips3_frontend::describe_cop1x(UINT32 op, opcode_desc &desc) -{ - // any COP1 instruction can potentially cause an exception -// desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; - - switch (op & 0x3f) - { - case 0x00: // LWXC1 - case 0x01: // LDXC1 - desc.regin[0] |= REGFLAG_R(RSREG) | REGFLAG_R(RTREG); - desc.regout[1] |= REGFLAG_CPR1(FDREG); - desc.flags |= OPFLAG_READS_MEMORY; - return true; - - case 0x08: // SWXC1 - case 0x09: // SDXC1 - desc.regin[0] |= REGFLAG_R(RSREG) | REGFLAG_R(RTREG); - desc.regin[1] |= REGFLAG_CPR1(FDREG); - desc.flags |= OPFLAG_WRITES_MEMORY; - return true; - - case 0x0f: // PREFX - // effective no-op - return true; - - case 0x20: case 0x21: // MADD - case 0x28: case 0x29: // MSUB - case 0x30: case 0x31: // NMADD - case 0x38: case 0x39: // NMSUB - desc.regin[1] |= REGFLAG_CPR1(FSREG) | REGFLAG_CPR1(FTREG) | REGFLAG_CPR1(FRREG); - desc.regout[1] |= REGFLAG_CPR1(FDREG); - return true; - } - - return false; -} - - -//------------------------------------------------- -// describe_cop2 - build a description of a -// single instruction in the COP2 group -//------------------------------------------------- - -bool mips3_frontend::describe_cop2(UINT32 op, opcode_desc &desc) -{ - // any COP2 instruction can potentially cause an exception - desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; - - switch (RSREG) - { - case 0x00: // MFCz - case 0x01: // DMFCz - case 0x02: // CFCz - desc.regout[0] |= REGFLAG_R(RTREG); - return true; - - case 0x04: // MTCz - case 0x05: // DMTCz - case 0x06: // CTCz - desc.regin[0] |= REGFLAG_R(RTREG); - return true; - - case 0x08: // BC - switch (RTREG) - { - case 0x00: // BCzF - case 0x01: // BCzT - desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH; - desc.targetpc = desc.pc + 4 + SIMMVAL * 4; - desc.delayslots = 1; - return true; - } - return false; - } - - return false; -} |