diff --git a/Source/Core/DSPCore/Src/Jit/DSPJitUtil.cpp b/Source/Core/DSPCore/Src/Jit/DSPJitUtil.cpp index 8c7edd5704..8af87b55ce 100644 --- a/Source/Core/DSPCore/Src/Jit/DSPJitUtil.cpp +++ b/Source/Core/DSPCore/Src/Jit/DSPJitUtil.cpp @@ -63,7 +63,7 @@ void DSPEmitter::increment_addr_reg(int reg) // if ((tmp & tmb) == tmb) AND(16, R(ECX), R(EAX)); CMP(16, R(EAX), R(ECX)); - FixupBranch not_equal = J_CC(CC_NZ); + FixupBranch not_equal = J_CC(CC_NE); // tmp ^= g_dsp.r[DSP_REG_WR0 + reg]; MOVZX(32, 16, ECX, M(&g_dsp.r[reg])); @@ -155,8 +155,6 @@ void DSPEmitter::increase_addr_reg(int reg) SetJumpTarget(posValue); SetJumpTarget(end); - - MOV(16, M(&g_dsp.r[reg]), R(EDX)); } // Decrease addr register according to the correspond ix register @@ -164,38 +162,35 @@ void DSPEmitter::decrease_addr_reg(int reg) { // s16 value = (s16)g_dsp.r[DSP_REG_IX0 + reg]; MOVSX(32, 16, EDX, M(&g_dsp.r[DSP_REG_IX0 + reg])); + XOR(32, R(ESI), R(ESI)); // i = 0 // if (value > 0) - CMP(16, R(EDX), Imm16(0)); - FixupBranch end = J_CC(CC_Z); + CMP(32, R(EDX), Imm32(0)); + FixupBranch end = J_CC(CC_Z, true); FixupBranch negValue = J_CC(CC_L); // for (int i = 0; i < value; i++) - XOR(32, R(ESI), R(ESI)); // i = 0 - - FixupBranch posloop; - SetJumpTarget(posloop); - + JumpTarget loop_pos = GetCodePtr(); decrement_addr_reg(reg); ADD(32, R(ESI), Imm32(1)); // i++ CMP(32, R(ESI), R(EDX)); // i < value - + J_CC(CC_NE, loop_pos); FixupBranch posValue = J(); - // FIXME: get normal abs with cdq - IMUL(32, EDX, Imm16(-1)); + + SetJumpTarget(negValue); + //abs == cdq; xor eax, edx; sub eax, edx + //we know its negative, and in that case edx is -1 + XOR(32, R(EDX), Imm32(-1)); + SUB(32, R(EDX), Imm32(-1)); // for (int i = 0; i < (int)(-value); i++) - XOR(32, R(ESI), R(ESI)); // i = 0 - - FixupBranch negloop; - SetJumpTarget(negloop); - + JumpTarget loop_neg = GetCodePtr(); increment_addr_reg(reg); + ADD(32, R(ESI), Imm32(1)); // i++ CMP(32, R(ESI), R(EDX)); // i < -value - - negloop = J_CC(CC_L); + J_CC(CC_NE, loop_neg); SetJumpTarget(posValue); SetJumpTarget(end); @@ -203,7 +198,6 @@ void DSPEmitter::decrease_addr_reg(int reg) void DSPEmitter::ext_dmem_write(u32 dest, u32 src) { - // u16 addr = g_dsp.r[dest]; MOVZX(32, 16, EAX, M(&g_dsp.r[dest])); diff --git a/Source/UnitTests/AudioJitTests.cpp b/Source/UnitTests/AudioJitTests.cpp index 60597c9512..295ec0e815 100644 --- a/Source/UnitTests/AudioJitTests.cpp +++ b/Source/UnitTests/AudioJitTests.cpp @@ -47,7 +47,7 @@ void nx_ir() void nx_nr() { SDSP test_dsp; - DSPJitTester tester(0x40, 0x0c, true); + DSPJitTester tester(0x40, 0x0c); for (u16 input_reg = 0; input_reg < 10; input_reg++) for (u16 input_wr0 = 0; input_wr0 < 10; input_wr0++) @@ -74,7 +74,7 @@ void AudioJitTests() nx_ir(); nx_dr(); - //nx_nr(); + nx_nr(); } //required to be able to link against DSPCore diff --git a/Source/UnitTests/DSPJitTester.cpp b/Source/UnitTests/DSPJitTester.cpp index 4be7ccf50b..2c1467f485 100644 --- a/Source/UnitTests/DSPJitTester.cpp +++ b/Source/UnitTests/DSPJitTester.cpp @@ -1,5 +1,15 @@ #include "DSPJitTester.h" +DSPJitTester::DSPJitTester(u16 opcode, u16 opcode_ext, bool verbose) + : be_verbose(verbose), run_count(0), fail_count(0) +{ + instruction = opcode << 9 | opcode_ext; + opcode_template = GetOpTemplate(instruction); + sprintf(instruction_name, "%s", opcode_template->name); + if (opcode_template->extended) + sprintf(&instruction_name[strlen(instruction_name)], "'%s", + extOpTable[instruction & (((instruction >> 12) == 0x3) ? 0x7F : 0xFF)]->name); +} bool DSPJitTester::Test(SDSP dsp_settings) { if (be_verbose) @@ -64,6 +74,18 @@ void DSPJitTester::Report() { printf("%s (0x%04x): Ran %d times, Failed %d times.\n", instruction_name, instruction, run_count, fail_count); } +void DSPJitTester::DumpJittedCode() +{ + ResetJit(); + const u8* code = jit.GetCodePtr(); + jit.WriteCallInterpreter(instruction); + int code_size = jit.GetCodePtr() - code; + + printf("%s emitted: ", instruction_name); + for (int i = 0; i < code_size; i++) + printf("%02x ", code[i]); + printf("\n"); +} void DSPJitTester::Initialize() { //init int diff --git a/Source/UnitTests/DSPJitTester.h b/Source/UnitTests/DSPJitTester.h index cd9dd5c217..b1e3360329 100644 --- a/Source/UnitTests/DSPJitTester.h +++ b/Source/UnitTests/DSPJitTester.h @@ -21,16 +21,7 @@ class DSPJitTester bool AreEqual(SDSP&, SDSP&); public: - DSPJitTester(u16 opcode, u16 opcode_ext, bool verbose = false) - : be_verbose(verbose), run_count(0), fail_count(0) - { - instruction = opcode << 9 | opcode_ext; - opcode_template = GetOpTemplate(instruction); - sprintf(instruction_name, "%s", opcode_template->name); - if (opcode_template->extended) - sprintf(&instruction_name[strlen(instruction_name)], "'%s", - extOpTable[instruction & (((instruction >> 12) == 0x3) ? 0x7F : 0xFF)]->name); - } + DSPJitTester(u16 opcode, u16 opcode_ext, bool verbose = false); bool Test(SDSP); SDSP RunInterpreter(SDSP); SDSP RunJit(SDSP); @@ -42,6 +33,7 @@ public: inline int GetFailCount() { return fail_count; } inline const char* GetInstructionName() { return instruction_name; } void Report(); + void DumpJittedCode(); static void Initialize(); };