From 82695ea6f42ee67b8b23e639bff9f2f2d679c598 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Mon, 6 Jan 2025 09:56:07 +0100 Subject: [PATCH] JitArm64: Optimize creqv setting eq/gt bit For the eq and gt bits specifically, setting negate_result is one instruction shorter than not setting it. --- .../JitArm64/JitArm64_SystemRegisters.cpp | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_SystemRegisters.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_SystemRegisters.cpp index 828e780ea4..4f9356fd68 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_SystemRegisters.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_SystemRegisters.cpp @@ -635,8 +635,11 @@ void JitArm64::crXXX(UGeckoInstruction inst) } } - // crnor or crnand - const bool negate_result = inst.SUBOP10 == 33 || inst.SUBOP10 == 225; + const u32 crbd_bit = 3 - (inst.CRBD & 3); + // crnor, crnand and sometimes creqv + const bool negate_result = + inst.SUBOP10 == 33 || inst.SUBOP10 == 225 || + (inst.SUBOP10 == 289 && (crbd_bit == PowerPC::CR_EQ_BIT || crbd_bit == PowerPC::CR_GT_BIT)); bool bits_1_to_31_are_set = false; auto WA = gpr.GetScopedReg(); @@ -666,8 +669,17 @@ void JitArm64::crXXX(UGeckoInstruction inst) break; case 289: // creqv: ~(A ^ B) = A ^ ~B - EON(WA, WA, WB); - bits_1_to_31_are_set = true; + // Both of these two implementations are equally correct, but which one is more efficient + // depends on which bit we're going to set in CRBD + if (negate_result) + { + ORR(XA, XA, XB); + } + else + { + EON(WA, WA, WB); + bits_1_to_31_are_set = true; + } break; case 33: // crnor: ~(A || B)