From 8ea7da56ecd2ac0b8b26e5067aa90ecb569d8cd2 Mon Sep 17 00:00:00 2001 From: Danila Malyutin Date: Wed, 26 Aug 2015 01:39:24 +0300 Subject: [PATCH] PPU/LLVM: Fix SUBFIC instruction Fixes sprites in Disgaea 3 --- rpcs3/Emu/Cell/PPULLVMRecompilerCore.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/rpcs3/Emu/Cell/PPULLVMRecompilerCore.cpp b/rpcs3/Emu/Cell/PPULLVMRecompilerCore.cpp index 83d850ab6ad1..565d973bb351 100644 --- a/rpcs3/Emu/Cell/PPULLVMRecompilerCore.cpp +++ b/rpcs3/Emu/Cell/PPULLVMRecompilerCore.cpp @@ -1676,10 +1676,12 @@ void Compiler::MULLI(u32 rd, u32 ra, s32 simm16) { void Compiler::SUBFIC(u32 rd, u32 ra, s32 simm16) { auto ra_i64 = GetGpr(ra); - ra_i64 = m_ir_builder->CreateNeg(ra_i64); + ra_i64 = m_ir_builder->CreateNeg(ra_i64); // simpler way of doing ~ra + 1 auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, m_ir_builder->getInt64((s64)simm16)); auto diff_i64 = m_ir_builder->CreateExtractValue(res_s, { 0 }); auto carry_i1 = m_ir_builder->CreateExtractValue(res_s, { 1 }); + auto is_zero = m_ir_builder->CreateICmpEQ(ra_i64, m_ir_builder->getInt64(0)); // if ra is zero when ~ra + 1 = 0 sets overflow bit + carry_i1 = m_ir_builder->CreateOr(is_zero, carry_i1); SetGpr(rd, diff_i64); SetXerCa(carry_i1); }