diff --git a/Source/Core/DSPCore/Src/Jit/DSPJitExtOps.cpp b/Source/Core/DSPCore/Src/Jit/DSPJitExtOps.cpp index 389310f3a5..b59f37d5f1 100644 --- a/Source/Core/DSPCore/Src/Jit/DSPJitExtOps.cpp +++ b/Source/Core/DSPCore/Src/Jit/DSPJitExtOps.cpp @@ -531,8 +531,15 @@ void DSPEmitter::pushExtValueFromMem(u16 dreg, u16 sreg) { } void DSPEmitter::popExtValueToReg() { + // in practise, we rarely ever have a non-NX main op + // with an extended op, so the OR here is either + // not run (storeIndex == -1) or ends up OR'ing + // EBX with 0 (becoming the MOV we have here) + // nakee wants to keep it clean, so lets do that. + // [nakeee] the or case never happens in real + // [nakeee] it's just how the hardware works so we added it if (storeIndex != -1) - OR(16, M(&g_dsp.r[storeIndex]), R(EBX)); + MOV(16, M(&g_dsp.r[storeIndex]), R(EBX)); storeIndex = -1; // TODO handle commands such as 'l diff --git a/Source/Core/DSPCore/Src/Jit/DSPJitUtil.cpp b/Source/Core/DSPCore/Src/Jit/DSPJitUtil.cpp index f6bf093128..b8ea950f1d 100644 --- a/Source/Core/DSPCore/Src/Jit/DSPJitUtil.cpp +++ b/Source/Core/DSPCore/Src/Jit/DSPJitUtil.cpp @@ -53,7 +53,7 @@ void DSPEmitter::increment_addr_reg(int reg) MOV(16, R(EAX), M(&g_dsp.r[reg])); MOV(16, R(EDX), M(&g_dsp.r[DSP_REG_WR0 + reg])); - //ToMask(WR0), calculating it into EDI + // ToMask(WR0), calculating it into EDI MOV(16, R(EDI), R(EDX)); ToMask(EDI); @@ -63,8 +63,8 @@ void DSPEmitter::increment_addr_reg(int reg) CMP(16, R(ESI), R(EDI)); FixupBranch not_equal = J_CC(CC_NE); - // tmp ^= wr_reg - XOR(16, R(EAX), R(EDX)); + // tmp -= wr_reg + SUB(16, R(EAX), R(EDX)); FixupBranch end = J(); SetJumpTarget(not_equal); @@ -77,27 +77,40 @@ void DSPEmitter::increment_addr_reg(int reg) MOV(16, M(&g_dsp.r[reg]), R(EAX)); } - // See http://code.google.com/p/dolphin-emu/source/detail?r=3125 // EAX = g_dsp.r[reg] // EDX = g_dsp.r[DSP_REG_WR0 + reg] void DSPEmitter::decrement_addr_reg(int reg) { - // s16 tmp = g_dsp.r[reg]; + // s16 ar = g_dsp.r[reg]; MOV(16, R(EAX), M(&g_dsp.r[reg])); MOV(16, R(EDX), M(&g_dsp.r[DSP_REG_WR0 + reg])); - // if ((tmp & g_dsp.r[DSP_REG_WR0 + reg]) == 0) - TEST(16, R(EAX), R(EDX)); - FixupBranch not_equal = J_CC(CC_NZ); + // ToMask(WR0), calculating it into EDI + MOV(16, R(EDI), R(EDX)); + ToMask(EDI); - // tmp |= g_dsp.r[DSP_REG_WR0 + reg]; - OR(16, R(EAX), R(EDX)); + //compute min from EDI and EAX + // min = (tmb+1-ar)&tmb; + LEA(16, ESI, MDisp(EDI, 1)); + SUB(16, R(ESI), R(EAX)); + AND(16, R(ESI), R(EDI)); - FixupBranch end = J(); - SetJumpTarget(not_equal); - // tmp--; + // wr < min + CMP(16, R(EDX), R(ESI)); + FixupBranch wr_lt_min = J_CC(CC_B); + // !min + TEST(16, R(ESI), R(ESI)); + FixupBranch min_zero = J_CC(CC_Z); + + // ar--; SUB(16, R(EAX), Imm16(1)); + FixupBranch end = J(); + + // ar += wr; + SetJumpTarget(wr_lt_min); + SetJumpTarget(min_zero); + ADD(16, R(EAX), R(EDX)); SetJumpTarget(end);