summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author mooglyguy <therealmogminer@gmail.com>2018-06-23 12:59:15 +0200
committer mooglyguy <therealmogminer@gmail.com>2018-06-23 12:59:38 +0200
commitdd30364632520a2137858d43760d5a6f8a6077fc (patch)
tree10cdd34eb1adc888c5b3c24ee59f9e415f9e8e4b
parentb307f27d54ec161b781fb48e88b426016d65d7a3 (diff)
mips3: Added disassembler for Emotion Engine core opcodes. VU macro ops are still to-do. [Ryan Holtz]
-rw-r--r--src/devices/cpu/mips/mips3.cpp89
-rw-r--r--src/devices/cpu/mips/mips3.h164
-rw-r--r--src/devices/cpu/mips/mips3com.cpp3
-rw-r--r--src/devices/cpu/mips/mips3dsm.cpp737
-rw-r--r--src/devices/cpu/mips/mips3dsm.h27
-rw-r--r--src/mame/drivers/ps2sony.cpp2
6 files changed, 707 insertions, 315 deletions
diff --git a/src/devices/cpu/mips/mips3.cpp b/src/devices/cpu/mips/mips3.cpp
index 411c6ca5d6f..08841b0f5a6 100644
--- a/src/devices/cpu/mips/mips3.cpp
+++ b/src/devices/cpu/mips/mips3.cpp
@@ -115,6 +115,7 @@ DEFINE_DEVICE_TYPE(R5000BE, r5000be_device, "r5000be", "MIPS R5000 (big)")
DEFINE_DEVICE_TYPE(R5000LE, r5000le_device, "r5000le", "MIPS R5000 (little)")
DEFINE_DEVICE_TYPE(VR5500BE, vr5500be_device, "vr5500be", "NEC VR5500 (big)")
DEFINE_DEVICE_TYPE(VR5500LE, vr5500le_device, "vr5500le", "NEC VR5500 (little)")
+DEFINE_DEVICE_TYPE(R5900LE, r5900le_device, "r5900le", "Emotion Engine Core")
DEFINE_DEVICE_TYPE(QED5271BE, qed5271be_device, "qed5271be", "MIPS QED5271 (big)")
DEFINE_DEVICE_TYPE(QED5271LE, qed5271le_device, "qed5271le", "MIPS QED5271 (little)")
DEFINE_DEVICE_TYPE(RM7000BE, rm7000be_device, "rm7000be", "MIPS RM7000 (big)")
@@ -334,6 +335,7 @@ void mips3_device::device_start()
/* initialize based on the config */
memset(m_core, 0, sizeof(internal_mips3_state));
+ m_core->vfr[0][3] = 1.0f;
m_cpu_clock = clock();
m_program = &space(AS_PROGRAM);
@@ -986,12 +988,16 @@ bool mips3_device::memory_translate(int spacenum, int intention, offs_t &address
return true;
}
-
std::unique_ptr<util::disasm_interface> mips3_device::create_disassembler()
{
return std::make_unique<mips3_disassembler>();
}
+std::unique_ptr<util::disasm_interface> r5900le_device::create_disassembler()
+{
+ return std::make_unique<ee_disassembler>();
+}
+
/***************************************************************************
@@ -2556,21 +2562,21 @@ void mips3_device::handle_regimm(uint32_t op)
{
switch (RTREG)
{
- case 0x00: /* BLTZ */ if ((int64_t)RSVAL64 < 0) ADDPC(SIMMVAL); break;
- case 0x01: /* BGEZ */ if ((int64_t)RSVAL64 >= 0) ADDPC(SIMMVAL); break;
- case 0x02: /* BLTZL */ if ((int64_t)RSVAL64 < 0) ADDPC(SIMMVAL); else m_core->pc += 4; break;
- case 0x03: /* BGEZL */ if ((int64_t)RSVAL64 >= 0) ADDPC(SIMMVAL); else m_core->pc += 4; break;
- case 0x08: /* TGEI */ if ((int64_t)RSVAL64 >= SIMMVAL) generate_exception(EXCEPTION_TRAP, 1); break;
- case 0x09: /* TGEIU */ if (RSVAL64 >= UIMMVAL) generate_exception(EXCEPTION_TRAP, 1); break;
- case 0x0a: /* TLTI */ if ((int64_t)RSVAL64 < SIMMVAL) generate_exception(EXCEPTION_TRAP, 1); break;
- case 0x0b: /* TLTIU */ if (RSVAL64 >= UIMMVAL) generate_exception(EXCEPTION_TRAP, 1); break;
- case 0x0c: /* TEQI */ if (RSVAL64 == UIMMVAL) generate_exception(EXCEPTION_TRAP, 1); break;
- case 0x0e: /* TNEI */ if (RSVAL64 != UIMMVAL) generate_exception(EXCEPTION_TRAP, 1); break;
+ case 0x00: /* BLTZ */ if ((int64_t)RSVAL64 < 0) ADDPC(SIMMVAL); break;
+ case 0x01: /* BGEZ */ if ((int64_t)RSVAL64 >= 0) ADDPC(SIMMVAL); break;
+ case 0x02: /* BLTZL */ if ((int64_t)RSVAL64 < 0) ADDPC(SIMMVAL); else m_core->pc += 4; break;
+ case 0x03: /* BGEZL */ if ((int64_t)RSVAL64 >= 0) ADDPC(SIMMVAL); else m_core->pc += 4; break;
+ case 0x08: /* TGEI */ if ((int64_t)RSVAL64 >= SIMMVAL) generate_exception(EXCEPTION_TRAP, 1); break;
+ case 0x09: /* TGEIU */ if (RSVAL64 >= UIMMVAL) generate_exception(EXCEPTION_TRAP, 1); break;
+ case 0x0a: /* TLTI */ if ((int64_t)RSVAL64 < SIMMVAL) generate_exception(EXCEPTION_TRAP, 1); break;
+ case 0x0b: /* TLTIU */ if (RSVAL64 >= UIMMVAL) generate_exception(EXCEPTION_TRAP, 1); break;
+ case 0x0c: /* TEQI */ if (RSVAL64 == UIMMVAL) generate_exception(EXCEPTION_TRAP, 1); break;
+ case 0x0e: /* TNEI */ if (RSVAL64 != UIMMVAL) generate_exception(EXCEPTION_TRAP, 1); break;
case 0x10: /* BLTZAL */ m_core->r[31] = (int32_t)(m_core->pc + 4); if ((int64_t)RSVAL64 < 0) ADDPC(SIMMVAL); break;
case 0x11: /* BGEZAL */ m_core->r[31] = (int32_t)(m_core->pc + 4); if ((int64_t)RSVAL64 >= 0) ADDPC(SIMMVAL); break;
case 0x12: /* BLTZALL */ m_core->r[31] = (int32_t)(m_core->pc + 4); if ((int64_t)RSVAL64 < 0) ADDPC(SIMMVAL); else m_core->pc += 4; break;
case 0x13: /* BGEZALL */ m_core->r[31] = (int32_t)(m_core->pc + 4); if ((int64_t)RSVAL64 >= 0) ADDPC(SIMMVAL); else m_core->pc += 4; break;
- default: /* ??? */ invalid_instruction(op); break;
+ default: /* ??? */ handle_extra_regimm(op); break;
}
}
@@ -2683,18 +2689,18 @@ void mips3_device::handle_special(uint32_t op)
if (ENABLE_OVERFLOWS && RSVAL32 > ~RTVAL32) generate_exception(EXCEPTION_OVERFLOW, 1);
else if (RDREG) RDVAL64 = (int32_t)(RSVAL32 + RTVAL32);
break;
- case 0x21: /* ADDU */ if (RDREG) RDVAL64 = (int32_t)(RSVAL32 + RTVAL32); break;
+ case 0x21: /* ADDU */ if (RDREG) RDVAL64 = (int32_t)(RSVAL32 + RTVAL32); break;
case 0x22: /* SUB */
if (ENABLE_OVERFLOWS && RSVAL32 < RTVAL32) generate_exception(EXCEPTION_OVERFLOW, 1);
else if (RDREG) RDVAL64 = (int32_t)(RSVAL32 - RTVAL32);
break;
- case 0x23: /* SUBU */ if (RDREG) RDVAL64 = (int32_t)(RSVAL32 - RTVAL32); break;
+ case 0x23: /* SUBU */ if (RDREG) RDVAL64 = (int32_t)(RSVAL32 - RTVAL32); break;
case 0x24: /* AND */ if (RDREG) RDVAL64 = RSVAL64 & RTVAL64; break;
case 0x25: /* OR */ if (RDREG) RDVAL64 = RSVAL64 | RTVAL64; break;
case 0x26: /* XOR */ if (RDREG) RDVAL64 = RSVAL64 ^ RTVAL64; break;
case 0x27: /* NOR */ if (RDREG) RDVAL64 = ~(RSVAL64 | RTVAL64); break;
- case 0x2a: /* SLT */ if (RDREG) RDVAL64 = (int64_t)RSVAL64 < (int64_t)RTVAL64; break;
- case 0x2b: /* SLTU */ if (RDREG) RDVAL64 = (uint64_t)RSVAL64 < (uint64_t)RTVAL64; break;
+ case 0x2a: /* SLT */ if (RDREG) RDVAL64 = (int64_t)RSVAL64 < (int64_t)RTVAL64; break;
+ case 0x2b: /* SLTU */ if (RDREG) RDVAL64 = (uint64_t)RSVAL64 < (uint64_t)RTVAL64; break;
case 0x2c: /* DADD */
if (ENABLE_OVERFLOWS && RSVAL64 > ~RTVAL64) generate_exception(EXCEPTION_OVERFLOW, 1);
else if (RDREG) RDVAL64 = RSVAL64 + RTVAL64;
@@ -2713,14 +2719,50 @@ void mips3_device::handle_special(uint32_t op)
case 0x36: /* TNE */ if (RSVAL64 != RTVAL64) generate_exception(EXCEPTION_TRAP, 1); break;
case 0x38: /* DSLL */ if (RDREG) RDVAL64 = RTVAL64 << SHIFT; break;
case 0x3a: /* DSRL */ if (RDREG) RDVAL64 = RTVAL64 >> SHIFT; break;
- case 0x3b: /* DSRA */ if (RDREG) RDVAL64 = (int64_t)RTVAL64 >> SHIFT; break;
+ case 0x3b: /* DSRA */ if (RDREG) RDVAL64 = (int64_t)RTVAL64 >> SHIFT; break;
case 0x3c: /* DSLL32 */ if (RDREG) RDVAL64 = RTVAL64 << (SHIFT + 32); break;
case 0x3e: /* DSRL32 */ if (RDREG) RDVAL64 = RTVAL64 >> (SHIFT + 32); break;
- case 0x3f: /* DSRA32 */ if (RDREG) RDVAL64 = (int64_t)RTVAL64 >> (SHIFT + 32); break;
- default: /* ??? */ invalid_instruction(op); break;
+ case 0x3f: /* DSRA32 */ if (RDREG) RDVAL64 = (int64_t)RTVAL64 >> (SHIFT + 32); break;
+ default: /* ??? */ handle_extra_special(op); break;
+ }
+}
+
+void mips3_device::handle_extra_special(uint32_t op)
+{
+ invalid_instruction(op);
+}
+
+void r5900le_device::handle_extra_special(uint32_t op)
+{
+}
+
+void mips3_device::handle_extra_regimm(uint32_t op)
+{
+ invalid_instruction(op);
+}
+
+void r5900le_device::handle_extra_regimm(uint32_t op)
+{
+}
+
+void mips3_device::handle_idt(uint32_t op)
+{
+ switch (op & 0x1f)
+ {
+ case 2: /* MUL */
+ RDVAL64 = (int32_t)((int32_t)RSVAL32 * (int32_t)RTVAL32);
+ m_core->icount -= 3;
+ break;
+ default:
+ invalid_instruction(op);
+ break;
}
}
+void r5900le_device::handle_idt(uint32_t op)
+{
+}
+
void mips3_device::burn_cycles(int32_t cycles)
{
execute_burn(cycles);
@@ -2858,14 +2900,7 @@ void mips3_device::execute_run()
case 0x1a: /* LDL */ (this->*m_ldl)(op); break;
case 0x1b: /* LDR */ (this->*m_ldr)(op); break;
case 0x1c: /* IDT-specific opcodes: mad/madu/mul on R4640/4650, msub on RC32364 */
- switch (op & 0x1f)
- {
- case 2: /* MUL */
- RDVAL64 = (int32_t)((int32_t)RSVAL32 * (int32_t)RTVAL32);
- m_core->icount -= 3;
- break;
- default: invalid_instruction(op);
- }
+ handle_idt(op);
break;
case 0x20: /* LB */ if (RBYTE(SIMMVAL+RSVAL32, &temp) && RTREG) RTVAL64 = (int8_t)temp; break;
case 0x21: /* LH */ if (RHALF(SIMMVAL+RSVAL32, &temp) && RTREG) RTVAL64 = (int16_t)temp; break;
diff --git a/src/devices/cpu/mips/mips3.h b/src/devices/cpu/mips/mips3.h
index 6c192b5436c..1b4c5a77f7e 100644
--- a/src/devices/cpu/mips/mips3.h
+++ b/src/devices/cpu/mips/mips3.h
@@ -42,6 +42,7 @@ DECLARE_DEVICE_TYPE(QED5271BE, qed5271be_device)
DECLARE_DEVICE_TYPE(QED5271LE, qed5271le_device)
DECLARE_DEVICE_TYPE(RM7000BE, rm7000be_device)
DECLARE_DEVICE_TYPE(RM7000LE, rm7000le_device)
+DECLARE_DEVICE_TYPE(R5900LE, r5900le_device)
/***************************************************************************
@@ -260,6 +261,7 @@ protected:
MIPS3_TYPE_R5000,
MIPS3_TYPE_VR5500,
MIPS3_TYPE_QED5271,
+ MIPS3_TYPE_R5900,
MIPS3_TYPE_RM7000
};
@@ -309,73 +311,79 @@ private:
struct internal_mips3_state
{
/* core registers */
- uint32_t pc;
- int icount;
- uint64_t r[35];
+ uint32_t pc;
+ int icount;
+ uint64_t r[35];
- /* COP registers */
- uint64_t cpr[3][32];
- uint64_t ccr[3][32];
- uint32_t llbit;
+ /* upper 64 bits of 128-bit GPRs (R5900 only) */
+ uint64_t rh[35];
- uint32_t mode; /* current global mode */
+ /* COP registers */
+ uint64_t cpr[3][32];
+ uint64_t ccr[3][32];
+ uint32_t llbit;
- /* parameters for subroutines */
- uint64_t numcycles; /* return value from gettotalcycles */
- const char * format; /* format string for print_debug */
- uint32_t arg0; /* print_debug argument 1 */
- uint32_t arg1; /* print_debug argument 2 */
+ /* VU0 registers (R5900 only) */
+ float vfr[32][4];
+ uint32_t vcr[32];
- uint64_t count_zero_time;
- uint32_t compare_armed;
- uint32_t jmpdest; /* destination jump target */
+ uint32_t mode; /* current global mode */
+ /* parameters for subroutines */
+ uint64_t numcycles; /* return value from gettotalcycles */
+ const char * format; /* format string for print_debug */
+ uint32_t arg0; /* print_debug argument 1 */
+ uint32_t arg1; /* print_debug argument 2 */
+
+ uint64_t count_zero_time;
+ uint32_t compare_armed;
+ uint32_t jmpdest; /* destination jump target */
};
address_space_config m_program_config;
- mips3_flavor m_flavor;
+ mips3_flavor m_flavor;
/* core state */
internal_mips3_state *m_core;
/* internal stuff */
- uint32_t m_ppc;
- uint32_t m_nextpc;
- uint32_t m_pcbase;
- uint8_t m_cf[4][8];
- bool m_delayslot;
- int m_op;
- int m_interrupt_cycles;
- uint32_t m_ll_value;
- uint64_t m_lld_value;
- uint32_t m_badcop_value;
+ uint32_t m_ppc;
+ uint32_t m_nextpc;
+ uint32_t m_pcbase;
+ uint8_t m_cf[4][8];
+ bool m_delayslot;
+ int m_op;
+ int m_interrupt_cycles;
+ uint32_t m_ll_value;
+ uint64_t m_lld_value;
+ uint32_t m_badcop_value;
/* endian-dependent load/store */
typedef void (mips3_device::*loadstore_func)(uint32_t op);
- loadstore_func m_lwl;
- loadstore_func m_lwr;
- loadstore_func m_swl;
- loadstore_func m_swr;
- loadstore_func m_ldl;
- loadstore_func m_ldr;
- loadstore_func m_sdl;
- loadstore_func m_sdr;
-
- address_space *m_program;
+ loadstore_func m_lwl;
+ loadstore_func m_lwr;
+ loadstore_func m_swl;
+ loadstore_func m_swr;
+ loadstore_func m_ldl;
+ loadstore_func m_ldr;
+ loadstore_func m_sdl;
+ loadstore_func m_sdr;
+
+ address_space * m_program;
std::function<u32 (offs_t)> m_pr32;
std::function<const void * (offs_t)> m_prptr;
- uint32_t c_system_clock;
- uint32_t m_cpu_clock;
+ uint32_t c_system_clock;
+ uint32_t m_cpu_clock;
emu_timer * m_compare_int_timer;
/* derived info based on flavor */
- uint32_t m_pfnmask;
- uint8_t m_tlbentries;
+ uint32_t m_pfnmask;
+ uint8_t m_tlbentries;
/* memory accesses */
- bool m_bigendian;
- uint32_t m_byte_xor;
- uint32_t m_word_xor;
+ bool m_bigendian;
+ uint32_t m_byte_xor;
+ uint32_t m_word_xor;
data_accessors m_memory;
/* cache memory */
@@ -386,35 +394,35 @@ private:
mips3_tlb_entry m_tlb[MIPS3_MAX_TLB_ENTRIES];
/* fast RAM */
- uint32_t m_fastram_select;
+ uint32_t m_fastram_select;
struct
{
- offs_t start; /* start of the RAM block */
- offs_t end; /* end of the RAM block */
- bool readonly; /* true if read-only */
- void * base; /* base in memory where the RAM lives */
- uint8_t * offset_base8; /* base in memory where the RAM lives, 8-bit pointer, with the start offset pre-applied */
- uint16_t * offset_base16; /* base in memory where the RAM lives, 16-bit pointer, with the start offset pre-applied */
- uint32_t * offset_base32; /* base in memory where the RAM lives, 32-bit pointer, with the start offset pre-applied */
- } m_fastram[MIPS3_MAX_FASTRAM];
+ offs_t start; /* start of the RAM block */
+ offs_t end; /* end of the RAM block */
+ bool readonly; /* true if read-only */
+ void * base; /* base in memory where the RAM lives */
+ uint8_t * offset_base8; /* base in memory where the RAM lives, 8-bit pointer, with the start offset pre-applied */
+ uint16_t * offset_base16; /* base in memory where the RAM lives, 16-bit pointer, with the start offset pre-applied */
+ uint32_t * offset_base32; /* base in memory where the RAM lives, 32-bit pointer, with the start offset pre-applied */
+ } m_fastram[MIPS3_MAX_FASTRAM];
- uint32_t m_debugger_temp;
+ uint32_t m_debugger_temp;
/* core state */
- drc_cache m_cache; /* pointer to the DRC code cache */
- std::unique_ptr<drcuml_state> m_drcuml; /* DRC UML generator state */
- std::unique_ptr<mips3_frontend> m_drcfe; /* pointer to the DRC front-end state */
- uint32_t m_drcoptions; /* configurable DRC options */
+ drc_cache m_cache; /* pointer to the DRC code cache */
+ std::unique_ptr<drcuml_state> m_drcuml;/* DRC UML generator state */
+ std::unique_ptr<mips3_frontend> m_drcfe; /* pointer to the DRC front-end state */
+ uint32_t m_drcoptions; /* configurable DRC options */
/* internal stuff */
- uint8_t m_cache_dirty; /* true if we need to flush the cache */
+ uint8_t m_cache_dirty; /* true if we need to flush the cache */
/* tables */
- uint8_t m_fpmode[4]; /* FPU mode table */
+ uint8_t m_fpmode[4]; /* FPU mode table */
/* register mappings */
- uml::parameter m_regmap[34]; /* parameter to register mappings for all 32 integer registers */
- uml::parameter m_regmaplo[34]; /* parameter to register mappings for all 32 integer registers */
+ uml::parameter m_regmap[34]; /* parameter to register mappings for all 32 integer registers */
+ uml::parameter m_regmaplo[34]; /* parameter to register mappings for all 32 integer registers */
/* subroutines */
uml::code_handle * m_entry; /* entry point */
@@ -437,14 +445,14 @@ private:
uml::code_handle * m_exception_norecover[18/*EXCEPTION_COUNT*/]; /* array of no-recover exception handlers */
/* hotspots */
- uint32_t m_hotspot_select;
+ uint32_t m_hotspot_select;
struct
{
- offs_t pc; /* PC to consider */
- uint32_t opcode; /* required opcode at that PC */
- uint32_t cycles; /* number of cycles to eat when hit */
- } m_hotspot[MIPS3_MAX_HOTSPOTS];
- bool m_isdrc;
+ offs_t pc; /* PC to consider */
+ uint32_t opcode; /* required opcode at that PC */
+ uint32_t cycles; /* number of cycles to eat when hit */
+ } m_hotspot[MIPS3_MAX_HOTSPOTS];
+ bool m_isdrc;
void generate_exception(int exception, int backup);
@@ -503,6 +511,9 @@ private:
void handle_special(uint32_t op);
void handle_regimm(uint32_t op);
+ virtual void handle_extra_special(uint32_t op);
+ virtual void handle_extra_regimm(uint32_t op);
+ virtual void handle_idt(uint32_t op);
void lwl_be(uint32_t op);
void lwr_be(uint32_t op);
@@ -722,6 +733,23 @@ public:
{ }
};
+class r5900le_device : public mips3_device
+{
+public:
+ // construction/destruction
+ r5900le_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : mips3_device(mconfig, R5900LE, tag, owner, clock, MIPS3_TYPE_R5900, ENDIANNESS_LITTLE)
+ { }
+
+protected:
+ // device_disasm_interface overrides
+ virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
+
+ void handle_extra_special(uint32_t op) override;
+ void handle_extra_regimm(uint32_t op) override;
+ void handle_idt(uint32_t op) override;
+};
+
class qed5271be_device : public mips3_device
{
public:
diff --git a/src/devices/cpu/mips/mips3com.cpp b/src/devices/cpu/mips/mips3com.cpp
index d5260a8b05e..9edd05f8b67 100644
--- a/src/devices/cpu/mips/mips3com.cpp
+++ b/src/devices/cpu/mips/mips3com.cpp
@@ -325,6 +325,9 @@ uint32_t mips3_device::compute_prid_register()
case MIPS3_TYPE_RM7000:
return 0x2700;
+ case MIPS3_TYPE_R5900:
+ return 0x2e59;
+
default:
fatalerror("Unknown MIPS flavor specified\n");
}
diff --git a/src/devices/cpu/mips/mips3dsm.cpp b/src/devices/cpu/mips/mips3dsm.cpp
index 5252a552b8c..42ebae6fe81 100644
--- a/src/devices/cpu/mips/mips3dsm.cpp
+++ b/src/devices/cpu/mips/mips3dsm.cpp
@@ -31,6 +31,14 @@ const char *const mips3_disassembler::reg[32] =
};
#endif
+const char *const ee_disassembler::vreg[32] =
+{
+ "$vf0", "$vf1", "$vf2", "$vf3", "$vf4", "$vf5", "$vf6", "$vf7",
+ "$vf8", "$vf9", "$vf10", "$vf11", "$vf12", "$vf13", "$vf14", "$vf15",
+ "$vf16", "$vf17", "$vf18", "$vf19", "$vf20", "$vf21", "$vf22", "$vf23",
+ "$vf24", "$vf25", "$vf26", "$vf27", "$vf28", "$vf29", "$vf30", "$vf31"
+};
+
const char *const mips3_disassembler::cacheop[32] =
{
"I_Invd", "D_WBInvd", "Unknown 2", "Unknown 3", "I_IndexLoadTag", "D_IndexLoadTag", "Unknown 6", "Unknown 7",
@@ -118,20 +126,20 @@ uint32_t mips3_disassembler::dasm_cop0(uint32_t pc, uint32_t op, std::ostream &s
switch ((op >> 21) & 31)
{
- case 0x00: util::stream_format(stream, "mfc0 %s,%s", reg[rt], cpreg[0][rd]); break;
- case 0x01: util::stream_format(stream, "dmfc0 %s,%s", reg[rt], cpreg[0][rd]); break;
- case 0x02: util::stream_format(stream, "cfc0 %s,%s", reg[rt], ccreg[0][rd]); break;
- case 0x04: util::stream_format(stream, "mtc0 %s,%s", reg[rt], cpreg[0][rd]); break;
- case 0x05: util::stream_format(stream, "dmtc0 %s,%s", reg[rt], cpreg[0][rd]); break;
- case 0x06: util::stream_format(stream, "ctc0 %s,%s", reg[rt], ccreg[0][rd]); break;
+ case 0x00: util::stream_format(stream, "mfc0 %s,%s", reg[rt], cpreg[0][rd]); break;
+ case 0x01: util::stream_format(stream, "dmfc0 %s,%s", reg[rt], cpreg[0][rd]); break;
+ case 0x02: util::stream_format(stream, "cfc0 %s,%s", reg[rt], ccreg[0][rd]); break;
+ case 0x04: util::stream_format(stream, "mtc0 %s,%s", reg[rt], cpreg[0][rd]); break;
+ case 0x05: util::stream_format(stream, "dmtc0 %s,%s", reg[rt], cpreg[0][rd]); break;
+ case 0x06: util::stream_format(stream, "ctc0 %s,%s", reg[rt], ccreg[0][rd]); break;
case 0x08: /* BC */
switch (rt)
{
- case 0x00: util::stream_format(stream, "bc0f $%08x", pc + 4 + ((int16_t)op << 2)); break;
- case 0x01: util::stream_format(stream, "bc0t $%08x", pc + 4 + ((int16_t)op << 2)); break;
- case 0x02: util::stream_format(stream, "bc0fl [invalid]"); break;
- case 0x03: util::stream_format(stream, "bc0tl [invalid]"); break;
- default: util::stream_format(stream, "dc.l $%08x [invalid]", op); break;
+ case 0x00: util::stream_format(stream, "bc0f $%08x", pc + 4 + ((int16_t)op << 2)); break;
+ case 0x01: util::stream_format(stream, "bc0t $%08x", pc + 4 + ((int16_t)op << 2)); break;
+ case 0x02: util::stream_format(stream, "bc0fl [invalid]"); break;
+ case 0x03: util::stream_format(stream, "bc0tl [invalid]"); break;
+ default: util::stream_format(stream, "dc.l $%08x [invalid]", op); break;
}
break;
case 0x10:
@@ -157,11 +165,11 @@ uint32_t mips3_disassembler::dasm_cop0(uint32_t pc, uint32_t op, std::ostream &s
case 0x06: util::stream_format(stream, "tlbwr"); break;
case 0x08: util::stream_format(stream, "tlbp"); break;
case 0x10: util::stream_format(stream, "rfe"); flags = STEP_OUT; break;
- case 0x18: util::stream_format(stream, "eret [invalid]"); break;
- default: util::stream_format(stream, "cop0 $%07x", op & 0x01ffffff); break;
+ case 0x18: util::stream_format(stream, "eret [invalid]"); break;
+ default: util::stream_format(stream, "cop0 $%07x", op & 0x01ffffff); break;
}
break;
- default: util::stream_format(stream, "dc.l $%08x [invalid]", op); break;
+ default: util::stream_format(stream, "dc.l $%08x [invalid]", op); break;
}
return flags;
}
@@ -183,66 +191,66 @@ uint32_t mips3_disassembler::dasm_cop1(uint32_t pc, uint32_t op, std::ostream &s
switch ((op >> 21) & 31)
{
- case 0x00: util::stream_format(stream, "mfc1 %s,%s", reg[rt], cpreg[1][rd]); break;
- case 0x01: util::stream_format(stream, "dmfc1 %s,%s", reg[rt], cpreg[1][rd]); break;
- case 0x02: util::stream_format(stream, "cfc1 %s,%s", reg[rt], ccreg[1][rd]); break;
- case 0x04: util::stream_format(stream, "mtc1 %s,%s", reg[rt], cpreg[1][rd]); break;
- case 0x05: util::stream_format(stream, "dmtc1 %s,%s", reg[rt], cpreg[1][rd]); break;
- case 0x06: util::stream_format(stream, "ctc1 %s,%s", reg[rt], ccreg[1][rd]); break;
+ case 0x00: util::stream_format(stream, "mfc1 %s,%s", reg[rt], cpreg[1][rd]); break;
+ case 0x01: util::stream_format(stream, "dmfc1 %s,%s", reg[rt], cpreg[1][rd]); break;
+ case 0x02: util::stream_format(stream, "cfc1 %s,%s", reg[rt], ccreg[1][rd]); break;
+ case 0x04: util::stream_format(stream, "mtc1 %s,%s", reg[rt], cpreg[1][rd]); break;
+ case 0x05: util::stream_format(stream, "dmtc1 %s,%s", reg[rt], cpreg[1][rd]); break;
+ case 0x06: util::stream_format(stream, "ctc1 %s,%s", reg[rt], ccreg[1][rd]); break;
case 0x08: /* BC */
switch (rt & 3)
{
- case 0x00: util::stream_format(stream, "bc1f $%08x,%d", pc + 4 + ((int16_t)op << 2), (op >> 18) & 7); break;
- case 0x01: util::stream_format(stream, "bc1t $%08x,%d", pc + 4 + ((int16_t)op << 2), (op >> 18) & 7); break;
- case 0x02: util::stream_format(stream, "bc1fl $%08x,%d", pc + 4 + ((int16_t)op << 2), (op >> 18) & 7); flags = STEP_OVER | step_over_extra(1); break;
- case 0x03: util::stream_format(stream, "bc1tl $%08x,%d", pc + 4 + ((int16_t)op << 2), (op >> 18) & 7); flags = STEP_OVER | step_over_extra(1); break;
+ case 0x00: util::stream_format(stream, "bc1f $%08x,%d", pc + 4 + ((int16_t)op << 2), (op >> 18) & 7); break;
+ case 0x01: util::stream_format(stream, "bc1t $%08x,%d", pc + 4 + ((int16_t)op << 2), (op >> 18) & 7); break;
+ case 0x02: util::stream_format(stream, "bc1fl $%08x,%d", pc + 4 + ((int16_t)op << 2), (op >> 18) & 7); flags = STEP_OVER | step_over_extra(1); break;
+ case 0x03: util::stream_format(stream, "bc1tl $%08x,%d", pc + 4 + ((int16_t)op << 2), (op >> 18) & 7); flags = STEP_OVER | step_over_extra(1); break;
}
break;
default: /* COP */
switch (op & 0x3f)
{
- case 0x00: util::stream_format(stream, "add.%s %s,%s,%s", fmt, cpreg[1][fd], cpreg[1][fs], cpreg[1][ft]); break;
- case 0x01: util::stream_format(stream, "sub.%s %s,%s,%s", fmt, cpreg[1][fd], cpreg[1][fs], cpreg[1][ft]); break;
- case 0x02: util::stream_format(stream, "mul.%s %s,%s,%s", fmt, cpreg[1][fd], cpreg[1][fs], cpreg[1][ft]); break;
- case 0x03: util::stream_format(stream, "div.%s %s,%s,%s", fmt, cpreg[1][fd], cpreg[1][fs], cpreg[1][ft]); break;
- case 0x04: util::stream_format(stream, "sqrt.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
- case 0x05: util::stream_format(stream, "abs.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
- case 0x06: util::stream_format(stream, "mov.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
- case 0x07: util::stream_format(stream, "neg.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
+ case 0x00: util::stream_format(stream, "add.%s %s,%s,%s", fmt, cpreg[1][fd], cpreg[1][fs], cpreg[1][ft]); break;
+ case 0x01: util::stream_format(stream, "sub.%s %s,%s,%s", fmt, cpreg[1][fd], cpreg[1][fs], cpreg[1][ft]); break;
+ case 0x02: util::stream_format(stream, "mul.%s %s,%s,%s", fmt, cpreg[1][fd], cpreg[1][fs], cpreg[1][ft]); break;
+ case 0x03: util::stream_format(stream, "div.%s %s,%s,%s", fmt, cpreg[1][fd], cpreg[1][fs], cpreg[1][ft]); break;
+ case 0x04: util::stream_format(stream, "sqrt.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
+ case 0x05: util::stream_format(stream, "abs.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
+ case 0x06: util::stream_format(stream, "mov.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
+ case 0x07: util::stream_format(stream, "neg.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
case 0x08: util::stream_format(stream, "round.l.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
case 0x09: util::stream_format(stream, "trunc.l.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
- case 0x0a: util::stream_format(stream, "ceil.l.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
+ case 0x0a: util::stream_format(stream, "ceil.l.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
case 0x0b: util::stream_format(stream, "floor.l.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
case 0x0c: util::stream_format(stream, "round.w.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
case 0x0d: util::stream_format(stream, "trunc.w.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
- case 0x0e: util::stream_format(stream, "ceil.w.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
+ case 0x0e: util::stream_format(stream, "ceil.w.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
case 0x0f: util::stream_format(stream, "floor.w.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
- case 0x11: util::stream_format(stream, "mov%c.%s %s,%s,%d", ((op >> 16) & 1) ? 't' : 'f', fmt, cpreg[1][fd], cpreg[1][fs], (op >> 18) & 7); break;
- case 0x12: util::stream_format(stream, "movz.%s %s,%s,%s", fmt, cpreg[1][fd], cpreg[1][fs], reg[rt]); break;
- case 0x13: util::stream_format(stream, "movn.%s %s,%s,%s", fmt, cpreg[1][fd], cpreg[1][fs], reg[rt]); break;
- case 0x15: util::stream_format(stream, "recip.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
- case 0x16: util::stream_format(stream, "rsqrt.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
- case 0x20: util::stream_format(stream, "cvt.s.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
- case 0x21: util::stream_format(stream, "cvt.d.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
- case 0x24: util::stream_format(stream, "cvt.w.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
- case 0x25: util::stream_format(stream, "cvt.l.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
- case 0x30: util::stream_format(stream, "c.f.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
- case 0x31: util::stream_format(stream, "c.un.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
- case 0x32: util::stream_format(stream, "c.eq.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
- case 0x33: util::stream_format(stream, "c.ueq.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
- case 0x34: util::stream_format(stream, "c.olt.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
- case 0x35: util::stream_format(stream, "c.ult.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
- case 0x36: util::stream_format(stream, "c.ole.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
- case 0x37: util::stream_format(stream, "c.ule.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
- case 0x38: util::stream_format(stream, "c.sf.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
- case 0x39: util::stream_format(stream, "c.ngle.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7);break;
- case 0x3a: util::stream_format(stream, "c.seq.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
- case 0x3b: util::stream_format(stream, "c.ngl.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
- case 0x3c: util::stream_format(stream, "c.lt.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
- case 0x3d: util::stream_format(stream, "c.nge.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
- case 0x3e: util::stream_format(stream, "c.le.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
- case 0x3f: util::stream_format(stream, "c.ngt.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
- default: util::stream_format(stream, "cop1 $%07x", op & 0x01ffffff); break;
+ case 0x11: util::stream_format(stream, "mov%c.%s %s,%s,%d", ((op >> 16) & 1) ? 't' : 'f', fmt, cpreg[1][fd], cpreg[1][fs], (op >> 18) & 7); break;
+ case 0x12: util::stream_format(stream, "movz.%s %s,%s,%s", fmt, cpreg[1][fd], cpreg[1][fs], reg[rt]); break;
+ case 0x13: util::stream_format(stream, "movn.%s %s,%s,%s", fmt, cpreg[1][fd], cpreg[1][fs], reg[rt]); break;
+ case 0x15: util::stream_format(stream, "recip.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
+ case 0x16: util::stream_format(stream, "rsqrt.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
+ case 0x20: util::stream_format(stream, "cvt.s.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
+ case 0x21: util::stream_format(stream, "cvt.d.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
+ case 0x24: util::stream_format(stream, "cvt.w.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
+ case 0x25: util::stream_format(stream, "cvt.l.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
+ case 0x30: util::stream_format(stream, "c.f.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
+ case 0x31: util::stream_format(stream, "c.un.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
+ case 0x32: util::stream_format(stream, "c.eq.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
+ case 0x33: util::stream_format(stream, "c.ueq.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
+ case 0x34: util::stream_format(stream, "c.olt.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
+ case 0x35: util::stream_format(stream, "c.ult.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
+ case 0x36: util::stream_format(stream, "c.ole.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
+ case 0x37: util::stream_format(stream, "c.ule.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
+ case 0x38: util::stream_format(stream, "c.sf.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
+ case 0x39: util::stream_format(stream, "c.ngle.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7);break;
+ case 0x3a: util::stream_format(stream, "c.seq.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
+ case 0x3b: util::stream_format(stream, "c.ngl.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
+ case 0x3c: util::stream_format(stream, "c.lt.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
+ case 0x3d: util::stream_format(stream, "c.nge.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
+ case 0x3e: util::stream_format(stream, "c.le.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
+ case 0x3f: util::stream_format(stream, "c.ngt.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
+ default: util::stream_format(stream, "cop1 $%07x", op & 0x01ffffff); break;
}
break;
}
@@ -267,11 +275,11 @@ uint32_t mips3_disassembler::dasm_cop1x(uint32_t pc, uint32_t op, std::ostream &
switch (op & 0x3f)
{
- case 0x00: util::stream_format(stream, "lwxc1 %s,%s(%s)", cpreg[1][fd], reg[rt], reg[rs]); break;
- case 0x01: util::stream_format(stream, "ldxc1 %s,%s(%s)", cpreg[1][fd], reg[rt], reg[rs]); break;
- case 0x08: util::stream_format(stream, "swxc1 %s,%s(%s)", cpreg[1][fd], reg[rt], reg[rs]); break;
- case 0x09: util::stream_format(stream, "sdxc1 %s,%s(%s)", cpreg[1][fd], reg[rt], reg[rs]); break;
- case 0x0f: util::stream_format(stream, "prefx %d,%s(%s)", rd, reg[rt], reg[rs]); break;
+ case 0x00: util::stream_format(stream, "lwxc1 %s,%s(%s)", cpreg[1][fd], reg[rt], reg[rs]); break;
+ case 0x01: util::stream_format(stream, "ldxc1 %s,%s(%s)", cpreg[1][fd], reg[rt], reg[rs]); break;
+ case 0x08: util::stream_format(stream, "swxc1 %s,%s(%s)", cpreg[1][fd], reg[rt], reg[rs]); break;
+ case 0x09: util::stream_format(stream, "sdxc1 %s,%s(%s)", cpreg[1][fd], reg[rt], reg[rs]); break;
+ case 0x0f: util::stream_format(stream, "prefx %d,%s(%s)", rd, reg[rt], reg[rs]); break;
case 0x20:
case 0x21:
case 0x22:
@@ -279,7 +287,7 @@ uint32_t mips3_disassembler::dasm_cop1x(uint32_t pc, uint32_t op, std::ostream &
case 0x24:
case 0x25:
case 0x26:
- case 0x27: util::stream_format(stream, "madd.%s %s,%s,%s,%s", fmt3, cpreg[1][fd], cpreg[1][fr], cpreg[1][fs], cpreg[1][ft]); break;
+ case 0x27: util::stream_format(stream, "madd.%s %s,%s,%s,%s", fmt3, cpreg[1][fd], cpreg[1][fr], cpreg[1][fs], cpreg[1][ft]); break;
case 0x28:
case 0x29:
case 0x2a:
@@ -287,7 +295,7 @@ uint32_t mips3_disassembler::dasm_cop1x(uint32_t pc, uint32_t op, std::ostream &
case 0x2c:
case 0x2d:
case 0x2e:
- case 0x2f: util::stream_format(stream, "msub.%s %s,%s,%s,%s", fmt3, cpreg[1][fd], cpreg[1][fr], cpreg[1][fs], cpreg[1][ft]); break;
+ case 0x2f: util::stream_format(stream, "msub.%s %s,%s,%s,%s", fmt3, cpreg[1][fd], cpreg[1][fr], cpreg[1][fs], cpreg[1][ft]); break;
case 0x30:
case 0x31:
case 0x32:
@@ -295,7 +303,7 @@ uint32_t mips3_disassembler::dasm_cop1x(uint32_t pc, uint32_t op, std::ostream &
case 0x34:
case 0x35:
case 0x36:
- case 0x37: util::stream_format(stream, "nmadd.%s %s,%s,%s,%s", fmt3, cpreg[1][fd], cpreg[1][fr], cpreg[1][fs], cpreg[1][ft]); break;
+ case 0x37: util::stream_format(stream, "nmadd.%s %s,%s,%s,%s", fmt3, cpreg[1][fd], cpreg[1][fr], cpreg[1][fs], cpreg[1][ft]); break;
case 0x38:
case 0x39:
case 0x3a:
@@ -303,8 +311,8 @@ uint32_t mips3_disassembler::dasm_cop1x(uint32_t pc, uint32_t op, std::ostream &
case 0x3c:
case 0x3d:
case 0x3e:
- case 0x3f: util::stream_format(stream, "nmsub.%s %s,%s,%s,%s", fmt3, cpreg[1][fd], cpreg[1][fr], cpreg[1][fs], cpreg[1][ft]); break;
- default: util::stream_format(stream, "cop1 $%07x", op & 0x01ffffff); break;
+ case 0x3f: util::stream_format(stream, "nmsub.%s %s,%s,%s,%s", fmt3, cpreg[1][fd], cpreg[1][fr], cpreg[1][fs], cpreg[1][ft]); break;
+ default: util::stream_format(stream, "cop1 $%07x", op & 0x01ffffff); break;
}
return flags;
}
@@ -317,20 +325,20 @@ uint32_t mips3_disassembler::dasm_cop2(uint32_t pc, uint32_t op, std::ostream &s
switch ((op >> 21) & 31)
{
- case 0x00: util::stream_format(stream, "mfc2 %s,%s", reg[rt], cpreg[2][rd]); break;
- case 0x01: util::stream_format(stream, "dmfc2 %s,%s", reg[rt], cpreg[2][rd]); break;
- case 0x02: util::stream_format(stream, "cfc2 %s,%s", reg[rt], ccreg[2][rd]); break;
- case 0x04: util::stream_format(stream, "mtc2 %s,%s", reg[rt], cpreg[2][rd]); break;
- case 0x05: util::stream_format(stream, "dmtc2 %s,%s", reg[rt], cpreg[2][rd]); break;
- case 0x06: util::stream_format(stream, "ctc2 %s,%s", reg[rt], ccreg[2][rd]); break;
+ case 0x00: util::stream_format(stream, "mfc2 %s,%s", reg[rt], cpreg[2][rd]); break;
+ case 0x01: util::stream_format(stream, "dmfc2 %s,%s", reg[rt], cpreg[2][rd]); break;
+ case 0x02: util::stream_format(stream, "cfc2 %s,%s", reg[rt], ccreg[2][rd]); break;
+ case 0x04: util::stream_format(stream, "mtc2 %s,%s", reg[rt], cpreg[2][rd]); break;
+ case 0x05: util::stream_format(stream, "dmtc2 %s,%s", reg[rt], cpreg[2][rd]); break;
+ case 0x06: util::stream_format(stream, "ctc2 %s,%s", reg[rt], ccreg[2][rd]); break;
case 0x08: /* BC */
switch (rt)
{
- case 0x00: util::stream_format(stream, "bc2f $%08x", pc + 4 + ((int16_t)op << 2)); break;
- case 0x01: util::stream_format(stream, "bc2t $%08x", pc + 4 + ((int16_t)op << 2)); break;
- case 0x02: util::stream_format(stream, "bc2fl [invalid]"); break;
- case 0x03: util::stream_format(stream, "bc2tl [invalid]"); break;
- default: util::stream_format(stream, "dc.l $%08x [invalid]", op); break;
+ case 0x00: util::stream_format(stream, "bc2f $%08x", pc + 4 + ((int16_t)op << 2)); break;
+ case 0x01: util::stream_format(stream, "bc2t $%08x", pc + 4 + ((int16_t)op << 2)); break;
+ case 0x02: util::stream_format(stream, "bc2fl [invalid]"); break;
+ case 0x03: util::stream_format(stream, "bc2tl [invalid]"); break;
+ default: util::stream_format(stream, "dc.l $%08x [invalid]", op); break;
}
break;
case 0x10:
@@ -349,13 +357,317 @@ uint32_t mips3_disassembler::dasm_cop2(uint32_t pc, uint32_t op, std::ostream &s
case 0x1d:
case 0x1e:
case 0x1f: /* COP */
- util::stream_format(stream, "cop2 $%07x", op & 0x01ffffff);
+ util::stream_format(stream, "cop2 $%07x", op & 0x01ffffff);
+ break;
+ default: util::stream_format(stream, "dc.l $%08x [invalid]", op); break;
+ }
+ return flags;
+}
+
+uint32_t mips3_disassembler::dasm_idt(uint32_t pc, uint32_t op, std::ostream &stream)
+{
+ int rs = (op >> 21) & 31;
+ int rt = (op >> 16) & 31;
+ int rd = (op >> 11) & 31;
+ uint32_t flags = 0;
+
+ /* IDT-specific opcodes: mad/madu/mul on R4640/4650, msub on RC32364 */
+ switch (op & 0x1f)
+ {
+ case 0: util::stream_format(stream, "mad %s,%s", reg[rs], reg[rt]); break;
+ case 1: util::stream_format(stream, "madu %s,%s", reg[rs], reg[rt]); break;
+ case 2: util::stream_format(stream, "mul %s,%s,%s", reg[rs], reg[rt], reg[rd]); break;
+ case 4: util::stream_format(stream, "msub %s,%s", reg[rs], reg[rt]); break;
+ default:util::stream_format(stream, "dc.l $%08x [invalid]", op); break;
+ }
+
+ return flags;
+}
+
+uint32_t mips3_disassembler::dasm_extra_base(uint32_t pc, uint32_t op, std::ostream &stream)
+{
+ util::stream_format(stream, "dc.l $%08x [invalid]", op);
+ return 0;
+}
+
+uint32_t mips3_disassembler::dasm_extra_regimm(uint32_t pc, uint32_t op, std::ostream &stream)
+{
+ util::stream_format(stream, "dc.l $%08x [invalid]", op);
+ return 0;
+}
+
+uint32_t mips3_disassembler::dasm_extra_special(uint32_t pc, uint32_t op, std::ostream &stream)
+{
+ util::stream_format(stream, "dc.l $%08x [invalid]", op);
+ return 0;
+}
+
+uint32_t ee_disassembler::dasm_idt(uint32_t pc, uint32_t op, std::ostream &stream)
+{
+ const int rs = (op >> 21) & 31;
+ const int rt = (op >> 16) & 31;
+ const int rd = (op >> 11) & 31;
+ const int fmt = (op >> 6) & 31;
+ const int shift = fmt; // convenience
+ uint32_t flags = 0;
+
+ switch (op & 0x3f)
+ {
+ case 0x00:
+ if (rd)
+ util::stream_format(stream, "madd %s,%s,%s", reg[rd], reg[rs], reg[rt]);
+ else
+ util::stream_format(stream, "madd %s,%s", reg[rs], reg[rt]);
+ break;
+ case 0x01:
+ if (rd)
+ util::stream_format(stream, "maddu %s,%s,%s", reg[rd], reg[rs], reg[rt]);
+ else
+ util::stream_format(stream, "maddu %s,%s", reg[rs], reg[rt]);
+ break;
+ case 0x04: util::stream_format(stream, "plzcw ?"); break;
+ case 0x08: flags = dasm_mmi0(pc, op, stream); break;
+ case 0x09: flags = dasm_mmi2(pc, op, stream); break;
+ case 0x10: util::stream_format(stream, "mfhi1 %s", reg[rd]); break;
+ case 0x11: util::stream_format(stream, "mthi1 %s", reg[rs]); break;
+ case 0x12: util::stream_format(stream, "mflo1 %s", reg[rd]); break;
+ case 0x13: util::stream_format(stream, "mtlo1 %s", reg[rs]); break;
+ case 0x18:
+ if (rd)
+ util::stream_format(stream, "mult1 %s,%s,%s", reg[rd], reg[rs], reg[rt]);
+ else
+ util::stream_format(stream, "mult1 %s,%s", reg[rs], reg[rt]);
+ break;
+ case 0x19:
+ if (rd)
+ util::stream_format(stream, "multu1 %s,%s,%s", reg[rd], reg[rs], reg[rt]);
+ else
+ util::stream_format(stream, "multu1 %s,%s", reg[rs], reg[rt]);
break;
- default: util::stream_format(stream, "dc.l $%08x [invalid]", op); break;
+ case 0x1a: util::stream_format(stream, "div1 %s,%s", reg[rs], reg[rt]); break;
+ case 0x1b: util::stream_format(stream, "divu1 %s,%s", reg[rs], reg[rt]); break;
+ case 0x20:
+ if (rd)
+ util::stream_format(stream, "madd1 %s,%s,%s", reg[rd], reg[rs], reg[rt]);
+ else
+ util::stream_format(stream, "madd1 %s,%s", reg[rs], reg[rt]);
+ break;
+ case 0x21:
+ if (rd)
+ util::stream_format(stream, "maddu1 %s,%s,%s", reg[rd], reg[rs], reg[rt]);
+ else
+ util::stream_format(stream, "maddu1 %s,%s", reg[rs], reg[rt]);
+ break;
+ case 0x28: flags = dasm_mmi1(pc, op, stream); break;
+ case 0x29: flags = dasm_mmi3(pc, op, stream); break;
+ case 0x30:
+ switch (fmt)
+ {
+ case 0: util::stream_format(stream, "pmfhl.lw %s", reg[rd]); break;
+ case 1: util::stream_format(stream, "pmfhl.uw %s", reg[rd]); break;
+ case 2: util::stream_format(stream, "pmfhl.slw %s", reg[rd]); break;
+ case 3: util::stream_format(stream, "pmfhl.lh %s", reg[rd]); break;
+ case 4: util::stream_format(stream, "pmfhl.sh %s", reg[rd]); break;
+ default: util::stream_format(stream, "dc.l $%08x [invalid]", op); break;
+ }
+ break;
+ case 0x31:
+ switch (fmt)
+ {
+ case 0: util::stream_format(stream, "pmthl.lw %s", reg[rd]); break;
+ default: util::stream_format(stream, "dc.l $%08x [invalid]", op); break;
+ }
+ break;
+ case 0x34: util::stream_format(stream, "psllh %s,%s,%d", reg[rd], reg[rt], shift); break;
+ case 0x36: util::stream_format(stream, "psrlh %s,%s,%d", reg[rd], reg[rt], shift); break;
+ case 0x37: util::stream_format(stream, "psrah %s,%s,%d", reg[rd], reg[rt], shift); break;
+ case 0x3c: util::stream_format(stream, "psllw %s,%s,%d", reg[rd], reg[rt], shift); break;
+ case 0x3e: util::stream_format(stream, "psrlw %s,%s,%d", reg[rd], reg[rt], shift); break;
+ case 0x3f: util::stream_format(stream, "psraw %s,%s,%d", reg[rd], reg[rt], shift); break;
+ default: util::stream_format(stream, "dc.l $%08x [invalid]", op); break;
}
+
return flags;
}
+uint32_t ee_disassembler::dasm_mmi0(uint32_t pc, uint32_t op, std::ostream &stream)
+{
+ const int rs = (op >> 21) & 31;
+ const int rt = (op >> 16) & 31;
+ const int rd = (op >> 11) & 31;
+ const int code = (op >> 6) & 31;
+
+ switch (code)
+ {
+ case 0x00: util::stream_format(stream, "paddw %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x01: util::stream_format(stream, "psubw %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x02: util::stream_format(stream, "pcgtw %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x03: util::stream_format(stream, "pmaxw %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x04: util::stream_format(stream, "paddh %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x05: util::stream_format(stream, "psubh %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x06: util::stream_format(stream, "pcgth %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x07: util::stream_format(stream, "pmaxh %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x08: util::stream_format(stream, "paddb %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x09: util::stream_format(stream, "psubb %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x0a: util::stream_format(stream, "pcgtb %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x10: util::stream_format(stream, "paddsw %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x11: util::stream_format(stream, "psubsw %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x12: util::stream_format(stream, "pextlw %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x13: util::stream_format(stream, "ppacw %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x14: util::stream_format(stream, "paddsh %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x15: util::stream_format(stream, "psubsh %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x16: util::stream_format(stream, "pextlh %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x17: util::stream_format(stream, "ppach %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x18: util::stream_format(stream, "paddsb %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x19: util::stream_format(stream, "psubsb %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x1a: util::stream_format(stream, "pextlb %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x1b: util::stream_format(stream, "ppacb %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x1e: util::stream_format(stream, "pext5 %s,%s", reg[rd], reg[rt]); break;
+ case 0x1f: util::stream_format(stream, "ppac5 %s,%s", reg[rd], reg[rt]); break;
+ default: util::stream_format(stream, "dc.l $%08x [invalid]", op); break;
+ }
+
+ return 0;
+}
+
+uint32_t ee_disassembler::dasm_mmi1(uint32_t pc, uint32_t op, std::ostream &stream)
+{
+ const int rs = (op >> 21) & 31;
+ const int rt = (op >> 16) & 31;
+ const int rd = (op >> 11) & 31;
+ const int code = (op >> 6) & 31;
+
+ switch (code)
+ {
+ case 0x01: util::stream_format(stream, "pabsw %s,%s", reg[rd], reg[rt]); break;
+ case 0x02: util::stream_format(stream, "pceqw %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x03: util::stream_format(stream, "pminw %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x04: util::stream_format(stream, "padsbh %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x05: util::stream_format(stream, "pabsh %s,%s", reg[rd], reg[rt]); break;
+ case 0x06: util::stream_format(stream, "pceqh %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x07: util::stream_format(stream, "pminh %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x0a: util::stream_format(stream, "pceqb %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x10: util::stream_format(stream, "padduw %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x11: util::stream_format(stream, "psubuw %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x12: util::stream_format(stream, "pextuw %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x14: util::stream_format(stream, "padduh %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x15: util::stream_format(stream, "psubuh %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x16: util::stream_format(stream, "pextuh %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x18: util::stream_format(stream, "paddub %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x19: util::stream_format(stream, "psubub %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x1a: util::stream_format(stream, "pextub %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x1b: util::stream_format(stream, "qfsrv %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ default: util::stream_format(stream, "dc.l $%08x [invalid]", op); break;
+ }
+
+ return 0;
+}
+
+uint32_t ee_disassembler::dasm_mmi2(uint32_t pc, uint32_t op, std::ostream &stream)
+{
+ const int rs = (op >> 21) & 31;
+ const int rt = (op >> 16) & 31;
+ const int rd = (op >> 11) & 31;
+ const int code = (op >> 6) & 31;
+
+ switch (code)
+ {
+ case 0x00: util::stream_format(stream, "pmaddw %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x02: util::stream_format(stream, "psllvw %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x03: util::stream_format(stream, "psrlvw %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x04: util::stream_format(stream, "pmsubw %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x08: util::stream_format(stream, "pmfhi %s", reg[rd]); break;
+ case 0x09: util::stream_format(stream, "pmflo %s", reg[rd]); break;
+ case 0x0a: util::stream_format(stream, "pinth %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x0c: util::stream_format(stream, "pmultw %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x0d: util::stream_format(stream, "pdivw %s,%s", reg[rs], reg[rt]); break;
+ case 0x0e: util::stream_format(stream, "pcpyld %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x10: util::stream_format(stream, "pmaddh %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x11: util::stream_format(stream, "phmadh %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x12: util::stream_format(stream, "pand %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x13: util::stream_format(stream, "pxor %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x14: util::stream_format(stream, "pmsubh %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x15: util::stream_format(stream, "phmsbh %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x1a: util::stream_format(stream, "pexeh %s,%s", reg[rd], reg[rt]); break;
+ case 0x1b: util::stream_format(stream, "prevh %s,%s", reg[rd], reg[rt]); break;
+ case 0x1c: util::stream_format(stream, "pmulth %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x1d: util::stream_format(stream, "pdivbw %s,%s", reg[rs], reg[rt]); break;
+ case 0x1e: util::stream_format(stream, "pexew %s,%s", reg[rd], reg[rt]); break;
+ case 0x1f: util::stream_format(stream, "prot3w %s,%s", reg[rd], reg[rt]); break;
+ default: util::stream_format(stream, "dc.l $%08x [invalid]", op); break;
+ }
+
+ return 0;
+}
+
+uint32_t ee_disassembler::dasm_mmi3(uint32_t pc, uint32_t op, std::ostream &stream)
+{
+ const int rs = (op >> 21) & 31;
+ const int rt = (op >> 16) & 31;
+ const int rd = (op >> 11) & 31;
+ const int code = (op >> 6) & 31;
+
+ switch (code)
+ {
+ case 0x00: util::stream_format(stream, "pmadduw %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x03: util::stream_format(stream, "psravw %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x08: util::stream_format(stream, "pmthi %s", reg[rs]); break;
+ case 0x09: util::stream_format(stream, "pmtlo %s", reg[rs]); break;
+ case 0x0a: util::stream_format(stream, "pinteh %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x0c: util::stream_format(stream, "pmultuw %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x0d: util::stream_format(stream, "pdivuw %s,%s", reg[rs], reg[rt]); break;
+ case 0x0e: util::stream_format(stream, "pcpyud %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x12: util::stream_format(stream, "por %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x13: util::stream_format(stream, "pnor %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x1a: util::stream_format(stream, "pexch %s,%s", reg[rd], reg[rt]); break;
+ case 0x1b: util::stream_format(stream, "pcpyh %s,%s", reg[rd], reg[rt]); break;
+ case 0x1e: util::stream_format(stream, "pexcw %s,%s", reg[rd], reg[rt]); break;
+ default: util::stream_format(stream, "dc.l $%08x [invalid]", op); break;
+ }
+
+ return 0;
+}
+
+uint32_t ee_disassembler::dasm_extra_base(uint32_t pc, uint32_t op, std::ostream &stream)
+{
+ const int rs = (op >> 21) & 31;
+ const int rt = (op >> 16) & 31;
+
+ switch (op >> 26)
+ {
+ case 0x1e: util::stream_format(stream, "lq %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
+ case 0x1f: util::stream_format(stream, "sq %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
+ default: util::stream_format(stream, "dc.l $%08x [invalid]", op); break;
+ }
+
+ return 0;
+}
+
+uint32_t ee_disassembler::dasm_extra_special(uint32_t pc, uint32_t op, std::ostream &stream)
+{
+ const int rs = (op >> 21) & 31;
+
+ switch (op & 63)
+ {
+ case 0x29: util::stream_format(stream, "mtsa %s", reg[rs]); break;
+ default: util::stream_format(stream, "dc.l $%08x [invalid]", op); break;
+ }
+ return 0;
+}
+
+uint32_t ee_disassembler::dasm_extra_regimm(uint32_t pc, uint32_t op, std::ostream &stream)
+{
+ const int rs = (op >> 21) & 31;
+
+ switch ((op >> 16) & 31)
+ {
+ case 0x18: util::stream_format(stream, "mtsab %s,%s", reg[rs], signed_16bit(op)); break;
+ case 0x19: util::stream_format(stream, "mtsah %s,%s", reg[rs], signed_16bit(op)); break;
+ default: util::stream_format(stream, "dc.l $%08x [invalid]", op); break;
+ }
+ return 0;
+}
+
u32 mips3_disassembler::opcode_alignment() const
{
return 4;
@@ -377,164 +689,155 @@ offs_t mips3_disassembler::dasm_one(std::ostream &stream, offs_t pc, u32 op)
case 0x00: if (op == 0)
util::stream_format(stream, "nop");
else
- util::stream_format(stream, "sll %s,%s,%d", reg[rd], reg[rt], shift);
+ util::stream_format(stream, "sll %s,%s,%d", reg[rd], reg[rt], shift);
break;
- case 0x01: util::stream_format(stream, "mov%c %s,%s,%d", ((op >> 16) & 1) ? 't' : 'f', reg[rd], reg[rs], (op >> 18) & 7); break;
- case 0x02: util::stream_format(stream, "srl %s,%s,%d", reg[rd], reg[rt], shift); break;
- case 0x03: util::stream_format(stream, "sra %s,%s,%d", reg[rd], reg[rt], shift); break;
- case 0x04: util::stream_format(stream, "sllv %s,%s,%s", reg[rd], reg[rt], reg[rs]); break;
- case 0x06: util::stream_format(stream, "srlv %s,%s,%s", reg[rd], reg[rt], reg[rs]); break;
- case 0x07: util::stream_format(stream, "srav %s,%s,%s", reg[rd], reg[rt], reg[rs]); break;
- case 0x08: util::stream_format(stream, "jr %s", reg[rs]); if (rs == 31) flags = STEP_OUT; break;
+ case 0x01: util::stream_format(stream, "mov%c %s,%s,%d", ((op >> 16) & 1) ? 't' : 'f', reg[rd], reg[rs], (op >> 18) & 7); break;
+ case 0x02: util::stream_format(stream, "srl %s,%s,%d", reg[rd], reg[rt], shift); break;
+ case 0x03: util::stream_format(stream, "sra %s,%s,%d", reg[rd], reg[rt], shift); break;
+ case 0x04: util::stream_format(stream, "sllv %s,%s,%s", reg[rd], reg[rt], reg[rs]); break;
+ case 0x06: util::stream_format(stream, "srlv %s,%s,%s", reg[rd], reg[rt], reg[rs]); break;
+ case 0x07: util::stream_format(stream, "srav %s,%s,%s", reg[rd], reg[rt], reg[rs]); break;
+ case 0x08: util::stream_format(stream, "jr %s", reg[rs]); if (rs == 31) flags = STEP_OUT; break;
case 0x09: if (rd == 31)
- util::stream_format(stream, "jalr %s", reg[rs]);
+ util::stream_format(stream, "jalr %s", reg[rs]);
else
- util::stream_format(stream, "jalr %s,%s", reg[rs], reg[rd]);
+ util::stream_format(stream, "jalr %s,%s", reg[rs], reg[rd]);
flags = STEP_OVER | step_over_extra(1);
break;
- case 0x0a: util::stream_format(stream, "movz %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
- case 0x0b: util::stream_format(stream, "movn %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x0a: util::stream_format(stream, "movz %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x0b: util::stream_format(stream, "movn %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
case 0x0c: util::stream_format(stream, "syscall"); flags = STEP_OVER; break;
case 0x0d: util::stream_format(stream, "break"); flags = STEP_OVER; break;
case 0x0f: util::stream_format(stream, "sync"); break;
- case 0x10: util::stream_format(stream, "mfhi %s", reg[rd]); break;
- case 0x11: util::stream_format(stream, "mthi %s", reg[rs]); break;
- case 0x12: util::stream_format(stream, "mflo %s", reg[rd]); break;
- case 0x13: util::stream_format(stream, "mtlo %s", reg[rs]); break;
- case 0x14: util::stream_format(stream, "dsllv %s,%s,%s", reg[rd], reg[rt], reg[rs]); break;
- case 0x16: util::stream_format(stream, "dsrlv %s,%s,%s", reg[rd], reg[rt], reg[rs]); break;
- case 0x17: util::stream_format(stream, "dsrav %s,%s,%s", reg[rd], reg[rt], reg[rs]); break;
- case 0x18: util::stream_format(stream, "mult %s,%s", reg[rs], reg[rt]); break;
- case 0x19: util::stream_format(stream, "multu %s,%s", reg[rs], reg[rt]); break;
- case 0x1a: util::stream_format(stream, "div %s,%s", reg[rs], reg[rt]); break;
- case 0x1b: util::stream_format(stream, "divu %s,%s", reg[rs], reg[rt]); break;
- case 0x1c: util::stream_format(stream, "dmult %s,%s", reg[rs], reg[rt]); break;
- case 0x1d: util::stream_format(stream, "dmultu %s,%s", reg[rs], reg[rt]); break;
- case 0x1e: util::stream_format(stream, "ddiv %s,%s", reg[rs], reg[rt]); break;
- case 0x1f: util::stream_format(stream, "ddivu %s,%s", reg[rs], reg[rt]); break;
- case 0x20: util::stream_format(stream, "add %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
- case 0x21: util::stream_format(stream, "addu %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
- case 0x22: util::stream_format(stream, "sub %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
- case 0x23: util::stream_format(stream, "subu %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
- case 0x24: util::stream_format(stream, "and %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
- case 0x25: util::stream_format(stream, "or %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
- case 0x26: util::stream_format(stream, "xor %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
- case 0x27: util::stream_format(stream, "nor %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
- case 0x2a: util::stream_format(stream, "slt %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
- case 0x2b: util::stream_format(stream, "sltu %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
- case 0x2c: util::stream_format(stream, "dadd %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
- case 0x2d: util::stream_format(stream, "daddu %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
- case 0x2e: util::stream_format(stream, "dsub %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
- case 0x2f: util::stream_format(stream, "dsubu %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
- case 0x30: util::stream_format(stream, "tge %s,%s", reg[rs], reg[rt]); flags = STEP_OVER; break;
- case 0x31: util::stream_format(stream, "tgeu %s,%s", reg[rs], reg[rt]); flags = STEP_OVER; break;
- case 0x32: util::stream_format(stream, "tlt %s,%s", reg[rs], reg[rt]); flags = STEP_OVER; break;
- case 0x33: util::stream_format(stream, "tltu %s,%s", reg[rs], reg[rt]); flags = STEP_OVER; break;
- case 0x34: util::stream_format(stream, "teq %s,%s", reg[rs], reg[rt]); flags = STEP_OVER; break;
- case 0x36: util::stream_format(stream, "tne %s,%s", reg[rs], reg[rt]) ;flags = STEP_OVER; break;
- case 0x38: util::stream_format(stream, "dsll %s,%s,%d", reg[rd], reg[rt], shift); break;
- case 0x3a: util::stream_format(stream, "dsrl %s,%s,%d", reg[rd], reg[rt], shift); break;
- case 0x3b: util::stream_format(stream, "dsra %s,%s,%d", reg[rd], reg[rt], shift); break;
- case 0x3c: util::stream_format(stream, "dsll %s,%s,%d", reg[rd], reg[rt], shift+32); break;
- case 0x3e: util::stream_format(stream, "dsrl %s,%s,%d", reg[rd], reg[rt], shift+32); break;
- case 0x3f: util::stream_format(stream, "dsra %s,%s,%d", reg[rd], reg[rt], shift+32); break;
- default: util::stream_format(stream, "dc.l $%08x [invalid]", op); break;
+ case 0x10: util::stream_format(stream, "mfhi %s", reg[rd]); break;
+ case 0x11: util::stream_format(stream, "mthi %s", reg[rs]); break;
+ case 0x12: util::stream_format(stream, "mflo %s", reg[rd]); break;
+ case 0x13: util::stream_format(stream, "mtlo %s", reg[rs]); break;
+ case 0x14: util::stream_format(stream, "dsllv %s,%s,%s", reg[rd], reg[rt], reg[rs]); break;
+ case 0x16: util::stream_format(stream, "dsrlv %s,%s,%s", reg[rd], reg[rt], reg[rs]); break;
+ case 0x17: util::stream_format(stream, "dsrav %s,%s,%s", reg[rd], reg[rt], reg[rs]); break;
+ case 0x18: util::stream_format(stream, "mult %s,%s", reg[rs], reg[rt]); break;
+ case 0x19: util::stream_format(stream, "multu %s,%s", reg[rs], reg[rt]); break;
+ case 0x1a: util::stream_format(stream, "div %s,%s", reg[rs], reg[rt]); break;
+ case 0x1b: util::stream_format(stream, "divu %s,%s", reg[rs], reg[rt]); break;
+ case 0x1c: util::stream_format(stream, "dmult %s,%s", reg[rs], reg[rt]); break;
+ case 0x1d: util::stream_format(stream, "dmultu %s,%s", reg[rs], reg[rt]); break;
+ case 0x1e: util::stream_format(stream, "ddiv %s,%s", reg[rs], reg[rt]); break;
+ case 0x1f: util::stream_format(stream, "ddivu %s,%s", reg[rs], reg[rt]); break;
+ case 0x20: util::stream_format(stream, "add %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x21: util::stream_format(stream, "addu %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x22: util::stream_format(stream, "sub %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x23: util::stream_format(stream, "subu %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x24: util::stream_format(stream, "and %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x25: util::stream_format(stream, "or %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x26: util::stream_format(stream, "xor %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x27: util::stream_format(stream, "nor %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x2a: util::stream_format(stream, "slt %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x2b: util::stream_format(stream, "sltu %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x2c: util::stream_format(stream, "dadd %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x2d: util::stream_format(stream, "daddu %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x2e: util::stream_format(stream, "dsub %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x2f: util::stream_format(stream, "dsubu %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
+ case 0x30: util::stream_format(stream, "tge %s,%s", reg[rs], reg[rt]); flags = STEP_OVER; break;
+ case 0x31: util::stream_format(stream, "tgeu %s,%s", reg[rs], reg[rt]); flags = STEP_OVER; break;
+ case 0x32: util::stream_format(stream, "tlt %s,%s", reg[rs], reg[rt]); flags = STEP_OVER; break;
+ case 0x33: util::stream_format(stream, "tltu %s,%s", reg[rs], reg[rt]); flags = STEP_OVER; break;
+ case 0x34: util::stream_format(stream, "teq %s,%s", reg[rs], reg[rt]); flags = STEP_OVER; break;
+ case 0x36: util::stream_format(stream, "tne %s,%s", reg[rs], reg[rt]) ;flags = STEP_OVER; break;
+ case 0x38: util::stream_format(stream, "dsll %s,%s,%d", reg[rd], reg[rt], shift); break;
+ case 0x3a: util::stream_format(stream, "dsrl %s,%s,%d", reg[rd], reg[rt], shift); break;
+ case 0x3b: util::stream_format(stream, "dsra %s,%s,%d", reg[rd], reg[rt], shift); break;
+ case 0x3c: util::stream_format(stream, "dsll %s,%s,%d", reg[rd], reg[rt], shift+32); break;
+ case 0x3e: util::stream_format(stream, "dsrl %s,%s,%d", reg[rd], reg[rt], shift+32); break;
+ case 0x3f: util::stream_format(stream, "dsra %s,%s,%d", reg[rd], reg[rt], shift+32); break;
+ default: flags = dasm_extra_special(pc, op, stream); break;
}
break;
case 0x01: /* REGIMM */
switch ((op >> 16) & 31)
{
- case 0x00: util::stream_format(stream, "bltz %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); break;
- case 0x01: util::stream_format(stream, "bgez %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); break;
- case 0x02: util::stream_format(stream, "bltzl %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); break;
- case 0x03: util::stream_format(stream, "bgezl %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); break;
- case 0x08: util::stream_format(stream, "tgei %s,%s", reg[rs], signed_16bit(op)); flags = STEP_OVER; break;
- case 0x09: util::stream_format(stream, "tgeiu %s,%s", reg[rs], signed_16bit(op)); flags = STEP_OVER; break;
- case 0x0a: util::stream_format(stream, "tlti %s,%s", reg[rs], signed_16bit(op)); flags = STEP_OVER; break;
- case 0x0b: util::stream_format(stream, "tltiu %s,%s", reg[rs], signed_16bit(op)); flags = STEP_OVER; break;
- case 0x0c: util::stream_format(stream, "teqi %s,%s", reg[rs], signed_16bit(op)); flags = STEP_OVER; break;
- case 0x0e: util::stream_format(stream, "tnei %s,%s", reg[rs], signed_16bit(op)); flags = STEP_OVER; break;
- case 0x10: util::stream_format(stream, "bltzal %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); flags = STEP_OVER | step_over_extra(1); break;
- case 0x11: util::stream_format(stream, "bgezal %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); flags = STEP_OVER | step_over_extra(1); break;
- case 0x12: util::stream_format(stream, "bltzall %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); flags = STEP_OVER | step_over_extra(1); break;
- case 0x13: util::stream_format(stream, "bgezall %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); flags = STEP_OVER | step_over_extra(1); break;
- default: util::stream_format(stream, "dc.l $%08x [invalid]", op); break;
+ case 0x00: util::stream_format(stream, "bltz %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); break;
+ case 0x01: util::stream_format(stream, "bgez %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); break;
+ case 0x02: util::stream_format(stream, "bltzl %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); break;
+ case 0x03: util::stream_format(stream, "bgezl %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); break;
+ case 0x08: util::stream_format(stream, "tgei %s,%s", reg[rs], signed_16bit(op)); flags = STEP_OVER; break;
+ case 0x09: util::stream_format(stream, "tgeiu %s,%s", reg[rs], signed_16bit(op)); flags = STEP_OVER; break;
+ case 0x0a: util::stream_format(stream, "tlti %s,%s", reg[rs], signed_16bit(op)); flags = STEP_OVER; break;
+ case 0x0b: util::stream_format(stream, "tltiu %s,%s", reg[rs], signed_16bit(op)); flags = STEP_OVER; break;
+ case 0x0c: util::stream_format(stream, "teqi %s,%s", reg[rs], signed_16bit(op)); flags = STEP_OVER; break;
+ case 0x0e: util::stream_format(stream, "tnei %s,%s", reg[rs], signed_16bit(op)); flags = STEP_OVER; break;
+ case 0x10: util::stream_format(stream, "bltzal %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); flags = STEP_OVER | step_over_extra(1); break;
+ case 0x11: util::stream_format(stream, "bgezal %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); flags = STEP_OVER | step_over_extra(1); break;
+ case 0x12: util::stream_format(stream, "bltzall %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); flags = STEP_OVER | step_over_extra(1); break;
+ case 0x13: util::stream_format(stream, "bgezall %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); flags = STEP_OVER | step_over_extra(1); break;
+ default: flags = dasm_extra_regimm(pc, op, stream); break;
}
break;
- case 0x02: util::stream_format(stream, "j $%08x", (pc & 0xf0000000) | ((op & 0x03ffffff) << 2)); break;
- case 0x03: util::stream_format(stream, "jal $%08x", (pc & 0xf0000000) | ((op & 0x03ffffff) << 2)); flags = STEP_OVER | step_over_extra(1); break;
+ case 0x02: util::stream_format(stream, "j $%08x", (pc & 0xf0000000) | ((op & 0x03ffffff) << 2)); break;
+ case 0x03: util::stream_format(stream, "jal $%08x", (pc & 0xf0000000) | ((op & 0x03ffffff) << 2)); flags = STEP_OVER | step_over_extra(1); break;
case 0x04: if (rs == 0 && rt == 0)
- util::stream_format(stream, "b $%08x", pc + 4 + ((int16_t)op << 2));
+ util::stream_format(stream, "b $%08x", pc + 4 + ((int16_t)op << 2));
else
- util::stream_format(stream, "beq %s,%s,$%08x", reg[rs], reg[rt], pc + 4 + ((int16_t)op << 2));
+ util::stream_format(stream, "beq %s,%s,$%08x", reg[rs], reg[rt], pc + 4 + ((int16_t)op << 2));
break;
- case 0x05: util::stream_format(stream, "bne %s,%s,$%08x", reg[rs], reg[rt], pc + 4 + ((int16_t)op << 2));break;
- case 0x06: util::stream_format(stream, "blez %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); break;
- case 0x07: util::stream_format(stream, "bgtz %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); break;
- case 0x08: util::stream_format(stream, "addi %s,%s,%s", reg[rt], reg[rs], signed_16bit(op)); break;
- case 0x09: util::stream_format(stream, "addiu %s,%s,%s", reg[rt], reg[rs], signed_16bit(op)); break;
- case 0x0a: util::stream_format(stream, "slti %s,%s,%s", reg[rt], reg[rs], signed_16bit(op)); break;
- case 0x0b: util::stream_format(stream, "sltiu %s,%s,%s", reg[rt], reg[rs], signed_16bit(op)); break;
- case 0x0c: util::stream_format(stream, "andi %s,%s,$%04x", reg[rt], reg[rs], (uint16_t)op); break;
- case 0x0d: util::stream_format(stream, "ori %s,%s,$%04x", reg[rt], reg[rs], (uint16_t)op); break;
- case 0x0e: util::stream_format(stream, "xori %s,%s,$%04x", reg[rt], reg[rs], (uint16_t)op); break;
- case 0x0f: util::stream_format(stream, "lui %s,$%04x", reg[rt], (uint16_t)op); break;
+ case 0x05: util::stream_format(stream, "bne %s,%s,$%08x", reg[rs], reg[rt], pc + 4 + ((int16_t)op << 2));break;
+ case 0x06: util::stream_format(stream, "blez %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); break;
+ case 0x07: util::stream_format(stream, "bgtz %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); break;
+ case 0x08: util::stream_format(stream, "addi %s,%s,%s", reg[rt], reg[rs], signed_16bit(op)); break;
+ case 0x09: util::stream_format(stream, "addiu %s,%s,%s", reg[rt], reg[rs], signed_16bit(op)); break;
+ case 0x0a: util::stream_format(stream, "slti %s,%s,%s", reg[rt], reg[rs], signed_16bit(op)); break;
+ case 0x0b: util::stream_format(stream, "sltiu %s,%s,%s", reg[rt], reg[rs], signed_16bit(op)); break;
+ case 0x0c: util::stream_format(stream, "andi %s,%s,$%04x", reg[rt], reg[rs], (uint16_t)op); break;
+ case 0x0d: util::stream_format(stream, "ori %s,%s,$%04x", reg[rt], reg[rs], (uint16_t)op); break;
+ case 0x0e: util::stream_format(stream, "xori %s,%s,$%04x", reg[rt], reg[rs], (uint16_t)op); break;
+ case 0x0f: util::stream_format(stream, "lui %s,$%04x", reg[rt], (uint16_t)op); break;
case 0x10: flags = dasm_cop0(pc, op, stream); break;
case 0x11: flags = dasm_cop1(pc, op, stream); break;
case 0x12: flags = dasm_cop2(pc, op, stream); break;
case 0x13: flags = dasm_cop1x(pc, op, stream); break;
- case 0x14: util::stream_format(stream, "beql %s,%s,$%08x", reg[rs], reg[rt], pc + 4 + ((int16_t)op << 2));break;
- case 0x15: util::stream_format(stream, "bnel %s,%s,$%08x", reg[rs], reg[rt], pc + 4 + ((int16_t)op << 2));break;
- case 0x16: util::stream_format(stream, "blezl %s,%s,$%08x", reg[rs], reg[rt], pc + 4 + ((int16_t)op << 2));break;
- case 0x17: util::stream_format(stream, "bgtzl %s,%s,$%08x", reg[rs], reg[rt], pc + 4 + ((int16_t)op << 2));break;
- case 0x18: util::stream_format(stream, "daddi %s,%s,%s", reg[rt], reg[rs], signed_16bit(op)); break;
- case 0x19: util::stream_format(stream, "daddiu %s,%s,%s", reg[rt], reg[rs], signed_16bit(op)); break;
- case 0x1a: util::stream_format(stream, "ldl %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
- case 0x1b: util::stream_format(stream, "ldr %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
- case 0x1c: /* IDT-specific opcodes: mad/madu/mul on R4640/4650, msub on RC32364 */
- switch (op & 0x1f)
- {
- case 0: util::stream_format(stream, "mad %s,%s", reg[rs], reg[rt]); break;
- case 1: util::stream_format(stream, "madu %s,%s", reg[rs], reg[rt]); break;
- case 2: util::stream_format(stream, "mul %s,%s,%s", reg[rs], reg[rt], reg[rd]); break;
- case 4: util::stream_format(stream, "msub %s,%s", reg[rs], reg[rt]); break;
- default:util::stream_format(stream, "dc.l $%08x [invalid]", op); break;
- }
- break;
- case 0x20: util::stream_format(stream, "lb %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
- case 0x21: util::stream_format(stream, "lh %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
- case 0x22: util::stream_format(stream, "lwl %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
- case 0x23: util::stream_format(stream, "lw %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
- case 0x24: util::stream_format(stream, "lbu %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
- case 0x25: util::stream_format(stream, "lhu %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
- case 0x26: util::stream_format(stream, "lwr %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
- case 0x27: util::stream_format(stream, "lwu %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
- case 0x28: util::stream_format(stream, "sb %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
- case 0x29: util::stream_format(stream, "sh %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
- case 0x2a: util::stream_format(stream, "swl %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
- case 0x2b: util::stream_format(stream, "sw %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
- case 0x2c: util::stream_format(stream, "sdl %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
- case 0x2d: util::stream_format(stream, "sdr %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
- case 0x2e: util::stream_format(stream, "swr %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
- case 0x2f: util::stream_format(stream, "cache %s,%s(%s)", cacheop[rt], reg[rs], signed_16bit(op)); break;
- case 0x30: util::stream_format(stream, "ll %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
- case 0x31: util::stream_format(stream, "lwc1 %s,%s(%s)", cpreg[1][rt], signed_16bit(op), reg[rs]); break;
- case 0x32: util::stream_format(stream, "lwc2 %s,%s(%s)", cpreg[2][rt], signed_16bit(op), reg[rs]); break;
- case 0x33: util::stream_format(stream, "pref $%x,%s(%s)", rt, signed_16bit(op), reg[rs]); break;
- case 0x34: util::stream_format(stream, "lld %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
- case 0x35: util::stream_format(stream, "ldc1 %s,%s(%s)", cpreg[1][rt], signed_16bit(op), reg[rs]); break;
- case 0x36: util::stream_format(stream, "ldc2 %s,%s(%s)", cpreg[2][rt], signed_16bit(op), reg[rs]); break;
- case 0x37: util::stream_format(stream, "ld %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
- case 0x38: util::stream_format(stream, "sc %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
- case 0x39: util::stream_format(stream, "swc1 %s,%s(%s)", cpreg[1][rt], signed_16bit(op), reg[rs]); break;
- case 0x3a: util::stream_format(stream, "swc2 %s,%s(%s)", cpreg[2][rt], signed_16bit(op), reg[rs]); break;
- case 0x3c: util::stream_format(stream, "scd %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
- case 0x3d: util::stream_format(stream, "sdc1 %s,%s(%s)", cpreg[1][rt], signed_16bit(op), reg[rs]); break;
- case 0x3e: util::stream_format(stream, "sdc2 %s,%s(%s)", cpreg[2][rt], signed_16bit(op), reg[rs]); break;
- case 0x3f: util::stream_format(stream, "sd %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
- default: util::stream_format(stream, "dc.l $%08x [invalid]", op); break;
+ case 0x14: util::stream_format(stream, "beql %s,%s,$%08x", reg[rs], reg[rt], pc + 4 + ((int16_t)op << 2));break;
+ case 0x15: util::stream_format(stream, "bnel %s,%s,$%08x", reg[rs], reg[rt], pc + 4 + ((int16_t)op << 2));break;
+ case 0x16: util::stream_format(stream, "blezl %s,%s,$%08x", reg[rs], reg[rt], pc + 4 + ((int16_t)op << 2));break;
+ case 0x17: util::stream_format(stream, "bgtzl %s,%s,$%08x", reg[rs], reg[rt], pc + 4 + ((int16_t)op << 2));break;
+ case 0x18: util::stream_format(stream, "daddi %s,%s,%s", reg[rt], reg[rs], signed_16bit(op)); break;
+ case 0x19: util::stream_format(stream, "daddiu %s,%s,%s", reg[rt], reg[rs], signed_16bit(op)); break;
+ case 0x1a: util::stream_format(stream, "ldl %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
+ case 0x1b: util::stream_format(stream, "ldr %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
+ case 0x1c: flags = dasm_idt(pc, op, stream); break;
+ case 0x20: util::stream_format(stream, "lb %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
+ case 0x21: util::stream_format(stream, "lh %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
+ case 0x22: util::stream_format(stream, "lwl %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
+ case 0x23: util::stream_format(stream, "lw %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
+ case 0x24: util::stream_format(stream, "lbu %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
+ case 0x25: util::stream_format(stream, "lhu %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
+ case 0x26: util::stream_format(stream, "lwr %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
+ case 0x27: util::stream_format(stream, "lwu %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
+ case 0x28: util::stream_format(stream, "sb %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
+ case 0x29: util::stream_format(stream, "sh %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
+ case 0x2a: util::stream_format(stream, "swl %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
+ case 0x2b: util::stream_format(stream, "sw %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
+ case 0x2c: util::stream_format(stream, "sdl %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
+ case 0x2d: util::stream_format(stream, "sdr %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
+ case 0x2e: util::stream_format(stream, "swr %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
+ case 0x2f: util::stream_format(stream, "cache %s,%s(%s)", cacheop[rt], reg[rs], signed_16bit(op)); break;
+ case 0x30: util::stream_format(stream, "ll %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
+ case 0x31: util::stream_format(stream, "lwc1 %s,%s(%s)", cpreg[1][rt], signed_16bit(op), reg[rs]); break;
+ case 0x32: util::stream_format(stream, "lwc2 %s,%s(%s)", cpreg[2][rt], signed_16bit(op), reg[rs]); break;
+ case 0x33: util::stream_format(stream, "pref $%x,%s(%s)", rt, signed_16bit(op), reg[rs]); break;
+ case 0x34: util::stream_format(stream, "lld %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
+ case 0x35: util::stream_format(stream, "ldc1 %s,%s(%s)", cpreg[1][rt], signed_16bit(op), reg[rs]); break;
+ case 0x36: util::stream_format(stream, "ldc2 %s,%s(%s)", cpreg[2][rt], signed_16bit(op), reg[rs]); break;
+ case 0x37: util::stream_format(stream, "ld %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
+ case 0x38: util::stream_format(stream, "sc %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
+ case 0x39: util::stream_format(stream, "swc1 %s,%s(%s)", cpreg[1][rt], signed_16bit(op), reg[rs]); break;
+ case 0x3a: util::stream_format(stream, "swc2 %s,%s(%s)", cpreg[2][rt], signed_16bit(op), reg[rs]); break;
+ case 0x3c: util::stream_format(stream, "scd %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
+ case 0x3d: util::stream_format(stream, "sdc1 %s,%s(%s)", cpreg[1][rt], signed_16bit(op), reg[rs]); break;
+ case 0x3e: util::stream_format(stream, "sdc2 %s,%s(%s)", cpreg[2][rt], signed_16bit(op), reg[rs]); break;
+ case 0x3f: util::stream_format(stream, "sd %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
+ default: flags = dasm_extra_base(pc, op, stream); break;
}
return 4 | flags | SUPPORTED;
}
diff --git a/src/devices/cpu/mips/mips3dsm.h b/src/devices/cpu/mips/mips3dsm.h
index a38771bbba0..50bb28875ea 100644
--- a/src/devices/cpu/mips/mips3dsm.h
+++ b/src/devices/cpu/mips/mips3dsm.h
@@ -24,17 +24,40 @@ public:
offs_t dasm_one(std::ostream &stream, offs_t pc, u32 op);
-private:
+protected:
static const char *const reg[32];
static const char *const cacheop[32];
static const char *const cpreg[4][32];
static const char *const ccreg[4][32];
inline std::string signed_16bit(int16_t val);
+ virtual uint32_t dasm_extra_base(uint32_t pc, uint32_t op, std::ostream &stream);
+ virtual uint32_t dasm_extra_special(uint32_t pc, uint32_t op, std::ostream &stream);
+ virtual uint32_t dasm_extra_regimm(uint32_t pc, uint32_t op, std::ostream &stream);
uint32_t dasm_cop0(uint32_t pc, uint32_t op, std::ostream &stream);
uint32_t dasm_cop1(uint32_t pc, uint32_t op, std::ostream &stream);
uint32_t dasm_cop1x(uint32_t pc, uint32_t op, std::ostream &stream);
- uint32_t dasm_cop2(uint32_t pc, uint32_t op, std::ostream &stream);
+ virtual uint32_t dasm_cop2(uint32_t pc, uint32_t op, std::ostream &stream);
+ virtual uint32_t dasm_idt(uint32_t pc, uint32_t op, std::ostream &stream);
+};
+class ee_disassembler : public mips3_disassembler
+{
+public:
+ ee_disassembler() = default;
+ virtual ~ee_disassembler() = default;
+
+protected:
+ static const char *const vreg[32];
+
+ uint32_t dasm_extra_base(uint32_t pc, uint32_t op, std::ostream &stream) override;
+ uint32_t dasm_extra_special(uint32_t pc, uint32_t op, std::ostream &stream) override;
+ uint32_t dasm_extra_regimm(uint32_t pc, uint32_t op, std::ostream &stream) override;
+ uint32_t dasm_idt(uint32_t pc, uint32_t op, std::ostream &stream) override;
+ uint32_t dasm_mmi(uint32_t pc, uint32_t op, std::ostream &stream);
+ uint32_t dasm_mmi0(uint32_t pc, uint32_t op, std::ostream &stream);
+ uint32_t dasm_mmi1(uint32_t pc, uint32_t op, std::ostream &stream);
+ uint32_t dasm_mmi2(uint32_t pc, uint32_t op, std::ostream &stream);
+ uint32_t dasm_mmi3(uint32_t pc, uint32_t op, std::ostream &stream);
};
#endif
diff --git a/src/mame/drivers/ps2sony.cpp b/src/mame/drivers/ps2sony.cpp
index 467be7f5da3..e13fcffeb0d 100644
--- a/src/mame/drivers/ps2sony.cpp
+++ b/src/mame/drivers/ps2sony.cpp
@@ -199,7 +199,7 @@ static INPUT_PORTS_START( ps2sony )
INPUT_PORTS_END
MACHINE_CONFIG_START(ps2sony_state::ps2sony)
- MCFG_DEVICE_ADD("maincpu", R5000LE, 294'912'000) // actually R5900
+ MCFG_DEVICE_ADD("maincpu", R5900LE, 294'912'000)
MCFG_MIPS3_ICACHE_SIZE(16384)
MCFG_MIPS3_DCACHE_SIZE(16384)
MCFG_DEVICE_PROGRAM_MAP(mem_map)