From 0de9960772e5f3aa1d1d3654c68551e122cbffe9 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Fri, 21 Jan 2022 12:49:52 +0300 Subject: [PATCH] PPU: rewrite MFOCRF+MFCR instructions --- rpcs3/Emu/Cell/PPUInterpreter.cpp | 76 +++++++++++++++++++++++-------- rpcs3/Emu/Cell/PPUTranslator.cpp | 4 +- 2 files changed, 59 insertions(+), 21 deletions(-) diff --git a/rpcs3/Emu/Cell/PPUInterpreter.cpp b/rpcs3/Emu/Cell/PPUInterpreter.cpp index eda93c446e..ca9bc435f5 100644 --- a/rpcs3/Emu/Cell/PPUInterpreter.cpp +++ b/rpcs3/Emu/Cell/PPUInterpreter.cpp @@ -3795,36 +3795,52 @@ auto MULHWU() RETURN_(ppu, op); } +template +struct MFOCRF +{ + template + static auto select(bs_t selected, auto func) + { + return ppu_exec_select<>::select(selected, func); + } + + template + static auto impl() + { + static const auto exec = [](ppu_thread& ppu, auto&& d) + { + const u32 p = N * 4; + const u32 v = ppu.cr[p + 0] << 3 | ppu.cr[p + 1] << 2 | ppu.cr[p + 2] << 1 | ppu.cr[p + 3] << 0; + + d = v << (p ^ 0x1c); + }; + + RETURN_(ppu, ppu.gpr[op.rd]); + } +}; + template -auto MFOCRF() +auto MFCR() { if constexpr (Build == 0xf1a6) return ppu_exec_select::template select<>(); - static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op) { - if (op.l11) + static const auto exec = [](ppu_thread& ppu, auto&& d) { - // MFOCRF - const u32 n = std::countl_zero(op.crm) & 7; - const u32 p = n * 4; - const u32 v = ppu.cr[p + 0] << 3 | ppu.cr[p + 1] << 2 | ppu.cr[p + 2] << 1 | ppu.cr[p + 3] << 0; - - ppu.gpr[op.rd] = v << (p ^ 0x1c); - } - else - { - // MFCR +#if defined(ARCH_X64) be_t lane0, lane1; std::memcpy(&lane0, ppu.cr.bits, sizeof(v128)); std::memcpy(&lane1, ppu.cr.bits + 16, sizeof(v128)); const u32 mh = _mm_movemask_epi8(_mm_slli_epi64(lane0.value(), 7)); const u32 ml = _mm_movemask_epi8(_mm_slli_epi64(lane1.value(), 7)); - ppu.gpr[op.rd] = (mh << 16) | ml; - } - + d = (mh << 16) | ml; +#else + d = ppu.cr.pack(); +#endif }; - RETURN_(ppu, op); + + RETURN_(ppu, ppu.gpr[op.rd]); } template @@ -6926,7 +6942,9 @@ struct ppu_interpreter_t IT ADDC; IT MULHDU; IT MULHWU; - IT MFOCRF; + IT MFOCRF{}; + IT MFOCRF_[8]; + IT MFCR; //+ IT LWARX; IT LDX; IT LWZX; @@ -7522,7 +7540,8 @@ ppu_interpreter_rt_base::ppu_interpreter_rt_base() noexcept INIT_RC_OV(ADDC); INIT_RC(MULHDU); INIT_RC(MULHWU); - INIT(MFOCRF); + INIT_PACK8(MFOCRF,); + INIT(MFCR); //+ INIT(LWARX); INIT(LDX); INIT(LWZX); @@ -7754,6 +7773,25 @@ ppu_intrp_func_t ppu_interpreter_rt::decode(u32 opv) const noexcept break; } case ppu_itype::VSLDOI: return ptrs->VSLDOI_[op.vsh]; + case ppu_itype::MFOCRF: + { + if (op.l11) + { + const u32 n = std::countl_zero(op.crm) & 7; + + if (0x80u >> n != op.crm) + { + return [](ppu_thread&, ppu_opcode_t op, be_t*, ppu_intrp_func*) + { + fmt::throw_exception("Invalid instruction: MFOCRF with bits 0x%x", op.crm); + }; + } + + return ptrs->MFOCRF_[n]; + } + + return ptrs->MFCR; + } default: break; } diff --git a/rpcs3/Emu/Cell/PPUTranslator.cpp b/rpcs3/Emu/Cell/PPUTranslator.cpp index 5a0edd23fd..e6542f0ea3 100644 --- a/rpcs3/Emu/Cell/PPUTranslator.cpp +++ b/rpcs3/Emu/Cell/PPUTranslator.cpp @@ -2495,8 +2495,8 @@ void PPUTranslator::MFOCRF(ppu_opcode_t op) ln1 = Shuffle(ln1, nullptr, {15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}); } - const auto m0 = Call(GetType(), m_pure_attr, "llvm.x86.sse2.pmovmskb.128", m_ir->CreateShl(ln0, 7)); - const auto m1 = Call(GetType(), m_pure_attr, "llvm.x86.sse2.pmovmskb.128", m_ir->CreateShl(ln1, 7)); + const auto m0 = ZExt(bitcast(Trunc(ln0, GetType()))); + const auto m1 = ZExt(bitcast(Trunc(ln1, GetType()))); SetGpr(op.rd, m_ir->CreateOr(m_ir->CreateShl(m0, 16), m1)); return; }