From 6a51c27fde3daaed219c4e68142096600109c974 Mon Sep 17 00:00:00 2001 From: Eladash Date: Thu, 30 Jul 2020 18:39:45 +0300 Subject: [PATCH] PPU LLVM: Fix VMAXFP, VMINFP NaN handling --- rpcs3/Emu/CPU/CPUTranslator.h | 30 ++++++++++++++++++++++++++---- rpcs3/Emu/Cell/PPUTranslator.cpp | 8 ++++---- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/rpcs3/Emu/CPU/CPUTranslator.h b/rpcs3/Emu/CPU/CPUTranslator.h index 2a063d3449..56e6c7d7f0 100644 --- a/rpcs3/Emu/CPU/CPUTranslator.h +++ b/rpcs3/Emu/CPU/CPUTranslator.h @@ -2744,22 +2744,44 @@ public: } // TODO: Support doubles - auto fre(value_t a) + template ::esize == 32u && llvm_value_t::is_float>> + auto fre(T a) { - decltype(a) result; + value_t result; const auto av = a.eval(m_ir); result.value = m_ir->CreateCall(m_module->getOrInsertFunction("llvm.x86.sse.rcp.ps", av->getType(), av->getType()).getCallee(), {av}); return result; } - auto frsqe(value_t a) + template ::esize == 32u && llvm_value_t::is_float>> + auto frsqe(T a) { - decltype(a) result; + value_t result; const auto av = a.eval(m_ir); result.value = m_ir->CreateCall(m_module->getOrInsertFunction("llvm.x86.sse.rsqrt.ps", av->getType(), av->getType()).getCallee(), {av}); return result; } + template && llvm_value_t::esize == 32u && llvm_value_t::is_float>> + auto fmax(T a, U b) + { + value_t result; + const auto av = a.eval(m_ir); + const auto bv = b.eval(m_ir); + result.value = m_ir->CreateCall(m_module->getOrInsertFunction("llvm.x86.sse.max.ps", av->getType(), av->getType(), av->getType()).getCallee(), {av, bv}); + return result; + } + + template && llvm_value_t::esize == 32u && llvm_value_t::is_float>> + auto fmin(T a, U b) + { + value_t result; + const auto av = a.eval(m_ir); + const auto bv = b.eval(m_ir); + result.value = m_ir->CreateCall(m_module->getOrInsertFunction("llvm.x86.sse.min.ps", av->getType(), av->getType(), av->getType()).getCallee(), {av, bv}); + return result; + } + template value_t pshufb(T1 a, T2 b) { diff --git a/rpcs3/Emu/Cell/PPUTranslator.cpp b/rpcs3/Emu/Cell/PPUTranslator.cpp index 591819f8d4..ae21d7592a 100644 --- a/rpcs3/Emu/Cell/PPUTranslator.cpp +++ b/rpcs3/Emu/Cell/PPUTranslator.cpp @@ -973,8 +973,8 @@ void PPUTranslator::VMADDFP(ppu_opcode_t op) void PPUTranslator::VMAXFP(ppu_opcode_t op) { - const auto ab = GetVrs(VrType::vf, op.va, op.vb); - SetVr(op.vd, VecHandleResult(m_ir->CreateSelect(m_ir->CreateFCmpOGT(ab[0], ab[1]), ab[0], ab[1]))); + const auto [a, b] = get_vrs(op.va, op.vb); + set_vr(op.vd, vec_handle_result(select(bitcast(fmin(a, b)) == bitcast(a), b, a))); } void PPUTranslator::VMAXSB(ppu_opcode_t op) @@ -1045,8 +1045,8 @@ void PPUTranslator::VMHRADDSHS(ppu_opcode_t op) void PPUTranslator::VMINFP(ppu_opcode_t op) { - const auto ab = GetVrs(VrType::vf, op.va, op.vb); - SetVr(op.vd, VecHandleResult(m_ir->CreateSelect(m_ir->CreateFCmpOLT(ab[0], ab[1]), ab[0], ab[1]))); + const auto [a, b] = get_vrs(op.va, op.vb); + set_vr(op.vd, vec_handle_result(select(bitcast(fmax(a, b)) == bitcast(a), b, a))); } void PPUTranslator::VMINSB(ppu_opcode_t op)