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",
]