From e3b424facdcf21b06cbe5e75c0e437b6e690b401 Mon Sep 17 00:00:00 2001 From: Sintendo Date: Sun, 16 Sep 2018 22:02:41 +0200 Subject: [PATCH 1/3] EmuCodeBlock: remove redundant instructions Their result is overwritten by a subsequent MOV. --- Source/Core/Core/PowerPC/Jit64Common/EmuCodeBlock.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/Source/Core/Core/PowerPC/Jit64Common/EmuCodeBlock.cpp b/Source/Core/Core/PowerPC/Jit64Common/EmuCodeBlock.cpp index 77cccda463..f726ce0c10 100644 --- a/Source/Core/Core/PowerPC/Jit64Common/EmuCodeBlock.cpp +++ b/Source/Core/Core/PowerPC/Jit64Common/EmuCodeBlock.cpp @@ -1056,8 +1056,6 @@ void EmuCodeBlock::SetFPRF(Gen::X64Reg xmm) MScaled(RSCRATCH, Common::PPC_FPCLASS_NN - Common::PPC_FPCLASS_PN, Common::PPC_FPCLASS_PN)); continue1 = J(); SetJumpTarget(nan); - MOVQ_xmm(R(RSCRATCH), xmm); - SHR(64, R(RSCRATCH), Imm8(63)); MOV(32, R(RSCRATCH), Imm32(Common::PPC_FPCLASS_QNAN)); continue2 = J(); SetJumpTarget(infinity); From ef94fca5040ecc1e80efba34e343a2ea953f0b17 Mon Sep 17 00:00:00 2001 From: Sintendo Date: Sun, 16 Sep 2018 23:29:22 +0200 Subject: [PATCH 2/3] DSPJit: various micro-optimizations --- .../Core/Core/DSP/Jit/x64/DSPJitArithmetic.cpp | 18 +++++++----------- Source/Core/Core/DSP/Jit/x64/DSPJitUtil.cpp | 4 +--- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/Source/Core/Core/DSP/Jit/x64/DSPJitArithmetic.cpp b/Source/Core/Core/DSP/Jit/x64/DSPJitArithmetic.cpp index 7c159085d7..8e54bd60aa 100644 --- a/Source/Core/Core/DSP/Jit/x64/DSPJitArithmetic.cpp +++ b/Source/Core/Core/DSP/Jit/x64/DSPJitArithmetic.cpp @@ -23,7 +23,7 @@ void DSPEmitter::clr(const UDSPInstruction opc) { u8 reg = (opc >> 11) & 0x1; // dsp_set_long_acc(reg, 0); - MOV(64, R(RAX), Imm64(0)); + XOR(32, R(EAX), R(EAX)); set_long_acc(reg); // Update_SR_Register64(0); if (FlagsNeeded()) @@ -431,7 +431,7 @@ void DSPEmitter::notc(const UDSPInstruction opc) u8 dreg = (opc >> 8) & 0x1; // u16 accm = g_dsp.r.acm[dreg] ^ 0xffff; get_acc_m(dreg, RAX); - XOR(16, R(RAX), Imm16(0xffff)); + NOT(16, R(AX)); // g_dsp.r.acm[dreg] = accm; set_acc_m(dreg); // Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg))); @@ -770,9 +770,8 @@ void DSPEmitter::incm(const UDSPInstruction opc) X64Reg tmp1 = m_gpr.GetFreeXReg(); // s64 acc = dsp_get_long_acc(dreg); get_long_acc(dreg, tmp1); - MOV(64, R(RAX), R(tmp1)); // s64 res = acc + sub; - ADD(64, R(RAX), Imm32((u32)subtract)); + LEA(64, RAX, MDisp(tmp1, subtract)); // dsp_set_long_acc(dreg, res); // res = dsp_get_long_acc(dreg); // Update_SR_Register64(res, isCarry(acc, res), isOverflow(acc, subtract, res)); @@ -801,9 +800,8 @@ void DSPEmitter::inc(const UDSPInstruction opc) X64Reg tmp1 = m_gpr.GetFreeXReg(); // s64 acc = dsp_get_long_acc(dreg); get_long_acc(dreg, tmp1); - MOV(64, R(RAX), R(tmp1)); // s64 res = acc + 1; - ADD(64, R(RAX), Imm8(1)); + LEA(64, RAX, MDisp(tmp1, 1)); // dsp_set_long_acc(dreg, res); // res = dsp_get_long_acc(dreg); // Update_SR_Register64(res, isCarry(acc, res), isOverflow(acc, 1, res)); @@ -973,9 +971,8 @@ void DSPEmitter::decm(const UDSPInstruction opc) X64Reg tmp1 = m_gpr.GetFreeXReg(); // s64 acc = dsp_get_long_acc(dreg); get_long_acc(dreg, tmp1); - MOV(64, R(RAX), R(tmp1)); // s64 res = acc - sub; - SUB(64, R(RAX), Imm32((u32)subtract)); + LEA(64, RAX, MDisp(tmp1, -subtract)); // dsp_set_long_acc(dreg, res); // res = dsp_get_long_acc(dreg); // Update_SR_Register64(res, isCarry2(acc, res), isOverflow(acc, -subtract, res)); @@ -1004,9 +1001,8 @@ void DSPEmitter::dec(const UDSPInstruction opc) X64Reg tmp1 = m_gpr.GetFreeXReg(); // s64 acc = dsp_get_long_acc(dreg); get_long_acc(dreg, tmp1); - MOV(64, R(RAX), R(tmp1)); // s64 res = acc - 1; - SUB(64, R(RAX), Imm32(1)); + LEA(64, RAX, MDisp(tmp1, -1)); // dsp_set_long_acc(dreg, res); // res = dsp_get_long_acc(dreg); // Update_SR_Register64(res, isCarry2(acc, res), isOverflow(acc, -1, res)); @@ -1175,7 +1171,7 @@ void DSPEmitter::lsr16(const UDSPInstruction opc) // causes // acc >>= 16; SHR(64, R(RAX), Imm8(16)); - AND(64, R(RAX), Imm32(0xffffff)); + AND(32, R(EAX), Imm32(0xffffff)); // dsp_set_long_acc(areg, (s64)acc); set_long_acc(areg); // Update_SR_Register64(dsp_get_long_acc(areg)); diff --git a/Source/Core/Core/DSP/Jit/x64/DSPJitUtil.cpp b/Source/Core/Core/DSP/Jit/x64/DSPJitUtil.cpp index f9a95b534e..630fc249d5 100644 --- a/Source/Core/Core/DSP/Jit/x64/DSPJitUtil.cpp +++ b/Source/Core/Core/DSP/Jit/x64/DSPJitUtil.cpp @@ -264,7 +264,7 @@ void DSPEmitter::dsp_op_read_reg(int reg, Gen::X64Reg host_dreg, RegisterExtensi CMP(64, R(host_dreg), acc_reg); FixupBranch no_saturate = J_CC(CC_Z); - CMP(64, acc_reg, Imm32(0)); + TEST(64, acc_reg, acc_reg); FixupBranch negative = J_CC(CC_LE); MOV(64, R(host_dreg), Imm32(0x7fff)); // this works for all extend modes @@ -594,7 +594,6 @@ void DSPEmitter::dmem_read(X64Reg address) FixupBranch dram = J_CC(CC_A); // return g_dsp.dram[addr & DSP_DRAM_MASK]; AND(32, R(address), Imm32(DSP_DRAM_MASK)); - MOVZX(64, 16, address, R(address)); MOV(64, R(ECX), ImmPtr(g_dsp.dram)); MOV(16, R(EAX), MComplex(ECX, address, SCALE_2, 0)); @@ -605,7 +604,6 @@ void DSPEmitter::dmem_read(X64Reg address) FixupBranch ifx = J_CC(CC_A); // return g_dsp.coef[addr & DSP_COEF_MASK]; AND(32, R(address), Imm32(DSP_COEF_MASK)); - MOVZX(64, 16, address, R(address)); MOV(64, R(ECX), ImmPtr(g_dsp.coef)); MOV(16, R(EAX), MComplex(ECX, address, SCALE_2, 0)); From d8953dbe57faeb25fe6a9da42fa5cfec0373ac69 Mon Sep 17 00:00:00 2001 From: Sintendo Date: Sun, 16 Sep 2018 23:34:27 +0200 Subject: [PATCH 3/3] x64Emitter: nit, use helper method in CMP_or_TEST --- Source/Core/Common/x64Emitter.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Source/Core/Common/x64Emitter.cpp b/Source/Core/Common/x64Emitter.cpp index d419f32af5..cc243810c1 100644 --- a/Source/Core/Common/x64Emitter.cpp +++ b/Source/Core/Common/x64Emitter.cpp @@ -1602,8 +1602,7 @@ void XEmitter::XCHG(int bits, const OpArg& a1, const OpArg& a2) void XEmitter::CMP_or_TEST(int bits, const OpArg& a1, const OpArg& a2) { CheckFlags(); - if (a1.IsSimpleReg() && a2.IsImm() && - a2.offset == 0) // turn 'CMP reg, 0' into shorter 'TEST reg, reg' + if (a1.IsSimpleReg() && a2.IsZero()) // turn 'CMP reg, 0' into shorter 'TEST reg, reg' { WriteNormalOp(bits, NormalOp::TEST, a1, a1); }