* 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
This commit is contained in:
skidau 2010-12-16 23:27:38 +00:00
parent a82a61c53a
commit 93a09ee7b5
12 changed files with 239 additions and 127 deletions

View File

@ -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)

View File

@ -462,6 +462,10 @@
RelativePath=".\Src\Jit\DSPJitArithmetic.cpp"
>
</File>
<File
RelativePath=".\Src\Jit\DSPJitLoadStore.cpp"
>
</File>
<File
RelativePath=".\Src\Jit\DSPJitCCUtil.cpp"
>

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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
}

View File

@ -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<r_jcc>(opc, *this);
#endif
}
void r_jmprcc(const UDSPInstruction opc, DSPEmitter& emitter)

View File

@ -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));

View File

@ -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

View File

@ -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
}

View File

@ -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()

View File

@ -28,6 +28,7 @@ files = [
"Jit/DSPJitUtil.cpp",
"Jit/DSPJitCCUtil.cpp",
"Jit/DSPJitArithmetic.cpp",
"Jit/DSPJitLoadStore.cpp",
"Jit/DSPJitMultiplier.cpp",
"Jit/DSPJitMisc.cpp",
]