From 93a09ee7b569d0edfa6967b947095e7c464160dc Mon Sep 17 00:00:00 2001 From: skidau Date: Thu, 16 Dec 2010 23:27:38 +0000 Subject: [PATCH] LLE JIT: * Added jit versions of 5 DSP LoadStore instructions: srs, lrs, lr, sr, si * Renamed MainOpFallback to Default for consistency in naming with JIT64 * Made ext_dmem_read and ext_dmem_write more generic for wider use * Optimised dmem_read and dmem_write slightly * Added dmem_read_imm and dmem_write_imm optimised versions git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6596 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/DSPCore/CMakeLists.txt | 1 + Source/Core/DSPCore/DSPCore.vcproj | 4 + Source/Core/DSPCore/Src/DSPEmitter.cpp | 9 +- Source/Core/DSPCore/Src/DSPEmitter.h | 16 ++- Source/Core/DSPCore/Src/DSPTables.cpp | 42 +++--- .../Core/DSPCore/Src/Jit/DSPJitArithmetic.cpp | 6 +- Source/Core/DSPCore/Src/Jit/DSPJitBranch.cpp | 4 + Source/Core/DSPCore/Src/Jit/DSPJitExtOps.cpp | 130 +++++++++++++++--- Source/Core/DSPCore/Src/Jit/DSPJitMisc.cpp | 18 +-- .../Core/DSPCore/Src/Jit/DSPJitMultiplier.cpp | 36 ++--- Source/Core/DSPCore/Src/Jit/DSPJitUtil.cpp | 99 +++++++------ Source/Core/DSPCore/Src/SConscript | 1 + 12 files changed, 239 insertions(+), 127 deletions(-) diff --git a/Source/Core/DSPCore/CMakeLists.txt b/Source/Core/DSPCore/CMakeLists.txt index 1089b129ae..ed422ef986 100644 --- a/Source/Core/DSPCore/CMakeLists.txt +++ b/Source/Core/DSPCore/CMakeLists.txt @@ -22,6 +22,7 @@ set(SRCS Src/assemble.cpp Src/Jit/DSPJitBranch.cpp Src/Jit/DSPJitCCUtil.cpp Src/Jit/DSPJitArithmetic.cpp + Src/Jit/DSPJitLoadStore.cpp Src/Jit/DSPJitMultiplier.cpp Src/Jit/DSPJitUtil.cpp Src/Jit/DSPJitMisc.cpp) diff --git a/Source/Core/DSPCore/DSPCore.vcproj b/Source/Core/DSPCore/DSPCore.vcproj index f9d9dd90ab..fada6bf602 100644 --- a/Source/Core/DSPCore/DSPCore.vcproj +++ b/Source/Core/DSPCore/DSPCore.vcproj @@ -462,6 +462,10 @@ RelativePath=".\Src\Jit\DSPJitArithmetic.cpp" > + + diff --git a/Source/Core/DSPCore/Src/DSPEmitter.cpp b/Source/Core/DSPCore/Src/DSPEmitter.cpp index d251a8ce75..89c2abcfa0 100644 --- a/Source/Core/DSPCore/Src/DSPEmitter.cpp +++ b/Source/Core/DSPCore/Src/DSPEmitter.cpp @@ -112,7 +112,7 @@ void DSPEmitter::checkExceptions(u32 retval) SetJumpTarget(skipCheck); } -void DSPEmitter::MainOpFallback(UDSPInstruction inst) +void DSPEmitter::Default(UDSPInstruction inst) { if (opTable[inst]->reads_pc) { @@ -161,7 +161,7 @@ void DSPEmitter::EmitInstruction(UDSPInstruction inst) // Main instruction if (!opTable[inst]->jitFunc) { - MainOpFallback(inst); + Default(inst); } else { @@ -185,11 +185,6 @@ void DSPEmitter::unknown_instruction(UDSPInstruction inst) PanicAlert("unknown_instruction %04x - Fix me ;)", inst); } -void DSPEmitter::Default(UDSPInstruction _inst) -{ - EmitInstruction(_inst); -} - void DSPEmitter::ClearCallFlag() { DSPAnalyzer::code_flags[startAddr] &= ~DSPAnalyzer::CODE_CALL; diff --git a/Source/Core/DSPCore/Src/DSPEmitter.h b/Source/Core/DSPCore/Src/DSPEmitter.h index 0571f87f6d..5884cd50ce 100644 --- a/Source/Core/DSPCore/Src/DSPEmitter.h +++ b/Source/Core/DSPCore/Src/DSPEmitter.h @@ -37,7 +37,6 @@ public: void EmitInstruction(UDSPInstruction inst); void unknown_instruction(UDSPInstruction inst); - void Default(UDSPInstruction _inst); void ClearIRAM(); void CompileDispatcher(); @@ -45,7 +44,7 @@ public: void Compile(int start_addr); void ClearCallFlag(); - void MainOpFallback(UDSPInstruction inst); + void Default(UDSPInstruction inst); int STACKALIGN RunForCycles(int cycles); @@ -62,8 +61,10 @@ public: void decrement_addr_reg(int reg); void increase_addr_reg(int reg); void decrease_addr_reg(int reg); - void ext_dmem_write(u32 src, u32 dest); - void ext_dmem_read(u16 addr); + void dmem_write(); + void dmem_write_imm(u16 addr); + void dmem_read(); + void dmem_read_imm(u16 addr); // Ext command helpers void pushExtValueFromReg(u16 dreg, u16 sreg); @@ -125,6 +126,13 @@ public: void call(const UDSPInstruction opc); void callr(const UDSPInstruction opc); + // Load/Store + void srs(const UDSPInstruction opc); + void lrs(const UDSPInstruction opc); + void lr(const UDSPInstruction opc); + void sr(const UDSPInstruction opc); + void si(const UDSPInstruction opc); + // Arithmetic void addr(const UDSPInstruction opc); void lsl16(const UDSPInstruction opc); diff --git a/Source/Core/DSPCore/Src/DSPTables.cpp b/Source/Core/DSPCore/Src/DSPTables.cpp index 41594bd7c7..6ed6e86925 100644 --- a/Source/Core/DSPCore/Src/DSPTables.cpp +++ b/Source/Core/DSPCore/Src/DSPTables.cpp @@ -95,22 +95,22 @@ const DSPOPCTemplate opcodes[] = {"IFO", 0x027e, 0xffff, DSPInterpreter::ifcc, NULL, 1, 0, {}, false, true, false, true}, {"IF", 0x027f, 0xffff, DSPInterpreter::ifcc, NULL, 1, 0, {}, false, true, true, true}, - {"JGE", 0x0290, 0xffff, DSPInterpreter::jcc, NULL, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true}, - {"JL", 0x0291, 0xffff, DSPInterpreter::jcc, NULL, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true}, - {"JG", 0x0292, 0xffff, DSPInterpreter::jcc, NULL, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true}, - {"JLE", 0x0293, 0xffff, DSPInterpreter::jcc, NULL, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true}, - {"JNZ", 0x0294, 0xffff, DSPInterpreter::jcc, NULL, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true}, - {"JZ", 0x0295, 0xffff, DSPInterpreter::jcc, NULL, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true}, - {"JNC", 0x0296, 0xffff, DSPInterpreter::jcc, NULL, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true}, - {"JC", 0x0297, 0xffff, DSPInterpreter::jcc, NULL, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true}, - {"JMPx8", 0x0298, 0xffff, DSPInterpreter::jcc, NULL, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true}, - {"JMPx9", 0x0299, 0xffff, DSPInterpreter::jcc, NULL, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true}, - {"JMPxA", 0x029a, 0xffff, DSPInterpreter::jcc, NULL, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true}, - {"JMPxB", 0x029b, 0xffff, DSPInterpreter::jcc, NULL, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true}, - {"JLNZ", 0x029c, 0xffff, DSPInterpreter::jcc, NULL, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true}, - {"JLZ", 0x029d, 0xffff, DSPInterpreter::jcc, NULL, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true}, - {"JO", 0x029e, 0xffff, DSPInterpreter::jcc, NULL, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true}, - {"JMP", 0x029f, 0xffff, DSPInterpreter::jcc, NULL, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, true, true}, + {"JGE", 0x0290, 0xffff, DSPInterpreter::jcc, &DSPEmitter::jcc, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true}, + {"JL", 0x0291, 0xffff, DSPInterpreter::jcc, &DSPEmitter::jcc, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true}, + {"JG", 0x0292, 0xffff, DSPInterpreter::jcc, &DSPEmitter::jcc, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true}, + {"JLE", 0x0293, 0xffff, DSPInterpreter::jcc, NULL/*&DSPEmitter::jcc*/, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true}, + {"JNZ", 0x0294, 0xffff, DSPInterpreter::jcc, &DSPEmitter::jcc, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true}, + {"JZ", 0x0295, 0xffff, DSPInterpreter::jcc, &DSPEmitter::jcc, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true}, + {"JNC", 0x0296, 0xffff, DSPInterpreter::jcc, &DSPEmitter::jcc, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true}, + {"JC", 0x0297, 0xffff, DSPInterpreter::jcc, &DSPEmitter::jcc, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true}, + {"JMPx8", 0x0298, 0xffff, DSPInterpreter::jcc, &DSPEmitter::jcc, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true}, + {"JMPx9", 0x0299, 0xffff, DSPInterpreter::jcc, &DSPEmitter::jcc, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true}, + {"JMPxA", 0x029a, 0xffff, DSPInterpreter::jcc, NULL/*&DSPEmitter::jcc*/, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true}, + {"JMPxB", 0x029b, 0xffff, DSPInterpreter::jcc, NULL/*&DSPEmitter::jcc*/, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true}, + {"JLNZ", 0x029c, 0xffff, DSPInterpreter::jcc, &DSPEmitter::jcc, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true}, + {"JLZ", 0x029d, 0xffff, DSPInterpreter::jcc, &DSPEmitter::jcc, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true}, + {"JO", 0x029e, 0xffff, DSPInterpreter::jcc, &DSPEmitter::jcc, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true}, + {"JMP", 0x029f, 0xffff, DSPInterpreter::jcc, &DSPEmitter::jcc, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, true, true}, {"JRGE", 0x1700, 0xff1f, DSPInterpreter::jmprcc, &DSPEmitter::jmprcc, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, false, true, false, false}, {"JRL", 0x1701, 0xff1f, DSPInterpreter::jmprcc, &DSPEmitter::jmprcc, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, false, true, false, false}, @@ -158,12 +158,12 @@ const DSPOPCTemplate opcodes[] = {"ASRN", 0x02cb, 0xffff, DSPInterpreter::asrn, NULL, 1, 0, {}, false, false, false, false}, // discovered by ector! {"LRI", 0x0080, 0xffe0, DSPInterpreter::lri, &DSPEmitter::lri, 2, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_IMM, 2, 1, 0, 0xffff}}, false, false, false, true}, - {"LR", 0x00c0, 0xffe0, DSPInterpreter::lr, NULL, 2, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_MEM, 2, 1, 0, 0xffff}}, false, false, false, true}, - {"SR", 0x00e0, 0xffe0, DSPInterpreter::sr, NULL, 2, 2, {{P_MEM, 2, 1, 0, 0xffff}, {P_REG, 1, 0, 0, 0x001f}}, false, false, false, true}, + {"LR", 0x00c0, 0xffe0, DSPInterpreter::lr, &DSPEmitter::lr, 2, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_MEM, 2, 1, 0, 0xffff}}, false, false, false, true}, + {"SR", 0x00e0, 0xffe0, DSPInterpreter::sr, &DSPEmitter::sr, 2, 2, {{P_MEM, 2, 1, 0, 0xffff}, {P_REG, 1, 0, 0, 0x001f}}, false, false, false, true}, {"MRR", 0x1c00, 0xfc00, DSPInterpreter::mrr, &DSPEmitter::mrr, 1, 2, {{P_REG, 1, 0, 5, 0x03e0}, {P_REG, 1, 0, 0, 0x001f}}, false, false, false, false}, - {"SI", 0x1600, 0xff00, DSPInterpreter::si, NULL, 2, 2, {{P_MEM, 1, 0, 0, 0x00ff}, {P_IMM, 2, 1, 0, 0xffff}}, false, false, false, true}, + {"SI", 0x1600, 0xff00, DSPInterpreter::si, &DSPEmitter::si, 2, 2, {{P_MEM, 1, 0, 0, 0x00ff}, {P_IMM, 2, 1, 0, 0xffff}}, false, false, false, true}, {"ADDIS", 0x0400, 0xfe00, DSPInterpreter::addis, NULL, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x00ff}}, false, false, false, false}, {"CMPIS", 0x0600, 0xfe00, DSPInterpreter::cmpis, NULL, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x00ff}}, false, false, false, false}, @@ -201,8 +201,8 @@ const DSPOPCTemplate opcodes[] = {"SRRN", 0x1b80, 0xff80, DSPInterpreter::srrn, NULL, 1, 2, {{P_PRG, 1, 0, 5, 0x0060}, {P_REG, 1, 0, 0, 0x001f}}, false, false, false, false}, //2 - {"LRS", 0x2000, 0xf800, DSPInterpreter::lrs, NULL, 1, 2, {{P_REG18, 1, 0, 8, 0x0700}, {P_MEM, 1, 0, 0, 0x00ff}}, false, false, false, false}, - {"SRS", 0x2800, 0xf800, DSPInterpreter::srs, NULL, 1, 2, {{P_MEM, 1, 0, 0, 0x00ff}, {P_REG18, 1, 0, 8, 0x0700}}, false, false, false, false}, + {"LRS", 0x2000, 0xf800, DSPInterpreter::lrs, &DSPEmitter::lrs, 1, 2, {{P_REG18, 1, 0, 8, 0x0700}, {P_MEM, 1, 0, 0, 0x00ff}}, false, false, false, false}, + {"SRS", 0x2800, 0xf800, DSPInterpreter::srs, &DSPEmitter::srs, 1, 2, {{P_MEM, 1, 0, 0, 0x00ff}, {P_REG18, 1, 0, 8, 0x0700}}, false, false, false, false}, // opcodes that can be extended diff --git a/Source/Core/DSPCore/Src/Jit/DSPJitArithmetic.cpp b/Source/Core/DSPCore/Src/Jit/DSPJitArithmetic.cpp index c50fdb62e6..54924be7e6 100644 --- a/Source/Core/DSPCore/Src/Jit/DSPJitArithmetic.cpp +++ b/Source/Core/DSPCore/Src/Jit/DSPJitArithmetic.cpp @@ -414,7 +414,7 @@ void DSPEmitter::addr(const UDSPInstruction opc) Update_SR_Register64(); #else - MainOpFallback(opc); + Default(opc); #endif } @@ -821,7 +821,7 @@ void DSPEmitter::lsl16(const UDSPInstruction opc) // Update_SR_Register64(dsp_get_long_acc(areg)); Update_SR_Register64(); #else - MainOpFallback(opc); + Default(opc); #endif } @@ -883,7 +883,7 @@ void DSPEmitter::lsl(const UDSPInstruction opc) // Update_SR_Register64(dsp_get_long_acc(rreg)); Update_SR_Register64(); #else - MainOpFallback(opc); + Default(opc); #endif } diff --git a/Source/Core/DSPCore/Src/Jit/DSPJitBranch.cpp b/Source/Core/DSPCore/Src/Jit/DSPJitBranch.cpp index ed7b1dbed1..04769bfef3 100644 --- a/Source/Core/DSPCore/Src/Jit/DSPJitBranch.cpp +++ b/Source/Core/DSPCore/Src/Jit/DSPJitBranch.cpp @@ -178,6 +178,9 @@ void r_jcc(const UDSPInstruction opc, DSPEmitter& emitter) // address represented by value that follows this "jmp" instruction. void DSPEmitter::jcc(const UDSPInstruction opc) { + // Disabled as jcc has issues in games + Default(opc); return; +#if 0 #ifdef _M_IX86 // All32 MOV(16, M(&(g_dsp.pc)), Imm16(compilePC + 1)); #else @@ -185,6 +188,7 @@ void DSPEmitter::jcc(const UDSPInstruction opc) MOV(16, MDisp(RAX,0), Imm16(compilePC + 1)); #endif ReJitConditional(opc, *this); +#endif } void r_jmprcc(const UDSPInstruction opc, DSPEmitter& emitter) diff --git a/Source/Core/DSPCore/Src/Jit/DSPJitExtOps.cpp b/Source/Core/DSPCore/Src/Jit/DSPJitExtOps.cpp index a4229a7557..3bf0b87d46 100644 --- a/Source/Core/DSPCore/Src/Jit/DSPJitExtOps.cpp +++ b/Source/Core/DSPCore/Src/Jit/DSPJitExtOps.cpp @@ -79,8 +79,17 @@ void DSPEmitter::s(const UDSPInstruction opc) { u8 dreg = opc & 0x3; u8 sreg = ((opc >> 3) & 0x3) + DSP_REG_ACL0; - - ext_dmem_write(dreg, sreg); + // u16 addr = g_dsp.r[dest]; +#ifdef _M_IX86 // All32 + MOVZX(32, 16, EAX, M(&g_dsp.r[dreg])); + MOVZX(32, 16, ECX, M(&g_dsp.r[sreg])); +#else + MOV(64, R(R11), ImmPtr(&g_dsp.r)); + MOVZX(64, 16, EAX, MDisp(R11,dreg*2)); + MOVZX(64, 16, ECX, MDisp(R11,sreg*2)); +#endif + // u16 val = g_dsp.r[src]; + dmem_write(); increment_addr_reg(dreg); } @@ -92,8 +101,15 @@ void DSPEmitter::sn(const UDSPInstruction opc) { u8 dreg = opc & 0x3; u8 sreg = ((opc >> 3) & 0x3) + DSP_REG_ACL0; - - ext_dmem_write(dreg, sreg); +#ifdef _M_IX86 // All32 + MOVZX(32, 16, EAX, M(&g_dsp.r[dreg])); + MOVZX(32, 16, ECX, M(&g_dsp.r[sreg])); +#else + MOV(64, R(R11), ImmPtr(&g_dsp.r)); + MOVZX(64, 16, EAX, MDisp(R11,dreg*2)); + MOVZX(64, 16, ECX, MDisp(R11,sreg*2)); +#endif + dmem_write(); increase_addr_reg(dreg); } @@ -164,8 +180,15 @@ void DSPEmitter::ls(const UDSPInstruction opc) { u8 sreg = (opc & 0x1) + DSP_REG_ACM0; u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0; - - ext_dmem_write(DSP_REG_AR3, sreg); +#ifdef _M_IX86 // All32 + MOVZX(32, 16, EAX, M(&g_dsp.r[DSP_REG_AR3])); + MOVZX(32, 16, ECX, M(&g_dsp.r[sreg])); +#else + MOV(64, R(R11), ImmPtr(&g_dsp.r)); + MOVZX(64, 16, EAX, MDisp(R11,DSP_REG_AR3*2)); + MOVZX(64, 16, ECX, MDisp(R11,sreg*2)); +#endif + dmem_write(); pushExtValueFromMem(dreg, DSP_REG_AR0); @@ -184,8 +207,15 @@ void DSPEmitter::lsn(const UDSPInstruction opc) { u8 sreg = (opc & 0x1) + DSP_REG_ACM0; u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0; - - ext_dmem_write(DSP_REG_AR3, sreg); +#ifdef _M_IX86 // All32 + MOVZX(32, 16, EAX, M(&g_dsp.r[DSP_REG_AR3])); + MOVZX(32, 16, ECX, M(&g_dsp.r[sreg])); +#else + MOV(64, R(R11), ImmPtr(&g_dsp.r)); + MOVZX(64, 16, EAX, MDisp(R11,DSP_REG_AR3*2)); + MOVZX(64, 16, ECX, MDisp(R11,sreg*2)); +#endif + dmem_write(); pushExtValueFromMem(dreg, DSP_REG_AR0); @@ -203,8 +233,15 @@ void DSPEmitter::lsm(const UDSPInstruction opc) { u8 sreg = (opc & 0x1) + DSP_REG_ACM0; u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0; - - ext_dmem_write(DSP_REG_AR3, sreg); +#ifdef _M_IX86 // All32 + MOVZX(32, 16, EAX, M(&g_dsp.r[DSP_REG_AR3])); + MOVZX(32, 16, ECX, M(&g_dsp.r[sreg])); +#else + MOV(64, R(R11), ImmPtr(&g_dsp.r)); + MOVZX(64, 16, EAX, MDisp(R11,DSP_REG_AR3*2)); + MOVZX(64, 16, ECX, MDisp(R11,sreg*2)); +#endif + dmem_write(); pushExtValueFromMem(dreg, DSP_REG_AR0); @@ -223,8 +260,15 @@ void DSPEmitter::lsnm(const UDSPInstruction opc) { u8 sreg = (opc & 0x1) + DSP_REG_ACM0; u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0; - - ext_dmem_write(DSP_REG_AR3, sreg); +#ifdef _M_IX86 // All32 + MOVZX(32, 16, EAX, M(&g_dsp.r[DSP_REG_AR3])); + MOVZX(32, 16, ECX, M(&g_dsp.r[sreg])); +#else + MOV(64, R(R11), ImmPtr(&g_dsp.r)); + MOVZX(64, 16, EAX, MDisp(R11,DSP_REG_AR3*2)); + MOVZX(64, 16, ECX, MDisp(R11,sreg*2)); +#endif + dmem_write(); pushExtValueFromMem(dreg, DSP_REG_AR0); @@ -241,8 +285,15 @@ void DSPEmitter::sl(const UDSPInstruction opc) { u8 sreg = (opc & 0x1) + DSP_REG_ACM0; u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0; - - ext_dmem_write(DSP_REG_AR0, sreg); +#ifdef _M_IX86 // All32 + MOVZX(32, 16, EAX, M(&g_dsp.r[DSP_REG_AR0])); + MOVZX(32, 16, ECX, M(&g_dsp.r[sreg])); +#else + MOV(64, R(R11), ImmPtr(&g_dsp.r)); + MOVZX(64, 16, EAX, MDisp(R11,DSP_REG_AR0*2)); + MOVZX(64, 16, ECX, MDisp(R11,sreg*2)); +#endif + dmem_write(); pushExtValueFromMem(dreg, DSP_REG_AR3); @@ -260,8 +311,15 @@ void DSPEmitter::sln(const UDSPInstruction opc) { u8 sreg = (opc & 0x1) + DSP_REG_ACM0; u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0; - - ext_dmem_write(DSP_REG_AR0, sreg); +#ifdef _M_IX86 // All32 + MOVZX(32, 16, EAX, M(&g_dsp.r[DSP_REG_AR0])); + MOVZX(32, 16, ECX, M(&g_dsp.r[sreg])); +#else + MOV(64, R(R11), ImmPtr(&g_dsp.r)); + MOVZX(64, 16, EAX, MDisp(R11,DSP_REG_AR0*2)); + MOVZX(64, 16, ECX, MDisp(R11,sreg*2)); +#endif + dmem_write(); pushExtValueFromMem(dreg, DSP_REG_AR3); @@ -279,8 +337,15 @@ void DSPEmitter::slm(const UDSPInstruction opc) { u8 sreg = (opc & 0x1) + DSP_REG_ACM0; u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0; - - ext_dmem_write(DSP_REG_AR0, sreg); +#ifdef _M_IX86 // All32 + MOVZX(32, 16, EAX, M(&g_dsp.r[DSP_REG_AR0])); + MOVZX(32, 16, ECX, M(&g_dsp.r[sreg])); +#else + MOV(64, R(R11), ImmPtr(&g_dsp.r)); + MOVZX(64, 16, EAX, MDisp(R11,DSP_REG_AR0*2)); + MOVZX(64, 16, ECX, MDisp(R11,sreg*2)); +#endif + dmem_write(); pushExtValueFromMem(dreg, DSP_REG_AR3); @@ -298,8 +363,15 @@ void DSPEmitter::slnm(const UDSPInstruction opc) { u8 sreg = (opc & 0x1) + DSP_REG_ACM0; u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0; - - ext_dmem_write(DSP_REG_AR0, sreg); +#ifdef _M_IX86 // All32 + MOVZX(32, 16, EAX, M(&g_dsp.r[DSP_REG_AR0])); + MOVZX(32, 16, ECX, M(&g_dsp.r[sreg])); +#else + MOV(64, R(R11), ImmPtr(&g_dsp.r)); + MOVZX(64, 16, EAX, MDisp(R11,DSP_REG_AR0*2)); + MOVZX(64, 16, ECX, MDisp(R11,sreg*2)); +#endif + dmem_write(); pushExtValueFromMem(dreg, DSP_REG_AR3); @@ -566,14 +638,28 @@ void DSPEmitter::pushExtValueFromReg(u16 dreg, u16 sreg) { } void DSPEmitter::pushExtValueFromMem(u16 dreg, u16 sreg) { - ext_dmem_read(sreg); + // u16 addr = g_dsp.r[addr]; +#ifdef _M_IX86 // All32 + MOVZX(32, 16, ECX, M(&g_dsp.r[sreg])); +#else + MOV(64, R(R11), ImmPtr(&g_dsp.r)); + MOVZX(64, 16, ECX, MDisp(R11,sreg*2)); +#endif + dmem_read(); MOVZX(32, 16, EBX, R(EAX)); storeIndex = dreg; } void DSPEmitter::pushExtValueFromMem2(u16 dreg, u16 sreg) { - ext_dmem_read(sreg); + // u16 addr = g_dsp.r[addr]; +#ifdef _M_IX86 // All32 + MOVZX(32, 16, ECX, M(&g_dsp.r[sreg])); +#else + MOV(64, R(R11), ImmPtr(&g_dsp.r)); + MOVZX(64, 16, ECX, MDisp(R11,sreg*2)); +#endif + dmem_read(); SHL(32,R(EAX),Imm8(16)); OR(32, R(EBX), R(EAX)); diff --git a/Source/Core/DSPCore/Src/Jit/DSPJitMisc.cpp b/Source/Core/DSPCore/Src/Jit/DSPJitMisc.cpp index 6d3ccee855..9eee86dfb9 100644 --- a/Source/Core/DSPCore/Src/Jit/DSPJitMisc.cpp +++ b/Source/Core/DSPCore/Src/Jit/DSPJitMisc.cpp @@ -108,7 +108,7 @@ void DSPEmitter::dsp_reg_store_stack(int stack_reg, Gen::X64Reg host_sreg) #ifdef _M_IX86 // All32 MOV(16, M(&g_dsp.r[DSP_REG_ST0+stack_reg]), R(EDX)); #else - MOV(64, R(R11), Imm64((u64)g_dsp.r)); + MOV(64, R(R11), ImmPtr(g_dsp.r)); MOV(16, MDisp(R11,(DSP_REG_ST0+stack_reg)*2), R(EDX)); #endif } @@ -119,7 +119,7 @@ void DSPEmitter::dsp_reg_load_stack(int stack_reg, Gen::X64Reg host_dreg) #ifdef _M_IX86 // All32 MOV(16, R(EDX), M(&g_dsp.r[DSP_REG_ST0+stack_reg])); #else - MOV(64, R(R11), Imm64((u64)g_dsp.r)); + MOV(64, R(R11), ImmPtr(g_dsp.r)); MOV(16, R(EDX), MDisp(R11,(DSP_REG_ST0+stack_reg)*2)); #endif dsp_reg_stack_pop(stack_reg); @@ -135,7 +135,7 @@ void DSPEmitter::dsp_reg_store_stack_imm(int stack_reg, u16 val) #ifdef _M_IX86 // All32 MOV(16, M(&g_dsp.r[DSP_REG_ST0+stack_reg]), Imm16(val)); #else - MOV(64, R(R11), Imm64((u64)g_dsp.r)); + MOV(64, R(R11), ImmPtr(g_dsp.r)); MOV(16, MDisp(R11,(DSP_REG_ST0+stack_reg)*2), Imm16(val)); #endif } @@ -151,7 +151,7 @@ void DSPEmitter::dsp_op_write_reg(int reg, Gen::X64Reg host_sreg) #ifdef _M_IX86 // All32 MOV(16, M(&g_dsp.r[reg]), R(host_sreg)); #else - MOV(64, R(R11), Imm64((u64)g_dsp.r)); + MOV(64, R(R11), ImmPtr(g_dsp.r)); MOV(16, MDisp(R11,reg*2), R(host_sreg)); #endif break; @@ -168,7 +168,7 @@ void DSPEmitter::dsp_op_write_reg(int reg, Gen::X64Reg host_sreg) #ifdef _M_IX86 // All32 MOV(16, M(&g_dsp.r[reg]), R(host_sreg)); #else - MOV(64, R(R11), Imm64((u64)g_dsp.r)); + MOV(64, R(R11), ImmPtr(g_dsp.r)); MOV(16, MDisp(R11,reg*2), R(host_sreg)); #endif break; @@ -185,7 +185,7 @@ void DSPEmitter::dsp_op_write_reg_imm(int reg, u16 val) #ifdef _M_IX86 // All32 MOV(16, M(&g_dsp.r[reg]), Imm16((u16)(s16)(s8)(u8)val)); #else - MOV(64, R(R11), Imm64((u64)g_dsp.r)); + MOV(64, R(R11), ImmPtr(g_dsp.r)); MOV(16, MDisp(R11,reg*2), Imm16((u16)(s16)(s8)(u8)val)); #endif break; @@ -202,7 +202,7 @@ void DSPEmitter::dsp_op_write_reg_imm(int reg, u16 val) #ifdef _M_IX86 // All32 MOV(16, M(&g_dsp.r[reg]), Imm16(val)); #else - MOV(64, R(R11), Imm64((u64)g_dsp.r)); + MOV(64, R(R11), ImmPtr(g_dsp.r)); MOV(16, MDisp(R11,reg*2), Imm16(val)); #endif break; @@ -231,7 +231,7 @@ void DSPEmitter::dsp_conditional_extend_accum(int reg) #ifdef _M_IX86 // All32 MOVSX(32, 16, EAX, M(&g_dsp.r[reg])); #else - MOVSX(32, 16, EAX, MDisp(R11,reg*2)); + MOVSX(64, 16, EAX, MDisp(R11,reg*2)); #endif SHR(32,R(EAX),Imm8(16)); //g_dsp.r[reg - DSP_REG_ACM0 + DSP_REG_ACH0] = (val & 0x8000) ? 0xFFFF : 0x0000; @@ -295,7 +295,7 @@ void DSPEmitter::dsp_op_read_reg(int reg, Gen::X64Reg host_dreg) case DSP_REG_ST1: case DSP_REG_ST2: case DSP_REG_ST3: - return dsp_reg_load_stack(reg - 0x0c, host_dreg); + return dsp_reg_load_stack(reg - DSP_REG_ST0, host_dreg); default: //return g_dsp.r[reg]; #ifdef _M_IX86 // All32 diff --git a/Source/Core/DSPCore/Src/Jit/DSPJitMultiplier.cpp b/Source/Core/DSPCore/Src/Jit/DSPJitMultiplier.cpp index 1eb5ee75d0..3dc6f7ff62 100644 --- a/Source/Core/DSPCore/Src/Jit/DSPJitMultiplier.cpp +++ b/Source/Core/DSPCore/Src/Jit/DSPJitMultiplier.cpp @@ -154,7 +154,7 @@ void DSPEmitter::clrp(const UDSPInstruction opc) // g_dsp.r[DSP_REG_PRODM2] = 0x0010; MOV(16, MDisp(R11, DSP_REG_PRODM2 * 2), Imm16(0x0010)); #else - MainOpFallback(opc); + Default(opc); #endif } @@ -171,7 +171,7 @@ void DSPEmitter::tstprod(const UDSPInstruction opc) // Update_SR_Register64(prod); Update_SR_Register64(); #else - MainOpFallback(opc); + Default(opc); #endif } @@ -194,7 +194,7 @@ void DSPEmitter::movp(const UDSPInstruction opc) // Update_SR_Register64(acc); Update_SR_Register64(); #else - MainOpFallback(opc); + Default(opc); #endif } @@ -217,7 +217,7 @@ void DSPEmitter::movnp(const UDSPInstruction opc) // Update_SR_Register64(acc); Update_SR_Register64(); #else - MainOpFallback(opc); + Default(opc); #endif } @@ -239,7 +239,7 @@ void DSPEmitter::movpz(const UDSPInstruction opc) // Update_SR_Register64(acc); Update_SR_Register64(); #else - MainOpFallback(opc); + Default(opc); #endif } @@ -282,7 +282,7 @@ void DSPEmitter::mulaxh(const UDSPInstruction opc) // dsp_set_long_prod(prod); set_long_prod(); #else - MainOpFallback(opc); + Default(opc); #endif } @@ -307,7 +307,7 @@ void DSPEmitter::mul(const UDSPInstruction opc) // dsp_set_long_prod(prod); set_long_prod(); #else - MainOpFallback(opc); + Default(opc); #endif } @@ -344,7 +344,7 @@ void DSPEmitter::mulac(const UDSPInstruction opc) // Update_SR_Register64(dsp_get_long_acc(rreg)); Update_SR_Register64(); #else - MainOpFallback(opc); + Default(opc); #endif } @@ -370,7 +370,7 @@ void DSPEmitter::mulmv(const UDSPInstruction opc) // Update_SR_Register64(dsp_get_long_acc(rreg)); Update_SR_Register64(); #else - MainOpFallback(opc); + Default(opc); #endif } @@ -397,7 +397,7 @@ void DSPEmitter::mulmvz(const UDSPInstruction opc) // Update_SR_Register64(dsp_get_long_acc(rreg)); Update_SR_Register64(); #else - MainOpFallback(opc); + Default(opc); #endif } @@ -519,7 +519,7 @@ void DSPEmitter::mulc(const UDSPInstruction opc) // dsp_set_long_prod(prod); set_long_prod(); #else - MainOpFallback(opc); + Default(opc); #endif } @@ -557,7 +557,7 @@ void DSPEmitter::mulcac(const UDSPInstruction opc) // Update_SR_Register64(dsp_get_long_acc(rreg)); Update_SR_Register64(); #else - MainOpFallback(opc); + Default(opc); #endif } @@ -593,7 +593,7 @@ void DSPEmitter::mulcmv(const UDSPInstruction opc) // Update_SR_Register64(dsp_get_long_acc(rreg)); Update_SR_Register64(); #else - MainOpFallback(opc); + Default(opc); #endif } @@ -631,7 +631,7 @@ void DSPEmitter::mulcmvz(const UDSPInstruction opc) // Update_SR_Register64(dsp_get_long_acc(rreg)); Update_SR_Register64(); #else - MainOpFallback(opc); + Default(opc); #endif } @@ -696,7 +696,7 @@ void DSPEmitter::maddc(const UDSPInstruction opc) // dsp_set_long_prod(prod); set_long_prod(); #else - MainOpFallback(opc); + Default(opc); #endif } @@ -721,7 +721,7 @@ void DSPEmitter::msubc(const UDSPInstruction opc) // dsp_set_long_prod(prod); set_long_prod(); #else - MainOpFallback(opc); + Default(opc); #endif } @@ -745,7 +745,7 @@ void DSPEmitter::madd(const UDSPInstruction opc) // dsp_set_long_prod(prod); set_long_prod(); #else - MainOpFallback(opc); + Default(opc); #endif } @@ -769,6 +769,6 @@ void DSPEmitter::msub(const UDSPInstruction opc) // dsp_set_long_prod(prod); set_long_prod(); #else - MainOpFallback(opc); + Default(opc); #endif } diff --git a/Source/Core/DSPCore/Src/Jit/DSPJitUtil.cpp b/Source/Core/DSPCore/Src/Jit/DSPJitUtil.cpp index 621b4dd9bb..0d9a70295f 100644 --- a/Source/Core/DSPCore/Src/Jit/DSPJitUtil.cpp +++ b/Source/Core/DSPCore/Src/Jit/DSPJitUtil.cpp @@ -304,33 +304,16 @@ void DSPEmitter::decrease_addr_reg(int reg) SetJumpTarget(end); } -// EAX - destination address (g_dsp.r[dest]) -// ECX - value (g_dsp.r[src]) -// ESI - the upper bits of the address (>> 12) -void DSPEmitter::ext_dmem_write(u32 dest, u32 src) + + +// EAX - destination address +// ECX - value +// ESI - Base of dram +void DSPEmitter::dmem_write() { - // u16 addr = g_dsp.r[dest]; -#ifdef _M_IX86 // All32 - MOVZX(32, 16, EAX, M(&g_dsp.r[dest])); -#else - MOV(64, R(R11), ImmPtr(&g_dsp.r)); - MOVZX(32, 16, EAX, MDisp(R11,dest*2)); -#endif - - // u16 val = g_dsp.r[src]; -#ifdef _M_IX86 // All32 - MOVZX(32, 16, ECX, M(&g_dsp.r[src])); -#else - MOVZX(32, 16, ECX, MDisp(R11,src*2)); -#endif - - // u16 saddr = addr >> 12; - MOV(32, R(ESI), R(EAX)); - SHR(16, R(ESI), Imm8(12)); - // if (saddr == 0) - TEST(16, R(ESI), R(ESI)); - FixupBranch ifx = J_CC(CC_NZ); + CMP(16, R(EAX), Imm16(0x0fff)); + FixupBranch ifx = J_CC(CC_A); // g_dsp.dram[addr & DSP_DRAM_MASK] = val; AND(16, R(EAX), Imm16(DSP_DRAM_MASK)); @@ -349,26 +332,35 @@ void DSPEmitter::ext_dmem_write(u32 dest, u32 src) SetJumpTarget(end); } +// ECX - value +void DSPEmitter::dmem_write_imm(u16 addr) +{ + switch (addr >> 12) + { + case 0x0: // 0xxx DRAM + MOV(16, M(&g_dsp.dram[addr & DSP_DRAM_MASK]), R(ECX)); + break; + + case 0xf: // Fxxx HW regs + MOV(16, R(EAX), Imm16(addr)); + ABI_CallFunctionRR((void *)gdsp_ifx_write, EAX, ECX); + break; + + default: // Unmapped/non-existing memory + ERROR_LOG(DSPLLE, "%04x DSP ERROR: Write to UNKNOWN (%04x) memory", g_dsp.pc, addr); + break; + } +} + // EAX - the result of the read (used by caller) // ECX - the address to read -// ESI - the upper bits of the address (>> 12) -void DSPEmitter::ext_dmem_read(u16 addr) +// ESI - Base +// Trashes R11 on gdsp_ifx_read +void DSPEmitter::dmem_read() { - // u16 addr = g_dsp.r[addr]; -#ifdef _M_IX86 // All32 - MOVZX(32, 16, ECX, M(&g_dsp.r[addr])); -#else - MOV(64, R(R11), ImmPtr(&g_dsp.r)); - MOVZX(32, 16, ECX, MDisp(R11,addr*2)); -#endif - - // u16 saddr = addr >> 12; - MOV(32, R(ESI), R(ECX)); - SHR(16, R(ESI), Imm8(12)); - // if (saddr == 0) - TEST(16, R(ESI), R(ESI)); - FixupBranch dram = J_CC(CC_NZ); + CMP(16, R(ECX), Imm16(0x0fff)); + FixupBranch dram = J_CC(CC_A); // return g_dsp.dram[addr & DSP_DRAM_MASK]; AND(16, R(ECX), Imm16(DSP_DRAM_MASK)); #ifdef _M_X64 @@ -381,8 +373,8 @@ void DSPEmitter::ext_dmem_read(u16 addr) FixupBranch end = J(); SetJumpTarget(dram); // else if (saddr == 0x1) - CMP(16, R(ESI), Imm16(0x1)); - FixupBranch ifx = J_CC(CC_NZ); + CMP(16, R(ECX), Imm16(0x1fff)); + FixupBranch ifx = J_CC(CC_A); // return g_dsp.coef[addr & DSP_COEF_MASK]; AND(16, R(ECX), Imm16(DSP_COEF_MASK)); #ifdef _M_X64 @@ -402,6 +394,27 @@ void DSPEmitter::ext_dmem_read(u16 addr) SetJumpTarget(end2); } +void DSPEmitter::dmem_read_imm(u16 addr) +{ + switch (addr >> 12) + { + case 0x0: // 0xxx DRAM + MOV(16, R(EAX), M(&g_dsp.dram[addr & DSP_DRAM_MASK])); + break; + + case 0x1: // 1xxx COEF + MOV(16, R(EAX), Imm16(g_dsp.coef[addr & DSP_COEF_MASK])); + break; + + case 0xf: // Fxxx HW regs + ABI_CallFunctionC16((void *)gdsp_ifx_read, addr); + break; + + default: // Unmapped/non-existing memory + ERROR_LOG(DSPLLE, "%04x DSP ERROR: Read from UNKNOWN (%04x) memory", g_dsp.pc, addr); + } +} + // Returns s64 in RAX // Clobbers RSI, RDI void DSPEmitter::get_long_prod() diff --git a/Source/Core/DSPCore/Src/SConscript b/Source/Core/DSPCore/Src/SConscript index 3f28f949ed..11b3d9dc56 100644 --- a/Source/Core/DSPCore/Src/SConscript +++ b/Source/Core/DSPCore/Src/SConscript @@ -28,6 +28,7 @@ files = [ "Jit/DSPJitUtil.cpp", "Jit/DSPJitCCUtil.cpp", "Jit/DSPJitArithmetic.cpp", + "Jit/DSPJitLoadStore.cpp", "Jit/DSPJitMultiplier.cpp", "Jit/DSPJitMisc.cpp", ]