diff --git a/rpcs3/Emu/Cell/PPUDisAsm.cpp b/rpcs3/Emu/Cell/PPUDisAsm.cpp index 180012a015..96ddc315ec 100644 --- a/rpcs3/Emu/Cell/PPUDisAsm.cpp +++ b/rpcs3/Emu/Cell/PPUDisAsm.cpp @@ -1051,12 +1051,18 @@ void PPUDisAsm::BCLR(ppu_opcode_t op) void PPUDisAsm::CRNOR(ppu_opcode_t op) { - DisAsm_INT3("crnor", op.crbd, op.crba, op.crbb); + if (op.crba == op.crbb) + { + DisAsm_BI2("crnot", op.crbd, op.crba); + return; + } + + DisAsm_BI3("crnor", op.crbd, op.crba, op.crbb); } void PPUDisAsm::CRANDC(ppu_opcode_t op) { - DisAsm_INT3("crandc", op.crbd, op.crba, op.crbb); + DisAsm_BI3("crandc", op.crbd, op.crba, op.crbb); } void PPUDisAsm::ISYNC(ppu_opcode_t op) @@ -1066,32 +1072,50 @@ void PPUDisAsm::ISYNC(ppu_opcode_t op) void PPUDisAsm::CRXOR(ppu_opcode_t op) { - DisAsm_INT3("crxor", op.crbd, op.crba, op.crbb); + if (op.crba == op.crbb && op.crba == op.crbd) + { + DisAsm_BI1("crclr", op.crbd); + return; + } + + DisAsm_BI3("crxor", op.crbd, op.crba, op.crbb); } void PPUDisAsm::CRNAND(ppu_opcode_t op) { - DisAsm_INT3("crnand", op.crbd, op.crba, op.crbb); + DisAsm_BI3("crnand", op.crbd, op.crba, op.crbb); } void PPUDisAsm::CRAND(ppu_opcode_t op) { - DisAsm_INT3("crand", op.crbd, op.crba, op.crbb); + DisAsm_BI3("crand", op.crbd, op.crba, op.crbb); } void PPUDisAsm::CREQV(ppu_opcode_t op) { - DisAsm_INT3("creqv", op.crbd, op.crba, op.crbb); + if (op.crba == op.crbb && op.crba == op.crbd) + { + DisAsm_BI1("crset", op.crbd); + return; + } + + DisAsm_BI3("creqv", op.crbd, op.crba, op.crbb); } void PPUDisAsm::CRORC(ppu_opcode_t op) { - DisAsm_INT3("crorc", op.crbd, op.crba, op.crbb); + DisAsm_BI3("crorc", op.crbd, op.crba, op.crbb); } void PPUDisAsm::CROR(ppu_opcode_t op) { - DisAsm_INT3("cror", op.crbd, op.crba, op.crbb); + if (op.crba == op.crbb) + { + DisAsm_BI2("crmove", op.crbd, op.crba); + return; + } + + DisAsm_BI3("cror", op.crbd, op.crba, op.crbb); } void PPUDisAsm::BCCTR(ppu_opcode_t op) @@ -1112,7 +1136,7 @@ void PPUDisAsm::BCCTR(ppu_opcode_t op) if (!inst || inst[1] == 'd') { // Invalid or unknown bcctr form - Write(fmt::format("bcctr %d, cr%d[%x], %d, %d", bo, bi / 4, bi % 4, bh, lk)); + Write(fmt::format("bcctr %d, cr%d[%s], %d, %d", bo, bi / 4, get_partial_BI_field(bi), bh, lk)); return; } diff --git a/rpcs3/Emu/Cell/PPUDisAsm.h b/rpcs3/Emu/Cell/PPUDisAsm.h index 06619f923e..6b324e2a4a 100644 --- a/rpcs3/Emu/Cell/PPUDisAsm.h +++ b/rpcs3/Emu/Cell/PPUDisAsm.h @@ -227,6 +227,19 @@ private: { Write(fmt::format("%s cr%d,cr%d", FixOp(op).c_str(), cr0, cr1)); } + void DisAsm_BI1(const std::string& op, const int i0) + { + Write(fmt::format("%s cr%d[%s]", FixOp(op).c_str(), i0 / 4, get_partial_BI_field(i0))); + } + void DisAsm_BI2(const std::string& op, const int i0, const int i1) + { + Write(fmt::format("%s cr%d[%s],cr%d[%s]", FixOp(op).c_str(), i0 / 4, get_partial_BI_field(i0), i1 / 4, get_partial_BI_field(i1))); + } + void DisAsm_BI3(const std::string& op, const int i0, const int i1, const int i2) + { + Write(fmt::format("%s cr%d[%s],cr%d[%s],cr%d[%s]", FixOp(op).c_str(), + i0 / 4, get_partial_BI_field(i0), i1 / 4, get_partial_BI_field(i1), i2 / 4, get_partial_BI_field(i2))); + } void DisAsm_INT3(const std::string& op, const int i0, const int i1, const int i2) { Write(fmt::format("%s %d,%d,%d", FixOp(op).c_str(), i0, i1, i2));