From 25a701aa1b14638a3837d3bd72639f1709209bda Mon Sep 17 00:00:00 2001 From: Tillmann Karras Date: Sun, 6 Jun 2021 06:12:21 +0100 Subject: [PATCH] PowerPC: move SO bit to a more convenient location Spacing the LT and SO bits like in the native PowerPC format makes it easier to convert to that format (see mfcr). --- Source/Core/Core/PowerPC/ConditionRegister.h | 14 ++++---- .../Interpreter/Interpreter_Integer.cpp | 2 +- .../PowerPC/Jit64/Jit_SystemRegisters.cpp | 18 +++++----- .../PowerPC/Jit64Common/Jit64AsmCommon.cpp | 16 ++++----- .../JitArm64/JitArm64_SystemRegisters.cpp | 34 +++++++++---------- 5 files changed, 39 insertions(+), 45 deletions(-) diff --git a/Source/Core/Core/PowerPC/ConditionRegister.h b/Source/Core/Core/PowerPC/ConditionRegister.h index f1897e9086..3a9c7cc4ad 100644 --- a/Source/Core/Core/PowerPC/ConditionRegister.h +++ b/Source/Core/Core/PowerPC/ConditionRegister.h @@ -25,7 +25,7 @@ enum CRBits // Optimized CR implementation. Instead of storing CR in its PowerPC format // (4 bit value, SO/EQ/LT/GT), we store instead a 64 bit value for each of // the 8 CR register parts. This 64 bit value follows this format: -// - SO iff. bit 61 is set +// - SO iff. bit 59 is set // - EQ iff. lower 32 bits == 0 // - GT iff. (s64)cr_val > 0 // - LT iff. bit 62 is set @@ -46,7 +46,7 @@ struct ConditionRegister static u64 PPCToInternal(u8 value) { u64 cr_val = 0x100000000; - cr_val |= (u64) !!(value & CR_SO) << 61; + cr_val |= (u64) !!(value & CR_SO) << 59; cr_val |= (u64) !(value & CR_EQ); cr_val |= (u64) !(value & CR_GT) << 63; cr_val |= (u64) !!(value & CR_LT) << 62; @@ -63,14 +63,12 @@ struct ConditionRegister const u64 cr_val = fields[cr_field]; u32 ppc_cr = 0; - // SO - ppc_cr |= !!(cr_val & (1ull << 61)); + // LT/SO + ppc_cr |= (cr_val >> 59) & (PowerPC::CR_LT | PowerPC::CR_SO); // EQ - ppc_cr |= ((cr_val & 0xFFFFFFFF) == 0) << 1; + ppc_cr |= ((cr_val & 0xFFFFFFFF) == 0) << PowerPC::CR_EQ_BIT; // GT - ppc_cr |= (static_cast(cr_val) > 0) << 2; - // LT - ppc_cr |= !!(cr_val & (1ull << 62)) << 3; + ppc_cr |= (static_cast(cr_val) > 0) << PowerPC::CR_GT_BIT; return ppc_cr; } diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Integer.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Integer.cpp index 188f181a80..3b9570efc1 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Integer.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Integer.cpp @@ -13,7 +13,7 @@ void Interpreter::Helper_UpdateCR0(u32 value) { s64 sign_extended = (s64)(s32)value; u64 cr_val = (u64)sign_extended; - cr_val = (cr_val & ~(1ull << 61)) | ((u64)PowerPC::GetXER_SO() << 61); + cr_val = (cr_val & ~(1ull << 59)) | ((u64)PowerPC::GetXER_SO() << 59); PowerPC::ppcState.cr.fields[0] = cr_val; } diff --git a/Source/Core/Core/PowerPC/Jit64/Jit_SystemRegisters.cpp b/Source/Core/Core/PowerPC/Jit64/Jit_SystemRegisters.cpp index 7965aab6e7..6e40d753ba 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit_SystemRegisters.cpp +++ b/Source/Core/Core/PowerPC/Jit64/Jit_SystemRegisters.cpp @@ -24,8 +24,8 @@ void Jit64::GetCRFieldBit(int field, int bit, X64Reg out, bool negate) { switch (bit) { - case PowerPC::CR_SO_BIT: // check bit 61 set - BT(64, CROffset(field), Imm8(61)); + case PowerPC::CR_SO_BIT: // check bit 59 set + BT(64, CROffset(field), Imm8(59)); SETcc(negate ? CC_NC : CC_C, R(out)); break; @@ -59,9 +59,9 @@ void Jit64::SetCRFieldBit(int field, int bit, X64Reg in) switch (bit) { - case PowerPC::CR_SO_BIT: // set bit 61 to input - BTR(64, R(RSCRATCH2), Imm8(61)); - SHL(64, R(in), Imm8(61)); + case PowerPC::CR_SO_BIT: // set bit 59 to input + BTR(64, R(RSCRATCH2), Imm8(59)); + SHL(64, R(in), Imm8(59)); OR(64, R(RSCRATCH2), R(in)); break; @@ -95,7 +95,7 @@ void Jit64::ClearCRFieldBit(int field, int bit) switch (bit) { case PowerPC::CR_SO_BIT: - BTR(64, CROffset(field), Imm8(61)); + BTR(64, CROffset(field), Imm8(59)); break; case PowerPC::CR_EQ_BIT: @@ -126,7 +126,7 @@ void Jit64::SetCRFieldBit(int field, int bit) switch (bit) { case PowerPC::CR_SO_BIT: - BTS(64, R(RSCRATCH), Imm8(61)); + BTS(64, R(RSCRATCH), Imm8(59)); break; case PowerPC::CR_EQ_BIT: @@ -162,8 +162,8 @@ FixupBranch Jit64::JumpIfCRFieldBit(int field, int bit, bool jump_if_set) { switch (bit) { - case PowerPC::CR_SO_BIT: // check bit 61 set - BT(64, CROffset(field), Imm8(61)); + case PowerPC::CR_SO_BIT: // check bit 59 set + BT(64, CROffset(field), Imm8(59)); return J_CC(jump_if_set ? CC_C : CC_NC, true); case PowerPC::CR_EQ_BIT: // check bits 31-0 == 0 diff --git a/Source/Core/Core/PowerPC/Jit64Common/Jit64AsmCommon.cpp b/Source/Core/Core/PowerPC/Jit64Common/Jit64AsmCommon.cpp index ef3fcc067a..71cf960cb3 100644 --- a/Source/Core/Core/PowerPC/Jit64Common/Jit64AsmCommon.cpp +++ b/Source/Core/Core/PowerPC/Jit64Common/Jit64AsmCommon.cpp @@ -301,19 +301,15 @@ void CommonAsmRoutines::GenMfcr() X64Reg tmp = RSCRATCH2; X64Reg cr_val = RSCRATCH_EXTRA; XOR(32, R(dst), R(dst)); + // Upper bits of tmp need to be zeroed. + XOR(32, R(tmp), R(tmp)); for (int i = 0; i < 8; i++) { - static const u32 m_flagTable[8] = {0x0, 0x1, 0x8, 0x9, 0x0, 0x1, 0x8, 0x9}; if (i != 0) SHL(32, R(dst), Imm8(4)); MOV(64, R(cr_val), PPCSTATE(cr.fields[i])); - // Upper bits of tmp need to be zeroed. - // Note: tmp is used later for address calculations and thus - // can't be zero-ed once. This also prevents partial - // register stalls due to SETcc. - XOR(32, R(tmp), R(tmp)); // EQ: Bits 31-0 == 0; set flag bit 1 TEST(32, R(cr_val), R(cr_val)); SETcc(CC_Z, R(tmp)); @@ -324,11 +320,11 @@ void CommonAsmRoutines::GenMfcr() SETcc(CC_G, R(tmp)); LEA(32, dst, MComplex(dst, tmp, SCALE_4, 0)); - // SO: Bit 61 set; set flag bit 0 + // SO: Bit 59 set; set flag bit 0 // LT: Bit 62 set; set flag bit 3 - SHR(64, R(cr_val), Imm8(61)); - LEA(64, tmp, MConst(m_flagTable)); - OR(32, R(dst), MComplex(tmp, cr_val, SCALE_4, 0)); + SHR(64, R(cr_val), Imm8(59)); + AND(32, R(cr_val), Imm8(PowerPC::CR_LT | PowerPC::CR_SO)); + OR(32, R(dst), R(cr_val)); } RET(); diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_SystemRegisters.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_SystemRegisters.cpp index 668e7fce26..ddb8cb337d 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_SystemRegisters.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_SystemRegisters.cpp @@ -21,8 +21,8 @@ FixupBranch JitArm64::JumpIfCRFieldBit(int field, int bit, bool jump_if_set) switch (bit) { - case PowerPC::CR_SO_BIT: // check bit 61 set - return jump_if_set ? TBNZ(XA, 61) : TBZ(XA, 61); + case PowerPC::CR_SO_BIT: // check bit 59 set + return jump_if_set ? TBNZ(XA, 59) : TBZ(XA, 59); case PowerPC::CR_EQ_BIT: // check bits 31-0 == 0 return jump_if_set ? CBZ(WA) : CBNZ(WA); case PowerPC::CR_GT_BIT: // check val > 0 @@ -441,20 +441,20 @@ void JitArm64::crXXX(UGeckoInstruction inst) switch (bit) { case PowerPC::CR_SO_BIT: - AND(XA, XA, 64 - 62, 62, true); // XA & ~(1<<61) + ANDI2R(XA, XA, ~(u64(1) << 59)); break; case PowerPC::CR_EQ_BIT: FixGTBeforeSettingCRFieldBit(XA); - ORR(XA, XA, 0, 0, true); // XA | 1<<0 + ORRI2R(XA, XA, 1); break; case PowerPC::CR_GT_BIT: - ORR(XA, XA, 64 - 63, 0, true); // XA | 1<<63 + ORRI2R(XA, XA, u64(1) << 63); break; case PowerPC::CR_LT_BIT: - AND(XA, XA, 64 - 63, 62, true); // XA & ~(1<<62) + ANDI2R(XA, XA, ~(u64(1) << 62)); break; } return; @@ -476,23 +476,23 @@ void JitArm64::crXXX(UGeckoInstruction inst) switch (bit) { case PowerPC::CR_SO_BIT: - ORR(XA, XA, 64 - 61, 0, true); // XA | 1<<61 + ORRI2R(XA, XA, u64(1) << 59); break; case PowerPC::CR_EQ_BIT: - AND(XA, XA, 32, 31, true); // Clear lower 32bits + ANDI2R(XA, XA, 0xFFFF'FFFF'0000'0000); break; case PowerPC::CR_GT_BIT: - AND(XA, XA, 0, 62, true); // XA & ~(1<<63) + ANDI2R(XA, XA, ~(u64(1) << 63)); break; case PowerPC::CR_LT_BIT: - ORR(XA, XA, 64 - 62, 0, true); // XA | 1<<62 + ORRI2R(XA, XA, u64(1) << 62); break; } - ORR(XA, XA, 32, 0, true); // XA | 1<<32 + ORRI2R(XA, XA, u64(1) << 32); return; } @@ -519,8 +519,8 @@ void JitArm64::crXXX(UGeckoInstruction inst) ARM64Reg WC = EncodeRegTo32(XC); switch (bit) { - case PowerPC::CR_SO_BIT: // check bit 61 set - UBFX(out, XC, 61, 1); + case PowerPC::CR_SO_BIT: // check bit 59 set + UBFX(out, XC, 59, 1); if (negate) EOR(out, out, 0, 0, true); // XC ^ 1 break; @@ -581,8 +581,8 @@ void JitArm64::crXXX(UGeckoInstruction inst) switch (bit) { - case PowerPC::CR_SO_BIT: // set bit 61 to input - BFI(XB, XA, 61, 1); + case PowerPC::CR_SO_BIT: // set bit 59 to input + BFI(XB, XA, 59, 1); break; case PowerPC::CR_EQ_BIT: // clear low 32 bits, set bit 0 to !input @@ -625,11 +625,11 @@ void JitArm64::mfcr(UGeckoInstruction inst) // SO if (i == 0) { - UBFX(XA, CR, 61, 1); + UBFX(XA, CR, 59, 1); } else { - UBFX(XC, CR, 61, 1); + UBFX(XC, CR, 59, 1); ORR(XA, XC, XA, ArithOption(XA, ShiftType::LSL, 4)); }