From da9546cb2f7f81178412d7d5c2df7f5582636b8d Mon Sep 17 00:00:00 2001 From: Sintendo Date: Tue, 21 Sep 2021 23:09:25 +0200 Subject: [PATCH] Jit64: Merge subfx and subfcx Again, logic and optimizations are mostly the same so it makes sense. --- Source/Core/Core/PowerPC/Jit64/Jit.h | 1 - .../Core/Core/PowerPC/Jit64/Jit64_Tables.cpp | 4 +- .../Core/Core/PowerPC/Jit64/Jit_Integer.cpp | 59 +++++++------------ 3 files changed, 22 insertions(+), 42 deletions(-) diff --git a/Source/Core/Core/PowerPC/Jit64/Jit.h b/Source/Core/Core/PowerPC/Jit64/Jit.h index 5916093295..a0874de36b 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit.h +++ b/Source/Core/Core/PowerPC/Jit64/Jit.h @@ -232,7 +232,6 @@ public: void subfic(UGeckoInstruction inst); void subfx(UGeckoInstruction inst); - void subfcx(UGeckoInstruction inst); void twX(UGeckoInstruction inst); diff --git a/Source/Core/Core/PowerPC/Jit64/Jit64_Tables.cpp b/Source/Core/Core/PowerPC/Jit64/Jit64_Tables.cpp index 2d77df1d38..2a5b77b258 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit64_Tables.cpp +++ b/Source/Core/Core/PowerPC/Jit64/Jit64_Tables.cpp @@ -170,8 +170,8 @@ constexpr std::array s_table31{{ {616, &Jit64::negx}, // negox {40, &Jit64::subfx}, // subfx {552, &Jit64::subfx}, // subfox - {8, &Jit64::subfcx}, // subfcx - {520, &Jit64::subfcx}, // subfcox + {8, &Jit64::subfx}, // subfcx + {520, &Jit64::subfx}, // subfcox {136, &Jit64::arithXex}, // subfex {648, &Jit64::arithXex}, // subfeox {232, &Jit64::arithXex}, // subfmex diff --git a/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp b/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp index c1a6846d16..e5f5071bc6 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp +++ b/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp @@ -938,10 +938,13 @@ void Jit64::subfx(UGeckoInstruction inst) INSTRUCTION_START JITDISABLE(bJITIntegerOff); int a = inst.RA, b = inst.RB, d = inst.RD; + const bool carry = !(inst.SUBOP10 & (1 << 5)); if (a == b) { gpr.SetImmediate32(d, 0); + if (carry) + FinalizeCarry(true); if (inst.OE) GenerateConstantOverflow(false); } @@ -949,6 +952,8 @@ void Jit64::subfx(UGeckoInstruction inst) { s32 i = gpr.SImm32(b), j = gpr.SImm32(a); gpr.SetImmediate32(d, i - j); + if (carry) + FinalizeCarry(j == 0 || Interpreter::Helper_Carry((u32)i, 0u - (u32)j)); if (inst.OE) GenerateConstantOverflow((s64)i - (s64)j); } @@ -963,16 +968,20 @@ void Jit64::subfx(UGeckoInstruction inst) { if (d != b) MOV(32, Rd, Rb); + if (carry) + FinalizeCarry(true); if (inst.OE) GenerateConstantOverflow(false); } else if (d == b) { SUB(32, Rd, Imm32(j)); + if (carry) + FinalizeCarry(CC_NC); if (inst.OE) GenerateOverflow(); } - else if (Rb.IsSimpleReg() && !inst.OE) + else if (Rb.IsSimpleReg() && !carry && !inst.OE) { LEA(32, Rd, MDisp(Rb.GetSimpleReg(), -j)); } @@ -980,6 +989,8 @@ void Jit64::subfx(UGeckoInstruction inst) { MOV(32, Rd, Rb); SUB(32, Rd, Imm32(j)); + if (carry) + FinalizeCarry(CC_NC); if (inst.OE) GenerateOverflow(); } @@ -993,6 +1004,8 @@ void Jit64::subfx(UGeckoInstruction inst) if (d != a) MOV(32, Rd, Ra); NEG(32, Rd); + if (carry) + FinalizeCarry(CC_NC); if (inst.OE) GenerateOverflow(); } @@ -1003,21 +1016,21 @@ void Jit64::subfx(UGeckoInstruction inst) RCX64Reg Rd = gpr.Bind(d, RCMode::Write); RegCache::Realize(Ra, Rb, Rd); - if (d == b) - { - SUB(32, Rd, Ra); - } - else if (d == a) + if (d == a && d != b) { + // special case, because sub isn't reversible MOV(32, R(RSCRATCH), Ra); MOV(32, Rd, Rb); SUB(32, Rd, R(RSCRATCH)); } else { - MOV(32, Rd, Rb); + if (d != b) + MOV(32, Rd, Rb); SUB(32, Rd, Ra); } + if (carry) + FinalizeCarry(CC_NC); if (inst.OE) GenerateOverflow(); } @@ -1818,38 +1831,6 @@ void Jit64::arithXex(UGeckoInstruction inst) ComputeRC(d); } -void Jit64::subfcx(UGeckoInstruction inst) -{ - INSTRUCTION_START - JITDISABLE(bJITIntegerOff); - int a = inst.RA, b = inst.RB, d = inst.RD; - - { - RCOpArg Ra = gpr.Use(a, RCMode::Read); - RCOpArg Rb = gpr.Use(b, RCMode::Read); - RCX64Reg Rd = gpr.Bind(d, RCMode::Write); - RegCache::Realize(Ra, Rb, Rd); - - if (d == a && d != b) - { - // special case, because sub isn't reversible - MOV(32, R(RSCRATCH), Ra); - MOV(32, Rd, Rb); - SUB(32, Rd, R(RSCRATCH)); - } - else - { - if (d != b) - MOV(32, Rd, Rb); - SUB(32, Rd, Ra); - } - } - - FinalizeCarryOverflow(inst.OE, true); - if (inst.Rc) - ComputeRC(d); -} - void Jit64::rlwinmx(UGeckoInstruction inst) { INSTRUCTION_START