diff options
| author | Admiral H. Curtiss <pikachu025@gmail.com> | 2022-09-28 21:58:06 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-09-28 21:58:06 +0200 |
| commit | 95615ab91b3ea63af12eee16758706a2096c8ff2 (patch) | |
| tree | e7d515d54944d2b746e2061be82bf0e8598ed787 /Source/Core | |
| parent | 32bdc54869528698fcef5b3da4e0ed5cf4f4e591 (diff) | |
| parent | 4914ff25d646281021edd82eebe35ac7faa24849 (diff) | |
Merge pull request #11096 from Sintendo/arm64boolx
JitArm64: boolX constant optimizations
Diffstat (limited to 'Source/Core')
| -rw-r--r-- | Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp index cb7341658a..fd13d0ec79 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp @@ -319,6 +319,98 @@ void JitArm64::boolX(UGeckoInstruction inst) PanicAlertFmt("WTF!"); } } + else if ((gpr.IsImm(s) && (gpr.GetImm(s) == 0 || gpr.GetImm(s) == 0xFFFFFFFF)) || + (gpr.IsImm(b) && (gpr.GetImm(b) == 0 || gpr.GetImm(b) == 0xFFFFFFFF))) + { + const auto [i, j] = gpr.IsImm(s) ? std::pair(s, b) : std::pair(b, s); + bool is_zero = gpr.GetImm(i) == 0; + + bool complement_b = (inst.SUBOP10 == 60 /* andcx */) || (inst.SUBOP10 == 412 /* orcx */); + const bool final_not = (inst.SUBOP10 == 476 /* nandx */) || (inst.SUBOP10 == 124 /* norx */); + const bool is_and = (inst.SUBOP10 == 28 /* andx */) || (inst.SUBOP10 == 60 /* andcx */) || + (inst.SUBOP10 == 476 /* nandx */); + const bool is_or = (inst.SUBOP10 == 444 /* orx */) || (inst.SUBOP10 == 412 /* orcx */) || + (inst.SUBOP10 == 124 /* norx */); + const bool is_xor = (inst.SUBOP10 == 316 /* xorx */) || (inst.SUBOP10 == 284 /* eqvx */); + + if ((complement_b && i == b) || (inst.SUBOP10 == 284 /* eqvx */)) + { + is_zero = !is_zero; + complement_b = false; + } + + if (is_xor) + { + if (!is_zero) + { + gpr.BindToRegister(a, a == j); + MVN(gpr.R(a), gpr.R(j)); + } + else if (a != j) + { + gpr.BindToRegister(a, false); + MOV(gpr.R(a), gpr.R(j)); + } + if (inst.Rc) + ComputeRC0(gpr.R(a)); + } + else if (is_and) + { + if (is_zero) + { + gpr.SetImmediate(a, final_not ? 0xFFFFFFFF : 0); + if (inst.Rc) + ComputeRC0(gpr.GetImm(a)); + } + else if (final_not || complement_b) + { + gpr.BindToRegister(a, a == j); + MVN(gpr.R(a), gpr.R(j)); + if (inst.Rc) + ComputeRC0(gpr.R(a)); + } + else + { + if (a != j) + { + gpr.BindToRegister(a, false); + MOV(gpr.R(a), gpr.R(j)); + } + if (inst.Rc) + ComputeRC0(gpr.R(a)); + } + } + else if (is_or) + { + if (!is_zero) + { + gpr.SetImmediate(a, final_not ? 0 : 0xFFFFFFFF); + if (inst.Rc) + ComputeRC0(gpr.GetImm(a)); + } + else if (final_not || complement_b) + { + gpr.BindToRegister(a, a == j); + MVN(gpr.R(a), gpr.R(j)); + if (inst.Rc) + ComputeRC0(gpr.R(a)); + } + else + { + if (a != j) + { + gpr.BindToRegister(a, false); + MOV(gpr.R(a), gpr.R(j)); + } + if (inst.Rc) + ComputeRC0(gpr.R(a)); + } + } + else + { + PanicAlertFmt("WTF!"); + } + } else { gpr.BindToRegister(a, (a == s) || (a == b)); |
