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:
parent
c8c805f720
commit
b80e207a8a
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue