summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorLC <mathew1800@gmail.com>2021-01-14 21:40:05 -0500
committerGitHub <noreply@github.com>2021-01-14 21:40:05 -0500
commit0c2bc3582db685db28254ffa8a901e61dc50b258 (patch)
tree59500c4b51d4c1bd90d7bf6c14211dd48dd8146f /Source/Core
parent8f67a1961f45c68e87b330a2b628b8009c9d5f7f (diff)
parentdf70077e6b27608bfdc9812fa0d2bec6c1a4247b (diff)
Merge pull request #9425 from Sintendo/jit64subfx
Jit64: subfx optimizations
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp56
-rw-r--r--Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp8
2 files changed, 58 insertions, 6 deletions
diff --git a/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp b/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp
index 8ec307889a..7279f2e7f7 100644
--- a/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp
+++ b/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp
@@ -933,13 +933,63 @@ void Jit64::subfx(UGeckoInstruction inst)
JITDISABLE(bJITIntegerOff);
int a = inst.RA, b = inst.RB, d = inst.RD;
- if (gpr.IsImm(a) && gpr.IsImm(b))
+ if (a == b)
+ {
+ gpr.SetImmediate32(d, 0);
+ if (inst.OE)
+ GenerateConstantOverflow(false);
+ }
+ else if (gpr.IsImm(a, b))
{
s32 i = gpr.SImm32(b), j = gpr.SImm32(a);
gpr.SetImmediate32(d, i - j);
if (inst.OE)
GenerateConstantOverflow((s64)i - (s64)j);
}
+ else if (gpr.IsImm(a))
+ {
+ s32 j = gpr.SImm32(a);
+ RCOpArg Rb = gpr.Use(b, RCMode::Read);
+ RCX64Reg Rd = gpr.Bind(d, RCMode::Write);
+ RegCache::Realize(Rb, Rd);
+
+ if (j == 0)
+ {
+ if (d != b)
+ MOV(32, Rd, Rb);
+ if (inst.OE)
+ GenerateConstantOverflow(false);
+ }
+ else if (d == b)
+ {
+ SUB(32, Rd, Imm32(j));
+ if (inst.OE)
+ GenerateOverflow();
+ }
+ else if (Rb.IsSimpleReg() && !inst.OE)
+ {
+ LEA(32, Rd, MDisp(Rb.GetSimpleReg(), -j));
+ }
+ else
+ {
+ MOV(32, Rd, Rb);
+ SUB(32, Rd, Imm32(j));
+ if (inst.OE)
+ GenerateOverflow();
+ }
+ }
+ else if (gpr.IsImm(b) && gpr.Imm32(b) == 0)
+ {
+ RCOpArg Ra = gpr.Use(a, RCMode::Read);
+ RCX64Reg Rd = gpr.Bind(d, RCMode::Write);
+ RegCache::Realize(Ra, Rd);
+
+ if (d != a)
+ MOV(32, Rd, Ra);
+ NEG(32, Rd);
+ if (inst.OE)
+ GenerateOverflow();
+ }
else
{
RCOpArg Ra = gpr.Use(a, RCMode::Read);
@@ -957,10 +1007,6 @@ void Jit64::subfx(UGeckoInstruction inst)
MOV(32, Rd, Rb);
SUB(32, Rd, R(RSCRATCH));
}
- else if (Rb.IsSimpleReg() && Ra.IsImm() && !inst.OE)
- {
- LEA(32, Rd, MDisp(Rb.GetSimpleReg(), -Ra.SImm32()));
- }
else
{
MOV(32, Rd, Rb);
diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp
index 645ffc4af5..33e8f47450 100644
--- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp
+++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp
@@ -856,7 +856,13 @@ void JitArm64::subfx(UGeckoInstruction inst)
int a = inst.RA, b = inst.RB, d = inst.RD;
- if (gpr.IsImm(a) && gpr.IsImm(b))
+ if (a == b)
+ {
+ gpr.SetImmediate(d, 0);
+ if (inst.Rc)
+ ComputeRC0(gpr.GetImm(d));
+ }
+ else if (gpr.IsImm(a) && gpr.IsImm(b))
{
u32 i = gpr.GetImm(a), j = gpr.GetImm(b);
gpr.SetImmediate(d, j - i);