From 8902d2fe3a3ccd9629603dead9e10c476caf684b Mon Sep 17 00:00:00 2001 From: JosJuice Date: Sat, 1 Oct 2022 19:29:41 +0200 Subject: [PATCH 1/2] JitArm64: Fix divwx BindToRegister condition a is being used both as an immediate and as a register here. Since it's being used as a register, it must be loaded. --- Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp index fd13d0ec79..7222a361cd 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp @@ -1433,7 +1433,7 @@ void JitArm64::divwx(UGeckoInstruction inst) { const u32 dividend = gpr.GetImm(a); - gpr.BindToRegister(d, d == b); + gpr.BindToRegister(d, d == a || d == b); ARM64Reg RB = gpr.R(b); ARM64Reg RD = gpr.R(d); From 8984777749b6053da703b5e219fe9a8f0e577fd2 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Sat, 1 Oct 2022 20:28:39 +0200 Subject: [PATCH 2/2] JitArm64: Call GetImm before BindToRegister In case the register we're binding is the same as the immediate register, we should fetch the immediate before calling BindToRegister. The way the register cache currently works, calling GetImm after BindToRegister actually does work, but it's better to not rely on it. --- Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp index 7222a361cd..2fc1524809 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp @@ -476,9 +476,11 @@ void JitArm64::addx(UGeckoInstruction inst) { int imm_reg = gpr.IsImm(a) ? a : b; int in_reg = gpr.IsImm(a) ? b : a; + int imm_value = gpr.GetImm(imm_reg); + gpr.BindToRegister(d, d == in_reg); ARM64Reg WA = gpr.GetReg(); - ADDI2R(gpr.R(d), gpr.R(in_reg), gpr.GetImm(imm_reg), WA); + ADDI2R(gpr.R(d), gpr.R(in_reg), imm_value, WA); gpr.Unlock(WA); if (inst.Rc) ComputeRC0(gpr.R(d)); @@ -745,11 +747,11 @@ void JitArm64::rlwnmx(UGeckoInstruction inst) } else if (gpr.IsImm(b)) { + int imm_value = gpr.GetImm(b) & 0x1f; gpr.BindToRegister(a, a == s); ARM64Reg WA = gpr.GetReg(); - ArithOption Shift(gpr.R(s), ShiftType::ROR, 32 - (gpr.GetImm(b) & 0x1f)); MOVI2R(WA, mask); - AND(gpr.R(a), WA, gpr.R(s), Shift); + AND(gpr.R(a), WA, gpr.R(s), ArithOption(gpr.R(s), ShiftType::ROR, 32 - imm_value)); gpr.Unlock(WA); if (inst.Rc) ComputeRC0(gpr.R(a));