diff options
| author | JosJuice <josjuice@gmail.com> | 2025-01-06 09:56:07 +0100 |
|---|---|---|
| committer | JosJuice <josjuice@gmail.com> | 2025-01-15 21:22:31 +0100 |
| commit | 85cd0ca51b304c385b73534c8cbcd50e30f0bd87 (patch) | |
| tree | a3b891d0569231365369b57792bd724b30d85ad4 /Source | |
| parent | aa9696e1c18550fa58f80a9fcf12da9a83fa667b (diff) | |
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.
Diffstat (limited to 'Source')
| -rw-r--r-- | Source/Core/Core/PowerPC/JitArm64/JitArm64_SystemRegisters.cpp | 20 |
1 files 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 da68b1876d..fe6af4c958 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(); @@ -665,8 +668,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) + { + EOR(XA, XA, XB); + } + else + { + EON(WA, WA, WB); + bits_1_to_31_are_set = true; + } break; case 33: // crnor: ~(A || B) |
