summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorBram Speeckaert <bram.speeckaert@guardsquare.com>2024-03-23 13:05:57 +0100
committerBram Speeckaert <bram.speeckaert@guardsquare.com>2024-03-23 20:13:15 +0100
commit749ee2ff5e0d80ea260160403c1a2d33491d1100 (patch)
tree2c86f8a1174e767746afd338683fb809865b9ab0 /Source/Core
parent825a10616c58e0dd7a733fed9d684ccadc97826c (diff)
Jit64: Refactor divwux
Now that we've moved the logic to DivUtils, refactor the Jit64 code to use it.
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp37
1 files changed, 12 insertions, 25 deletions
diff --git a/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp b/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp
index 671bd9fa9e..9925fd4c0d 100644
--- a/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp
+++ b/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp
@@ -1451,12 +1451,10 @@ void Jit64::divwux(UGeckoInstruction inst)
}
else
{
- u32 shift = 31;
- while (!(divisor & (1 << shift)))
- shift--;
-
- if (divisor == (u32)(1 << shift))
+ if (MathUtil::IsPow2(divisor))
{
+ u32 shift = MathUtil::IntLog2(divisor);
+
RCOpArg Ra = gpr.Use(a, RCMode::Read);
RCX64Reg Rd = gpr.Bind(d, RCMode::Write);
RegCache::Realize(Ra, Rd);
@@ -1468,24 +1466,22 @@ void Jit64::divwux(UGeckoInstruction inst)
}
else
{
- u64 magic_dividend = 0x100000000ULL << shift;
- u32 magic = (u32)(magic_dividend / divisor);
- u32 max_quotient = magic >> shift;
+ UnsignedMagic m = UnsignedDivisionConstants(divisor);
// Test for failure in round-up method
- if (((u64)(magic + 1) * (max_quotient * divisor - 1)) >> (shift + 32) != max_quotient - 1)
+ if (!m.fast)
{
// If failed, use slower round-down method
RCOpArg Ra = gpr.Use(a, RCMode::Read);
RCX64Reg Rd = gpr.Bind(d, RCMode::Write);
RegCache::Realize(Ra, Rd);
- MOV(32, R(RSCRATCH), Imm32(magic));
+ MOV(32, R(RSCRATCH), Imm32(m.multiplier));
if (d != a)
MOV(32, Rd, Ra);
IMUL(64, Rd, R(RSCRATCH));
ADD(64, Rd, R(RSCRATCH));
- SHR(64, Rd, Imm8(shift + 32));
+ SHR(64, Rd, Imm8(m.shift + 32));
}
else
{
@@ -1494,32 +1490,23 @@ void Jit64::divwux(UGeckoInstruction inst)
RCX64Reg Rd = gpr.Bind(d, RCMode::Write);
RegCache::Realize(Ra, Rd);
- magic++;
-
- // Use smallest magic number and shift amount possible
- while ((magic & 1) == 0 && shift > 0)
- {
- magic >>= 1;
- shift--;
- }
-
// Three-operand IMUL sign extends the immediate to 64 bits, so we may only
// use it when the magic number has its most significant bit set to 0
- if ((magic & 0x80000000) == 0)
+ if ((m.multiplier & 0x80000000) == 0)
{
- IMUL(64, Rd, Ra, Imm32(magic));
+ IMUL(64, Rd, Ra, Imm32(m.multiplier));
}
else if (d == a)
{
- MOV(32, R(RSCRATCH), Imm32(magic));
+ MOV(32, R(RSCRATCH), Imm32(m.multiplier));
IMUL(64, Rd, R(RSCRATCH));
}
else
{
- MOV(32, Rd, Imm32(magic));
+ MOV(32, Rd, Imm32(m.multiplier));
IMUL(64, Rd, Ra);
}
- SHR(64, Rd, Imm8(shift + 32));
+ SHR(64, Rd, Imm8(m.shift + 32));
}
}
if (inst.OE)