From da44d5f10dcfafe6e3c04050dad376143aa89e80 Mon Sep 17 00:00:00 2001 From: Eladash Date: Sat, 25 Jul 2020 19:13:58 +0300 Subject: [PATCH] PPU: Fix DIVW, DIVWU, MULHW, MULLW, MULHWU when op.rc is set (#8630) --- rpcs3/Emu/Cell/PPUInterpreter.cpp | 10 +++++----- rpcs3/Emu/Cell/PPUTranslator.cpp | 12 ++++++------ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/rpcs3/Emu/Cell/PPUInterpreter.cpp b/rpcs3/Emu/Cell/PPUInterpreter.cpp index d347860d11..dac0e2f0dd 100644 --- a/rpcs3/Emu/Cell/PPUInterpreter.cpp +++ b/rpcs3/Emu/Cell/PPUInterpreter.cpp @@ -3332,7 +3332,7 @@ bool ppu_interpreter::MULHWU(ppu_thread& ppu, ppu_opcode_t op) u32 a = static_cast(ppu.gpr[op.ra]); u32 b = static_cast(ppu.gpr[op.rb]); ppu.gpr[op.rd] = (u64{a} * b) >> 32; - if (op.rc) [[unlikely]] ppu_cr_set(ppu, 0, false, false, false, ppu.xer.so); + if (op.rc) [[unlikely]] ppu_cr_set(ppu, 0, ppu.gpr[op.rd], 0); return true; } @@ -3515,7 +3515,7 @@ bool ppu_interpreter::MULHW(ppu_thread& ppu, ppu_opcode_t op) s32 a = static_cast(ppu.gpr[op.ra]); s32 b = static_cast(ppu.gpr[op.rb]); ppu.gpr[op.rd] = (s64{a} * b) >> 32; - if (op.rc) [[unlikely]] ppu_cr_set(ppu, 0, false, false, false, ppu.xer.so); + if (op.rc) [[unlikely]] ppu_cr_set(ppu, 0, ppu.gpr[op.rd], 0); return true; } @@ -3785,7 +3785,7 @@ bool ppu_interpreter::MULLW(ppu_thread& ppu, ppu_opcode_t op) { ppu.gpr[op.rd] = s64{static_cast(ppu.gpr[op.ra])} * static_cast(ppu.gpr[op.rb]); if (op.oe) [[unlikely]] ppu_ov_set(ppu, s64(ppu.gpr[op.rd]) < INT32_MIN || s64(ppu.gpr[op.rd]) > INT32_MAX); - if (op.rc) [[unlikely]] ppu_cr_set(ppu, 0, ppu.gpr[op.ra], 0); + if (op.rc) [[unlikely]] ppu_cr_set(ppu, 0, ppu.gpr[op.rd], 0); return true; } @@ -3981,7 +3981,7 @@ bool ppu_interpreter::DIVWU(ppu_thread& ppu, ppu_opcode_t op) const u32 RB = static_cast(ppu.gpr[op.rb]); ppu.gpr[op.rd] = RB == 0 ? 0 : RA / RB; if (op.oe) [[unlikely]] ppu_ov_set(ppu, RB == 0); - if (op.rc) [[unlikely]] ppu_cr_set(ppu, 0, false, false, false, ppu.xer.so); + if (op.rc) [[unlikely]] ppu_cr_set(ppu, 0, ppu.gpr[op.rd], 0); return true; } @@ -4046,7 +4046,7 @@ bool ppu_interpreter::DIVW(ppu_thread& ppu, ppu_opcode_t op) const bool o = RB == 0 || (RA == INT32_MIN && RB == -1); ppu.gpr[op.rd] = o ? 0 : static_cast(RA / RB); if (op.oe) [[unlikely]] ppu_ov_set(ppu, o); - if (op.rc) [[unlikely]] ppu_cr_set(ppu, 0, false, false, false, ppu.xer.so); + if (op.rc) [[unlikely]] ppu_cr_set(ppu, 0, ppu.gpr[op.rd], 0); return true; } diff --git a/rpcs3/Emu/Cell/PPUTranslator.cpp b/rpcs3/Emu/Cell/PPUTranslator.cpp index ae749b80c2..4d84c79572 100644 --- a/rpcs3/Emu/Cell/PPUTranslator.cpp +++ b/rpcs3/Emu/Cell/PPUTranslator.cpp @@ -2399,7 +2399,7 @@ void PPUTranslator::MULHWU(ppu_opcode_t op) const auto a = ZExt(GetGpr(op.ra, 32)); const auto b = ZExt(GetGpr(op.rb, 32)); SetGpr(op.rd, m_ir->CreateLShr(m_ir->CreateMul(a, b), 32)); - if (op.rc) SetCrField(0, GetUndef(), GetUndef(), GetUndef()); + if (op.rc) SetCrFieldSignedCmp(0, GetGpr(op.rd), m_ir->getInt64(0)); } void PPUTranslator::MFOCRF(ppu_opcode_t op) @@ -2586,7 +2586,7 @@ void PPUTranslator::MULHW(ppu_opcode_t op) const auto a = SExt(GetGpr(op.ra, 32)); const auto b = SExt(GetGpr(op.rb, 32)); SetGpr(op.rd, m_ir->CreateAShr(m_ir->CreateMul(a, b), 32)); - if (op.rc) SetCrField(0, GetUndef(), GetUndef(), GetUndef()); + if (op.rc) SetCrFieldSignedCmp(0, GetGpr(op.rd), m_ir->getInt64(0)); } void PPUTranslator::LDARX(ppu_opcode_t op) @@ -3034,7 +3034,7 @@ void PPUTranslator::DIVDU(ppu_opcode_t op) const auto o = IsZero(b); const auto result = m_ir->CreateUDiv(a, m_ir->CreateSelect(o, m_ir->getInt64(-1), b)); SetGpr(op.rd, m_ir->CreateSelect(o, m_ir->getInt64(0), result)); - if (op.rc) SetCrFieldSignedCmp(0, result, m_ir->getInt64(0)); + if (op.rc) SetCrFieldSignedCmp(0, GetGpr(op.rd), m_ir->getInt64(0)); if (op.oe) SetOverflow(o); } @@ -3045,7 +3045,7 @@ void PPUTranslator::DIVWU(ppu_opcode_t op) const auto o = IsZero(b); const auto result = m_ir->CreateUDiv(a, m_ir->CreateSelect(o, m_ir->getInt32(0xffffffff), b)); SetGpr(op.rd, m_ir->CreateSelect(o, m_ir->getInt32(0), result)); - if (op.rc) SetCrField(0, GetUndef(), GetUndef(), GetUndef()); + if (op.rc) SetCrFieldSignedCmp(0, GetGpr(op.rd), m_ir->getInt64(0)); if (op.oe) SetOverflow(o); } @@ -3095,7 +3095,7 @@ void PPUTranslator::DIVD(ppu_opcode_t op) const auto o = m_ir->CreateOr(IsZero(b), m_ir->CreateAnd(m_ir->CreateICmpEQ(a, m_ir->getInt64(1ull << 63)), IsOnes(b))); const auto result = m_ir->CreateSDiv(a, m_ir->CreateSelect(o, m_ir->getInt64(1ull << 63), b)); SetGpr(op.rd, m_ir->CreateSelect(o, m_ir->getInt64(0), result)); - if (op.rc) SetCrFieldSignedCmp(0, result, m_ir->getInt64(0)); + if (op.rc) SetCrFieldSignedCmp(0, GetGpr(op.rd), m_ir->getInt64(0)); if (op.oe) SetOverflow(o); } @@ -3106,7 +3106,7 @@ void PPUTranslator::DIVW(ppu_opcode_t op) const auto o = m_ir->CreateOr(IsZero(b), m_ir->CreateAnd(m_ir->CreateICmpEQ(a, m_ir->getInt32(INT32_MIN)), IsOnes(b))); const auto result = m_ir->CreateSDiv(a, m_ir->CreateSelect(o, m_ir->getInt32(INT32_MIN), b)); SetGpr(op.rd, m_ir->CreateSelect(o, m_ir->getInt32(0), result)); - if (op.rc) SetCrField(0, GetUndef(), GetUndef(), GetUndef()); + if (op.rc) SetCrFieldSignedCmp(0, GetGpr(op.rd), m_ir->getInt64(0)); if (op.oe) SetOverflow(o); }