diff --git a/Source/Core/Core/DSP/Jit/x64/DSPEmitter.h b/Source/Core/Core/DSP/Jit/x64/DSPEmitter.h index f64e211e00..21fab446e1 100644 --- a/Source/Core/Core/DSP/Jit/x64/DSPEmitter.h +++ b/Source/Core/Core/DSP/Jit/x64/DSPEmitter.h @@ -257,8 +257,8 @@ private: { UpdateSR64AddSub(val1, val2, result, scratch, true); } - void Update_SR_Register16(Gen::X64Reg val = Gen::EAX); - void Update_SR_Register16_OverS32(Gen::X64Reg val = Gen::EAX); + void Update_SR_Register16(Gen::X64Reg val); + void Update_SR_Register16_OverS32(Gen::X64Reg val, Gen::X64Reg full_val, Gen::X64Reg scratch); // Register helpers void setCompileSR(u16 bit); diff --git a/Source/Core/Core/DSP/Jit/x64/DSPJitArithmetic.cpp b/Source/Core/Core/DSP/Jit/x64/DSPJitArithmetic.cpp index 716781750e..7958787f94 100644 --- a/Source/Core/Core/DSP/Jit/x64/DSPJitArithmetic.cpp +++ b/Source/Core/Core/DSP/Jit/x64/DSPJitArithmetic.cpp @@ -152,9 +152,9 @@ void DSPEmitter::tstaxh(const UDSPInstruction opc) { u8 reg = (opc >> 8) & 0x1; // s16 val = dsp_get_ax_h(reg); - get_ax_h(reg); + get_ax_h(reg, EAX); // Update_SR_Register16(val); - Update_SR_Register16(); + Update_SR_Register16(EAX); } } @@ -301,16 +301,18 @@ void DSPEmitter::xorr(const UDSPInstruction opc) u8 dreg = (opc >> 8) & 0x1; u8 sreg = (opc >> 9) & 0x1; // u16 accm = g_dsp.r.acm[dreg] ^ g_dsp.r.axh[sreg]; - get_acc_m(dreg, RAX); + X64Reg accm = RAX; + get_acc_m(dreg, accm); get_ax_h(sreg, RDX); - XOR(64, R(RAX), R(RDX)); + XOR(64, R(accm), R(RDX)); // g_dsp.r.acm[dreg] = accm; - set_acc_m(dreg); + set_acc_m(dreg, R(accm)); // Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg))); if (FlagsNeeded()) { - get_long_acc(dreg, RCX); - Update_SR_Register16_OverS32(); + X64Reg acc_full = RCX; + get_long_acc(dreg, acc_full); + Update_SR_Register16_OverS32(accm, acc_full, RDX); } } @@ -326,16 +328,18 @@ void DSPEmitter::andr(const UDSPInstruction opc) u8 dreg = (opc >> 8) & 0x1; u8 sreg = (opc >> 9) & 0x1; // u16 accm = g_dsp.r.acm[dreg] & g_dsp.r.axh[sreg]; - get_acc_m(dreg, RAX); + X64Reg accm = RAX; + get_acc_m(dreg, accm); get_ax_h(sreg, RDX); - AND(64, R(RAX), R(RDX)); + AND(64, R(accm), R(RDX)); // g_dsp.r.acm[dreg] = accm; - set_acc_m(dreg); + set_acc_m(dreg, R(accm)); // Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg))); if (FlagsNeeded()) { - get_long_acc(dreg, RCX); - Update_SR_Register16_OverS32(); + X64Reg acc_full = RCX; + get_long_acc(dreg, acc_full); + Update_SR_Register16_OverS32(accm, acc_full, RDX); } } @@ -351,16 +355,18 @@ void DSPEmitter::orr(const UDSPInstruction opc) u8 dreg = (opc >> 8) & 0x1; u8 sreg = (opc >> 9) & 0x1; // u16 accm = g_dsp.r.acm[dreg] | g_dsp.r.axh[sreg]; - get_acc_m(dreg, RAX); + X64Reg accm = RAX; + get_acc_m(dreg, accm); get_ax_h(sreg, RDX); - OR(64, R(RAX), R(RDX)); + OR(64, R(accm), R(RDX)); // g_dsp.r.acm[dreg] = accm; - set_acc_m(dreg); + set_acc_m(dreg, R(accm)); // Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg))); if (FlagsNeeded()) { - get_long_acc(dreg, RCX); - Update_SR_Register16_OverS32(); + X64Reg acc_full = RCX; + get_long_acc(dreg, acc_full); + Update_SR_Register16_OverS32(accm, acc_full, RDX); } } @@ -375,16 +381,18 @@ void DSPEmitter::andc(const UDSPInstruction opc) { u8 dreg = (opc >> 8) & 0x1; // u16 accm = g_dsp.r.acm[dreg] & g_dsp.r.acm[1 - dreg]; - get_acc_m(dreg, RAX); + X64Reg accm = RAX; + get_acc_m(dreg, accm); get_acc_m(1 - dreg, RDX); - AND(64, R(RAX), R(RDX)); + AND(64, R(accm), R(RDX)); // g_dsp.r.acm[dreg] = accm; - set_acc_m(dreg); + set_acc_m(dreg, R(accm)); // Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg))); if (FlagsNeeded()) { - get_long_acc(dreg, RCX); - Update_SR_Register16_OverS32(); + X64Reg acc_full = RCX; + get_long_acc(dreg, acc_full); + Update_SR_Register16_OverS32(accm, acc_full, RDX); } } @@ -399,16 +407,18 @@ void DSPEmitter::orc(const UDSPInstruction opc) { u8 dreg = (opc >> 8) & 0x1; // u16 accm = g_dsp.r.acm[dreg] | g_dsp.r.acm[1 - dreg]; - get_acc_m(dreg, RAX); + X64Reg accm = RAX; + get_acc_m(dreg, accm); get_acc_m(1 - dreg, RDX); - OR(64, R(RAX), R(RDX)); + OR(64, R(accm), R(RDX)); // g_dsp.r.acm[dreg] = accm; - set_acc_m(dreg); + set_acc_m(dreg, R(accm)); // Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg))); if (FlagsNeeded()) { - get_long_acc(dreg, RCX); - Update_SR_Register16_OverS32(); + X64Reg acc_full = RCX; + get_long_acc(dreg, acc_full); + Update_SR_Register16_OverS32(accm, acc_full, RDX); } } @@ -422,16 +432,18 @@ void DSPEmitter::xorc(const UDSPInstruction opc) { u8 dreg = (opc >> 8) & 0x1; // u16 accm = g_dsp.r.acm[dreg] ^ g_dsp.r.acm[1 - dreg]; - get_acc_m(dreg, RAX); + X64Reg accm = RAX; + get_acc_m(dreg, accm); get_acc_m(1 - dreg, RDX); - XOR(64, R(RAX), R(RDX)); + XOR(64, R(accm), R(RDX)); // g_dsp.r.acm[dreg] = accm; - set_acc_m(dreg); + set_acc_m(dreg, R(accm)); // Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg))); if (FlagsNeeded()) { - get_long_acc(dreg, RCX); - Update_SR_Register16_OverS32(); + X64Reg acc_full = RCX; + get_long_acc(dreg, acc_full); + Update_SR_Register16_OverS32(accm, acc_full, RDX); } } @@ -445,15 +457,17 @@ void DSPEmitter::notc(const UDSPInstruction opc) { u8 dreg = (opc >> 8) & 0x1; // u16 accm = g_dsp.r.acm[dreg] ^ 0xffff; - get_acc_m(dreg, RAX); - NOT(16, R(AX)); + X64Reg accm = RAX; + get_acc_m(dreg, accm); + NOT(16, R(accm)); // g_dsp.r.acm[dreg] = accm; - set_acc_m(dreg); + set_acc_m(dreg, R(accm)); // Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg))); if (FlagsNeeded()) { - get_long_acc(dreg, RCX); - Update_SR_Register16_OverS32(); + X64Reg acc_full = RCX; + get_long_acc(dreg, acc_full); + Update_SR_Register16_OverS32(accm, acc_full, RDX); } } @@ -470,14 +484,16 @@ void DSPEmitter::xori(const UDSPInstruction opc) // u16 imm = dsp_fetch_code(); const u16 imm = m_dsp_core.DSPState().ReadIMEM(m_compile_pc + 1); // g_dsp.r.acm[reg] ^= imm; - get_acc_m(reg, RAX); - XOR(16, R(RAX), Imm16(imm)); - set_acc_m(reg); + X64Reg accm = RAX; + get_acc_m(reg, accm); + XOR(16, R(accm), Imm16(imm)); + set_acc_m(reg, R(accm)); // Update_SR_Register16((s16)g_dsp.r.acm[reg], false, false, isOverS32(dsp_get_long_acc(reg))); if (FlagsNeeded()) { - get_long_acc(reg, RCX); - Update_SR_Register16_OverS32(); + X64Reg acc_full = RCX; + get_long_acc(reg, acc_full); + Update_SR_Register16_OverS32(accm, acc_full, RDX); } } @@ -493,14 +509,16 @@ void DSPEmitter::andi(const UDSPInstruction opc) // u16 imm = dsp_fetch_code(); const u16 imm = m_dsp_core.DSPState().ReadIMEM(m_compile_pc + 1); // g_dsp.r.acm[reg] &= imm; - get_acc_m(reg, RAX); - AND(16, R(RAX), Imm16(imm)); - set_acc_m(reg); + X64Reg accm = RAX; + get_acc_m(reg, accm); + AND(16, R(accm), Imm16(imm)); + set_acc_m(reg, R(accm)); // Update_SR_Register16((s16)g_dsp.r.acm[reg], false, false, isOverS32(dsp_get_long_acc(reg))); if (FlagsNeeded()) { - get_long_acc(reg, RCX); - Update_SR_Register16_OverS32(); + X64Reg acc_full = RCX; + get_long_acc(reg, acc_full); + Update_SR_Register16_OverS32(accm, acc_full, RDX); } } @@ -516,14 +534,16 @@ void DSPEmitter::ori(const UDSPInstruction opc) // u16 imm = dsp_fetch_code(); const u16 imm = m_dsp_core.DSPState().ReadIMEM(m_compile_pc + 1); // g_dsp.r.acm[reg] |= imm; - get_acc_m(reg, RAX); - OR(16, R(RAX), Imm16(imm)); - set_acc_m(reg); + X64Reg accm = RAX; + get_acc_m(reg, accm); + OR(16, R(accm), Imm16(imm)); + set_acc_m(reg, R(accm)); // Update_SR_Register16((s16)g_dsp.r.acm[reg], false, false, isOverS32(dsp_get_long_acc(reg))); if (FlagsNeeded()) { - get_long_acc(reg, RCX); - Update_SR_Register16_OverS32(); + X64Reg acc_full = RCX; + get_long_acc(reg, acc_full); + Update_SR_Register16_OverS32(accm, acc_full, RDX); } } diff --git a/Source/Core/Core/DSP/Jit/x64/DSPJitCCUtil.cpp b/Source/Core/Core/DSP/Jit/x64/DSPJitCCUtil.cpp index 30cd5d8497..3fd5a70646 100644 --- a/Source/Core/Core/DSP/Jit/x64/DSPJitCCUtil.cpp +++ b/Source/Core/Core/DSP/Jit/x64/DSPJitCCUtil.cpp @@ -114,7 +114,7 @@ void DSPEmitter::UpdateSR64AddSub(Gen::X64Reg val1, Gen::X64Reg val2, Gen::X64Re Update_SR_Register(result, scratch); } -// In: RAX: s64 _Value +// In: RAX: s16 _Value (middle) void DSPEmitter::Update_SR_Register16(X64Reg val) { const OpArg sr_reg = m_gpr.GetReg(DSP_REG_SR); @@ -122,7 +122,7 @@ void DSPEmitter::Update_SR_Register16(X64Reg val) // // 0x04 // if (_Value == 0) g_dsp.r[DSP_REG_SR] |= SR_ARITH_ZERO; - TEST(64, R(val), R(val)); + TEST(16, R(val), R(val)); FixupBranch notZero = J_CC(CC_NZ); OR(16, sr_reg, Imm16(SR_ARITH_ZERO | SR_TOP2BITS)); FixupBranch end = J(); @@ -149,26 +149,25 @@ void DSPEmitter::Update_SR_Register16(X64Reg val) m_gpr.PutReg(DSP_REG_SR); } -// In: RAX: s64 _Value -// Clobbers RCX -void DSPEmitter::Update_SR_Register16_OverS32(Gen::X64Reg val) +// In: RAX: s16 _Value (middle) +// In: RDX: s64 _FullValue +// Clobbers scratch +void DSPEmitter::Update_SR_Register16_OverS32(Gen::X64Reg val, Gen::X64Reg full_val, + Gen::X64Reg scratch) { + Update_SR_Register16(val); + const OpArg sr_reg = m_gpr.GetReg(DSP_REG_SR); - AND(16, sr_reg, Imm16(~SR_CMP_MASK)); // // 0x10 - // if (_Value != (s32)_Value) g_dsp.r[DSP_REG_SR] |= SR_OVER_S32; - MOVSX(64, 32, RCX, R(val)); - CMP(64, R(RCX), R(val)); + // if (_FullValue != (s32)_FullValue) g_dsp.r[DSP_REG_SR] |= SR_OVER_S32; + MOVSX(64, 32, scratch, R(full_val)); + CMP(64, R(scratch), R(full_val)); FixupBranch noOverS32 = J_CC(CC_E); OR(16, sr_reg, Imm16(SR_OVER_S32)); SetJumpTarget(noOverS32); m_gpr.PutReg(DSP_REG_SR); - // // 0x20 - Checks if top bits of m are equal - // if ((((u16)_Value >> 14) == 0) || (((u16)_Value >> 14) == 3)) - // AND(32, R(val), Imm32(0xc0000000)); - Update_SR_Register16(val); } } // namespace DSP::JIT::x64