From 3c3168706c02ef0a22ad208442217254125d50e2 Mon Sep 17 00:00:00 2001 From: Sintendo Date: Tue, 10 Oct 2023 22:47:31 +0200 Subject: [PATCH] PowerPC: Negate m_dec values in frsqrte table This value is used in a multiplication. The result of this multiplication is then subtracted from m_base. By negating m_dec, we are free to use an addition instead. On x64, this saves an instruction. --- Source/Core/Common/FloatUtils.cpp | 18 +++++++++--------- .../PowerPC/Jit64Common/Jit64AsmCommon.cpp | 9 ++++----- Source/Core/Core/PowerPC/JitArm64/JitAsm.cpp | 2 +- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/Source/Core/Common/FloatUtils.cpp b/Source/Core/Common/FloatUtils.cpp index 57add0d18e..dbe2a0b508 100644 --- a/Source/Core/Common/FloatUtils.cpp +++ b/Source/Core/Common/FloatUtils.cpp @@ -74,14 +74,14 @@ u32 ClassifyFloat(float fvalue) } const std::array frsqrte_expected = {{ - {0x1a7e800, 0x568}, {0x17cb800, 0x4f3}, {0x1552800, 0x48d}, {0x130c000, 0x435}, - {0x10f2000, 0x3e7}, {0x0eff000, 0x3a2}, {0x0d2e000, 0x365}, {0x0b7c000, 0x32e}, - {0x09e5000, 0x2fc}, {0x0867000, 0x2d0}, {0x06ff000, 0x2a8}, {0x05ab800, 0x283}, - {0x046a000, 0x261}, {0x0339800, 0x243}, {0x0218800, 0x226}, {0x0105800, 0x20b}, - {0x3ffa000, 0x7a4}, {0x3c29000, 0x700}, {0x38aa000, 0x670}, {0x3572000, 0x5f2}, - {0x3279000, 0x584}, {0x2fb7000, 0x524}, {0x2d26000, 0x4cc}, {0x2ac0000, 0x47e}, - {0x2881000, 0x43a}, {0x2665000, 0x3fa}, {0x2468000, 0x3c2}, {0x2287000, 0x38e}, - {0x20c1000, 0x35e}, {0x1f12000, 0x332}, {0x1d79000, 0x30a}, {0x1bf4000, 0x2e6}, + {0x1a7e800, -0x568}, {0x17cb800, -0x4f3}, {0x1552800, -0x48d}, {0x130c000, -0x435}, + {0x10f2000, -0x3e7}, {0x0eff000, -0x3a2}, {0x0d2e000, -0x365}, {0x0b7c000, -0x32e}, + {0x09e5000, -0x2fc}, {0x0867000, -0x2d0}, {0x06ff000, -0x2a8}, {0x05ab800, -0x283}, + {0x046a000, -0x261}, {0x0339800, -0x243}, {0x0218800, -0x226}, {0x0105800, -0x20b}, + {0x3ffa000, -0x7a4}, {0x3c29000, -0x700}, {0x38aa000, -0x670}, {0x3572000, -0x5f2}, + {0x3279000, -0x584}, {0x2fb7000, -0x524}, {0x2d26000, -0x4cc}, {0x2ac0000, -0x47e}, + {0x2881000, -0x43a}, {0x2665000, -0x3fa}, {0x2468000, -0x3c2}, {0x2287000, -0x38e}, + {0x20c1000, -0x35e}, {0x1f12000, -0x332}, {0x1d79000, -0x30a}, {0x1bf4000, -0x2e6}, }}; double ApproximateReciprocalSquareRoot(double val) @@ -134,7 +134,7 @@ double ApproximateReciprocalSquareRoot(double val) const int i = static_cast((exponent_lsb | mantissa) >> 37); const auto& entry = frsqrte_expected[i / 2048]; - integral |= static_cast(entry.m_base - entry.m_dec * (i % 2048)) << 26; + integral |= static_cast(entry.m_base + entry.m_dec * (i % 2048)) << 26; return BitCast(integral); } diff --git a/Source/Core/Core/PowerPC/Jit64Common/Jit64AsmCommon.cpp b/Source/Core/Core/PowerPC/Jit64Common/Jit64AsmCommon.cpp index a08e8b3c07..94e7f99423 100644 --- a/Source/Core/Core/PowerPC/Jit64Common/Jit64AsmCommon.cpp +++ b/Source/Core/Core/PowerPC/Jit64Common/Jit64AsmCommon.cpp @@ -150,14 +150,13 @@ void CommonAsmRoutines::GenFrsqrte() AND(32, R(RSCRATCH), Imm32(0x7FF)); IMUL(32, RSCRATCH, MComplex(RSCRATCH2, RSCRATCH_EXTRA, SCALE_8, offsetof(Common::BaseAndDec, m_dec))); - MOV(32, R(RSCRATCH_EXTRA), + ADD(32, R(RSCRATCH), MComplex(RSCRATCH2, RSCRATCH_EXTRA, SCALE_8, offsetof(Common::BaseAndDec, m_base))); - SUB(32, R(RSCRATCH_EXTRA), R(RSCRATCH)); - SHL(64, R(RSCRATCH_EXTRA), Imm8(26)); + SHL(64, R(RSCRATCH), Imm8(26)); POP(RSCRATCH2); - OR(64, R(RSCRATCH2), R(RSCRATCH_EXTRA)); // vali |= (s64)(frsqrte_expected_base[index] - - // frsqrte_expected_dec[index] * (i % 2048)) << 26; + OR(64, R(RSCRATCH2), R(RSCRATCH)); // vali |= (s64)(frsqrte_expected_base[index] + + // frsqrte_expected_dec[index] * (i % 2048)) << 26; MOVQ_xmm(XMM0, R(RSCRATCH2)); RET(); diff --git a/Source/Core/Core/PowerPC/JitArm64/JitAsm.cpp b/Source/Core/Core/PowerPC/JitArm64/JitAsm.cpp index 8c3a4307b0..e6296f4d31 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitAsm.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitAsm.cpp @@ -347,7 +347,7 @@ void JitArm64::GenerateFrsqrte() LDP(IndexType::Signed, ARM64Reg::W1, ARM64Reg::W2, ARM64Reg::X2, 0); UBFX(ARM64Reg::X3, ARM64Reg::X3, 37, 11); AND(ARM64Reg::X0, ARM64Reg::X0, LogicalImm(Common::DOUBLE_SIGN | Common::DOUBLE_EXP, 64)); - MSUB(ARM64Reg::W3, ARM64Reg::W3, ARM64Reg::W2, ARM64Reg::W1); + MADD(ARM64Reg::W3, ARM64Reg::W3, ARM64Reg::W2, ARM64Reg::W1); ORR(ARM64Reg::X0, ARM64Reg::X0, ARM64Reg::X3, ArithOption(ARM64Reg::X3, ShiftType::LSL, 26)); RET();