From b00c60618b09a77c10ac1d973a08fd2826dc24ee Mon Sep 17 00:00:00 2001 From: degasus Date: Tue, 22 Aug 2017 08:47:43 +0200 Subject: [PATCH] JitArm64: Fix rlwinmx. Seems like I was wrong that ANDI2R doesn't require a temporary register here. There is *one* case when the mask won't fit in the ARM AND instruction: mask = 0xFFFFFFFF But let's just use MOV instead of AND here for this case... --- Source/Core/Common/Arm64Emitter.cpp | 2 +- Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/Source/Core/Common/Arm64Emitter.cpp b/Source/Core/Common/Arm64Emitter.cpp index 91ad58d9f0..bd72df2e94 100644 --- a/Source/Core/Common/Arm64Emitter.cpp +++ b/Source/Core/Common/Arm64Emitter.cpp @@ -4057,7 +4057,7 @@ void ARM64XEmitter::ANDI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch) else { _assert_msg_(DYNA_REC, scratch != INVALID_REG, - "ANDSI2R - failed to construct logical immediate value from %08x, need scratch", + "ANDI2R - failed to construct logical immediate value from %08x, need scratch", (u32)imm); MOVI2R(scratch, imm); AND(Rd, Rn, scratch); diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp index 11b267d2f7..e3761f1673 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp @@ -532,7 +532,12 @@ void JitArm64::rlwinmx(UGeckoInstruction inst) gpr.BindToRegister(a, a == s); - if (!inst.SH) + if (!inst.SH && mask == 0xFFFFFFFF) + { + if (a != s) + MOV(gpr.R(a), gpr.R(s)); + } + else if (!inst.SH) { // Immediate mask ANDI2R(gpr.R(a), gpr.R(s), mask);