Core/Core/Src/DSP: Drop the indirect addressing hackery from DSP Jit

Was made possible by the move of Core/DSPCommon to Core/Core.
This should not give a significant speed difference, but frees
another register for register allocator use on x64 and
generally simplifies the code.


git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@7252 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
pierre 2011-02-26 21:30:49 +00:00
parent 565ab76e63
commit 8351177738
8 changed files with 21 additions and 289 deletions

View File

@ -81,20 +81,10 @@ void DSPEmitter::ClearIRAM() {
void DSPEmitter::checkExceptions(u32 retval)
{
// Check for interrupts and exceptions
#ifdef _M_IX86 // All32
TEST(8, M(&g_dsp.exceptions), Imm8(0xff));
#else
MOV(64, R(RAX), ImmPtr(&g_dsp.exceptions));
TEST(8, MatR(RAX), Imm8(0xff));
#endif
FixupBranch skipCheck = J_CC(CC_Z);
FixupBranch skipCheck = J_CC(CC_Z, true);
#ifdef _M_IX86 // All32
MOV(16, M(&(g_dsp.pc)), Imm16(compilePC));
#else
MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
MOV(16, MatR(RAX), Imm16(compilePC));
#endif
DSPJitRegCache c(gpr);
SaveDSPRegs();
@ -113,12 +103,7 @@ void DSPEmitter::Default(UDSPInstruction inst)
// Increment PC - we shouldn't need to do this for every instruction. only for branches and end of block.
// Fallbacks to interpreter need this for fetching immediate values
#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
}
// Fall back to interpreter
@ -237,32 +222,18 @@ void DSPEmitter::Compile(u16 start_addr)
// by the analyzer.
if (DSPAnalyzer::code_flags[compilePC-1] & DSPAnalyzer::CODE_LOOP_END)
{
#ifdef _M_IX86 // All32
MOVZX(32, 16, EAX, M(&(g_dsp.r.st[2])));
#else
MOV(64, R(R11), ImmPtr(&g_dsp.r));
MOVZX(32, 16, EAX, MDisp(R11, STRUCT_OFFSET(g_dsp.r, st[2])));
#endif
CMP(32, R(EAX), Imm32(0));
FixupBranch rLoopAddressExit = J_CC(CC_LE, true);
#ifdef _M_IX86 // All32
MOVZX(32, 16, EAX, M(&g_dsp.r.st[3]));
#else
MOVZX(32, 16, EAX, MDisp(R11, STRUCT_OFFSET(g_dsp.r, st[3])));
#endif
CMP(32, R(EAX), Imm32(0));
FixupBranch rLoopCounterExit = J_CC(CC_LE, true);
if (!opcode->branch)
{
//branch insns update the g_dsp.pc
#ifdef _M_IX86 // All32
MOV(16, M(&(g_dsp.pc)), Imm16(compilePC));
#else
MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
MOV(16, MatR(RAX), Imm16(compilePC));
#endif
}
// These functions branch and therefore only need to be called in the
@ -296,14 +267,9 @@ void DSPEmitter::Compile(u16 start_addr)
else if (!opcode->jitFunc)
{
//look at g_dsp.pc if we actually branched
#ifdef _M_IX86 // All32
MOV(16, R(AX), M(&g_dsp.pc));
#else
MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
MOV(16, R(AX), MatR(RAX));
#endif
CMP(16, R(AX), Imm16(compilePC));
FixupBranch rNoBranch = J_CC(CC_Z);
FixupBranch rNoBranch = J_CC(CC_Z, true);
DSPJitRegCache c(gpr);
//don't update g_dsp.pc -- the branch insn already did
@ -331,12 +297,7 @@ void DSPEmitter::Compile(u16 start_addr)
}
if (fixup_pc) {
#ifdef _M_IX86 // All32
MOV(16, M(&(g_dsp.pc)), Imm16(compilePC));
#else
MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
MOV(16, MatR(RAX), Imm16(compilePC));
#endif
}
blocks[start_addr] = (DSPCompiledCode)entryPoint;
@ -389,7 +350,6 @@ const u8 *DSPEmitter::CompileStub()
{
const u8 *entryPoint = AlignCode16();
ABI_CallFunction((void *)&CompileCurrent);
//MOVZX(32, 16, ECX, M(&g_dsp.pc));
XOR(32, R(EAX), R(EAX)); // Return 0 cycles executed
JMP(returnDispatcher);
return entryPoint;
@ -410,26 +370,17 @@ void DSPEmitter::CompileDispatcher()
}
// Check for DSP halt
#ifdef _M_IX86
TEST(8, M(&g_dsp.cr), Imm8(CR_HALT));
#else
MOV(64, R(RAX), ImmPtr(&g_dsp.cr));
TEST(8, MatR(RAX), Imm8(CR_HALT));
#endif
FixupBranch _halt = J_CC(CC_NE);
#ifdef _M_IX86
MOVZX(32, 16, ECX, M(&g_dsp.pc));
#else
MOV(64, R(RCX), ImmPtr(&g_dsp.pc));
MOVZX(64, 16, RCX, MatR(RCX));
#endif
// Execute block. Cycles executed returned in EAX.
#ifdef _M_IX86
MOVZX(32, 16, ECX, M(&g_dsp.pc));
MOV(32, R(EBX), ImmPtr(blocks));
JMPptr(MComplex(EBX, ECX, SCALE_4, 0));
#else
MOVZX(64, 16, ECX, M(&g_dsp.pc));//for clarity, use 64 here.
MOV(64, R(RBX), ImmPtr(blocks));
JMPptr(MComplex(RBX, RCX, SCALE_8, 0));
#endif
@ -437,15 +388,10 @@ void DSPEmitter::CompileDispatcher()
returnDispatcher = GetCodePtr();
// Decrement cyclesLeft
#ifdef _M_IX86
SUB(16, M(&cyclesLeft), R(EAX));
#else
MOV(64, R(R12), ImmPtr(&cyclesLeft));
SUB(16, MatR(R12), R(EAX));
#endif
J_CC(CC_A, dispatcherLoop);
// DSP gave up the remaining cycles.
SetJumpTarget(_halt);
if (DSPHost_OnThread())

View File

@ -102,7 +102,6 @@ void DSPEmitter::andcf(const UDSPInstruction opc)
gpr.getReg(DSP_REG_SR,sr_reg);
AND(16, R(RAX), Imm16(imm));
CMP(16, R(RAX), Imm16(imm));
// MOV(64, R(R11), ImmPtr(&g_dsp.r));
FixupBranch notLogicZero = J_CC(CC_NE);
OR(16, sr_reg, Imm16(SR_LOGIC_ZERO));
FixupBranch exit = J();
@ -142,7 +141,6 @@ void DSPEmitter::andf(const UDSPInstruction opc)
OpArg sr_reg;
gpr.getReg(DSP_REG_SR,sr_reg);
TEST(16, R(RAX), Imm16(imm));
// MOV(64, R(R11), ImmPtr(&g_dsp.r));
FixupBranch notLogicZero = J_CC(CC_NE);
OR(16, sr_reg, Imm16(SR_LOGIC_ZERO));
FixupBranch exit = J();
@ -613,7 +611,6 @@ void DSPEmitter::addr(const UDSPInstruction opc)
u8 dreg = (opc >> 8) & 0x1;
u8 sreg = ((opc >> 9) & 0x3) + DSP_REG_AXL0;
// MOV(64, R(R11), ImmPtr(&g_dsp.r));
// s64 acc = dsp_get_long_acc(dreg);
get_long_acc(dreg, RCX);
MOV(64, R(RAX), R(RCX));
@ -947,7 +944,6 @@ void DSPEmitter::subr(const UDSPInstruction opc)
get_long_acc(dreg, RCX);
MOV(64, R(RAX), R(RCX));
// s64 ax = (s16)g_dsp.r[sreg];
// MOV(64, R(R11), ImmPtr(&g_dsp.r));
dsp_op_read_reg(sreg, RDX, SIGN);
// ax <<= 16;
SHL(64, R(RDX), Imm8(16));
@ -1218,7 +1214,6 @@ void DSPEmitter::movr(const UDSPInstruction opc)
u8 sreg = ((opc >> 9) & 0x3) + DSP_REG_AXL0;
// s64 acc = (s16)g_dsp.r[sreg];
// MOV(64, R(R11), ImmPtr(&g_dsp.r));
dsp_op_read_reg(sreg, RAX, SIGN);
// acc <<= 16;
SHL(64, R(RAX), Imm8(16));

View File

@ -141,7 +141,6 @@ static void WriteBlockLink(DSPEmitter& emitter, u16 dest)
if (emitter.blockLinks[dest] != 0 )
{
emitter.gpr.flushRegs();
#ifdef _M_IX86 // All32
// Check if we have enough cycles to execute the next block
emitter.MOV(16, R(ESI), M(&cyclesLeft));
emitter.CMP(16, R(ESI), Imm16(emitter.blockSize[emitter.startAddr] + emitter.blockSize[dest]));
@ -149,14 +148,6 @@ static void WriteBlockLink(DSPEmitter& emitter, u16 dest)
emitter.SUB(16, R(ESI), Imm16(emitter.blockSize[emitter.startAddr]));
emitter.MOV(16, M(&cyclesLeft), R(ESI));
#else
// Check if we have enough cycles to execute the next block
emitter.MOV(64, R(R12), ImmPtr(&cyclesLeft));
emitter.CMP(16, MatR(R12), Imm16(emitter.blockSize[emitter.startAddr] + emitter.blockSize[dest]));
FixupBranch notEnoughCycles = emitter.J_CC(CC_BE);
emitter.SUB(16, MatR(R12), Imm16(emitter.blockSize[emitter.startAddr]));
#endif
emitter.JMP(emitter.blockLinks[dest], true);
emitter.SetJumpTarget(notEnoughCycles);
}
@ -177,12 +168,7 @@ void r_jcc(const UDSPInstruction opc, DSPEmitter& emitter)
// If the block is unconditional, attempt to link block
if (opcode->uncond_branch)
WriteBlockLink(emitter, dest);
#ifdef _M_IX86 // All32
emitter.MOV(16, M(&(g_dsp.pc)), Imm16(dest));
#else
emitter.MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
emitter.MOV(16, MatR(RAX), Imm16(dest));
#endif
WriteBranchExit(emitter);
}
// Generic jmp implementation
@ -194,12 +180,7 @@ void r_jcc(const UDSPInstruction opc, DSPEmitter& emitter)
// NOTE: Cannot use Default(opc) here because of the need to write branch exit
void DSPEmitter::jcc(const UDSPInstruction opc)
{
#ifdef _M_IX86 // All32
MOV(16, M(&(g_dsp.pc)), Imm16(compilePC + 2));
#else
MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
MOV(16, MatR(RAX), Imm16(compilePC + 2));
#endif
ReJitConditional<r_jcc>(opc, *this);
}
@ -209,12 +190,7 @@ void r_jmprcc(const UDSPInstruction opc, DSPEmitter& emitter)
//reg can only be DSP_REG_ARx and DSP_REG_IXx now,
//no need to handle DSP_REG_STx.
emitter.dsp_op_read_reg(reg, RAX, NONE);
#ifdef _M_IX86 // All32
emitter.MOV(16, M(&g_dsp.pc), R(EAX));
#else
emitter.MOV(64, R(RSI), ImmPtr(&(g_dsp.pc)));
emitter.MOV(16, MatR(RSI), R(RAX));
#endif
WriteBranchExit(emitter);
}
// Generic jmpr implementation
@ -224,12 +200,7 @@ void r_jmprcc(const UDSPInstruction opc, DSPEmitter& emitter)
// NOTE: Cannot use Default(opc) here because of the need to write branch exit
void DSPEmitter::jmprcc(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_jmprcc>(opc, *this);
}
@ -243,12 +214,7 @@ void r_call(const UDSPInstruction opc, DSPEmitter& emitter)
// If the block is unconditional, attempt to link block
if (opcode->uncond_branch)
WriteBlockLink(emitter, dest);
#ifdef _M_IX86 // All32
emitter.MOV(16, M(&(g_dsp.pc)), Imm16(dest));
#else
emitter.MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
emitter.MOV(16, MatR(RAX), Imm16(dest));
#endif
WriteBranchExit(emitter);
}
// Generic call implementation
@ -261,12 +227,7 @@ void r_call(const UDSPInstruction opc, DSPEmitter& emitter)
// NOTE: Cannot use Default(opc) here because of the need to write branch exit
void DSPEmitter::call(const UDSPInstruction opc)
{
#ifdef _M_IX86 // All32
MOV(16, M(&(g_dsp.pc)), Imm16(compilePC + 2));
#else
MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
MOV(16, MatR(RAX), Imm16(compilePC + 2));
#endif
ReJitConditional<r_call>(opc, *this);
}
@ -276,12 +237,7 @@ void r_callr(const UDSPInstruction opc, DSPEmitter& emitter)
emitter.MOV(16, R(DX), Imm16(emitter.compilePC + 1));
emitter.dsp_reg_store_stack(DSP_STACK_C);
emitter.dsp_op_read_reg(reg, RAX, NONE);
#ifdef _M_IX86 // All32
emitter.MOV(16, M(&g_dsp.pc), R(EAX));
#else
emitter.MOV(64, R(RSI), ImmPtr(&(g_dsp.pc)));
emitter.MOV(16, MatR(RSI), R(RAX));
#endif
WriteBranchExit(emitter);
}
// Generic callr implementation
@ -293,23 +249,13 @@ void r_callr(const UDSPInstruction opc, DSPEmitter& emitter)
// NOTE: Cannot use Default(opc) here because of the need to write branch exit
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);
}
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 if implementation
// IFcc
@ -318,12 +264,7 @@ void r_ifcc(const UDSPInstruction opc, DSPEmitter& emitter)
// NOTE: Cannot use Default(opc) here because of the need to write branch exit
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);
WriteBranchExit(*this);
}
@ -331,12 +272,7 @@ void DSPEmitter::ifcc(const UDSPInstruction opc)
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
WriteBranchExit(emitter);
}
@ -348,12 +284,7 @@ void r_ret(const UDSPInstruction opc, DSPEmitter& emitter)
// NOTE: Cannot use Default(opc) here because of the need to write branch exit
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);
}
@ -369,12 +300,7 @@ void DSPEmitter::rti(const UDSPInstruction opc)
dsp_op_write_reg(DSP_REG_SR, RDX);
// 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
@ -382,20 +308,10 @@ void DSPEmitter::rti(const UDSPInstruction opc)
// 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
@ -406,37 +322,20 @@ void DSPEmitter::halt(const UDSPInstruction opc)
// continues at next opcode.
void DSPEmitter::HandleLoop()
{
#ifdef _M_IX86 // All32
MOVZX(32, 16, EAX, M(&g_dsp.r.st[2]));
MOVZX(32, 16, ECX, M(&g_dsp.r.st[3]));
#else
// MOV(64, R(R11), ImmPtr(&g_dsp.r));
MOVZX(32, 16, EAX, MDisp(R11, STRUCT_OFFSET(g_dsp.r, st[2])));
MOVZX(32, 16, ECX, MDisp(R11, STRUCT_OFFSET(g_dsp.r, st[3])));
#endif
CMP(32, R(RCX), Imm32(0));
FixupBranch rLoopCntG = J_CC(CC_LE, true);
CMP(16, R(RAX), Imm16(compilePC - 1));
FixupBranch rLoopAddrG = J_CC(CC_NE, true);
#ifdef _M_IX86 // All32
SUB(16, M(&(g_dsp.r.st[3])), Imm16(1));
CMP(16, M(&(g_dsp.r.st[3])), Imm16(0));
#else
SUB(16, MDisp(R11, STRUCT_OFFSET(g_dsp.r, st[3])), Imm16(1));
CMP(16, MDisp(R11, STRUCT_OFFSET(g_dsp.r, st[3])), Imm16(0));
#endif
FixupBranch loadStack = J_CC(CC_LE, true);
#ifdef _M_IX86 // All32
MOVZX(32, 16, ECX, M(&(g_dsp.r.st[0])));
MOV(16, M(&g_dsp.pc), R(RCX));
#else
MOVZX(32, 16, RCX, MDisp(R11, STRUCT_OFFSET(g_dsp.r, st[0])));
MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
MOV(16, MatR(RAX), R(RCX));
#endif
FixupBranch loopUpdated = J(true);
SetJumpTarget(loadStack);
@ -447,7 +346,6 @@ void DSPEmitter::HandleLoop()
SetJumpTarget(loopUpdated);
SetJumpTarget(rLoopAddrG);
SetJumpTarget(rLoopCntG);
}
// LOOP $R
@ -474,12 +372,7 @@ void DSPEmitter::loop(const UDSPInstruction opc)
dsp_reg_store_stack(2);
SetJumpTarget(cnt);
#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
}
// LOOPI #I
@ -504,12 +397,7 @@ void DSPEmitter::loopi(const UDSPInstruction opc)
MOV(16, R(RDX), Imm16(cnt));
dsp_reg_store_stack(3);
#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
}
}
@ -537,23 +425,13 @@ void DSPEmitter::bloop(const UDSPInstruction opc)
dsp_reg_store_stack(0);
MOV(16, R(RDX), Imm16(loop_pc));
dsp_reg_store_stack(2);
#ifdef _M_IX86 // All32
MOV(16, M(&(g_dsp.pc)), Imm16(compilePC + 2));
#else
MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
MOV(16, MatR(RAX), Imm16(compilePC + 2));
#endif
FixupBranch exit = J();
FixupBranch exit = J(true);
SetJumpTarget(cnt);
// g_dsp.pc = loop_pc;
// dsp_skip_inst();
#ifdef _M_IX86 // All32
MOV(16, M(&g_dsp.pc), Imm16(loop_pc + opTable[loop_pc]->size));
#else
MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
MOV(16, MatR(RAX), Imm16(loop_pc + opTable[loop_pc]->size));
#endif
DSPJitRegCache c(gpr);
WriteBranchExit(*this);
gpr.flushRegs(c,false);
@ -584,23 +462,13 @@ void DSPEmitter::bloopi(const UDSPInstruction opc)
MOV(16, R(RDX), Imm16(cnt));
dsp_reg_store_stack(3);
#ifdef _M_IX86 // All32
MOV(16, M(&(g_dsp.pc)), Imm16(compilePC + 2));
#else
MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
MOV(16, MatR(RAX), Imm16(compilePC + 2));
#endif
}
else
{
// g_dsp.pc = loop_pc;
// dsp_skip_inst();
#ifdef _M_IX86 // All32
MOV(16, M(&g_dsp.pc), Imm16(loop_pc + opTable[loop_pc]->size));
#else
MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
MOV(16, MatR(RAX), Imm16(loop_pc + opTable[loop_pc]->size));
#endif
WriteBranchExit(*this);
}
}

View File

@ -117,12 +117,7 @@ void DSPEmitter::l(const UDSPInstruction opc)
//even if only for one bit, can only
//store (up to) two registers in EBX,
//so store all of SR
#ifdef _M_IX86 // All32
MOV(16, R(EAX), M(&g_dsp.r.sr));
#else
MOV(64, R(RAX), ImmPtr(&g_dsp.r.sr));
MOV(16, R(RAX), MatR(RAX));
#endif
SHL(32, R(EAX), Imm8(16));
OR(32, R(EBX), R(EAX));
}
@ -146,12 +141,7 @@ void DSPEmitter::ln(const UDSPInstruction opc)
//even if only for one bit, can only
//store (up to) two registers in EBX,
//so store all of SR
#ifdef _M_IX86 // All32
MOV(16, R(EAX), M(&g_dsp.r.sr));
#else
MOV(64, R(RAX), ImmPtr(&g_dsp.r.sr));
MOV(16, R(RAX), MatR(RAX));
#endif
SHL(32, R(EAX), Imm8(16));
OR(32, R(EBX), R(EAX));
}

View File

@ -26,78 +26,45 @@ using namespace Gen;
//clobbers:
//EAX = (s8)g_dsp.reg_stack_ptr[stack_reg]
//CX = g_dsp.reg_stack[stack_reg][g_dsp.reg_stack_ptr[stack_reg]]
//expects:
//R11 = &g_dsp.r
void DSPEmitter::dsp_reg_stack_push(int stack_reg)
{
//g_dsp.reg_stack_ptr[stack_reg]++;
//g_dsp.reg_stack_ptr[stack_reg] &= DSP_STACK_MASK;
#ifdef _M_IX86 // All32
MOV(8, R(AL), M(&g_dsp.reg_stack_ptr[stack_reg]));
#else
MOV(8, R(AL), MDisp(R11, PtrOffset(&g_dsp.reg_stack_ptr[stack_reg],
&g_dsp.r)));
#endif
ADD(8, R(AL), Imm8(1));
AND(8, R(AL), Imm8(DSP_STACK_MASK));
#ifdef _M_IX86 // All32
MOV(8, M(&g_dsp.reg_stack_ptr[stack_reg]), R(AL));
#else
MOV(8, MDisp(R11, PtrOffset(&g_dsp.reg_stack_ptr[stack_reg],
&g_dsp.r)), R(AL));
#endif
//g_dsp.reg_stack[stack_reg][g_dsp.reg_stack_ptr[stack_reg]] = g_dsp.r[DSP_REG_ST0 + stack_reg];
#ifdef _M_IX86 // All32
MOV(16, R(CX), M(&g_dsp.r.st[stack_reg]));
#ifdef _M_IX86 // All32
MOVZX(32, 8, EAX, R(AL));
MOV(16, MComplex(EAX, EAX, 1, (u32)&g_dsp.reg_stack[stack_reg][0]), R(CX));
#else
// MOV(64, R(R11), ImmPtr(&g_dsp.r));
MOV(16, R(CX), MDisp(R11, STRUCT_OFFSET(g_dsp.r, st[stack_reg])));
MOVZX(64, 8, RAX, R(AL));
MOV(16, MComplex(R11, RAX, 2,
PtrOffset(&g_dsp.reg_stack[stack_reg][0],&g_dsp.r)),
R(CX));
#endif
MOV(16, MComplex(EAX, EAX, 1, (u64)&g_dsp.reg_stack[stack_reg][0]), R(CX));
}
//clobbers:
//EAX = (s8)g_dsp.reg_stack_ptr[stack_reg]
//CX = g_dsp.reg_stack[stack_reg][g_dsp.reg_stack_ptr[stack_reg]]
//expects:
//R11 = &g_dsp.r
void DSPEmitter::dsp_reg_stack_pop(int stack_reg)
{
//g_dsp.r[DSP_REG_ST0 + stack_reg] = g_dsp.reg_stack[stack_reg][g_dsp.reg_stack_ptr[stack_reg]];
#ifdef _M_IX86 // All32
MOV(8, R(AL), M(&g_dsp.reg_stack_ptr[stack_reg]));
#else
MOV(8, R(AL),
MDisp(R11, PtrOffset(&g_dsp.reg_stack_ptr[stack_reg],&g_dsp.r)));
#endif
#ifdef _M_IX86 // All32
MOVZX(32, 8, EAX, R(AL));
MOV(16, R(CX), MComplex(EAX, EAX, 1, (u32)&g_dsp.reg_stack[stack_reg][0]));
MOV(16, M(&g_dsp.r.st[stack_reg]), R(CX));
#else
MOVZX(64, 8, RAX, R(AL));
MOV(16, R(CX), MComplex(R11, RAX, 2,
PtrOffset(&g_dsp.reg_stack[stack_reg][0],
&g_dsp.r)));
MOV(16, MDisp(R11, STRUCT_OFFSET(g_dsp.r, st[stack_reg])), R(CX));
#endif
MOV(16, R(CX), MComplex(EAX, EAX, 1, (u64)&g_dsp.reg_stack[stack_reg][0]));
MOV(16, M(&g_dsp.r.st[stack_reg]), R(CX));
//g_dsp.reg_stack_ptr[stack_reg]--;
//g_dsp.reg_stack_ptr[stack_reg] &= DSP_STACK_MASK;
SUB(8, R(AL), Imm8(1));
AND(8, R(AL), Imm8(DSP_STACK_MASK));
#ifdef _M_IX86 // All32
MOV(8, M(&g_dsp.reg_stack_ptr[stack_reg]), R(AL));
#else
MOV(8, MDisp(R11, PtrOffset(&g_dsp.reg_stack_ptr[stack_reg],&g_dsp.r)),
R(AL));
#endif
}
@ -108,23 +75,13 @@ void DSPEmitter::dsp_reg_store_stack(int stack_reg, Gen::X64Reg host_sreg)
}
dsp_reg_stack_push(stack_reg);
//g_dsp.r[DSP_REG_ST0 + stack_reg] = val;
#ifdef _M_IX86 // All32
MOV(16, M(&g_dsp.r.st[stack_reg]), R(EDX));
#else
// MOV(64, R(R11), ImmPtr(&g_dsp.r));
MOV(16, MDisp(R11, STRUCT_OFFSET(g_dsp.r, st[stack_reg])), R(EDX));
#endif
}
void DSPEmitter::dsp_reg_load_stack(int stack_reg, Gen::X64Reg host_dreg)
{
//u16 val = g_dsp.r[DSP_REG_ST0 + stack_reg];
#ifdef _M_IX86 // All32
MOV(16, R(EDX), M(&g_dsp.r.st[stack_reg]));
#else
// MOV(64, R(R11), ImmPtr(&g_dsp.r));
MOV(16, R(EDX), MDisp(R11, STRUCT_OFFSET(g_dsp.r, st[stack_reg])));
#endif
dsp_reg_stack_pop(stack_reg);
if (host_dreg != EDX) {
MOV(16, R(host_dreg), R(EDX));
@ -135,12 +92,7 @@ void DSPEmitter::dsp_reg_store_stack_imm(int stack_reg, u16 val)
{
dsp_reg_stack_push(stack_reg);
//g_dsp.r[DSP_REG_ST0 + stack_reg] = val;
#ifdef _M_IX86 // All32
MOV(16, M(&g_dsp.r.st[stack_reg]), Imm16(val));
#else
// MOV(64, R(R11), ImmPtr(&g_dsp.r));
MOV(16, MDisp(R11, STRUCT_OFFSET(g_dsp.r, st[stack_reg])), Imm16(val));
#endif
}
void DSPEmitter::dsp_op_write_reg(int reg, Gen::X64Reg host_sreg)

View File

@ -168,8 +168,8 @@ void DSPEmitter::clrp(const UDSPInstruction opc)
// g_dsp.r[DSP_REG_PRODH] = 0x00ff;
// g_dsp.r[DSP_REG_PRODM2] = 0x0010;
//64bit move to memory does not work. use 2 32bits
MOV(32, MDisp(R11, STRUCT_OFFSET(g_dsp.r, prod.val)+0), Imm32(0xfff00000U));
MOV(32, MDisp(R11, STRUCT_OFFSET(g_dsp.r, prod.val)+4), Imm32(0x001000ffU));
MOV(32, M(&g_dsp.r.prod.val), Imm32(0xfff00000U));
MOV(32, M((u8*)(&g_dsp.r.prod.val)+4), Imm32(0x001000ffU));
#else
Default(opc);
#endif
@ -466,7 +466,6 @@ void DSPEmitter::mulx(const UDSPInstruction opc)
u8 treg = ((opc >> 11) & 0x1);
u8 sreg = ((opc >> 12) & 0x1);
// MOV(64, R(R11), ImmPtr(&g_dsp.r));
// u16 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0);
dsp_op_read_reg(DSP_REG_AXL0 + sreg*2, RSI, SIGN);
// u16 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1);
@ -715,7 +714,6 @@ void DSPEmitter::mulcmvz(const UDSPInstruction opc)
u8 treg = (opc >> 11) & 0x1;
u8 sreg = (opc >> 12) & 0x1;
// MOV(64, R(R11), ImmPtr(&g_dsp.r));
// s64 acc = dsp_get_long_prod_round_prodl();
get_long_prod_round_prodl();
PUSH(64, R(RAX));

View File

@ -126,11 +126,7 @@ DSPJitRegCache::DSPJitRegCache(DSPEmitter &_emitter)
regs[DSP_REG_AX1_32].size = 4;
for(unsigned int i = 0; i < DSP_REG_MAX_MEM_BACKED+1; i++) {
regs[i].dirty = false;
#ifdef _M_IX86 // All32
regs[i].loc = M(regs[i].mem);
#else
regs[i].loc = MDisp(R11, PtrOffset(regs[i].mem, &g_dsp.r));
#endif
}
}
@ -218,10 +214,10 @@ void DSPJitRegCache::loadStaticRegs()
{
#ifdef _M_X64
#ifdef ROTATED_REG_ACCS
emitter.MOV(64, R(R8), MDisp(R11, STRUCT_OFFSET(g_dsp.r, ac[0].val)));
emitter.MOV(64, R(R9), MDisp(R11, STRUCT_OFFSET(g_dsp.r, ac[1].val)));
emitter.MOV(64, R(R8), M(&g_dsp.r.ac[0].val));
emitter.MOV(64, R(R9), M(&g_dsp.r.ac[1].val));
#endif
emitter.MOV(64, MDisp(R11, PtrOffset(&ebp_store, &g_dsp.r)), R(RBP));
emitter.MOV(64, M(&ebp_store), R(RBP));
#else
emitter.MOV(32, M(&ebp_store), R(EBP));
#endif
@ -232,10 +228,10 @@ void DSPJitRegCache::saveStaticRegs()
flushRegs();
#ifdef _M_X64
#ifdef ROTATED_REG_ACCS
emitter.MOV(64, MDisp(R11, STRUCT_OFFSET(g_dsp.r, ac[0].val)), R(R8));
emitter.MOV(64, MDisp(R11, STRUCT_OFFSET(g_dsp.r, ac[1].val)), R(R9));
emitter.MOV(64, M(&g_dsp.r.ac[0].val), R(R8));
emitter.MOV(64, M(&g_dsp.r.ac[1].val), R(R9));
#endif
emitter.MOV(64, R(RBP), MDisp(R11, PtrOffset(&ebp_store, &g_dsp.r)));
emitter.MOV(64, R(RBP), M(&ebp_store));
#else
emitter.MOV(32, R(EBP), M(&ebp_store));
#endif
@ -327,11 +323,7 @@ void DSPJitRegCache::getReg(int reg, OpArg &oparg, bool load)
if (load) {
u16 *regp = reg_ptr(reg);
#ifdef _M_IX86 // All32
emitter.MOV(16, oparg, M(regp));
#else
emitter.MOV(16, oparg, MDisp(R11, PtrOffset(regp, &g_dsp.r)));
#endif
}
*/
oparg = regs[reg].loc; //when loading/storing from/to mem, need to consider regs[reg].size
@ -390,7 +382,7 @@ void DSPJitRegCache::putReg(int reg, bool dirty)
//need to fix in memory for now.
u16 *regp = reg_ptr(reg);
OpArg mem;
mem = MDisp(R11,PtrOffset(regp,&g_dsp.r));
mem = M(regp);
X64Reg tmp;
getFreeXReg(tmp);
// sign extend from the bottom 8 bits.
@ -424,11 +416,7 @@ void DSPJitRegCache::putReg(int reg, bool dirty)
if(dirty) {
u16 *regp = reg_ptr(reg);
#ifdef _M_IX86 // All32
emitter.MOV(16, M(dregp), R(tmp));
#else
emitter.MOV(16, MDisp(R11, PtrOffset(dregp, &g_dsp.r)), R(tmp));
#endif
}
*/
}

View File

@ -324,7 +324,6 @@ void DSPEmitter::imem_read()
// In: ECX - the address to read
// Out: EAX - the result of the read (used by caller)
// ESI - Base
// Trashes R11 on gdsp_ifx_read
void DSPEmitter::dmem_read()
{
// if (saddr == 0)
@ -408,7 +407,6 @@ void DSPEmitter::dmem_read_imm(u16 address)
void DSPEmitter::get_long_prod(X64Reg long_prod)
{
#ifdef _M_X64
// MOV(64, R(R11), ImmPtr(&g_dsp.r));
//s64 val = (s8)(u8)g_dsp.r[DSP_REG_PRODH];
OpArg reg;
gpr.getReg(DSP_REG_PROD_64, reg);
@ -581,9 +579,6 @@ void DSPEmitter::get_ax_h(int _reg, X64Reg axh)
void DSPEmitter::LoadDSPRegs()
{
#ifdef _M_X64
MOV(64, R(R11), ImmPtr(&g_dsp.r));
#endif
// Load DSP register state here...
gpr.loadStaticRegs();