Core/DSPCore: Make JIT work on 64 bit hosts

This is the safe variant that does not assume other
functions use R11 for &g_dsp.r, which they actually do.
So there is a lot unnecessary reloading of the register
getting emitted.

There are a few small changes exploiting pointers known
at emission time and making use of MComplex math.

Also renames m_LLEplaying to m_AIplaying in Core/AudioCommon.


git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6245 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
pierre 2010-10-01 23:23:13 +00:00
parent c8c805f720
commit b80e207a8a
6 changed files with 313 additions and 26 deletions

View File

@ -37,17 +37,17 @@ unsigned int CMixer::Mix(short* samples, unsigned int numSamples)
}
unsigned int numLeft = Common::AtomicLoad(m_numSamples);
if (m_LLEplaying) {
if (m_AIplaying) {
if (numLeft < numSamples)//cannot do much about this
m_LLEplaying = false;
m_AIplaying = false;
if (numLeft < MAX_SAMPLES/4)//low watermark
m_LLEplaying = false;
m_AIplaying = false;
} else {
if (numLeft > MAX_SAMPLES/2)//high watermark
m_LLEplaying = true;
m_AIplaying = true;
}
if (m_LLEplaying) {
if (m_AIplaying) {
numLeft = (numLeft > numSamples) ? numSamples : numLeft;
// Do re-sampling if needed

View File

@ -35,7 +35,7 @@ public:
, m_numSamples(0)
, m_indexW(0)
, m_indexR(0)
, m_LLEplaying(true)
, m_AIplaying(true)
{
// AyuanX: The internal (Core & DSP) sample rate is fixed at 32KHz
// So when AI/DAC sample rate differs than 32KHz, we have to do re-sampling
@ -81,7 +81,7 @@ protected:
u32 m_indexW;
u32 m_indexR;
bool m_LLEplaying;
bool m_AIplaying;
private:

View File

@ -85,7 +85,12 @@ void DSPEmitter::checkExceptions() {
*/
ABI_CallFunction((void *)&DSPCore_CheckExternalInterrupt);
// 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, MDisp(RAX,0), Imm8(0xff));
#endif
FixupBranch skipCheck = J_CC(CC_Z);
ABI_CallFunction((void *)&DSPCore_CheckExceptions);
@ -165,7 +170,12 @@ const u8 *DSPEmitter::Compile(int start_addr) {
const DSPOPCTemplate *opcode = GetOpTemplate(inst);
// Increment PC - we shouldn't need to do this for every instruction. only for branches and end of block.
#ifdef _M_IX86 // All32
ADD(16, M(&(g_dsp.pc)), Imm16(1));
#else
MOV(64, R(RAX), ImmPtr(&(g_dsp.pc)));
ADD(16, MDisp(RAX,0), Imm16(1));
#endif
EmitInstruction(inst);
@ -175,11 +185,20 @@ const u8 *DSPEmitter::Compile(int start_addr) {
// if (DSPAnalyzer::code_flags[addr] & DSPAnalyzer::CODE_LOOP_END)
{
// TODO: Change to TEST for some reason (who added this comment?)
#ifdef _M_IX86 // All32
MOVZX(32, 16, EAX, M(&(g_dsp.r[DSP_REG_ST2])));
#else
MOV(64, R(R11), ImmPtr(&g_dsp.r));
MOVZX(32, 16, EAX, MDisp(R11,DSP_REG_ST2*2));
#endif
CMP(32, R(EAX), Imm32(0));
FixupBranch rLoopAddressExit = J_CC(CC_LE);
#ifdef _M_IX86 // All32
MOVZX(32, 16, EAX, M(&(g_dsp.r[DSP_REG_ST3])));
#else
MOVZX(32, 16, EAX, MDisp(R11,DSP_REG_ST3*2));
#endif
CMP(32, R(EAX), Imm32(0));
FixupBranch rLoopCounterExit = J_CC(CC_LE);

View File

@ -106,7 +106,12 @@ void DSPEmitter::l(const UDSPInstruction opc)
else
{
ext_dmem_read(sreg);
#ifdef _M_IX86 // All32
MOV(16, M(&g_dsp.r[dreg]), R(EAX));
#else
MOV(64, R(R11), ImmPtr(&g_dsp.r));
MOV(16, MDisp(RDX,dreg*2), R(EAX));
#endif
increment_addr_reg(sreg);
}
}
@ -133,7 +138,12 @@ void DSPEmitter::ln(const UDSPInstruction opc)
else
{
ext_dmem_read(sreg);
#ifdef _M_IX86 // All32
MOV(16, M(&g_dsp.r[dreg]), R(EAX));
#else
MOV(64, R(R11), ImmPtr(&g_dsp.r));
MOV(16, MDisp(RDX,dreg*2), R(EAX));
#endif
increase_addr_reg(sreg);
}
}
@ -309,21 +319,42 @@ void DSPEmitter::ld(const UDSPInstruction opc)
if (sreg != DSP_REG_AR3) {
ext_dmem_read(sreg);
#ifdef _M_IX86 // All32
MOV(16, M(&g_dsp.r[(dreg << 1) + DSP_REG_AXL0]), R(EAX));
#else
MOV(64, R(R11), ImmPtr(&g_dsp.r));
MOV(16, MDisp(R11,((dreg << 1) + DSP_REG_AXL0)*2), R(EAX));
#endif
// if (IsSameMemArea(g_dsp.r[sreg], g_dsp.r[DSP_REG_AR3])) {
#ifdef _M_IX86 // All32
MOV(16, R(ESI), M(&g_dsp.r[sreg]));
MOV(16, R(EDI), M(&g_dsp.r[g_dsp.r[DSP_REG_AR3]]));
#else
MOV(16, R(ESI), MDisp(R11,sreg*2));
MOVZX(64, 16, RDI, MDisp(R11,DSP_REG_AR3*2));
MOV(16, R(EDI), MComplex(R11,RDI,2,0));
#endif
SHR(16, R(ESI), Imm8(10));
SHR(16, R(EDI), Imm8(10));
CMP(16, R(ESI), R(EDI));
FixupBranch not_equal = J_CC(CC_NE);
ext_dmem_read(sreg);
#ifdef _M_IX86 // All32
MOV(16, M(&g_dsp.r[(rreg << 1) + DSP_REG_AXL1]), R(EAX));
FixupBranch after = J();
#else
MOV(64, R(R11), ImmPtr(&g_dsp.r));
MOV(16, MDisp(R11,((rreg << 1) + DSP_REG_AXL1)*2), R(EAX));
#endif
FixupBranch after = J();
SetJumpTarget(not_equal); // else
ext_dmem_read(DSP_REG_AR3);
MOV(16, M(&g_dsp.r[(rreg << 1) + DSP_REG_AXL1]), R(EAX));
#ifdef _M_IX86 // All32
MOV(16, M(&g_dsp.r[(rreg << 1) + DSP_REG_AXL1]), R(EAX));
#else
MOV(64, R(R11), ImmPtr(&g_dsp.r));
MOV(16, MDisp(R11,((rreg << 1) + DSP_REG_AXL1)*2), R(EAX));
#endif
SetJumpTarget(after);
increment_addr_reg(sreg);
@ -331,21 +362,42 @@ void DSPEmitter::ld(const UDSPInstruction opc)
} else {
ext_dmem_read(dreg);
#ifdef _M_IX86 // All32
MOV(16, M(&g_dsp.r[rreg + DSP_REG_AXH0]), R(EAX));
#else
MOV(64, R(R11), ImmPtr(g_dsp.r));
MOV(16, MDisp(R11,(rreg + DSP_REG_AXH0)*2), R(EAX));
#endif
//if (IsSameMemArea(g_dsp.r[dreg], g_dsp.r[DSP_REG_AR3])) {
#ifdef _M_IX86 // All32
MOV(16, R(ESI), M(&g_dsp.r[dreg]));
MOV(16, R(EDI), M(&g_dsp.r[g_dsp.r[DSP_REG_AR3]]));
#else
MOV(16, R(ESI), MDisp(R11,dreg*2));
MOVZX(64, 16, RDI, MDisp(R11,DSP_REG_AR3*2));
MOV(16, R(EDI), MComplex(R11,RDI,2,0));
#endif
SHR(16, R(ESI), Imm8(10));
SHR(16, R(EDI), Imm8(10));
CMP(16, R(ESI), R(EDI));
FixupBranch not_equal = J_CC(CC_NE);
ext_dmem_read(dreg);
#ifdef _M_IX86 // All32
MOV(16, M(&g_dsp.r[rreg + DSP_REG_AXL0]), R(EAX));
#else
MOV(64, R(R11), ImmPtr(&g_dsp.r));
MOV(16, MDisp(R11,(rreg + DSP_REG_AXL0)*2), R(EAX));
#endif
FixupBranch after = J(); // else
SetJumpTarget(not_equal);
ext_dmem_read(DSP_REG_AR3);
#ifdef _M_IX86 // All32
MOV(16, M(&g_dsp.r[rreg + DSP_REG_AXL0]), R(EAX));
#else
MOV(64, R(R11), ImmPtr(&g_dsp.r));
MOV(16, MDisp(R11,(rreg + DSP_REG_AXL0)*2), R(EAX));
#endif
SetJumpTarget(after);
increment_addr_reg(dreg);
@ -365,41 +417,83 @@ void DSPEmitter::ldn(const UDSPInstruction opc)
if (sreg != DSP_REG_AR3) {
ext_dmem_read(sreg);
#ifdef _M_IX86 // All32
MOV(16, M(&g_dsp.r[(dreg << 1) + DSP_REG_AXL0]), R(EAX));
#else
MOV(64, R(R11), ImmPtr(g_dsp.r));
MOV(16, MDisp(R11,((dreg << 1) + DSP_REG_AXL0)*2), R(EAX));
#endif
// if (IsSameMemArea(g_dsp.r[sreg], g_dsp.r[DSP_REG_AR3])) {
#ifdef _M_IX86 // All32
MOV(16, R(ESI), M(&g_dsp.r[sreg]));
MOV(16, R(EDI), M(&g_dsp.r[g_dsp.r[DSP_REG_AR3]]));
#else
MOV(16, R(ESI), MDisp(R11,sreg*2));
MOVZX(64, 16, RDI, MDisp(R11,DSP_REG_AR3*2));
MOV(16, R(EDI), MComplex(R11,RDI,2,0));
#endif
SHR(16, R(ESI), Imm8(10));
SHR(16, R(EDI), Imm8(10));
CMP(16, R(ESI), R(EDI));
FixupBranch not_equal = J_CC(CC_NE);
ext_dmem_read(sreg);
#ifdef _M_IX86 // All32
MOV(16, M(&g_dsp.r[(rreg << 1) + DSP_REG_AXL1]), R(EAX));
FixupBranch after = J();
#else
MOV(64, R(R11), ImmPtr(&g_dsp.r));
MOV(16, MDisp(R11,((rreg << 1) + DSP_REG_AXL1)*2), R(EAX));
#endif
FixupBranch after = J();
SetJumpTarget(not_equal); // else
ext_dmem_read(DSP_REG_AR3);
MOV(16, M(&g_dsp.r[(rreg << 1) + DSP_REG_AXL1]), R(EAX));
#ifdef _M_IX86 // All32
MOV(16, M(&g_dsp.r[(rreg << 1) + DSP_REG_AXL1]), R(EAX));
#else
MOV(64, R(R11), ImmPtr(&g_dsp.r));
MOV(16, MDisp(R11,((rreg << 1) + DSP_REG_AXL1)*2), R(EAX));
#endif
SetJumpTarget(after);
increase_addr_reg(sreg);
} else {
ext_dmem_read(dreg);
#ifdef _M_IX86 // All32
MOV(16, M(&g_dsp.r[rreg + DSP_REG_AXH0]), R(EAX));
#else
MOV(64, R(R11), ImmPtr(g_dsp.r));
MOV(16, MDisp(R11,(rreg + DSP_REG_AXH0)*2), R(EAX));
#endif
//if (IsSameMemArea(g_dsp.r[dreg], g_dsp.r[DSP_REG_AR3])) {
#ifdef _M_IX86 // All32
MOV(16, R(ESI), M(&g_dsp.r[dreg]));
MOV(16, R(EDI), M(&g_dsp.r[g_dsp.r[DSP_REG_AR3]]));
#else
MOV(16, R(ESI), MDisp(R11,dreg*2));
MOVZX(64, 16, RDI, MDisp(R11,DSP_REG_AR3*2));
MOV(16, R(EDI), MComplex(R11,RDI,2,0));
#endif
SHR(16, R(ESI), Imm8(10));
SHR(16, R(EDI), Imm8(10));
CMP(16, R(ESI), R(EDI));
FixupBranch not_equal = J_CC(CC_NE);
ext_dmem_read(dreg);
#ifdef _M_IX86 // All32
MOV(16, M(&g_dsp.r[rreg + DSP_REG_AXL0]), R(EAX));
#else
MOV(64, R(R11), ImmPtr(&g_dsp.r));
MOV(16, MDisp(R11,(rreg + DSP_REG_AXL0)*2), R(EAX));
#endif
FixupBranch after = J(); // else
SetJumpTarget(not_equal);
ext_dmem_read(DSP_REG_AR3);
#ifdef _M_IX86 // All32
MOV(16, M(&g_dsp.r[rreg + DSP_REG_AXL0]), R(EAX));
#else
MOV(64, R(R11), ImmPtr(&g_dsp.r));
MOV(16, MDisp(R11,(rreg + DSP_REG_AXL0)*2), R(EAX));
#endif
SetJumpTarget(after);
increase_addr_reg(dreg);
@ -418,42 +512,84 @@ void DSPEmitter::ldm(const UDSPInstruction opc)
if (sreg != DSP_REG_AR3) {
ext_dmem_read(sreg);
#ifdef _M_IX86 // All32
MOV(16, M(&g_dsp.r[(dreg << 1) + DSP_REG_AXL0]), R(EAX));
#else
MOV(64, R(R11), ImmPtr(g_dsp.r));
MOV(16, MDisp(R11,((dreg << 1) + DSP_REG_AXL0)*2), R(EAX));
#endif
// if (IsSameMemArea(g_dsp.r[sreg], g_dsp.r[DSP_REG_AR3])) {
#ifdef _M_IX86 // All32
MOV(16, R(ESI), M(&g_dsp.r[sreg]));
MOV(16, R(EDI), M(&g_dsp.r[g_dsp.r[DSP_REG_AR3]]));
#else
MOV(16, R(ESI), MDisp(R11,sreg*2));
MOVZX(64, 16, RDI, MDisp(R11,DSP_REG_AR3*2));
MOV(16, R(EDI), MComplex(R11,RDI,2,0));
#endif
SHR(16, R(ESI), Imm8(10));
SHR(16, R(EDI), Imm8(10));
CMP(16, R(ESI), R(EDI));
FixupBranch not_equal = J_CC(CC_NE);
ext_dmem_read(sreg);
#ifdef _M_IX86 // All32
MOV(16, M(&g_dsp.r[(rreg << 1) + DSP_REG_AXL1]), R(EAX));
#else
MOV(64, R(R11), ImmPtr(&g_dsp.r));
MOV(16, MDisp(R11,((rreg << 1) + DSP_REG_AXL1)*2), R(EAX));
#endif
FixupBranch after = J();
SetJumpTarget(not_equal); // else
ext_dmem_read(DSP_REG_AR3);
MOV(16, M(&g_dsp.r[(rreg << 1) + DSP_REG_AXL1]), R(EAX));
#ifdef _M_IX86 // All32
MOV(16, M(&g_dsp.r[(rreg << 1) + DSP_REG_AXL1]), R(EAX));
#else
MOV(64, R(R11), ImmPtr(&g_dsp.r));
MOV(16, MDisp(R11,((rreg << 1) + DSP_REG_AXL1)*2), R(EAX));
#endif
SetJumpTarget(after);
increment_addr_reg(sreg);
} else {
ext_dmem_read(dreg);
#ifdef _M_IX86 // All32
MOV(16, M(&g_dsp.r[rreg + DSP_REG_AXH0]), R(EAX));
#else
MOV(64, R(R11), ImmPtr(g_dsp.r));
MOV(16, MDisp(R11,(rreg + DSP_REG_AXH0)*2), R(EAX));
#endif
//if (IsSameMemArea(g_dsp.r[dreg], g_dsp.r[DSP_REG_AR3])) {
#ifdef _M_IX86 // All32
MOV(16, R(ESI), M(&g_dsp.r[dreg]));
MOV(16, R(EDI), M(&g_dsp.r[g_dsp.r[DSP_REG_AR3]]));
#else
MOV(16, R(ESI), MDisp(R11,dreg*2));
MOVZX(64, 16, RDI, MDisp(R11,DSP_REG_AR3*2));
MOV(16, R(EDI), MComplex(R11,RDI,2,0));
#endif
SHR(16, R(ESI), Imm8(10));
SHR(16, R(EDI), Imm8(10));
CMP(16, R(ESI), R(EDI));
FixupBranch not_equal = J_CC(CC_NE);
ext_dmem_read(dreg);
#ifdef _M_IX86 // All32
MOV(16, M(&g_dsp.r[rreg + DSP_REG_AXL0]), R(EAX));
#else
MOV(64, R(R11), ImmPtr(&g_dsp.r));
MOV(16, MDisp(R11,(rreg + DSP_REG_AXL0)*2), R(EAX));
#endif
FixupBranch after = J(); // else
SetJumpTarget(not_equal);
ext_dmem_read(DSP_REG_AR3);
#ifdef _M_IX86 // All32
MOV(16, M(&g_dsp.r[rreg + DSP_REG_AXL0]), R(EAX));
#else
MOV(64, R(R11), ImmPtr(&g_dsp.r));
MOV(16, MDisp(R11,(rreg + DSP_REG_AXL0)*2), R(EAX));
#endif
SetJumpTarget(after);
increment_addr_reg(dreg);
@ -472,41 +608,83 @@ void DSPEmitter::ldnm(const UDSPInstruction opc)
if (sreg != DSP_REG_AR3) {
ext_dmem_read(sreg);
#ifdef _M_IX86 // All32
MOV(16, M(&g_dsp.r[(dreg << 1) + DSP_REG_AXL0]), R(EAX));
#else
MOV(64, R(R11), ImmPtr(&g_dsp.r));
MOV(16, MDisp(R11,((dreg << 1) + DSP_REG_AXL0)*2), R(EAX));
#endif
// if (IsSameMemArea(g_dsp.r[sreg], g_dsp.r[DSP_REG_AR3])) {
#ifdef _M_IX86 // All32
MOV(16, R(ESI), M(&g_dsp.r[sreg]));
MOV(16, R(EDI), M(&g_dsp.r[g_dsp.r[DSP_REG_AR3]]));
#else
MOV(16, R(ESI), MDisp(R11,sreg*2));
MOVZX(64, 16, RDI, MDisp(R11,DSP_REG_AR3*2));
MOV(16, R(EDI), MComplex(R11,RDI,2,0));
#endif
SHR(16, R(ESI), Imm8(10));
SHR(16, R(EDI), Imm8(10));
CMP(16, R(ESI), R(EDI));
FixupBranch not_equal = J_CC(CC_NE);
ext_dmem_read(sreg);
#ifdef _M_IX86 // All32
MOV(16, M(&g_dsp.r[(rreg << 1) + DSP_REG_AXL1]), R(EAX));
#else
MOV(64, R(R11), ImmPtr(&g_dsp.r));
MOV(16, MDisp(R11,((rreg << 1) + DSP_REG_AXL1)*2), R(EAX));
#endif
FixupBranch after = J();
SetJumpTarget(not_equal); // else
ext_dmem_read(DSP_REG_AR3);
MOV(16, M(&g_dsp.r[(rreg << 1) + DSP_REG_AXL1]), R(EAX));
#ifdef _M_IX86 // All32
MOV(16, M(&g_dsp.r[(rreg << 1) + DSP_REG_AXL1]), R(EAX));
#else
MOV(64, R(R11), ImmPtr(&g_dsp.r));
MOV(16, MDisp(R11,((rreg << 1) + DSP_REG_AXL1)*2), R(EAX));
#endif
SetJumpTarget(after);
increase_addr_reg(sreg);
} else {
ext_dmem_read(dreg);
#ifdef _M_IX86 // All32
MOV(16, M(&g_dsp.r[rreg + DSP_REG_AXH0]), R(EAX));
#else
MOV(64, R(R11), ImmPtr(g_dsp.r));
MOV(16, MDisp(R11,(rreg + DSP_REG_AXH0)*2), R(EAX));
#endif
//if (IsSameMemArea(g_dsp.r[dreg], g_dsp.r[DSP_REG_AR3])) {
#ifdef _M_IX86 // All32
MOV(16, R(ESI), M(&g_dsp.r[dreg]));
MOV(16, R(EDI), M(&g_dsp.r[g_dsp.r[DSP_REG_AR3]]));
#else
MOV(16, R(ESI), MDisp(R11,dreg*2));
MOVZX(64, 16, RDI, MDisp(R11,DSP_REG_AR3*2));
MOV(16, R(EDI), MComplex(R11,RDI,2,0));
#endif
SHR(16, R(ESI), Imm8(10));
SHR(16, R(EDI), Imm8(10));
CMP(16, R(ESI), R(EDI));
FixupBranch not_equal = J_CC(CC_NE);
ext_dmem_read(dreg);
#ifdef _M_IX86 // All32
MOV(16, M(&g_dsp.r[rreg + DSP_REG_AXL0]), R(EAX));
#else
MOV(64, R(R11), ImmPtr(&g_dsp.r));
MOV(16, MDisp(R11,(rreg + DSP_REG_AXL0)*2), R(EAX));
#endif
FixupBranch after = J(); // else
SetJumpTarget(not_equal);
ext_dmem_read(DSP_REG_AR3);
#ifdef _M_IX86 // All32
MOV(16, M(&g_dsp.r[rreg + DSP_REG_AXL0]), R(EAX));
#else
MOV(64, R(R11), ImmPtr(&g_dsp.r));
MOV(16, MDisp(R11,(rreg + DSP_REG_AXL0)*2), R(EAX));
#endif
SetJumpTarget(after);
increase_addr_reg(dreg);
@ -519,7 +697,12 @@ void DSPEmitter::ldnm(const UDSPInstruction opc)
// Push value from g_dsp.r[sreg] into EBX and stores the destinationindex in
// storeIndex
void DSPEmitter::pushExtValueFromReg(u16 dreg, u16 sreg) {
#ifdef _M_IX86 // All32
MOVZX(32, 16, EBX, M(&g_dsp.r[sreg]));
#else
MOV(64, R(RBX), ImmPtr(&g_dsp.r));
MOVZX(32, 16, EBX, MDisp(RBX,sreg*2));
#endif
storeIndex = dreg;
}
@ -538,8 +721,14 @@ void DSPEmitter::popExtValueToReg() {
// nakee wants to keep it clean, so lets do that.
// [nakeee] the or case never happens in real
// [nakeee] it's just how the hardware works so we added it
if (storeIndex != -1)
if (storeIndex != -1) {
#ifdef _M_IX86 // All32
MOV(16, M(&g_dsp.r[storeIndex]), R(EBX));
#else
MOV(64, R(R11), ImmPtr(&g_dsp.r));
MOV(16, MDisp(R11,storeIndex*2), R(EBX));
#endif
}
storeIndex = -1;
// TODO handle commands such as 'l

View File

@ -132,7 +132,12 @@ void DSPEmitter::addarn(const UDSPInstruction opc)
void DSPEmitter::setCompileSR(u16 bit) {
// g_dsp.r[DSP_REG_SR] |= bit
#ifdef _M_IX86 // All32
OR(16, M(&g_dsp.r[DSP_REG_SR]), Imm16(bit));
#else
MOV(64, R(R11), ImmPtr(g_dsp.r));
OR(16, MDisp(R11,DSP_REG_SR*2), Imm16(bit));
#endif
compileSR |= bit;
}
@ -140,7 +145,12 @@ void DSPEmitter::setCompileSR(u16 bit) {
void DSPEmitter::clrCompileSR(u16 bit) {
// g_dsp.r[DSP_REG_SR] &= bit
#ifdef _M_IX86 // All32
AND(16, M(&g_dsp.r[DSP_REG_SR]), Imm16(~bit));
#else
MOV(64, R(R11), ImmPtr(g_dsp.r));
AND(16, MDisp(R11,DSP_REG_SR*2), Imm16(~bit));
#endif
compileSR &= ~bit;
}

View File

@ -69,17 +69,28 @@ void DSPEmitter::dsp_increment_one(X64Reg ar, X64Reg wr, X64Reg wr_pow, X64Reg t
void DSPEmitter::increment_addr_reg(int reg)
{
// s16 tmp = g_dsp.r[reg];
#ifdef _M_IX86 // All32
MOV(16, R(EAX), M(&g_dsp.r[reg]));
MOV(16, R(EDX), M(&g_dsp.r[DSP_REG_WR0 + reg]));
#else
MOV(64, R(R11), ImmPtr(g_dsp.r));
MOV(16, R(EAX), MDisp(R11,reg*2));
MOV(16, R(EDX), MDisp(R11,(DSP_REG_WR0 + reg)*2));
#endif
// ToMask(WR0), calculating it into EDI
MOV(16, R(EDI), R(EDX));
ToMask(EDI);
dsp_increment_one(EAX, EDX, EDI);
// g_dsp.r[reg] = tmp;
// g_dsp.r[reg] = tmp;
#ifdef _M_IX86 // All32
MOV(16, M(&g_dsp.r[reg]), R(EAX));
#else
MOV(64, R(R11), ImmPtr(g_dsp.r));
MOV(16, MDisp(R11,reg*2), R(EAX));
#endif
}
// See http://code.google.com/p/dolphin-emu/source/detail?r=3125
@ -115,8 +126,14 @@ void DSPEmitter::dsp_decrement_one(X64Reg ar, X64Reg wr, X64Reg wr_pow, X64Reg t
void DSPEmitter::decrement_addr_reg(int reg)
{
// s16 ar = g_dsp.r[reg];
#ifdef _M_IX86 // All32
MOV(16, R(EAX), M(&g_dsp.r[reg]));
MOV(16, R(EDX), M(&g_dsp.r[DSP_REG_WR0 + reg]));
#else
MOV(64, R(R11), ImmPtr(&g_dsp.r));
MOV(16, R(EAX), MDisp(R11,reg*2));
MOV(16, R(EDX), MDisp(R11,(DSP_REG_WR0 + reg)*2));
#endif
// ToMask(WR0), calculating it into EDI
MOV(16, R(EDI), R(EDX));
@ -125,7 +142,12 @@ void DSPEmitter::decrement_addr_reg(int reg)
dsp_decrement_one(EAX, EDX, EDI);
// g_dsp.r[reg] = tmp;
#ifdef _M_IX86 // All32
MOV(16, M(&g_dsp.r[reg]), R(EAX));
#else
MOV(64, R(R11), ImmPtr(g_dsp.r));
MOV(16, MDisp(R11,reg*2), R(EAX));
#endif
}
// Increase addr register according to the correspond ix register
@ -135,7 +157,12 @@ void DSPEmitter::decrement_addr_reg(int reg)
// EDI = tomask(EDX)
void DSPEmitter::increase_addr_reg(int reg)
{
#ifdef _M_IX86 // All32
MOVZX(32, 16, ECX, M(&g_dsp.r[DSP_REG_IX0 + reg]));
#else
MOV(64, R(R11), ImmPtr(&g_dsp.r));
MOVZX(32, 16, ECX, MDisp(R11,(DSP_REG_IX0 + reg)*2));
#endif
// IX0 == 0, bail out
TEST(16, R(ECX), R(ECX));
@ -143,8 +170,13 @@ void DSPEmitter::increase_addr_reg(int reg)
// TODO: optimize a bit, maybe merge loops?
FixupBranch end = J_CC(CC_Z, true);
#ifdef _M_IX86 // All32
MOV(16, R(EAX), M(&g_dsp.r[reg]));
MOV(16, R(EDX), M(&g_dsp.r[DSP_REG_WR0 + reg]));
#else
MOV(16, R(EAX), MDisp(R11,reg*2));
MOV(16, R(EDX), MDisp(R11,(DSP_REG_WR0 + reg)*2));
#endif
// ToMask(WR0), calculating it into EDI
MOV(16, R(EDI), R(EDX));
@ -162,7 +194,12 @@ void DSPEmitter::increase_addr_reg(int reg)
dsp_increment_one(EAX, EDX, EDI);
SUB(16, R(ECX), Imm16(1)); // value--
#ifdef _M_IX86 // All32
CMP(16, M(&g_dsp.r[DSP_REG_IX0 + reg]), Imm16(127));
#else
MOV(64, R(R11), ImmPtr(g_dsp.r));
CMP(16, MDisp(R11,(DSP_REG_IX0 + reg)*2), Imm16(127));
#endif
FixupBranch dbg = J_CC(CC_NE);
CMP(16, R(ECX), Imm16(1));
FixupBranch dbg2 = J_CC(CC_NE);
@ -187,7 +224,12 @@ void DSPEmitter::increase_addr_reg(int reg)
SetJumpTarget(end_pos);
// g_dsp.r[reg] = tmp;
#ifdef _M_IX86 // All32
MOV(16, M(&g_dsp.r[reg]), R(EAX));
#else
MOV(64, R(R11), ImmPtr(g_dsp.r));
MOV(16, MDisp(R11,reg*2), R(EAX));
#endif
SetJumpTarget(end);
}
@ -199,15 +241,25 @@ void DSPEmitter::increase_addr_reg(int reg)
// EDI = tomask(EDX)
void DSPEmitter::decrease_addr_reg(int reg)
{
#ifdef _M_IX86 // All32
MOV(16, R(ECX), M(&g_dsp.r[DSP_REG_IX0 + reg]));
#else
MOV(64, R(R11), ImmPtr(&g_dsp.r));
MOV(16, R(ECX), MDisp(R11,(DSP_REG_IX0 + reg)*2));
#endif
// IX0 == 0, bail out
TEST(16, R(ECX), R(ECX));
// code too long for a 5-byte jump
// TODO: optimize a bit, maybe merge loops?
FixupBranch end = J_CC(CC_Z, true);
#ifdef _M_IX86 // All32
MOV(16, R(EAX), M(&g_dsp.r[reg]));
MOV(16, R(EDX), M(&g_dsp.r[DSP_REG_WR0 + reg]));
#else
MOV(16, R(EAX), MDisp(R11,reg*2));
MOV(16, R(EDX), MDisp(R11,(DSP_REG_WR0 + reg)*2));
#endif
// ToMask(WR0), calculating it into EDI
MOV(16, R(EDI), R(EDX));
@ -243,7 +295,12 @@ void DSPEmitter::decrease_addr_reg(int reg)
SetJumpTarget(end_pos);
// g_dsp.r[reg] = tmp;
#ifdef _M_IX86 // All32
MOV(16, M(&g_dsp.r[reg]), R(EAX));
#else
MOV(64, R(R11), ImmPtr(g_dsp.r));
MOV(16, MDisp(R11,reg*2), R(EAX));
#endif
SetJumpTarget(end);
}
@ -253,10 +310,19 @@ void DSPEmitter::decrease_addr_reg(int reg)
void DSPEmitter::ext_dmem_write(u32 dest, u32 src)
{
// 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));
@ -269,9 +335,9 @@ void DSPEmitter::ext_dmem_write(u32 dest, u32 src)
// g_dsp.dram[addr & DSP_DRAM_MASK] = val;
AND(16, R(EAX), Imm16(DSP_DRAM_MASK));
#ifdef _M_X64
MOV(64, R(ESI), M(&g_dsp.dram));
MOV(64, R(ESI), ImmPtr(g_dsp.dram));
#else
MOV(32, R(ESI), M(&g_dsp.dram));
MOV(32, R(ESI), ImmPtr(g_dsp.dram));
#endif
MOV(16, MComplex(ESI, EAX, 2, 0), R(ECX));
@ -289,9 +355,14 @@ void DSPEmitter::ext_dmem_write(u32 dest, u32 src)
void DSPEmitter::ext_dmem_read(u16 addr)
{
// 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;
// u16 saddr = addr >> 12;
MOV(32, R(ESI), R(ECX));
SHR(16, R(ESI), Imm8(12));
@ -301,9 +372,9 @@ void DSPEmitter::ext_dmem_read(u16 addr)
// return g_dsp.dram[addr & DSP_DRAM_MASK];
AND(16, R(ECX), Imm16(DSP_DRAM_MASK));
#ifdef _M_X64
MOV(64, R(ESI), M(&g_dsp.dram));
MOV(64, R(ESI), ImmPtr(g_dsp.dram));
#else
MOV(32, R(ESI), M(&g_dsp.dram));
MOV(32, R(ESI), ImmPtr(g_dsp.dram));
#endif
MOV(16, R(EAX), MComplex(ESI, ECX, 2, 0));
@ -314,14 +385,12 @@ void DSPEmitter::ext_dmem_read(u16 addr)
FixupBranch ifx = J_CC(CC_NZ);
// return g_dsp.coef[addr & DSP_COEF_MASK];
AND(16, R(ECX), Imm16(DSP_COEF_MASK));
SHL(16, R(ECX), Imm8(1)); // * sizeof(u16)
#ifdef _M_X64
MOV(64, R(R11), Imm64((u64)g_dsp.dram));
ADD(64, R(ECX), R(R11));
MOV(64, R(ESI), ImmPtr(g_dsp.dram));
#else
ADD(32, R(ECX), Imm32((u32)g_dsp.dram));
MOV(32, R(ESI), ImmPtr(g_dsp.dram));
#endif
MOV(16, R(EAX), MDisp(ECX,0));
MOV(16, R(EAX), MComplex(ESI,ECX,2,0));
FixupBranch end2 = J();
SetJumpTarget(ifx);