From 0049a767751807c124f099a7ba7f9a3add7c18f7 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Tue, 14 Feb 2023 18:39:00 +0100 Subject: [PATCH] JitArm64: Fix special cases of cmp This fixes a regression from 592ba31. When `a` was a constant 0 and `b` was a non-constant 0x80000000, the 32-bit negation operation would overflow, causing an incorrect result. The sign extension needs to happen before the negation to avoid overflow. Note that I can't merge the SXTW and NEG into one instruction. NEG is an alias for SUB with the first operand being set to ZR, but "SUB (extended register)" treats register 31 as SP instead of ZR. I've also changed the order for the case where `a` is a constant 0xFFFFFFFF. I don't think the order actually affects correctness here, but let's use the same order for all the cases since it makes the code easier to reason about. --- Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp index 02bee2f636..a9a0f540bb 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp @@ -584,13 +584,13 @@ void JitArm64::cmp(UGeckoInstruction inst) } else if (gpr.IsImm(a) && !gpr.GetImm(a)) { - NEG(EncodeRegTo32(CR), gpr.R(b)); - SXTW(CR, EncodeRegTo32(CR)); + SXTW(CR, gpr.R(b)); + NEG(CR, CR); } else if (gpr.IsImm(a) && gpr.GetImm(a) == 0xFFFFFFFF) { - MVN(EncodeRegTo32(CR), gpr.R(b)); - SXTW(CR, EncodeRegTo32(CR)); + SXTW(CR, gpr.R(b)); + MVN(CR, CR); } else if (gpr.IsImm(b) && !gpr.GetImm(b)) {