diff --git a/rpcs3/Emu/Cell/SPUDisAsm.h b/rpcs3/Emu/Cell/SPUDisAsm.h index 001c5a4ffa..ae8b2e7e0e 100644 --- a/rpcs3/Emu/Cell/SPUDisAsm.h +++ b/rpcs3/Emu/Cell/SPUDisAsm.h @@ -83,6 +83,17 @@ private: return spu_branch_target(dump_pc, imm); } + static const char* BrIndirectSuffix(u32 de) + { + switch (de) + { + case 0b01: return "e"; + case 0b10: return "d"; + //case 0b11: return "(undef)"; + default: return ""; + } + } + private: std::string& FixOp(std::string& op) { @@ -134,6 +145,16 @@ private: Write(fmt::format("%s %s,%s,%s,%s", FixOp(op).c_str(), a1, a2, a3, a4)); } + using field_de_t = decltype(spu_opcode_t{}.de); + void DisAsm(std::string op, field_de_t de, const char* a1) + { + Write(fmt::format("%s%s %s", FixOp(op).c_str(), BrIndirectSuffix(de), a1)); + } + void DisAsm(std::string op, field_de_t de, const char* a1, const char* a2) + { + Write(fmt::format("%s%s %s", FixOp(op).c_str(), BrIndirectSuffix(de), a1, a2)); + } + public: u32 disasm(u32 pc) override; @@ -288,19 +309,19 @@ public: } void BIZ(spu_opcode_t op) { - DisAsm("biz", spu_reg_name[op.rt], spu_reg_name[op.ra]); + DisAsm("biz", op.de, spu_reg_name[op.rt], spu_reg_name[op.ra]); } void BINZ(spu_opcode_t op) { - DisAsm("binz", spu_reg_name[op.rt], spu_reg_name[op.ra]); + DisAsm("binz", op.de, spu_reg_name[op.rt], spu_reg_name[op.ra]); } void BIHZ(spu_opcode_t op) { - DisAsm("bihz", spu_reg_name[op.rt], spu_reg_name[op.ra]); + DisAsm("bihz", op.de, spu_reg_name[op.rt], spu_reg_name[op.ra]); } void BIHNZ(spu_opcode_t op) { - DisAsm("bihnz", spu_reg_name[op.rt], spu_reg_name[op.ra]); + DisAsm("bihnz", op.de, spu_reg_name[op.rt], spu_reg_name[op.ra]); } void STOPD(spu_opcode_t op) { @@ -312,19 +333,19 @@ public: } void BI(spu_opcode_t op) { - DisAsm("bi", spu_reg_name[op.ra]); + DisAsm("bi", op.de, spu_reg_name[op.ra]); } void BISL(spu_opcode_t op) { - DisAsm("bisl", spu_reg_name[op.rt], spu_reg_name[op.ra]); + DisAsm("bisl", op.de, spu_reg_name[op.rt], spu_reg_name[op.ra]); } void IRET(spu_opcode_t op) { - DisAsm("iret", spu_reg_name[op.ra]); + DisAsm("iret", op.de, spu_reg_name[op.ra]); } void BISLED(spu_opcode_t op) { - DisAsm("bisled", spu_reg_name[op.rt], spu_reg_name[op.ra]); + DisAsm("bisled", op.de, spu_reg_name[op.rt], spu_reg_name[op.ra]); } void HBR(spu_opcode_t op) { diff --git a/rpcs3/Emu/Cell/SPUOpcodes.h b/rpcs3/Emu/Cell/SPUOpcodes.h index 35c9e0103a..ad2262b6f1 100644 --- a/rpcs3/Emu/Cell/SPUOpcodes.h +++ b/rpcs3/Emu/Cell/SPUOpcodes.h @@ -13,6 +13,7 @@ union spu_opcode_t bf_t rt4; // 4..10, for 4-op instructions bf_t e; // 13, "enable interrupts" bit bf_t d; // 12, "disable interrupts" bit + bf_t de; // 12..13 combined 'e' and 'd' bits bf_t c; // 11, "C" bit for SYNC instruction bf_t r0h; // 7..8, signed bf_t roh; // 16..17, signed