From fca69f37020dd58a8e631d060a5e13deea5bd6f3 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Sat, 25 May 2024 21:05:31 +0200 Subject: [PATCH] Jit: Skip setting bit 32 of CRs when possible Setting SO and LT can be done without setting bit 32. Setting bit 32 is required in situations where clearing bits in the host representation of a CR could otherwise cause the host representation to become all zeroes, but it's impossible to generate a host representation whose SO and/or LT bits are set without any other bits being set. (Any attempt to do so would require either starting with a host representation of all zeroes and then setting the SO or LT bit, which results in bit 63 getting set, or clearing bit 63 by setting the emulated GT bit, which results in bit 32 getting set, or clearing the lower 32 bits by setting the emulated EQ bit, which results in bit 32 getting set.) --- Source/Core/Core/PowerPC/Jit64/Jit_SystemRegisters.cpp | 6 ++++-- .../Core/PowerPC/JitArm64/JitArm64_SystemRegisters.cpp | 8 ++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/Source/Core/Core/PowerPC/Jit64/Jit_SystemRegisters.cpp b/Source/Core/Core/PowerPC/Jit64/Jit_SystemRegisters.cpp index 6331358359..edab5ba3ea 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit_SystemRegisters.cpp +++ b/Source/Core/Core/PowerPC/Jit64/Jit_SystemRegisters.cpp @@ -71,6 +71,7 @@ void Jit64::SetCRFieldBit(int field, int bit, X64Reg in) case PowerPC::CR_EQ_BIT: // clear low 32 bits, set bit 0 to !input SHR(64, R(RSCRATCH2), Imm8(32)); SHL(64, R(RSCRATCH2), Imm8(32)); + BTS(64, R(RSCRATCH2), Imm8(32)); XOR(32, R(in), Imm8(1)); OR(64, R(RSCRATCH2), R(in)); break; @@ -78,6 +79,7 @@ void Jit64::SetCRFieldBit(int field, int bit, X64Reg in) case PowerPC::CR_GT_BIT: // set bit 63 to !input BTR(64, R(RSCRATCH2), Imm8(63)); NOT(32, R(in)); + BTS(64, R(RSCRATCH2), Imm8(32)); SHL(64, R(in), Imm8(63)); OR(64, R(RSCRATCH2), R(in)); break; @@ -89,7 +91,6 @@ void Jit64::SetCRFieldBit(int field, int bit, X64Reg in) break; } - BTS(64, R(RSCRATCH2), Imm8(32)); MOV(64, CROffset(field), R(RSCRATCH2)); } @@ -135,10 +136,12 @@ void Jit64::SetCRFieldBit(int field, int bit) case PowerPC::CR_EQ_BIT: SHR(64, R(RSCRATCH), Imm8(32)); SHL(64, R(RSCRATCH), Imm8(32)); + BTS(64, R(RSCRATCH), Imm8(32)); break; case PowerPC::CR_GT_BIT: BTR(64, R(RSCRATCH), Imm8(63)); + BTS(64, R(RSCRATCH), Imm8(32)); break; case PowerPC::CR_LT_BIT: @@ -146,7 +149,6 @@ void Jit64::SetCRFieldBit(int field, int bit) break; } - BTS(64, R(RSCRATCH), Imm8(32)); MOV(64, CROffset(field), R(RSCRATCH)); } diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_SystemRegisters.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_SystemRegisters.cpp index a0084953b9..a60fa9b8f5 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_SystemRegisters.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_SystemRegisters.cpp @@ -68,12 +68,14 @@ void JitArm64::SetCRFieldBit(int field, int bit, ARM64Reg in, bool negate) case PowerPC::CR_EQ_BIT: // clear low 32 bits, set bit 0 to !input AND(CR, CR, LogicalImm(0xFFFF'FFFF'0000'0000, GPRSize::B64)); + ORR(CR, CR, LogicalImm(1ULL << 32, GPRSize::B64)); ORR(CR, CR, in); if (!negate) EOR(CR, CR, LogicalImm(1ULL << 0, GPRSize::B64)); break; case PowerPC::CR_GT_BIT: // set bit 63 to !input + ORR(CR, CR, LogicalImm(1ULL << 32, GPRSize::B64)); BFI(CR, in, 63, 1); if (!negate) EOR(CR, CR, LogicalImm(1ULL << 63, GPRSize::B64)); @@ -85,8 +87,6 @@ void JitArm64::SetCRFieldBit(int field, int bit, ARM64Reg in, bool negate) EOR(CR, CR, LogicalImm(1ULL << PowerPC::CR_EMU_LT_BIT, GPRSize::B64)); break; } - - ORR(CR, CR, LogicalImm(1ULL << 32, GPRSize::B64)); } void JitArm64::ClearCRFieldBit(int field, int bit) @@ -131,18 +131,18 @@ void JitArm64::SetCRFieldBit(int field, int bit) case PowerPC::CR_EQ_BIT: AND(XA, XA, LogicalImm(0xFFFF'FFFF'0000'0000, GPRSize::B64)); + ORR(XA, XA, LogicalImm(u64(1) << 32, GPRSize::B64)); break; case PowerPC::CR_GT_BIT: AND(XA, XA, LogicalImm(~(u64(1) << 63), GPRSize::B64)); + ORR(XA, XA, LogicalImm(u64(1) << 32, GPRSize::B64)); break; case PowerPC::CR_LT_BIT: ORR(XA, XA, LogicalImm(u64(1) << PowerPC::CR_EMU_LT_BIT, GPRSize::B64)); break; } - - ORR(XA, XA, LogicalImm(u64(1) << 32, GPRSize::B64)); } void JitArm64::FixGTBeforeSettingCRFieldBit(ARM64Reg reg)