mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-26 15:55:31 +01:00
LLE JIT: Completed the JIT versions of the DSP Branch instructions (added ifcc, ret, rti and halt).
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6674 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
9553aa0100
commit
677fd7c052
@ -99,7 +99,7 @@ void DSPEmitter::checkExceptions(u32 retval)
|
|||||||
MOV(16, M(&(g_dsp.pc)), Imm16(compilePC));
|
MOV(16, M(&(g_dsp.pc)), Imm16(compilePC));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
|
MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
|
||||||
MOV(16, MDisp(RAX,0), Imm16(compilePC));
|
MOV(16, MatR(RAX), Imm16(compilePC));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ABI_CallFunction((void *)&DSPCore_CheckExceptions);
|
ABI_CallFunction((void *)&DSPCore_CheckExceptions);
|
||||||
@ -316,7 +316,7 @@ void DSPEmitter::Compile(int start_addr)
|
|||||||
MOV(16, M(&(g_dsp.pc)), Imm16(compilePC));
|
MOV(16, M(&(g_dsp.pc)), Imm16(compilePC));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
|
MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
|
||||||
MOV(16, MDisp(RAX,0), Imm16(compilePC));
|
MOV(16, MatR(RAX), Imm16(compilePC));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -354,7 +354,7 @@ void DSPEmitter::Compile(int start_addr)
|
|||||||
MOV(16, R(AX), M(&g_dsp.pc));
|
MOV(16, R(AX), M(&g_dsp.pc));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
|
MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
|
||||||
MOV(16, R(AX), MDisp(RAX,0));
|
MOV(16, R(AX), MatR(RAX));
|
||||||
#endif
|
#endif
|
||||||
CMP(16, R(AX), Imm16(compilePC));
|
CMP(16, R(AX), Imm16(compilePC));
|
||||||
FixupBranch rNoBranch = J_CC(CC_Z);
|
FixupBranch rNoBranch = J_CC(CC_Z);
|
||||||
@ -388,7 +388,7 @@ void DSPEmitter::Compile(int start_addr)
|
|||||||
MOV(16, M(&(g_dsp.pc)), Imm16(compilePC));
|
MOV(16, M(&(g_dsp.pc)), Imm16(compilePC));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
|
MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
|
||||||
MOV(16, MDisp(RAX,0), Imm16(compilePC));
|
MOV(16, MatR(RAX), Imm16(compilePC));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,6 +132,10 @@ public:
|
|||||||
void jmprcc(const UDSPInstruction opc);
|
void jmprcc(const UDSPInstruction opc);
|
||||||
void call(const UDSPInstruction opc);
|
void call(const UDSPInstruction opc);
|
||||||
void callr(const UDSPInstruction opc);
|
void callr(const UDSPInstruction opc);
|
||||||
|
void ifcc(const UDSPInstruction opc);
|
||||||
|
void ret(const UDSPInstruction opc);
|
||||||
|
void rti(const UDSPInstruction opc);
|
||||||
|
void halt(const UDSPInstruction opc);
|
||||||
void loop(const UDSPInstruction opc);
|
void loop(const UDSPInstruction opc);
|
||||||
void loopi(const UDSPInstruction opc);
|
void loopi(const UDSPInstruction opc);
|
||||||
void bloop(const UDSPInstruction opc);
|
void bloop(const UDSPInstruction opc);
|
||||||
|
@ -40,26 +40,26 @@ const DSPOPCTemplate opcodes[] =
|
|||||||
{"SUBARN", 0x000c, 0xfffc, DSPInterpreter::subarn, &DSPEmitter::subarn, 1, 1, {{P_REG, 1, 0, 0, 0x0003}}, false, false, false, false, false},
|
{"SUBARN", 0x000c, 0xfffc, DSPInterpreter::subarn, &DSPEmitter::subarn, 1, 1, {{P_REG, 1, 0, 0, 0x0003}}, false, false, false, false, false},
|
||||||
{"ADDARN", 0x0010, 0xfff0, DSPInterpreter::addarn, &DSPEmitter::addarn, 1, 2, {{P_REG, 1, 0, 0, 0x0003}, {P_REG04, 1, 0, 2, 0x000c}}, false, false, false, false, false},
|
{"ADDARN", 0x0010, 0xfff0, DSPInterpreter::addarn, &DSPEmitter::addarn, 1, 2, {{P_REG, 1, 0, 0, 0x0003}, {P_REG04, 1, 0, 2, 0x000c}}, false, false, false, false, false},
|
||||||
|
|
||||||
{"HALT", 0x0021, 0xffff, DSPInterpreter::halt, NULL, 1, 0, {}, false, true, true, false, false},
|
{"HALT", 0x0021, 0xffff, DSPInterpreter::halt, &DSPEmitter::halt, 1, 0, {}, false, true, true, false, false},
|
||||||
|
|
||||||
{"RETGE", 0x02d0, 0xffff, DSPInterpreter::ret, NULL, 1, 0, {}, false, true, false, true, false},
|
{"RETGE", 0x02d0, 0xffff, DSPInterpreter::ret, &DSPEmitter::ret, 1, 0, {}, false, true, false, true, false},
|
||||||
{"RETL", 0x02d1, 0xffff, DSPInterpreter::ret, NULL, 1, 0, {}, false, true, false, true, false},
|
{"RETL", 0x02d1, 0xffff, DSPInterpreter::ret, &DSPEmitter::ret, 1, 0, {}, false, true, false, true, false},
|
||||||
{"RETG", 0x02d2, 0xffff, DSPInterpreter::ret, NULL, 1, 0, {}, false, true, false, true, false},
|
{"RETG", 0x02d2, 0xffff, DSPInterpreter::ret, &DSPEmitter::ret, 1, 0, {}, false, true, false, true, false},
|
||||||
{"RETLE", 0x02d3, 0xffff, DSPInterpreter::ret, NULL, 1, 0, {}, false, true, false, true, false},
|
{"RETLE", 0x02d3, 0xffff, DSPInterpreter::ret, NULL/*&DSPEmitter::ret*/, 1, 0, {}, false, true, false, true, false},
|
||||||
{"RETNZ", 0x02d4, 0xffff, DSPInterpreter::ret, NULL, 1, 0, {}, false, true, false, true, false},
|
{"RETNZ", 0x02d4, 0xffff, DSPInterpreter::ret, &DSPEmitter::ret, 1, 0, {}, false, true, false, true, false},
|
||||||
{"RETZ", 0x02d5, 0xffff, DSPInterpreter::ret, NULL, 1, 0, {}, false, true, false, true, false},
|
{"RETZ", 0x02d5, 0xffff, DSPInterpreter::ret, &DSPEmitter::ret, 1, 0, {}, false, true, false, true, false},
|
||||||
{"RETNC", 0x02d6, 0xffff, DSPInterpreter::ret, NULL, 1, 0, {}, false, true, false, true, false},
|
{"RETNC", 0x02d6, 0xffff, DSPInterpreter::ret, &DSPEmitter::ret, 1, 0, {}, false, true, false, true, false},
|
||||||
{"RETC", 0x02d7, 0xffff, DSPInterpreter::ret, NULL, 1, 0, {}, false, true, false, true, false},
|
{"RETC", 0x02d7, 0xffff, DSPInterpreter::ret, &DSPEmitter::ret, 1, 0, {}, false, true, false, true, false},
|
||||||
{"RETx8", 0x02d8, 0xffff, DSPInterpreter::ret, NULL, 1, 0, {}, false, true, false, true, false},
|
{"RETx8", 0x02d8, 0xffff, DSPInterpreter::ret, &DSPEmitter::ret, 1, 0, {}, false, true, false, true, false},
|
||||||
{"RETx9", 0x02d9, 0xffff, DSPInterpreter::ret, NULL, 1, 0, {}, false, true, false, true, false},
|
{"RETx9", 0x02d9, 0xffff, DSPInterpreter::ret, &DSPEmitter::ret, 1, 0, {}, false, true, false, true, false},
|
||||||
{"RETxA", 0x02da, 0xffff, DSPInterpreter::ret, NULL, 1, 0, {}, false, true, false, true, false},
|
{"RETxA", 0x02da, 0xffff, DSPInterpreter::ret, NULL/*&DSPEmitter::ret*/, 1, 0, {}, false, true, false, true, false},
|
||||||
{"RETxB", 0x02db, 0xffff, DSPInterpreter::ret, NULL, 1, 0, {}, false, true, false, true, false},
|
{"RETxB", 0x02db, 0xffff, DSPInterpreter::ret, NULL/*&DSPEmitter::ret*/, 1, 0, {}, false, true, false, true, false},
|
||||||
{"RETLNZ", 0x02dc, 0xffff, DSPInterpreter::ret, NULL, 1, 0, {}, false, true, false, true, false},
|
{"RETLNZ", 0x02dc, 0xffff, DSPInterpreter::ret, &DSPEmitter::ret, 1, 0, {}, false, true, false, true, false},
|
||||||
{"RETLZ", 0x02dd, 0xffff, DSPInterpreter::ret, NULL, 1, 0, {}, false, true, false, true, false},
|
{"RETLZ", 0x02dd, 0xffff, DSPInterpreter::ret, &DSPEmitter::ret, 1, 0, {}, false, true, false, true, false},
|
||||||
{"RETO", 0x02de, 0xffff, DSPInterpreter::ret, NULL, 1, 0, {}, false, true, false, true, false},
|
{"RETO", 0x02de, 0xffff, DSPInterpreter::ret, &DSPEmitter::ret, 1, 0, {}, false, true, false, true, false},
|
||||||
{"RET", 0x02df, 0xffff, DSPInterpreter::ret, NULL, 1, 0, {}, false, true, true, false, false},
|
{"RET", 0x02df, 0xffff, DSPInterpreter::ret, &DSPEmitter::ret, 1, 0, {}, false, true, true, false, false},
|
||||||
|
|
||||||
{"RTI", 0x02ff, 0xffff, DSPInterpreter::rti, NULL, 1, 0, {}, false, true, true, false, false},
|
{"RTI", 0x02ff, 0xffff, DSPInterpreter::rti, &DSPEmitter::rti, 1, 0, {}, false, true, true, false, false},
|
||||||
|
|
||||||
{"CALLGE", 0x02b0, 0xffff, DSPInterpreter::call, &DSPEmitter::call, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true, false},
|
{"CALLGE", 0x02b0, 0xffff, DSPInterpreter::call, &DSPEmitter::call, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true, false},
|
||||||
{"CALLL", 0x02b1, 0xffff, DSPInterpreter::call, &DSPEmitter::call, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true, false},
|
{"CALLL", 0x02b1, 0xffff, DSPInterpreter::call, &DSPEmitter::call, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true, false},
|
||||||
@ -78,22 +78,22 @@ const DSPOPCTemplate opcodes[] =
|
|||||||
{"CALLO", 0x02be, 0xffff, DSPInterpreter::call, &DSPEmitter::call, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true, false},
|
{"CALLO", 0x02be, 0xffff, DSPInterpreter::call, &DSPEmitter::call, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true, false},
|
||||||
{"CALL", 0x02bf, 0xffff, DSPInterpreter::call, &DSPEmitter::call, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, true, true, false},
|
{"CALL", 0x02bf, 0xffff, DSPInterpreter::call, &DSPEmitter::call, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, true, true, false},
|
||||||
|
|
||||||
{"IFGE", 0x0270, 0xffff, DSPInterpreter::ifcc, NULL, 1, 0, {}, false, true, false, true, false},
|
{"IFGE", 0x0270, 0xffff, DSPInterpreter::ifcc, &DSPEmitter::ifcc, 1, 0, {}, false, true, false, true, false},
|
||||||
{"IFL", 0x0271, 0xffff, DSPInterpreter::ifcc, NULL, 1, 0, {}, false, true, false, true, false},
|
{"IFL", 0x0271, 0xffff, DSPInterpreter::ifcc, &DSPEmitter::ifcc, 1, 0, {}, false, true, false, true, false},
|
||||||
{"IFG", 0x0272, 0xffff, DSPInterpreter::ifcc, NULL, 1, 0, {}, false, true, false, true, false},
|
{"IFG", 0x0272, 0xffff, DSPInterpreter::ifcc, &DSPEmitter::ifcc, 1, 0, {}, false, true, false, true, false},
|
||||||
{"IFLE", 0x0273, 0xffff, DSPInterpreter::ifcc, NULL, 1, 0, {}, false, true, false, true, false},
|
{"IFLE", 0x0273, 0xffff, DSPInterpreter::ifcc, NULL/*&DSPEmitter::ifcc*/, 1, 0, {}, false, true, false, true, false},
|
||||||
{"IFNZ", 0x0274, 0xffff, DSPInterpreter::ifcc, NULL, 1, 0, {}, false, true, false, true, false},
|
{"IFNZ", 0x0274, 0xffff, DSPInterpreter::ifcc, &DSPEmitter::ifcc, 1, 0, {}, false, true, false, true, false},
|
||||||
{"IFZ", 0x0275, 0xffff, DSPInterpreter::ifcc, NULL, 1, 0, {}, false, true, false, true, false},
|
{"IFZ", 0x0275, 0xffff, DSPInterpreter::ifcc, &DSPEmitter::ifcc, 1, 0, {}, false, true, false, true, false},
|
||||||
{"IFNC", 0x0276, 0xffff, DSPInterpreter::ifcc, NULL, 1, 0, {}, false, true, false, true, false},
|
{"IFNC", 0x0276, 0xffff, DSPInterpreter::ifcc, &DSPEmitter::ifcc, 1, 0, {}, false, true, false, true, false},
|
||||||
{"IFC", 0x0277, 0xffff, DSPInterpreter::ifcc, NULL, 1, 0, {}, false, true, false, true, false},
|
{"IFC", 0x0277, 0xffff, DSPInterpreter::ifcc, &DSPEmitter::ifcc, 1, 0, {}, false, true, false, true, false},
|
||||||
{"IFx8", 0x0278, 0xffff, DSPInterpreter::ifcc, NULL, 1, 0, {}, false, true, false, true, false},
|
{"IFx8", 0x0278, 0xffff, DSPInterpreter::ifcc, &DSPEmitter::ifcc, 1, 0, {}, false, true, false, true, false},
|
||||||
{"IFx9", 0x0279, 0xffff, DSPInterpreter::ifcc, NULL, 1, 0, {}, false, true, false, true, false},
|
{"IFx9", 0x0279, 0xffff, DSPInterpreter::ifcc, &DSPEmitter::ifcc, 1, 0, {}, false, true, false, true, false},
|
||||||
{"IFxA", 0x027a, 0xffff, DSPInterpreter::ifcc, NULL, 1, 0, {}, false, true, false, true, false},
|
{"IFxA", 0x027a, 0xffff, DSPInterpreter::ifcc, NULL/*&DSPEmitter::ifcc*/, 1, 0, {}, false, true, false, true, false},
|
||||||
{"IFxB", 0x027b, 0xffff, DSPInterpreter::ifcc, NULL, 1, 0, {}, false, true, false, true, false},
|
{"IFxB", 0x027b, 0xffff, DSPInterpreter::ifcc, NULL/*&DSPEmitter::ifcc*/, 1, 0, {}, false, true, false, true, false},
|
||||||
{"IFLNZ", 0x027c, 0xffff, DSPInterpreter::ifcc, NULL, 1, 0, {}, false, true, false, true, false},
|
{"IFLNZ", 0x027c, 0xffff, DSPInterpreter::ifcc, &DSPEmitter::ifcc, 1, 0, {}, false, true, false, true, false},
|
||||||
{"IFLZ", 0x027d, 0xffff, DSPInterpreter::ifcc, NULL, 1, 0, {}, false, true, false, true, false},
|
{"IFLZ", 0x027d, 0xffff, DSPInterpreter::ifcc, &DSPEmitter::ifcc, 1, 0, {}, false, true, false, true, false},
|
||||||
{"IFO", 0x027e, 0xffff, DSPInterpreter::ifcc, NULL, 1, 0, {}, false, true, false, true, false},
|
{"IFO", 0x027e, 0xffff, DSPInterpreter::ifcc, &DSPEmitter::ifcc, 1, 0, {}, false, true, false, true, false},
|
||||||
{"IF", 0x027f, 0xffff, DSPInterpreter::ifcc, NULL, 1, 0, {}, false, true, true, true, false},
|
{"IF", 0x027f, 0xffff, DSPInterpreter::ifcc, &DSPEmitter::ifcc, 1, 0, {}, false, true, true, true, false},
|
||||||
|
|
||||||
{"JGE", 0x0290, 0xffff, DSPInterpreter::jcc, &DSPEmitter::jcc, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true, false},
|
{"JGE", 0x0290, 0xffff, DSPInterpreter::jcc, &DSPEmitter::jcc, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true, false},
|
||||||
{"JL", 0x0291, 0xffff, DSPInterpreter::jcc, &DSPEmitter::jcc, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true, false},
|
{"JL", 0x0291, 0xffff, DSPInterpreter::jcc, &DSPEmitter::jcc, 2, 1, {{P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true, false},
|
||||||
|
@ -185,7 +185,7 @@ void DSPEmitter::jcc(const UDSPInstruction opc)
|
|||||||
MOV(16, M(&(g_dsp.pc)), Imm16(compilePC + 1));
|
MOV(16, M(&(g_dsp.pc)), Imm16(compilePC + 1));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
|
MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
|
||||||
MOV(16, MDisp(RAX,0), Imm16(compilePC + 1));
|
MOV(16, MatR(RAX), Imm16(compilePC + 1));
|
||||||
#endif
|
#endif
|
||||||
ReJitConditional<r_jcc>(opc, *this);
|
ReJitConditional<r_jcc>(opc, *this);
|
||||||
#endif
|
#endif
|
||||||
@ -218,7 +218,8 @@ void DSPEmitter::jmprcc(const UDSPInstruction opc)
|
|||||||
void r_call(const UDSPInstruction opc, DSPEmitter& emitter)
|
void r_call(const UDSPInstruction opc, DSPEmitter& emitter)
|
||||||
{
|
{
|
||||||
u16 dest = dsp_imem_read(emitter.compilePC + 1);
|
u16 dest = dsp_imem_read(emitter.compilePC + 1);
|
||||||
emitter.ABI_CallFunctionCC16((void *)dsp_reg_store_stack, DSP_STACK_C, emitter.compilePC + 2);
|
emitter.MOV(16, R(DX), Imm16(emitter.compilePC + 2));
|
||||||
|
emitter.dsp_reg_store_stack(DSP_STACK_C);
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
emitter.MOV(16, M(&(g_dsp.pc)), Imm16(dest));
|
emitter.MOV(16, M(&(g_dsp.pc)), Imm16(dest));
|
||||||
|
|
||||||
@ -230,7 +231,7 @@ void r_call(const UDSPInstruction opc, DSPEmitter& emitter)
|
|||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
emitter.MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
|
emitter.MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
|
||||||
emitter.MOV(16, MDisp(RAX,0), Imm16(dest));
|
emitter.MOV(16, MatR(RAX), Imm16(dest));
|
||||||
|
|
||||||
// Jump directly to the called block if it has already been compiled.
|
// Jump directly to the called block if it has already been compiled.
|
||||||
// TODO: Subtract cycles from cyclesLeft
|
// TODO: Subtract cycles from cyclesLeft
|
||||||
@ -255,7 +256,7 @@ void DSPEmitter::call(const UDSPInstruction opc)
|
|||||||
MOV(16, M(&(g_dsp.pc)), Imm16(compilePC + 1));
|
MOV(16, M(&(g_dsp.pc)), Imm16(compilePC + 1));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
|
MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
|
||||||
MOV(16, MDisp(RAX,0), Imm16(compilePC + 1));
|
MOV(16, MatR(RAX), Imm16(compilePC + 1));
|
||||||
#endif
|
#endif
|
||||||
ReJitConditional<r_call>(opc, *this);
|
ReJitConditional<r_call>(opc, *this);
|
||||||
}
|
}
|
||||||
@ -263,7 +264,8 @@ void DSPEmitter::call(const UDSPInstruction opc)
|
|||||||
void r_callr(const UDSPInstruction opc, DSPEmitter& emitter)
|
void r_callr(const UDSPInstruction opc, DSPEmitter& emitter)
|
||||||
{
|
{
|
||||||
u8 reg = (opc >> 5) & 0x7;
|
u8 reg = (opc >> 5) & 0x7;
|
||||||
emitter.ABI_CallFunctionCC16((void *)dsp_reg_store_stack, DSP_STACK_C, emitter.compilePC + 1);
|
emitter.MOV(16, R(DX), Imm16(emitter.compilePC + 1));
|
||||||
|
emitter.dsp_reg_store_stack(DSP_STACK_C);
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
emitter.MOV(16, R(EAX), M(&g_dsp.r[reg]));
|
emitter.MOV(16, R(EAX), M(&g_dsp.r[reg]));
|
||||||
emitter.MOV(16, M(&g_dsp.pc), R(EAX));
|
emitter.MOV(16, M(&g_dsp.pc), R(EAX));
|
||||||
@ -271,7 +273,7 @@ void r_callr(const UDSPInstruction opc, DSPEmitter& emitter)
|
|||||||
emitter.MOV(64, R(RSI), ImmPtr(&g_dsp.r[reg]));
|
emitter.MOV(64, R(RSI), ImmPtr(&g_dsp.r[reg]));
|
||||||
emitter.MOV(16, R(RSI), MatR(RSI));
|
emitter.MOV(16, R(RSI), MatR(RSI));
|
||||||
emitter.MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
|
emitter.MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
|
||||||
emitter.MOV(16, MDisp(RAX,0), R(RSI));
|
emitter.MOV(16, MatR(RAX), R(RSI));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
// Generic callr implementation
|
// Generic callr implementation
|
||||||
@ -282,9 +284,113 @@ void r_callr(const UDSPInstruction opc, DSPEmitter& emitter)
|
|||||||
// register $R.
|
// register $R.
|
||||||
void DSPEmitter::callr(const UDSPInstruction opc)
|
void DSPEmitter::callr(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
|
#ifdef _M_IX86 // All32
|
||||||
|
MOV(16, M(&g_dsp.pc), Imm16(compilePC + 1));
|
||||||
|
#else
|
||||||
|
MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
|
||||||
|
MOV(16, MatR(RAX), Imm16(compilePC + 1));
|
||||||
|
#endif
|
||||||
ReJitConditional<r_callr>(opc, *this);
|
ReJitConditional<r_callr>(opc, *this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void r_ifcc(const UDSPInstruction opc, DSPEmitter& emitter)
|
||||||
|
{
|
||||||
|
#ifdef _M_IX86 // All32
|
||||||
|
emitter.MOV(16, M(&g_dsp.pc), Imm16(emitter.compilePC + 1));
|
||||||
|
#else
|
||||||
|
emitter.MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
|
||||||
|
emitter.MOV(16, MatR(RAX), Imm16(emitter.compilePC + 1));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generic jmpr implementation
|
||||||
|
// JMPcc $R
|
||||||
|
// 0001 0111 rrr0 cccc
|
||||||
|
// Jump to address; set program counter to a value from register $R.
|
||||||
|
void DSPEmitter::ifcc(const UDSPInstruction opc)
|
||||||
|
{
|
||||||
|
#ifdef _M_IX86 // All32
|
||||||
|
MOV(16, M(&g_dsp.pc), Imm16((compilePC + 1) + opTable[compilePC + 1]->size));
|
||||||
|
#else
|
||||||
|
MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
|
||||||
|
MOV(16, MatR(RAX), Imm16((compilePC + 1) + opTable[compilePC + 1]->size));
|
||||||
|
#endif
|
||||||
|
ReJitConditional<r_ifcc>(opc, *this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void r_ret(const UDSPInstruction opc, DSPEmitter& emitter)
|
||||||
|
{
|
||||||
|
emitter.dsp_reg_load_stack(DSP_STACK_C);
|
||||||
|
#ifdef _M_IX86 // All32
|
||||||
|
emitter.MOV(16, M(&g_dsp.pc), R(DX));
|
||||||
|
#else
|
||||||
|
emitter.MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
|
||||||
|
emitter.MOV(16, MatR(RAX), R(DX));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generic ret implementation
|
||||||
|
// RETcc
|
||||||
|
// 0000 0010 1101 cccc
|
||||||
|
// Return from subroutine if condition cc has been met. Pops stored PC
|
||||||
|
// from call stack $st0 and sets $pc to this location.
|
||||||
|
void DSPEmitter::ret(const UDSPInstruction opc)
|
||||||
|
{
|
||||||
|
#ifdef _M_IX86 // All32
|
||||||
|
MOV(16, M(&g_dsp.pc), Imm16(compilePC + 1));
|
||||||
|
#else
|
||||||
|
MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
|
||||||
|
MOV(16, MatR(RAX), Imm16(compilePC + 1));
|
||||||
|
#endif
|
||||||
|
ReJitConditional<r_ret>(opc, *this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// RTI
|
||||||
|
// 0000 0010 1111 1111
|
||||||
|
// Return from exception. Pops stored status register $sr from data stack
|
||||||
|
// $st1 and program counter PC from call stack $st0 and sets $pc to this
|
||||||
|
// location.
|
||||||
|
void DSPEmitter::rti(const UDSPInstruction opc)
|
||||||
|
{
|
||||||
|
// g_dsp.r[DSP_REG_SR] = dsp_reg_load_stack(DSP_STACK_D);
|
||||||
|
dsp_reg_load_stack(DSP_STACK_D);
|
||||||
|
#ifdef _M_IX86 // All32
|
||||||
|
MOV(16, M(&g_dsp.r[DSP_REG_SR]), R(DX));
|
||||||
|
#else
|
||||||
|
MOV(64, R(R11), ImmPtr(&g_dsp.r));
|
||||||
|
MOV(16, MDisp(R11,DSP_REG_SR*2), R(DX));
|
||||||
|
#endif
|
||||||
|
// g_dsp.pc = dsp_reg_load_stack(DSP_STACK_C);
|
||||||
|
dsp_reg_load_stack(DSP_STACK_C);
|
||||||
|
#ifdef _M_IX86 // All32
|
||||||
|
MOV(16, M(&g_dsp.pc), R(DX));
|
||||||
|
#else
|
||||||
|
MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
|
||||||
|
MOV(16, MatR(RAX), R(DX));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// HALT
|
||||||
|
// 0000 0000 0020 0001
|
||||||
|
// Stops execution of DSP code. Sets bit DSP_CR_HALT in register DREG_CR.
|
||||||
|
void DSPEmitter::halt(const UDSPInstruction opc)
|
||||||
|
{
|
||||||
|
#ifdef _M_IX86 // All32
|
||||||
|
OR(16, M(&g_dsp.cr), Imm16(4));
|
||||||
|
#else
|
||||||
|
MOV(64, R(RAX), ImmPtr(&g_dsp.cr));
|
||||||
|
OR(16, MatR(RAX), Imm16(4));
|
||||||
|
#endif
|
||||||
|
// g_dsp.pc = dsp_reg_load_stack(DSP_STACK_C);
|
||||||
|
dsp_reg_load_stack(DSP_STACK_C);
|
||||||
|
#ifdef _M_IX86 // All32
|
||||||
|
MOV(16, M(&g_dsp.pc), R(DX));
|
||||||
|
#else
|
||||||
|
MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
|
||||||
|
MOV(16, MatR(RAX), R(DX));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
// LOOP handling: Loop stack is used to control execution of repeated blocks of
|
// LOOP handling: Loop stack is used to control execution of repeated blocks of
|
||||||
// instructions. Whenever there is value on stack $st2 and current PC is equal
|
// instructions. Whenever there is value on stack $st2 and current PC is equal
|
||||||
// value at $st2, then value at stack $st3 is decremented. If value is not zero
|
// value at $st2, then value at stack $st3 is decremented. If value is not zero
|
||||||
@ -370,7 +476,7 @@ void DSPEmitter::loop(const UDSPInstruction opc)
|
|||||||
MOV(16, M(&(g_dsp.pc)), Imm16(compilePC + 1));
|
MOV(16, M(&(g_dsp.pc)), Imm16(compilePC + 1));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
|
MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
|
||||||
MOV(16, MDisp(RAX,0), Imm16(compilePC + 1));
|
MOV(16, MatR(RAX), Imm16(compilePC + 1));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -400,7 +506,7 @@ void DSPEmitter::loopi(const UDSPInstruction opc)
|
|||||||
MOV(16, M(&(g_dsp.pc)), Imm16(compilePC + 1));
|
MOV(16, M(&(g_dsp.pc)), Imm16(compilePC + 1));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
|
MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
|
||||||
MOV(16, MDisp(RAX,0), Imm16(compilePC + 1));
|
MOV(16, MatR(RAX), Imm16(compilePC + 1));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -438,7 +544,7 @@ void DSPEmitter::bloop(const UDSPInstruction opc)
|
|||||||
MOV(16, M(&(g_dsp.pc)), Imm16(compilePC + 2));
|
MOV(16, M(&(g_dsp.pc)), Imm16(compilePC + 2));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
|
MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
|
||||||
MOV(16, MDisp(RAX,0), Imm16(compilePC + 2));
|
MOV(16, MatR(RAX), Imm16(compilePC + 2));
|
||||||
#endif
|
#endif
|
||||||
FixupBranch exit = J();
|
FixupBranch exit = J();
|
||||||
|
|
||||||
@ -482,7 +588,7 @@ void DSPEmitter::bloopi(const UDSPInstruction opc)
|
|||||||
MOV(16, M(&(g_dsp.pc)), Imm16(compilePC + 2));
|
MOV(16, M(&(g_dsp.pc)), Imm16(compilePC + 2));
|
||||||
#else
|
#else
|
||||||
MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
|
MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
|
||||||
MOV(16, MDisp(RAX,0), Imm16(compilePC + 2));
|
MOV(16, MatR(RAX), Imm16(compilePC + 2));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
Loading…
x
Reference in New Issue
Block a user