From 1020a3cb8e027c7c3cc45b58d0d9da2bc9c9dcb9 Mon Sep 17 00:00:00 2001 From: MerryMage Date: Tue, 14 Mar 2017 19:09:18 +0000 Subject: [PATCH] DSP/Jit: Explicitly specify scratch register for Update_SR_Register There were cases when the value register was RDX and thus was being clobbered as RDX was implictly used as a scratch register. --- Source/Core/Core/DSP/Jit/DSPEmitter.h | 4 +-- Source/Core/Core/DSP/Jit/DSPJitArithmetic.cpp | 12 ++++----- Source/Core/Core/DSP/Jit/DSPJitCCUtil.cpp | 26 ++++++++++--------- Source/Core/Core/DSP/Jit/DSPJitMultiplier.cpp | 2 +- 4 files changed, 23 insertions(+), 21 deletions(-) diff --git a/Source/Core/Core/DSP/Jit/DSPEmitter.h b/Source/Core/Core/DSP/Jit/DSPEmitter.h index 56238c3b06..7c1c947e40 100644 --- a/Source/Core/Core/DSP/Jit/DSPEmitter.h +++ b/Source/Core/Core/DSP/Jit/DSPEmitter.h @@ -221,7 +221,7 @@ private: void r_ifcc(UDSPInstruction opc); void r_ret(UDSPInstruction opc); - void Update_SR_Register(Gen::X64Reg val = Gen::EAX); + void Update_SR_Register(Gen::X64Reg val = Gen::EAX, Gen::X64Reg scratch = Gen::EDX); void get_long_prod(Gen::X64Reg long_prod = Gen::RAX); void get_long_prod_round_prodl(Gen::X64Reg long_prod = Gen::RAX); @@ -243,7 +243,7 @@ private: void HandleLoop(); // CC helpers - void Update_SR_Register64(Gen::X64Reg val = Gen::EAX); + void Update_SR_Register64(Gen::X64Reg val = Gen::EAX, Gen::X64Reg scratch = Gen::EDX); void Update_SR_Register64_Carry(Gen::X64Reg val, Gen::X64Reg carry_ovfl, bool carry_eq = false); void Update_SR_Register16(Gen::X64Reg val = Gen::EAX); void Update_SR_Register16_OverS32(Gen::X64Reg val = Gen::EAX); diff --git a/Source/Core/Core/DSP/Jit/DSPJitArithmetic.cpp b/Source/Core/Core/DSP/Jit/DSPJitArithmetic.cpp index 8b934afab7..1802253e21 100644 --- a/Source/Core/Core/DSP/Jit/DSPJitArithmetic.cpp +++ b/Source/Core/Core/DSP/Jit/DSPJitArithmetic.cpp @@ -1382,7 +1382,7 @@ void DSPEmitter::lsrn(const UDSPInstruction opc) // Update_SR_Register64(dsp_get_long_acc(0)); if (FlagsNeeded()) { - Update_SR_Register64(RDX); + Update_SR_Register64(RDX, RCX); } } @@ -1439,7 +1439,7 @@ void DSPEmitter::asrn(const UDSPInstruction opc) SetJumpTarget(zero); if (FlagsNeeded()) { - Update_SR_Register64(RDX); + Update_SR_Register64(RDX, RCX); } } @@ -1502,7 +1502,7 @@ void DSPEmitter::lsrnrx(const UDSPInstruction opc) SetJumpTarget(zero); if (FlagsNeeded()) { - Update_SR_Register64(RDX); + Update_SR_Register64(RDX, RCX); } } @@ -1559,7 +1559,7 @@ void DSPEmitter::asrnrx(const UDSPInstruction opc) // Update_SR_Register64(dsp_get_long_acc(dreg)); if (FlagsNeeded()) { - Update_SR_Register64(RDX); + Update_SR_Register64(RDX, RCX); } } @@ -1617,7 +1617,7 @@ void DSPEmitter::lsrnr(const UDSPInstruction opc) // Update_SR_Register64(dsp_get_long_acc(dreg)); if (FlagsNeeded()) { - Update_SR_Register64(RDX); + Update_SR_Register64(RDX, RCX); } } @@ -1672,7 +1672,7 @@ void DSPEmitter::asrnr(const UDSPInstruction opc) // Update_SR_Register64(dsp_get_long_acc(dreg)); if (FlagsNeeded()) { - Update_SR_Register64(RDX); + Update_SR_Register64(RDX, RCX); } } diff --git a/Source/Core/Core/DSP/Jit/DSPJitCCUtil.cpp b/Source/Core/Core/DSP/Jit/DSPJitCCUtil.cpp index 827243741b..d296486327 100644 --- a/Source/Core/Core/DSP/Jit/DSPJitCCUtil.cpp +++ b/Source/Core/Core/DSP/Jit/DSPJitCCUtil.cpp @@ -15,10 +15,12 @@ namespace JIT { namespace x86 { -// In: RAX: s64 _Value -// Clobbers RDX -void DSPEmitter::Update_SR_Register(Gen::X64Reg val) +// In: val: s64 _Value +// Clobbers scratch +void DSPEmitter::Update_SR_Register(Gen::X64Reg val, Gen::X64Reg scratch) { + _assert_(val != scratch); + const OpArg sr_reg = m_gpr.GetReg(DSP_REG_SR); // // 0x04 // if (_Value == 0) g_dsp.r[DSP_REG_SR] |= SR_ARITH_ZERO; @@ -36,18 +38,18 @@ void DSPEmitter::Update_SR_Register(Gen::X64Reg val) // // 0x10 // if (_Value != (s32)_Value) g_dsp.r[DSP_REG_SR] |= SR_OVER_S32; - MOVSX(64, 32, RDX, R(val)); - CMP(64, R(RDX), R(val)); + MOVSX(64, 32, scratch, R(val)); + CMP(64, R(scratch), R(val)); FixupBranch noOverS32 = J_CC(CC_E); OR(16, sr_reg, Imm16(SR_OVER_S32)); SetJumpTarget(noOverS32); // // 0x20 - Checks if top bits of m are equal // if (((_Value & 0xc0000000) == 0) || ((_Value & 0xc0000000) == 0xc0000000)) - MOV(32, R(RDX), Imm32(0xc0000000)); - AND(32, R(val), R(RDX)); + MOV(32, R(scratch), Imm32(0xc0000000)); + AND(32, R(val), R(scratch)); FixupBranch zeroC = J_CC(CC_Z); - CMP(32, R(val), R(RDX)); + CMP(32, R(val), R(scratch)); FixupBranch cC = J_CC(CC_NE); SetJumpTarget(zeroC); // g_dsp.r[DSP_REG_SR] |= SR_TOP2BITS; @@ -57,15 +59,15 @@ void DSPEmitter::Update_SR_Register(Gen::X64Reg val) m_gpr.PutReg(DSP_REG_SR); } -// In: RAX: s64 _Value -// Clobbers RDX -void DSPEmitter::Update_SR_Register64(Gen::X64Reg val) +// In: val: s64 _Value +// Clobbers scratch +void DSPEmitter::Update_SR_Register64(Gen::X64Reg val, Gen::X64Reg scratch) { // g_dsp.r[DSP_REG_SR] &= ~SR_CMP_MASK; const OpArg sr_reg = m_gpr.GetReg(DSP_REG_SR); AND(16, sr_reg, Imm16(~SR_CMP_MASK)); m_gpr.PutReg(DSP_REG_SR); - Update_SR_Register(val); + Update_SR_Register(val, scratch); } // In: (val): s64 _Value diff --git a/Source/Core/Core/DSP/Jit/DSPJitMultiplier.cpp b/Source/Core/Core/DSP/Jit/DSPJitMultiplier.cpp index 77d6e38032..fb4c1ae8f4 100644 --- a/Source/Core/Core/DSP/Jit/DSPJitMultiplier.cpp +++ b/Source/Core/Core/DSP/Jit/DSPJitMultiplier.cpp @@ -393,7 +393,7 @@ void DSPEmitter::mulmvz(const UDSPInstruction opc) // Update_SR_Register64(dsp_get_long_acc(rreg)); if (FlagsNeeded()) { - Update_SR_Register64(RDX); + Update_SR_Register64(RDX, RCX); } }