mirror of
https://github.com/RPCS3/rpcs3.git
synced 2026-10-12 02:09:17 +00:00
PPU: Stop inverting float-to-int saturation on ARM64
- This was breaking armored core 4/4a on ARM - Original fix credit to jpolo1224 of armsx3 https://github.com/ARMSX2/ARMSX3/commit/87ccdb85152a707f5d0c8122ed39344b4648501e Co-authored-by: jpolo1224 <[email protected]>
This commit is contained in:
committed by
Ani
co-authored by
jpolo1224
parent
de33fda28c
commit
6161ecd7aa
@@ -4760,13 +4760,14 @@ void PPUTranslator::FRSP(ppu_opcode_t op)
|
||||
void PPUTranslator::FCTIW(ppu_opcode_t op)
|
||||
{
|
||||
const auto b = GetFpr(op.frb);
|
||||
|
||||
#if defined(ARCH_X64)
|
||||
const auto xormask = m_ir->CreateSExt(m_ir->CreateFCmpOGE(b, ConstantFP::get(GetType<f64>(), std::exp2l(31.))), GetType<s32>());
|
||||
|
||||
// fix result saturation (0x80000000 -> 0x7fffffff)
|
||||
#if defined(ARCH_X64)
|
||||
SetFpr(op.frd, m_ir->CreateXor(xormask, Call(GetType<s32>(), "llvm.x86.sse2.cvtsd2si", m_ir->CreateInsertElement(GetUndef<f64[2]>(), b, u64{0}))));
|
||||
#elif defined(ARCH_ARM64)
|
||||
SetFpr(op.frd, m_ir->CreateXor(xormask, Call(GetType<s32>(), "llvm.aarch64.neon.fcvtns.i32.f64", b)));
|
||||
SetFpr(op.frd, Call(GetType<s32>(), "llvm.aarch64.neon.fcvtns.i32.f64", b));
|
||||
#endif
|
||||
|
||||
//SetFPSCR_FR(Call(GetType<bool>(), m_pure_attr, "__fctiw_get_fr", b));
|
||||
@@ -4780,13 +4781,14 @@ void PPUTranslator::FCTIW(ppu_opcode_t op)
|
||||
void PPUTranslator::FCTIWZ(ppu_opcode_t op)
|
||||
{
|
||||
const auto b = GetFpr(op.frb);
|
||||
|
||||
#if defined(ARCH_X64)
|
||||
const auto xormask = m_ir->CreateSExt(m_ir->CreateFCmpOGE(b, ConstantFP::get(GetType<f64>(), std::exp2l(31.))), GetType<s32>());
|
||||
|
||||
// fix result saturation (0x80000000 -> 0x7fffffff)
|
||||
#if defined(ARCH_X64)
|
||||
SetFpr(op.frd, m_ir->CreateXor(xormask, Call(GetType<s32>(), "llvm.x86.sse2.cvttsd2si", m_ir->CreateInsertElement(GetUndef<f64[2]>(), b, u64{0}))));
|
||||
#elif defined(ARCH_ARM64)
|
||||
SetFpr(op.frd, m_ir->CreateXor(xormask, Call(GetType<s32>(), "llvm.aarch64.neon.fcvtzs.i32.f64", b)));
|
||||
SetFpr(op.frd, Call(GetType<s32>(), "llvm.aarch64.neon.fcvtzs.i32.f64", b));
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -5062,13 +5064,14 @@ void PPUTranslator::FABS(ppu_opcode_t op)
|
||||
void PPUTranslator::FCTID(ppu_opcode_t op)
|
||||
{
|
||||
const auto b = GetFpr(op.frb);
|
||||
|
||||
#if defined(ARCH_X64)
|
||||
const auto xormask = m_ir->CreateSExt(m_ir->CreateFCmpOGE(b, ConstantFP::get(GetType<f64>(), std::exp2l(63.))), GetType<s64>());
|
||||
|
||||
// fix result saturation (0x8000000000000000 -> 0x7fffffffffffffff)
|
||||
#if defined(ARCH_X64)
|
||||
SetFpr(op.frd, m_ir->CreateXor(xormask, Call(GetType<s64>(), "llvm.x86.sse2.cvtsd2si64", m_ir->CreateInsertElement(GetUndef<f64[2]>(), b, u64{0}))));
|
||||
#elif defined(ARCH_ARM64)
|
||||
SetFpr(op.frd, m_ir->CreateXor(xormask, Call(GetType<s64>(), "llvm.aarch64.neon.fcvtns.i64.f64", b)));
|
||||
SetFpr(op.frd, Call(GetType<s64>(), "llvm.aarch64.neon.fcvtns.i64.f64", b));
|
||||
#endif
|
||||
|
||||
|
||||
@@ -5083,13 +5086,14 @@ void PPUTranslator::FCTID(ppu_opcode_t op)
|
||||
void PPUTranslator::FCTIDZ(ppu_opcode_t op)
|
||||
{
|
||||
const auto b = GetFpr(op.frb);
|
||||
|
||||
#if defined(ARCH_X64)
|
||||
const auto xormask = m_ir->CreateSExt(m_ir->CreateFCmpOGE(b, ConstantFP::get(GetType<f64>(), std::exp2l(63.))), GetType<s64>());
|
||||
|
||||
// fix result saturation (0x8000000000000000 -> 0x7fffffffffffffff)
|
||||
#if defined(ARCH_X64)
|
||||
SetFpr(op.frd, m_ir->CreateXor(xormask, Call(GetType<s64>(), "llvm.x86.sse2.cvttsd2si64", m_ir->CreateInsertElement(GetUndef<f64[2]>(), b, u64{0}))));
|
||||
#elif defined(ARCH_ARM64)
|
||||
SetFpr(op.frd, m_ir->CreateXor(xormask, Call(GetType<s64>(), "llvm.aarch64.neon.fcvtzs.i64.f64", b)));
|
||||
SetFpr(op.frd, Call(GetType<s64>(), "llvm.aarch64.neon.fcvtzs.i64.f64", b));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user