Merge pull request #4753 from lioncash/dspjit
DSPEmitter: Amend member variable naming
This commit is contained in:
commit
0a07df13d2
|
@ -253,7 +253,7 @@ int DSPCore_RunCycles(int cycles)
|
||||||
}
|
}
|
||||||
|
|
||||||
g_cycles_left = cycles;
|
g_cycles_left = cycles;
|
||||||
auto exec_addr = (JIT::x86::DSPEmitter::DSPCompiledCode)g_dsp_jit->enterDispatcher;
|
auto exec_addr = (JIT::x86::DSPEmitter::DSPCompiledCode)g_dsp_jit->m_enter_dispatcher;
|
||||||
exec_addr();
|
exec_addr();
|
||||||
|
|
||||||
if (g_dsp.reset_dspjit_codespace)
|
if (g_dsp.reset_dspjit_codespace)
|
||||||
|
@ -325,11 +325,11 @@ void CompileCurrent()
|
||||||
retry = false;
|
retry = false;
|
||||||
for (u16 i = 0x0000; i < 0xffff; ++i)
|
for (u16 i = 0x0000; i < 0xffff; ++i)
|
||||||
{
|
{
|
||||||
if (!g_dsp_jit->unresolvedJumps[i].empty())
|
if (!g_dsp_jit->m_unresolved_jumps[i].empty())
|
||||||
{
|
{
|
||||||
u16 addrToCompile = g_dsp_jit->unresolvedJumps[i].front();
|
u16 addrToCompile = g_dsp_jit->m_unresolved_jumps[i].front();
|
||||||
g_dsp_jit->Compile(addrToCompile);
|
g_dsp_jit->Compile(addrToCompile);
|
||||||
if (!g_dsp_jit->unresolvedJumps[i].empty())
|
if (!g_dsp_jit->m_unresolved_jumps[i].empty())
|
||||||
retry = true;
|
retry = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,16 +31,16 @@ constexpr size_t MAX_BLOCK_SIZE = 250;
|
||||||
constexpr u16 DSP_IDLE_SKIP_CYCLES = 0x1000;
|
constexpr u16 DSP_IDLE_SKIP_CYCLES = 0x1000;
|
||||||
|
|
||||||
DSPEmitter::DSPEmitter()
|
DSPEmitter::DSPEmitter()
|
||||||
: blockLinks(MAX_BLOCKS), blockSize(MAX_BLOCKS), blocks(MAX_BLOCKS),
|
: m_block_links(MAX_BLOCKS), m_block_size(MAX_BLOCKS), m_blocks(MAX_BLOCKS),
|
||||||
compileSR{SR_INT_ENABLE | SR_EXT_INT_ENABLE}
|
m_compile_status_register{SR_INT_ENABLE | SR_EXT_INT_ENABLE}
|
||||||
{
|
{
|
||||||
AllocCodeSpace(COMPILED_CODE_SIZE);
|
AllocCodeSpace(COMPILED_CODE_SIZE);
|
||||||
|
|
||||||
CompileDispatcher();
|
CompileDispatcher();
|
||||||
stubEntryPoint = CompileStub();
|
m_stub_entry_point = CompileStub();
|
||||||
|
|
||||||
// Clear all of the block references
|
// Clear all of the block references
|
||||||
std::fill(blocks.begin(), blocks.end(), (DSPCompiledCode)stubEntryPoint);
|
std::fill(m_blocks.begin(), m_blocks.end(), (DSPCompiledCode)m_stub_entry_point);
|
||||||
}
|
}
|
||||||
|
|
||||||
DSPEmitter::~DSPEmitter()
|
DSPEmitter::~DSPEmitter()
|
||||||
|
@ -52,10 +52,10 @@ void DSPEmitter::ClearIRAM()
|
||||||
{
|
{
|
||||||
for (int i = 0x0000; i < 0x1000; i++)
|
for (int i = 0x0000; i < 0x1000; i++)
|
||||||
{
|
{
|
||||||
blocks[i] = (DSPCompiledCode)stubEntryPoint;
|
m_blocks[i] = (DSPCompiledCode)m_stub_entry_point;
|
||||||
blockLinks[i] = nullptr;
|
m_block_links[i] = nullptr;
|
||||||
blockSize[i] = 0;
|
m_block_size[i] = 0;
|
||||||
unresolvedJumps[i].clear();
|
m_unresolved_jumps[i].clear();
|
||||||
}
|
}
|
||||||
g_dsp.reset_dspjit_codespace = true;
|
g_dsp.reset_dspjit_codespace = true;
|
||||||
}
|
}
|
||||||
|
@ -64,14 +64,14 @@ void DSPEmitter::ClearIRAMandDSPJITCodespaceReset()
|
||||||
{
|
{
|
||||||
ClearCodeSpace();
|
ClearCodeSpace();
|
||||||
CompileDispatcher();
|
CompileDispatcher();
|
||||||
stubEntryPoint = CompileStub();
|
m_stub_entry_point = CompileStub();
|
||||||
|
|
||||||
for (int i = 0x0000; i < 0x10000; i++)
|
for (int i = 0x0000; i < 0x10000; i++)
|
||||||
{
|
{
|
||||||
blocks[i] = (DSPCompiledCode)stubEntryPoint;
|
m_blocks[i] = (DSPCompiledCode)m_stub_entry_point;
|
||||||
blockLinks[i] = nullptr;
|
m_block_links[i] = nullptr;
|
||||||
blockSize[i] = 0;
|
m_block_size[i] = 0;
|
||||||
unresolvedJumps[i].clear();
|
m_unresolved_jumps[i].clear();
|
||||||
}
|
}
|
||||||
g_dsp.reset_dspjit_codespace = false;
|
g_dsp.reset_dspjit_codespace = false;
|
||||||
}
|
}
|
||||||
|
@ -83,22 +83,22 @@ void DSPEmitter::checkExceptions(u32 retval)
|
||||||
TEST(8, M(&g_dsp.exceptions), Imm8(0xff));
|
TEST(8, M(&g_dsp.exceptions), Imm8(0xff));
|
||||||
FixupBranch skipCheck = J_CC(CC_Z, true);
|
FixupBranch skipCheck = J_CC(CC_Z, true);
|
||||||
|
|
||||||
MOV(16, M(&(g_dsp.pc)), Imm16(compilePC));
|
MOV(16, M(&(g_dsp.pc)), Imm16(m_compile_pc));
|
||||||
|
|
||||||
DSPJitRegCache c(gpr);
|
DSPJitRegCache c(m_gpr);
|
||||||
gpr.SaveRegs();
|
m_gpr.SaveRegs();
|
||||||
ABI_CallFunction(DSPCore_CheckExceptions);
|
ABI_CallFunction(DSPCore_CheckExceptions);
|
||||||
MOV(32, R(EAX), Imm32(retval));
|
MOV(32, R(EAX), Imm32(retval));
|
||||||
JMP(returnDispatcher, true);
|
JMP(m_return_dispatcher, true);
|
||||||
gpr.LoadRegs(false);
|
m_gpr.LoadRegs(false);
|
||||||
gpr.FlushRegs(c, false);
|
m_gpr.FlushRegs(c, false);
|
||||||
|
|
||||||
SetJumpTarget(skipCheck);
|
SetJumpTarget(skipCheck);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DSPEmitter::FlagsNeeded() const
|
bool DSPEmitter::FlagsNeeded() const
|
||||||
{
|
{
|
||||||
const u8 flags = Analyzer::GetCodeFlags(compilePC);
|
const u8 flags = Analyzer::GetCodeFlags(m_compile_pc);
|
||||||
|
|
||||||
return !(flags & Analyzer::CODE_START_OF_INST) || (flags & Analyzer::CODE_UPDATE_SR);
|
return !(flags & Analyzer::CODE_START_OF_INST) || (flags & Analyzer::CODE_UPDATE_SR);
|
||||||
}
|
}
|
||||||
|
@ -113,14 +113,14 @@ void DSPEmitter::FallBackToInterpreter(UDSPInstruction inst)
|
||||||
// of block.
|
// of block.
|
||||||
// Fallbacks to interpreter need this for fetching immediate values
|
// Fallbacks to interpreter need this for fetching immediate values
|
||||||
|
|
||||||
MOV(16, M(&(g_dsp.pc)), Imm16(compilePC + 1));
|
MOV(16, M(&(g_dsp.pc)), Imm16(m_compile_pc + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fall back to interpreter
|
// Fall back to interpreter
|
||||||
gpr.PushRegs();
|
m_gpr.PushRegs();
|
||||||
_assert_msg_(DSPLLE, op_template->intFunc, "No function for %04x", inst);
|
_assert_msg_(DSPLLE, op_template->intFunc, "No function for %04x", inst);
|
||||||
ABI_CallFunctionC16(op_template->intFunc, inst);
|
ABI_CallFunctionC16(op_template->intFunc, inst);
|
||||||
gpr.PopRegs();
|
m_gpr.PopRegs();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DSPEmitter::EmitInstruction(UDSPInstruction inst)
|
void DSPEmitter::EmitInstruction(UDSPInstruction inst)
|
||||||
|
@ -136,9 +136,9 @@ void DSPEmitter::EmitInstruction(UDSPInstruction inst)
|
||||||
if (!ext_op_template->jitFunc)
|
if (!ext_op_template->jitFunc)
|
||||||
{
|
{
|
||||||
// Fall back to interpreter
|
// Fall back to interpreter
|
||||||
gpr.PushRegs();
|
m_gpr.PushRegs();
|
||||||
ABI_CallFunctionC16(ext_op_template->intFunc, inst);
|
ABI_CallFunctionC16(ext_op_template->intFunc, inst);
|
||||||
gpr.PopRegs();
|
m_gpr.PopRegs();
|
||||||
INFO_LOG(DSPLLE, "Instruction not JITed(ext part): %04x", inst);
|
INFO_LOG(DSPLLE, "Instruction not JITed(ext part): %04x", inst);
|
||||||
ext_is_jit = false;
|
ext_is_jit = false;
|
||||||
}
|
}
|
||||||
|
@ -167,9 +167,9 @@ void DSPEmitter::EmitInstruction(UDSPInstruction inst)
|
||||||
{
|
{
|
||||||
// need to call the online cleanup function because
|
// need to call the online cleanup function because
|
||||||
// the writeBackLog gets populated at runtime
|
// the writeBackLog gets populated at runtime
|
||||||
gpr.PushRegs();
|
m_gpr.PushRegs();
|
||||||
ABI_CallFunction(applyWriteBackLog);
|
ABI_CallFunction(applyWriteBackLog);
|
||||||
gpr.PopRegs();
|
m_gpr.PopRegs();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -181,8 +181,8 @@ void DSPEmitter::EmitInstruction(UDSPInstruction inst)
|
||||||
void DSPEmitter::Compile(u16 start_addr)
|
void DSPEmitter::Compile(u16 start_addr)
|
||||||
{
|
{
|
||||||
// Remember the current block address for later
|
// Remember the current block address for later
|
||||||
startAddr = start_addr;
|
m_start_address = start_addr;
|
||||||
unresolvedJumps[start_addr].clear();
|
m_unresolved_jumps[start_addr].clear();
|
||||||
|
|
||||||
const u8* entryPoint = AlignCode16();
|
const u8* entryPoint = AlignCode16();
|
||||||
|
|
||||||
|
@ -195,35 +195,35 @@ void DSPEmitter::Compile(u16 start_addr)
|
||||||
return;
|
return;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
gpr.LoadRegs();
|
m_gpr.LoadRegs();
|
||||||
|
|
||||||
blockLinkEntry = GetCodePtr();
|
m_block_link_entry = GetCodePtr();
|
||||||
|
|
||||||
compilePC = start_addr;
|
m_compile_pc = start_addr;
|
||||||
bool fixup_pc = false;
|
bool fixup_pc = false;
|
||||||
blockSize[start_addr] = 0;
|
m_block_size[start_addr] = 0;
|
||||||
|
|
||||||
while (compilePC < start_addr + MAX_BLOCK_SIZE)
|
while (m_compile_pc < start_addr + MAX_BLOCK_SIZE)
|
||||||
{
|
{
|
||||||
if (Analyzer::GetCodeFlags(compilePC) & Analyzer::CODE_CHECK_INT)
|
if (Analyzer::GetCodeFlags(m_compile_pc) & Analyzer::CODE_CHECK_INT)
|
||||||
checkExceptions(blockSize[start_addr]);
|
checkExceptions(m_block_size[start_addr]);
|
||||||
|
|
||||||
UDSPInstruction inst = dsp_imem_read(compilePC);
|
UDSPInstruction inst = dsp_imem_read(m_compile_pc);
|
||||||
const DSPOPCTemplate* opcode = GetOpTemplate(inst);
|
const DSPOPCTemplate* opcode = GetOpTemplate(inst);
|
||||||
|
|
||||||
EmitInstruction(inst);
|
EmitInstruction(inst);
|
||||||
|
|
||||||
blockSize[start_addr]++;
|
m_block_size[start_addr]++;
|
||||||
compilePC += opcode->size;
|
m_compile_pc += opcode->size;
|
||||||
|
|
||||||
// If the block was trying to link into itself, remove the link
|
// If the block was trying to link into itself, remove the link
|
||||||
unresolvedJumps[start_addr].remove(compilePC);
|
m_unresolved_jumps[start_addr].remove(m_compile_pc);
|
||||||
|
|
||||||
fixup_pc = true;
|
fixup_pc = true;
|
||||||
|
|
||||||
// Handle loop condition, only if current instruction was flagged as a loop destination
|
// Handle loop condition, only if current instruction was flagged as a loop destination
|
||||||
// by the analyzer.
|
// by the analyzer.
|
||||||
if (Analyzer::GetCodeFlags(static_cast<u16>(compilePC - 1u)) & Analyzer::CODE_LOOP_END)
|
if (Analyzer::GetCodeFlags(static_cast<u16>(m_compile_pc - 1u)) & Analyzer::CODE_LOOP_END)
|
||||||
{
|
{
|
||||||
MOVZX(32, 16, EAX, M(&(g_dsp.r.st[2])));
|
MOVZX(32, 16, EAX, M(&(g_dsp.r.st[2])));
|
||||||
TEST(32, R(EAX), R(EAX));
|
TEST(32, R(EAX), R(EAX));
|
||||||
|
@ -236,25 +236,25 @@ void DSPEmitter::Compile(u16 start_addr)
|
||||||
if (!opcode->branch)
|
if (!opcode->branch)
|
||||||
{
|
{
|
||||||
// branch insns update the g_dsp.pc
|
// branch insns update the g_dsp.pc
|
||||||
MOV(16, M(&(g_dsp.pc)), Imm16(compilePC));
|
MOV(16, M(&(g_dsp.pc)), Imm16(m_compile_pc));
|
||||||
}
|
}
|
||||||
|
|
||||||
// These functions branch and therefore only need to be called in the
|
// These functions branch and therefore only need to be called in the
|
||||||
// end of each block and in this order
|
// end of each block and in this order
|
||||||
DSPJitRegCache c(gpr);
|
DSPJitRegCache c(m_gpr);
|
||||||
HandleLoop();
|
HandleLoop();
|
||||||
gpr.SaveRegs();
|
m_gpr.SaveRegs();
|
||||||
if (!Host::OnThread() && Analyzer::GetCodeFlags(start_addr) & Analyzer::CODE_IDLE_SKIP)
|
if (!Host::OnThread() && Analyzer::GetCodeFlags(start_addr) & Analyzer::CODE_IDLE_SKIP)
|
||||||
{
|
{
|
||||||
MOV(16, R(EAX), Imm16(DSP_IDLE_SKIP_CYCLES));
|
MOV(16, R(EAX), Imm16(DSP_IDLE_SKIP_CYCLES));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MOV(16, R(EAX), Imm16(blockSize[start_addr]));
|
MOV(16, R(EAX), Imm16(m_block_size[start_addr]));
|
||||||
}
|
}
|
||||||
JMP(returnDispatcher, true);
|
JMP(m_return_dispatcher, true);
|
||||||
gpr.LoadRegs(false);
|
m_gpr.LoadRegs(false);
|
||||||
gpr.FlushRegs(c, false);
|
m_gpr.FlushRegs(c, false);
|
||||||
|
|
||||||
SetJumpTarget(rLoopAddressExit);
|
SetJumpTarget(rLoopAddressExit);
|
||||||
SetJumpTarget(rLoopCounterExit);
|
SetJumpTarget(rLoopCounterExit);
|
||||||
|
@ -272,30 +272,30 @@ void DSPEmitter::Compile(u16 start_addr)
|
||||||
{
|
{
|
||||||
// look at g_dsp.pc if we actually branched
|
// look at g_dsp.pc if we actually branched
|
||||||
MOV(16, R(AX), M(&g_dsp.pc));
|
MOV(16, R(AX), M(&g_dsp.pc));
|
||||||
CMP(16, R(AX), Imm16(compilePC));
|
CMP(16, R(AX), Imm16(m_compile_pc));
|
||||||
FixupBranch rNoBranch = J_CC(CC_Z, true);
|
FixupBranch rNoBranch = J_CC(CC_Z, true);
|
||||||
|
|
||||||
DSPJitRegCache c(gpr);
|
DSPJitRegCache c(m_gpr);
|
||||||
// don't update g_dsp.pc -- the branch insn already did
|
// don't update g_dsp.pc -- the branch insn already did
|
||||||
gpr.SaveRegs();
|
m_gpr.SaveRegs();
|
||||||
if (!Host::OnThread() && Analyzer::GetCodeFlags(start_addr) & Analyzer::CODE_IDLE_SKIP)
|
if (!Host::OnThread() && Analyzer::GetCodeFlags(start_addr) & Analyzer::CODE_IDLE_SKIP)
|
||||||
{
|
{
|
||||||
MOV(16, R(EAX), Imm16(DSP_IDLE_SKIP_CYCLES));
|
MOV(16, R(EAX), Imm16(DSP_IDLE_SKIP_CYCLES));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MOV(16, R(EAX), Imm16(blockSize[start_addr]));
|
MOV(16, R(EAX), Imm16(m_block_size[start_addr]));
|
||||||
}
|
}
|
||||||
JMP(returnDispatcher, true);
|
JMP(m_return_dispatcher, true);
|
||||||
gpr.LoadRegs(false);
|
m_gpr.LoadRegs(false);
|
||||||
gpr.FlushRegs(c, false);
|
m_gpr.FlushRegs(c, false);
|
||||||
|
|
||||||
SetJumpTarget(rNoBranch);
|
SetJumpTarget(rNoBranch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// End the block if we're before an idle skip address
|
// End the block if we're before an idle skip address
|
||||||
if (Analyzer::GetCodeFlags(compilePC) & Analyzer::CODE_IDLE_SKIP)
|
if (Analyzer::GetCodeFlags(m_compile_pc) & Analyzer::CODE_IDLE_SKIP)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -303,53 +303,53 @@ void DSPEmitter::Compile(u16 start_addr)
|
||||||
|
|
||||||
if (fixup_pc)
|
if (fixup_pc)
|
||||||
{
|
{
|
||||||
MOV(16, M(&(g_dsp.pc)), Imm16(compilePC));
|
MOV(16, M(&(g_dsp.pc)), Imm16(m_compile_pc));
|
||||||
}
|
}
|
||||||
|
|
||||||
blocks[start_addr] = (DSPCompiledCode)entryPoint;
|
m_blocks[start_addr] = (DSPCompiledCode)entryPoint;
|
||||||
|
|
||||||
// Mark this block as a linkable destination if it does not contain
|
// Mark this block as a linkable destination if it does not contain
|
||||||
// any unresolved CALL's
|
// any unresolved CALL's
|
||||||
if (unresolvedJumps[start_addr].empty())
|
if (m_unresolved_jumps[start_addr].empty())
|
||||||
{
|
{
|
||||||
blockLinks[start_addr] = blockLinkEntry;
|
m_block_links[start_addr] = m_block_link_entry;
|
||||||
|
|
||||||
for (u16 i = 0x0000; i < 0xffff; ++i)
|
for (u16 i = 0x0000; i < 0xffff; ++i)
|
||||||
{
|
{
|
||||||
if (!unresolvedJumps[i].empty())
|
if (!m_unresolved_jumps[i].empty())
|
||||||
{
|
{
|
||||||
// Check if there were any blocks waiting for this block to be linkable
|
// Check if there were any blocks waiting for this block to be linkable
|
||||||
size_t size = unresolvedJumps[i].size();
|
size_t size = m_unresolved_jumps[i].size();
|
||||||
unresolvedJumps[i].remove(start_addr);
|
m_unresolved_jumps[i].remove(start_addr);
|
||||||
if (unresolvedJumps[i].size() < size)
|
if (m_unresolved_jumps[i].size() < size)
|
||||||
{
|
{
|
||||||
// Mark the block to be recompiled again
|
// Mark the block to be recompiled again
|
||||||
blocks[i] = (DSPCompiledCode)stubEntryPoint;
|
m_blocks[i] = (DSPCompiledCode)m_stub_entry_point;
|
||||||
blockLinks[i] = nullptr;
|
m_block_links[i] = nullptr;
|
||||||
blockSize[i] = 0;
|
m_block_size[i] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (blockSize[start_addr] == 0)
|
if (m_block_size[start_addr] == 0)
|
||||||
{
|
{
|
||||||
// just a safeguard, should never happen anymore.
|
// just a safeguard, should never happen anymore.
|
||||||
// if it does we might get stuck over in RunForCycles.
|
// if it does we might get stuck over in RunForCycles.
|
||||||
ERROR_LOG(DSPLLE, "Block at 0x%04x has zero size", start_addr);
|
ERROR_LOG(DSPLLE, "Block at 0x%04x has zero size", start_addr);
|
||||||
blockSize[start_addr] = 1;
|
m_block_size[start_addr] = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
gpr.SaveRegs();
|
m_gpr.SaveRegs();
|
||||||
if (!Host::OnThread() && Analyzer::GetCodeFlags(start_addr) & Analyzer::CODE_IDLE_SKIP)
|
if (!Host::OnThread() && Analyzer::GetCodeFlags(start_addr) & Analyzer::CODE_IDLE_SKIP)
|
||||||
{
|
{
|
||||||
MOV(16, R(EAX), Imm16(DSP_IDLE_SKIP_CYCLES));
|
MOV(16, R(EAX), Imm16(DSP_IDLE_SKIP_CYCLES));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MOV(16, R(EAX), Imm16(blockSize[start_addr]));
|
MOV(16, R(EAX), Imm16(m_block_size[start_addr]));
|
||||||
}
|
}
|
||||||
JMP(returnDispatcher, true);
|
JMP(m_return_dispatcher, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
const u8* DSPEmitter::CompileStub()
|
const u8* DSPEmitter::CompileStub()
|
||||||
|
@ -357,13 +357,13 @@ const u8* DSPEmitter::CompileStub()
|
||||||
const u8* entryPoint = AlignCode16();
|
const u8* entryPoint = AlignCode16();
|
||||||
ABI_CallFunction(CompileCurrent);
|
ABI_CallFunction(CompileCurrent);
|
||||||
XOR(32, R(EAX), R(EAX)); // Return 0 cycles executed
|
XOR(32, R(EAX), R(EAX)); // Return 0 cycles executed
|
||||||
JMP(returnDispatcher);
|
JMP(m_return_dispatcher);
|
||||||
return entryPoint;
|
return entryPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DSPEmitter::CompileDispatcher()
|
void DSPEmitter::CompileDispatcher()
|
||||||
{
|
{
|
||||||
enterDispatcher = AlignCode16();
|
m_enter_dispatcher = AlignCode16();
|
||||||
// We don't use floating point (high 16 bits).
|
// We don't use floating point (high 16 bits).
|
||||||
BitSet32 registers_used = ABI_ALL_CALLEE_SAVED & BitSet32(0xffff);
|
BitSet32 registers_used = ABI_ALL_CALLEE_SAVED & BitSet32(0xffff);
|
||||||
ABI_PushRegistersAndAdjustStack(registers_used, 8);
|
ABI_PushRegistersAndAdjustStack(registers_used, 8);
|
||||||
|
@ -383,10 +383,10 @@ void DSPEmitter::CompileDispatcher()
|
||||||
|
|
||||||
// Execute block. Cycles executed returned in EAX.
|
// Execute block. Cycles executed returned in EAX.
|
||||||
MOVZX(64, 16, ECX, M(&g_dsp.pc));
|
MOVZX(64, 16, ECX, M(&g_dsp.pc));
|
||||||
MOV(64, R(RBX), ImmPtr(blocks.data()));
|
MOV(64, R(RBX), ImmPtr(m_blocks.data()));
|
||||||
JMPptr(MComplex(RBX, RCX, SCALE_8, 0));
|
JMPptr(MComplex(RBX, RCX, SCALE_8, 0));
|
||||||
|
|
||||||
returnDispatcher = GetCodePtr();
|
m_return_dispatcher = GetCodePtr();
|
||||||
|
|
||||||
// Decrement cyclesLeft
|
// Decrement cyclesLeft
|
||||||
SUB(16, M(&g_cycles_left), R(EAX));
|
SUB(16, M(&g_cycles_left), R(EAX));
|
||||||
|
|
|
@ -245,29 +245,26 @@ public:
|
||||||
void msub(const UDSPInstruction opc);
|
void msub(const UDSPInstruction opc);
|
||||||
|
|
||||||
// CALL this to start the dispatcher
|
// CALL this to start the dispatcher
|
||||||
const u8* enterDispatcher;
|
const u8* m_enter_dispatcher;
|
||||||
const u8* reenterDispatcher;
|
const u8* m_reenter_dispatcher;
|
||||||
const u8* stubEntryPoint;
|
const u8* m_stub_entry_point;
|
||||||
const u8* returnDispatcher;
|
const u8* m_return_dispatcher;
|
||||||
u16 compilePC;
|
u16 m_compile_pc;
|
||||||
u16 startAddr;
|
u16 m_start_address;
|
||||||
std::vector<Block> blockLinks;
|
std::vector<Block> m_block_links;
|
||||||
std::vector<u16> blockSize;
|
std::vector<u16> m_block_size;
|
||||||
std::list<u16> unresolvedJumps[MAX_BLOCKS];
|
std::list<u16> m_unresolved_jumps[MAX_BLOCKS];
|
||||||
|
|
||||||
DSPJitRegCache gpr{*this};
|
DSPJitRegCache m_gpr{*this};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<DSPCompiledCode> blocks;
|
std::vector<DSPCompiledCode> m_blocks;
|
||||||
Block blockLinkEntry;
|
Block m_block_link_entry;
|
||||||
u16 compileSR;
|
u16 m_compile_status_register;
|
||||||
|
|
||||||
// The index of the last stored ext value (compile time).
|
// The index of the last stored ext value (compile time).
|
||||||
int storeIndex = -1;
|
int m_store_index = -1;
|
||||||
int storeIndex2 = -1;
|
int m_store_index2 = -1;
|
||||||
|
|
||||||
// Counts down.
|
|
||||||
// int cycles;
|
|
||||||
|
|
||||||
void Update_SR_Register(Gen::X64Reg val = Gen::EAX);
|
void Update_SR_Register(Gen::X64Reg val = Gen::EAX);
|
||||||
|
|
||||||
|
|
|
@ -71,7 +71,7 @@ void DSPEmitter::andcf(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 reg = (opc >> 8) & 0x1;
|
u8 reg = (opc >> 8) & 0x1;
|
||||||
// u16 imm = dsp_fetch_code();
|
// u16 imm = dsp_fetch_code();
|
||||||
u16 imm = dsp_imem_read(compilePC + 1);
|
u16 imm = dsp_imem_read(m_compile_pc + 1);
|
||||||
// u16 val = dsp_get_acc_m(reg);
|
// u16 val = dsp_get_acc_m(reg);
|
||||||
get_acc_m(reg);
|
get_acc_m(reg);
|
||||||
// Update_SR_LZ(((val & imm) == imm) ? true : false);
|
// Update_SR_LZ(((val & imm) == imm) ? true : false);
|
||||||
|
@ -79,7 +79,7 @@ void DSPEmitter::andcf(const UDSPInstruction opc)
|
||||||
// g_dsp.r.sr |= SR_LOGIC_ZERO;
|
// g_dsp.r.sr |= SR_LOGIC_ZERO;
|
||||||
// else
|
// else
|
||||||
// g_dsp.r.sr &= ~SR_LOGIC_ZERO;
|
// g_dsp.r.sr &= ~SR_LOGIC_ZERO;
|
||||||
const OpArg sr_reg = gpr.GetReg(DSP_REG_SR);
|
const OpArg sr_reg = m_gpr.GetReg(DSP_REG_SR);
|
||||||
AND(16, R(RAX), Imm16(imm));
|
AND(16, R(RAX), Imm16(imm));
|
||||||
CMP(16, R(RAX), Imm16(imm));
|
CMP(16, R(RAX), Imm16(imm));
|
||||||
FixupBranch notLogicZero = J_CC(CC_NE);
|
FixupBranch notLogicZero = J_CC(CC_NE);
|
||||||
|
@ -88,7 +88,7 @@ void DSPEmitter::andcf(const UDSPInstruction opc)
|
||||||
SetJumpTarget(notLogicZero);
|
SetJumpTarget(notLogicZero);
|
||||||
AND(16, sr_reg, Imm16(~SR_LOGIC_ZERO));
|
AND(16, sr_reg, Imm16(~SR_LOGIC_ZERO));
|
||||||
SetJumpTarget(exit);
|
SetJumpTarget(exit);
|
||||||
gpr.PutReg(DSP_REG_SR);
|
m_gpr.PutReg(DSP_REG_SR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,7 +106,7 @@ void DSPEmitter::andf(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 reg = (opc >> 8) & 0x1;
|
u8 reg = (opc >> 8) & 0x1;
|
||||||
// u16 imm = dsp_fetch_code();
|
// u16 imm = dsp_fetch_code();
|
||||||
u16 imm = dsp_imem_read(compilePC + 1);
|
u16 imm = dsp_imem_read(m_compile_pc + 1);
|
||||||
// u16 val = dsp_get_acc_m(reg);
|
// u16 val = dsp_get_acc_m(reg);
|
||||||
get_acc_m(reg);
|
get_acc_m(reg);
|
||||||
// Update_SR_LZ(((val & imm) == 0) ? true : false);
|
// Update_SR_LZ(((val & imm) == 0) ? true : false);
|
||||||
|
@ -114,7 +114,7 @@ void DSPEmitter::andf(const UDSPInstruction opc)
|
||||||
// g_dsp.r.sr |= SR_LOGIC_ZERO;
|
// g_dsp.r.sr |= SR_LOGIC_ZERO;
|
||||||
// else
|
// else
|
||||||
// g_dsp.r.sr &= ~SR_LOGIC_ZERO;
|
// g_dsp.r.sr &= ~SR_LOGIC_ZERO;
|
||||||
const OpArg sr_reg = gpr.GetReg(DSP_REG_SR);
|
const OpArg sr_reg = m_gpr.GetReg(DSP_REG_SR);
|
||||||
TEST(16, R(RAX), Imm16(imm));
|
TEST(16, R(RAX), Imm16(imm));
|
||||||
FixupBranch notLogicZero = J_CC(CC_NE);
|
FixupBranch notLogicZero = J_CC(CC_NE);
|
||||||
OR(16, sr_reg, Imm16(SR_LOGIC_ZERO));
|
OR(16, sr_reg, Imm16(SR_LOGIC_ZERO));
|
||||||
|
@ -122,7 +122,7 @@ void DSPEmitter::andf(const UDSPInstruction opc)
|
||||||
SetJumpTarget(notLogicZero);
|
SetJumpTarget(notLogicZero);
|
||||||
AND(16, sr_reg, Imm16(~SR_LOGIC_ZERO));
|
AND(16, sr_reg, Imm16(~SR_LOGIC_ZERO));
|
||||||
SetJumpTarget(exit);
|
SetJumpTarget(exit);
|
||||||
gpr.PutReg(DSP_REG_SR);
|
m_gpr.PutReg(DSP_REG_SR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,7 +173,7 @@ void DSPEmitter::cmp(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
if (FlagsNeeded())
|
if (FlagsNeeded())
|
||||||
{
|
{
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
// s64 acc0 = dsp_get_long_acc(0);
|
// s64 acc0 = dsp_get_long_acc(0);
|
||||||
get_long_acc(0, tmp1);
|
get_long_acc(0, tmp1);
|
||||||
MOV(64, R(RAX), R(tmp1));
|
MOV(64, R(RAX), R(tmp1));
|
||||||
|
@ -185,7 +185,7 @@ void DSPEmitter::cmp(const UDSPInstruction opc)
|
||||||
// influence on ABS/0xa100
|
// influence on ABS/0xa100
|
||||||
NEG(64, R(RDX));
|
NEG(64, R(RDX));
|
||||||
Update_SR_Register64_Carry(EAX, tmp1, true);
|
Update_SR_Register64_Carry(EAX, tmp1, true);
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,7 +202,7 @@ void DSPEmitter::cmpar(const UDSPInstruction opc)
|
||||||
u8 rreg = ((opc >> 12) & 0x1);
|
u8 rreg = ((opc >> 12) & 0x1);
|
||||||
u8 sreg = (opc >> 11) & 0x1;
|
u8 sreg = (opc >> 11) & 0x1;
|
||||||
|
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
// s64 sr = dsp_get_long_acc(sreg);
|
// s64 sr = dsp_get_long_acc(sreg);
|
||||||
get_long_acc(sreg, tmp1);
|
get_long_acc(sreg, tmp1);
|
||||||
MOV(64, R(RAX), R(tmp1));
|
MOV(64, R(RAX), R(tmp1));
|
||||||
|
@ -215,7 +215,7 @@ void DSPEmitter::cmpar(const UDSPInstruction opc)
|
||||||
// Update_SR_Register64(res, isCarry2(sr, res), isOverflow(sr, -rr, res));
|
// Update_SR_Register64(res, isCarry2(sr, res), isOverflow(sr, -rr, res));
|
||||||
NEG(64, R(RDX));
|
NEG(64, R(RDX));
|
||||||
Update_SR_Register64_Carry(EAX, tmp1, true);
|
Update_SR_Register64_Carry(EAX, tmp1, true);
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -231,20 +231,20 @@ void DSPEmitter::cmpi(const UDSPInstruction opc)
|
||||||
if (FlagsNeeded())
|
if (FlagsNeeded())
|
||||||
{
|
{
|
||||||
u8 reg = (opc >> 8) & 0x1;
|
u8 reg = (opc >> 8) & 0x1;
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
// s64 val = dsp_get_long_acc(reg);
|
// s64 val = dsp_get_long_acc(reg);
|
||||||
get_long_acc(reg, tmp1);
|
get_long_acc(reg, tmp1);
|
||||||
MOV(64, R(RAX), R(tmp1));
|
MOV(64, R(RAX), R(tmp1));
|
||||||
// s64 imm = (s64)(s16)dsp_fetch_code() << 16; // Immediate is considered to be at M level in
|
// s64 imm = (s64)(s16)dsp_fetch_code() << 16; // Immediate is considered to be at M level in
|
||||||
// the 40-bit accumulator.
|
// the 40-bit accumulator.
|
||||||
u16 imm = dsp_imem_read(compilePC + 1);
|
u16 imm = dsp_imem_read(m_compile_pc + 1);
|
||||||
MOV(64, R(RDX), Imm64((s64)(s16)imm << 16));
|
MOV(64, R(RDX), Imm64((s64)(s16)imm << 16));
|
||||||
// s64 res = dsp_convert_long_acc(val - imm);
|
// s64 res = dsp_convert_long_acc(val - imm);
|
||||||
SUB(64, R(RAX), R(RDX));
|
SUB(64, R(RAX), R(RDX));
|
||||||
// Update_SR_Register64(res, isCarry2(val, res), isOverflow(val, -imm, res));
|
// Update_SR_Register64(res, isCarry2(val, res), isOverflow(val, -imm, res));
|
||||||
NEG(64, R(RDX));
|
NEG(64, R(RDX));
|
||||||
Update_SR_Register64_Carry(EAX, tmp1, true);
|
Update_SR_Register64_Carry(EAX, tmp1, true);
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,7 +261,7 @@ void DSPEmitter::cmpis(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 areg = (opc >> 8) & 0x1;
|
u8 areg = (opc >> 8) & 0x1;
|
||||||
// s64 acc = dsp_get_long_acc(areg);
|
// s64 acc = dsp_get_long_acc(areg);
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
get_long_acc(areg, tmp1);
|
get_long_acc(areg, tmp1);
|
||||||
MOV(64, R(RAX), R(tmp1));
|
MOV(64, R(RAX), R(tmp1));
|
||||||
// s64 val = (s8)opc;
|
// s64 val = (s8)opc;
|
||||||
|
@ -272,7 +272,7 @@ void DSPEmitter::cmpis(const UDSPInstruction opc)
|
||||||
// Update_SR_Register64(res, isCarry2(acc, res), isOverflow(acc, -val, res));
|
// Update_SR_Register64(res, isCarry2(acc, res), isOverflow(acc, -val, res));
|
||||||
NEG(64, R(RDX));
|
NEG(64, R(RDX));
|
||||||
Update_SR_Register64_Carry(EAX, tmp1, true);
|
Update_SR_Register64_Carry(EAX, tmp1, true);
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -457,7 +457,7 @@ void DSPEmitter::xori(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 reg = (opc >> 8) & 0x1;
|
u8 reg = (opc >> 8) & 0x1;
|
||||||
// u16 imm = dsp_fetch_code();
|
// u16 imm = dsp_fetch_code();
|
||||||
u16 imm = dsp_imem_read(compilePC + 1);
|
u16 imm = dsp_imem_read(m_compile_pc + 1);
|
||||||
// g_dsp.r.acm[reg] ^= imm;
|
// g_dsp.r.acm[reg] ^= imm;
|
||||||
get_acc_m(reg, RAX);
|
get_acc_m(reg, RAX);
|
||||||
XOR(16, R(RAX), Imm16(imm));
|
XOR(16, R(RAX), Imm16(imm));
|
||||||
|
@ -480,7 +480,7 @@ void DSPEmitter::andi(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 reg = (opc >> 8) & 0x1;
|
u8 reg = (opc >> 8) & 0x1;
|
||||||
// u16 imm = dsp_fetch_code();
|
// u16 imm = dsp_fetch_code();
|
||||||
u16 imm = dsp_imem_read(compilePC + 1);
|
u16 imm = dsp_imem_read(m_compile_pc + 1);
|
||||||
// g_dsp.r.acm[reg] &= imm;
|
// g_dsp.r.acm[reg] &= imm;
|
||||||
get_acc_m(reg, RAX);
|
get_acc_m(reg, RAX);
|
||||||
AND(16, R(RAX), Imm16(imm));
|
AND(16, R(RAX), Imm16(imm));
|
||||||
|
@ -503,7 +503,7 @@ void DSPEmitter::ori(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 reg = (opc >> 8) & 0x1;
|
u8 reg = (opc >> 8) & 0x1;
|
||||||
// u16 imm = dsp_fetch_code();
|
// u16 imm = dsp_fetch_code();
|
||||||
u16 imm = dsp_imem_read(compilePC + 1);
|
u16 imm = dsp_imem_read(m_compile_pc + 1);
|
||||||
// g_dsp.r.acm[reg] |= imm;
|
// g_dsp.r.acm[reg] |= imm;
|
||||||
get_acc_m(reg, RAX);
|
get_acc_m(reg, RAX);
|
||||||
OR(16, R(RAX), Imm16(imm));
|
OR(16, R(RAX), Imm16(imm));
|
||||||
|
@ -529,7 +529,7 @@ void DSPEmitter::addr(const UDSPInstruction opc)
|
||||||
u8 sreg = ((opc >> 9) & 0x3) + DSP_REG_AXL0;
|
u8 sreg = ((opc >> 9) & 0x3) + DSP_REG_AXL0;
|
||||||
|
|
||||||
// s64 acc = dsp_get_long_acc(dreg);
|
// s64 acc = dsp_get_long_acc(dreg);
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
get_long_acc(dreg, tmp1);
|
get_long_acc(dreg, tmp1);
|
||||||
MOV(64, R(RAX), R(tmp1));
|
MOV(64, R(RAX), R(tmp1));
|
||||||
// s64 ax = (s16)g_dsp.r[sreg];
|
// s64 ax = (s16)g_dsp.r[sreg];
|
||||||
|
@ -550,7 +550,7 @@ void DSPEmitter::addr(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
set_long_acc(dreg, RAX);
|
set_long_acc(dreg, RAX);
|
||||||
}
|
}
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ADDAX $acD, $axS
|
// ADDAX $acD, $axS
|
||||||
|
@ -563,7 +563,7 @@ void DSPEmitter::addax(const UDSPInstruction opc)
|
||||||
u8 dreg = (opc >> 8) & 0x1;
|
u8 dreg = (opc >> 8) & 0x1;
|
||||||
u8 sreg = (opc >> 9) & 0x1;
|
u8 sreg = (opc >> 9) & 0x1;
|
||||||
|
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
// s64 acc = dsp_get_long_acc(dreg);
|
// s64 acc = dsp_get_long_acc(dreg);
|
||||||
get_long_acc(dreg, tmp1);
|
get_long_acc(dreg, tmp1);
|
||||||
MOV(64, R(RAX), R(tmp1));
|
MOV(64, R(RAX), R(tmp1));
|
||||||
|
@ -584,7 +584,7 @@ void DSPEmitter::addax(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
set_long_acc(dreg, RAX);
|
set_long_acc(dreg, RAX);
|
||||||
}
|
}
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ADD $acD, $ac(1-D)
|
// ADD $acD, $ac(1-D)
|
||||||
|
@ -596,7 +596,7 @@ void DSPEmitter::add(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 dreg = (opc >> 8) & 0x1;
|
u8 dreg = (opc >> 8) & 0x1;
|
||||||
|
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
// s64 acc0 = dsp_get_long_acc(dreg);
|
// s64 acc0 = dsp_get_long_acc(dreg);
|
||||||
get_long_acc(dreg, tmp1);
|
get_long_acc(dreg, tmp1);
|
||||||
MOV(64, R(RAX), R(tmp1));
|
MOV(64, R(RAX), R(tmp1));
|
||||||
|
@ -617,7 +617,7 @@ void DSPEmitter::add(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
set_long_acc(dreg, RAX);
|
set_long_acc(dreg, RAX);
|
||||||
}
|
}
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ADDP $acD
|
// ADDP $acD
|
||||||
|
@ -629,7 +629,7 @@ void DSPEmitter::addp(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 dreg = (opc >> 8) & 0x1;
|
u8 dreg = (opc >> 8) & 0x1;
|
||||||
|
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
// s64 acc = dsp_get_long_acc(dreg);
|
// s64 acc = dsp_get_long_acc(dreg);
|
||||||
get_long_acc(dreg, tmp1);
|
get_long_acc(dreg, tmp1);
|
||||||
MOV(64, R(RAX), R(tmp1));
|
MOV(64, R(RAX), R(tmp1));
|
||||||
|
@ -650,7 +650,7 @@ void DSPEmitter::addp(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
set_long_acc(dreg, RAX);
|
set_long_acc(dreg, RAX);
|
||||||
}
|
}
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ADDAXL $acD, $axS.l
|
// ADDAXL $acD, $axS.l
|
||||||
|
@ -664,7 +664,7 @@ void DSPEmitter::addaxl(const UDSPInstruction opc)
|
||||||
u8 sreg = (opc >> 9) & 0x1;
|
u8 sreg = (opc >> 9) & 0x1;
|
||||||
u8 dreg = (opc >> 8) & 0x1;
|
u8 dreg = (opc >> 8) & 0x1;
|
||||||
|
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
// u64 acc = dsp_get_long_acc(dreg);
|
// u64 acc = dsp_get_long_acc(dreg);
|
||||||
get_long_acc(dreg, tmp1);
|
get_long_acc(dreg, tmp1);
|
||||||
MOV(64, R(RAX), R(tmp1));
|
MOV(64, R(RAX), R(tmp1));
|
||||||
|
@ -686,7 +686,7 @@ void DSPEmitter::addaxl(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
set_long_acc(dreg, RAX);
|
set_long_acc(dreg, RAX);
|
||||||
}
|
}
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ADDI $amR, #I
|
// ADDI $amR, #I
|
||||||
|
@ -698,12 +698,12 @@ void DSPEmitter::addaxl(const UDSPInstruction opc)
|
||||||
void DSPEmitter::addi(const UDSPInstruction opc)
|
void DSPEmitter::addi(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 areg = (opc >> 8) & 0x1;
|
u8 areg = (opc >> 8) & 0x1;
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
// s64 acc = dsp_get_long_acc(areg);
|
// s64 acc = dsp_get_long_acc(areg);
|
||||||
get_long_acc(areg, tmp1);
|
get_long_acc(areg, tmp1);
|
||||||
MOV(64, R(RAX), R(tmp1));
|
MOV(64, R(RAX), R(tmp1));
|
||||||
// s64 imm = (s16)dsp_fetch_code();
|
// s64 imm = (s16)dsp_fetch_code();
|
||||||
s16 imm = dsp_imem_read(compilePC + 1);
|
s16 imm = dsp_imem_read(m_compile_pc + 1);
|
||||||
// imm <<= 16;
|
// imm <<= 16;
|
||||||
MOV(16, R(RDX), Imm16(imm));
|
MOV(16, R(RDX), Imm16(imm));
|
||||||
MOVSX(64, 16, RDX, R(RDX));
|
MOVSX(64, 16, RDX, R(RDX));
|
||||||
|
@ -723,7 +723,7 @@ void DSPEmitter::addi(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
set_long_acc(areg, RAX);
|
set_long_acc(areg, RAX);
|
||||||
}
|
}
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ADDIS $acD, #I
|
// ADDIS $acD, #I
|
||||||
|
@ -735,7 +735,7 @@ void DSPEmitter::addis(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 dreg = (opc >> 8) & 0x1;
|
u8 dreg = (opc >> 8) & 0x1;
|
||||||
|
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
// s64 acc = dsp_get_long_acc(dreg);
|
// s64 acc = dsp_get_long_acc(dreg);
|
||||||
get_long_acc(dreg, tmp1);
|
get_long_acc(dreg, tmp1);
|
||||||
MOV(64, R(RAX), R(tmp1));
|
MOV(64, R(RAX), R(tmp1));
|
||||||
|
@ -759,7 +759,7 @@ void DSPEmitter::addis(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
set_long_acc(dreg, RAX);
|
set_long_acc(dreg, RAX);
|
||||||
}
|
}
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// INCM $acsD
|
// INCM $acsD
|
||||||
|
@ -771,7 +771,7 @@ void DSPEmitter::incm(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 dreg = (opc >> 8) & 0x1;
|
u8 dreg = (opc >> 8) & 0x1;
|
||||||
s64 subtract = 0x10000;
|
s64 subtract = 0x10000;
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
// s64 acc = dsp_get_long_acc(dreg);
|
// s64 acc = dsp_get_long_acc(dreg);
|
||||||
get_long_acc(dreg, tmp1);
|
get_long_acc(dreg, tmp1);
|
||||||
MOV(64, R(RAX), R(tmp1));
|
MOV(64, R(RAX), R(tmp1));
|
||||||
|
@ -791,7 +791,7 @@ void DSPEmitter::incm(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
set_long_acc(dreg);
|
set_long_acc(dreg);
|
||||||
}
|
}
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// INC $acD
|
// INC $acD
|
||||||
|
@ -802,7 +802,7 @@ void DSPEmitter::incm(const UDSPInstruction opc)
|
||||||
void DSPEmitter::inc(const UDSPInstruction opc)
|
void DSPEmitter::inc(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 dreg = (opc >> 8) & 0x1;
|
u8 dreg = (opc >> 8) & 0x1;
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
// s64 acc = dsp_get_long_acc(dreg);
|
// s64 acc = dsp_get_long_acc(dreg);
|
||||||
get_long_acc(dreg, tmp1);
|
get_long_acc(dreg, tmp1);
|
||||||
MOV(64, R(RAX), R(tmp1));
|
MOV(64, R(RAX), R(tmp1));
|
||||||
|
@ -822,7 +822,7 @@ void DSPEmitter::inc(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
set_long_acc(dreg);
|
set_long_acc(dreg);
|
||||||
}
|
}
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
}
|
}
|
||||||
|
|
||||||
//----
|
//----
|
||||||
|
@ -837,7 +837,7 @@ void DSPEmitter::subr(const UDSPInstruction opc)
|
||||||
u8 dreg = (opc >> 8) & 0x1;
|
u8 dreg = (opc >> 8) & 0x1;
|
||||||
u8 sreg = ((opc >> 9) & 0x3) + DSP_REG_AXL0;
|
u8 sreg = ((opc >> 9) & 0x3) + DSP_REG_AXL0;
|
||||||
|
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
// s64 acc = dsp_get_long_acc(dreg);
|
// s64 acc = dsp_get_long_acc(dreg);
|
||||||
get_long_acc(dreg, tmp1);
|
get_long_acc(dreg, tmp1);
|
||||||
MOV(64, R(RAX), R(tmp1));
|
MOV(64, R(RAX), R(tmp1));
|
||||||
|
@ -861,7 +861,7 @@ void DSPEmitter::subr(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
set_long_acc(dreg, RAX);
|
set_long_acc(dreg, RAX);
|
||||||
}
|
}
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// SUBAX $acD, $axS
|
// SUBAX $acD, $axS
|
||||||
|
@ -874,7 +874,7 @@ void DSPEmitter::subax(const UDSPInstruction opc)
|
||||||
u8 dreg = (opc >> 8) & 0x1;
|
u8 dreg = (opc >> 8) & 0x1;
|
||||||
u8 sreg = (opc >> 9) & 0x1;
|
u8 sreg = (opc >> 9) & 0x1;
|
||||||
|
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
// s64 acc = dsp_get_long_acc(dreg);
|
// s64 acc = dsp_get_long_acc(dreg);
|
||||||
get_long_acc(dreg, tmp1);
|
get_long_acc(dreg, tmp1);
|
||||||
MOV(64, R(RAX), R(tmp1));
|
MOV(64, R(RAX), R(tmp1));
|
||||||
|
@ -896,7 +896,7 @@ void DSPEmitter::subax(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
set_long_acc(dreg, RAX);
|
set_long_acc(dreg, RAX);
|
||||||
}
|
}
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// SUB $acD, $ac(1-D)
|
// SUB $acD, $ac(1-D)
|
||||||
|
@ -907,7 +907,7 @@ void DSPEmitter::subax(const UDSPInstruction opc)
|
||||||
void DSPEmitter::sub(const UDSPInstruction opc)
|
void DSPEmitter::sub(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 dreg = (opc >> 8) & 0x1;
|
u8 dreg = (opc >> 8) & 0x1;
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
// s64 acc1 = dsp_get_long_acc(dreg);
|
// s64 acc1 = dsp_get_long_acc(dreg);
|
||||||
get_long_acc(dreg, tmp1);
|
get_long_acc(dreg, tmp1);
|
||||||
MOV(64, R(RAX), R(tmp1));
|
MOV(64, R(RAX), R(tmp1));
|
||||||
|
@ -929,7 +929,7 @@ void DSPEmitter::sub(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
set_long_acc(dreg, RAX);
|
set_long_acc(dreg, RAX);
|
||||||
}
|
}
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// SUBP $acD
|
// SUBP $acD
|
||||||
|
@ -940,7 +940,7 @@ void DSPEmitter::sub(const UDSPInstruction opc)
|
||||||
void DSPEmitter::subp(const UDSPInstruction opc)
|
void DSPEmitter::subp(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 dreg = (opc >> 8) & 0x1;
|
u8 dreg = (opc >> 8) & 0x1;
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
// s64 acc = dsp_get_long_acc(dreg);
|
// s64 acc = dsp_get_long_acc(dreg);
|
||||||
get_long_acc(dreg, tmp1);
|
get_long_acc(dreg, tmp1);
|
||||||
MOV(64, R(RAX), R(tmp1));
|
MOV(64, R(RAX), R(tmp1));
|
||||||
|
@ -962,7 +962,7 @@ void DSPEmitter::subp(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
set_long_acc(dreg, RAX);
|
set_long_acc(dreg, RAX);
|
||||||
}
|
}
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// DECM $acsD
|
// DECM $acsD
|
||||||
|
@ -974,7 +974,7 @@ void DSPEmitter::decm(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 dreg = (opc >> 8) & 0x01;
|
u8 dreg = (opc >> 8) & 0x01;
|
||||||
s64 subtract = 0x10000;
|
s64 subtract = 0x10000;
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
// s64 acc = dsp_get_long_acc(dreg);
|
// s64 acc = dsp_get_long_acc(dreg);
|
||||||
get_long_acc(dreg, tmp1);
|
get_long_acc(dreg, tmp1);
|
||||||
MOV(64, R(RAX), R(tmp1));
|
MOV(64, R(RAX), R(tmp1));
|
||||||
|
@ -994,7 +994,7 @@ void DSPEmitter::decm(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
set_long_acc(dreg, RAX);
|
set_long_acc(dreg, RAX);
|
||||||
}
|
}
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// DEC $acD
|
// DEC $acD
|
||||||
|
@ -1005,7 +1005,7 @@ void DSPEmitter::decm(const UDSPInstruction opc)
|
||||||
void DSPEmitter::dec(const UDSPInstruction opc)
|
void DSPEmitter::dec(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 dreg = (opc >> 8) & 0x01;
|
u8 dreg = (opc >> 8) & 0x01;
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
// s64 acc = dsp_get_long_acc(dreg);
|
// s64 acc = dsp_get_long_acc(dreg);
|
||||||
get_long_acc(dreg, tmp1);
|
get_long_acc(dreg, tmp1);
|
||||||
MOV(64, R(RAX), R(tmp1));
|
MOV(64, R(RAX), R(tmp1));
|
||||||
|
@ -1025,7 +1025,7 @@ void DSPEmitter::dec(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
set_long_acc(dreg);
|
set_long_acc(dreg);
|
||||||
}
|
}
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
}
|
}
|
||||||
|
|
||||||
//----
|
//----
|
||||||
|
|
|
@ -75,62 +75,62 @@ static void ReJitConditional(const UDSPInstruction opc, DSPEmitter& emitter)
|
||||||
emitter.TEST(16, R(EAX), Imm16(SR_OVERFLOW));
|
emitter.TEST(16, R(EAX), Imm16(SR_OVERFLOW));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
DSPJitRegCache c1(emitter.gpr);
|
DSPJitRegCache c1(emitter.m_gpr);
|
||||||
FixupBranch skipCode =
|
FixupBranch skipCode =
|
||||||
cond == 0xe ? emitter.J_CC(CC_E, true) : emitter.J_CC((CCFlags)(CC_NE - (cond & 1)), true);
|
cond == 0xe ? emitter.J_CC(CC_E, true) : emitter.J_CC((CCFlags)(CC_NE - (cond & 1)), true);
|
||||||
jitCode(opc, emitter);
|
jitCode(opc, emitter);
|
||||||
emitter.gpr.FlushRegs(c1);
|
emitter.m_gpr.FlushRegs(c1);
|
||||||
emitter.SetJumpTarget(skipCode);
|
emitter.SetJumpTarget(skipCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void WriteBranchExit(DSPEmitter& emitter)
|
static void WriteBranchExit(DSPEmitter& emitter)
|
||||||
{
|
{
|
||||||
DSPJitRegCache c(emitter.gpr);
|
DSPJitRegCache c(emitter.m_gpr);
|
||||||
emitter.gpr.SaveRegs();
|
emitter.m_gpr.SaveRegs();
|
||||||
if (Analyzer::GetCodeFlags(emitter.startAddr) & Analyzer::CODE_IDLE_SKIP)
|
if (Analyzer::GetCodeFlags(emitter.m_start_address) & Analyzer::CODE_IDLE_SKIP)
|
||||||
{
|
{
|
||||||
emitter.MOV(16, R(EAX), Imm16(0x1000));
|
emitter.MOV(16, R(EAX), Imm16(0x1000));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
emitter.MOV(16, R(EAX), Imm16(emitter.blockSize[emitter.startAddr]));
|
emitter.MOV(16, R(EAX), Imm16(emitter.m_block_size[emitter.m_start_address]));
|
||||||
}
|
}
|
||||||
emitter.JMP(emitter.returnDispatcher, true);
|
emitter.JMP(emitter.m_return_dispatcher, true);
|
||||||
emitter.gpr.LoadRegs(false);
|
emitter.m_gpr.LoadRegs(false);
|
||||||
emitter.gpr.FlushRegs(c, false);
|
emitter.m_gpr.FlushRegs(c, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void WriteBlockLink(DSPEmitter& emitter, u16 dest)
|
static void WriteBlockLink(DSPEmitter& emitter, u16 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.
|
||||||
if (!(dest >= emitter.startAddr && dest <= emitter.compilePC))
|
if (!(dest >= emitter.m_start_address && dest <= emitter.m_compile_pc))
|
||||||
{
|
{
|
||||||
if (emitter.blockLinks[dest] != nullptr)
|
if (emitter.m_block_links[dest] != nullptr)
|
||||||
{
|
{
|
||||||
emitter.gpr.FlushRegs();
|
emitter.m_gpr.FlushRegs();
|
||||||
// Check if we have enough cycles to execute the next block
|
// Check if we have enough cycles to execute the next block
|
||||||
emitter.MOV(16, R(ECX), M(&g_cycles_left));
|
emitter.MOV(16, R(ECX), M(&g_cycles_left));
|
||||||
emitter.CMP(16, R(ECX),
|
emitter.CMP(16, R(ECX), Imm16(emitter.m_block_size[emitter.m_start_address] +
|
||||||
Imm16(emitter.blockSize[emitter.startAddr] + emitter.blockSize[dest]));
|
emitter.m_block_size[dest]));
|
||||||
FixupBranch notEnoughCycles = emitter.J_CC(CC_BE);
|
FixupBranch notEnoughCycles = emitter.J_CC(CC_BE);
|
||||||
|
|
||||||
emitter.SUB(16, R(ECX), Imm16(emitter.blockSize[emitter.startAddr]));
|
emitter.SUB(16, R(ECX), Imm16(emitter.m_block_size[emitter.m_start_address]));
|
||||||
emitter.MOV(16, M(&g_cycles_left), R(ECX));
|
emitter.MOV(16, M(&g_cycles_left), R(ECX));
|
||||||
emitter.JMP(emitter.blockLinks[dest], true);
|
emitter.JMP(emitter.m_block_links[dest], true);
|
||||||
emitter.SetJumpTarget(notEnoughCycles);
|
emitter.SetJumpTarget(notEnoughCycles);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// The destination has not been compiled yet. Add it to the list
|
// The destination has not been compiled yet. Add it to the list
|
||||||
// of blocks that this block is waiting on.
|
// of blocks that this block is waiting on.
|
||||||
emitter.unresolvedJumps[emitter.startAddr].push_back(dest);
|
emitter.m_unresolved_jumps[emitter.m_start_address].push_back(dest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void r_jcc(const UDSPInstruction opc, DSPEmitter& emitter)
|
static void r_jcc(const UDSPInstruction opc, DSPEmitter& emitter)
|
||||||
{
|
{
|
||||||
u16 dest = dsp_imem_read(emitter.compilePC + 1);
|
u16 dest = dsp_imem_read(emitter.m_compile_pc + 1);
|
||||||
const DSPOPCTemplate* opcode = GetOpTemplate(opc);
|
const DSPOPCTemplate* opcode = GetOpTemplate(opc);
|
||||||
|
|
||||||
// If the block is unconditional, attempt to link block
|
// If the block is unconditional, attempt to link block
|
||||||
|
@ -148,7 +148,7 @@ static void r_jcc(const UDSPInstruction opc, DSPEmitter& emitter)
|
||||||
// NOTE: Cannot use FallBackToInterpreter(opc) here because of the need to write branch exit
|
// NOTE: Cannot use FallBackToInterpreter(opc) here because of the need to write branch exit
|
||||||
void DSPEmitter::jcc(const UDSPInstruction opc)
|
void DSPEmitter::jcc(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
MOV(16, M(&(g_dsp.pc)), Imm16(compilePC + 2));
|
MOV(16, M(&(g_dsp.pc)), Imm16(m_compile_pc + 2));
|
||||||
ReJitConditional<r_jcc>(opc, *this);
|
ReJitConditional<r_jcc>(opc, *this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,15 +168,15 @@ static void r_jmprcc(const UDSPInstruction opc, DSPEmitter& emitter)
|
||||||
// NOTE: Cannot use FallBackToInterpreter(opc) here because of the need to write branch exit
|
// NOTE: Cannot use FallBackToInterpreter(opc) here because of the need to write branch exit
|
||||||
void DSPEmitter::jmprcc(const UDSPInstruction opc)
|
void DSPEmitter::jmprcc(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
MOV(16, M(&g_dsp.pc), Imm16(compilePC + 1));
|
MOV(16, M(&g_dsp.pc), Imm16(m_compile_pc + 1));
|
||||||
ReJitConditional<r_jmprcc>(opc, *this);
|
ReJitConditional<r_jmprcc>(opc, *this);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void r_call(const UDSPInstruction opc, DSPEmitter& emitter)
|
static void r_call(const UDSPInstruction opc, DSPEmitter& emitter)
|
||||||
{
|
{
|
||||||
emitter.MOV(16, R(DX), Imm16(emitter.compilePC + 2));
|
emitter.MOV(16, R(DX), Imm16(emitter.m_compile_pc + 2));
|
||||||
emitter.dsp_reg_store_stack(DSP_STACK_C);
|
emitter.dsp_reg_store_stack(DSP_STACK_C);
|
||||||
u16 dest = dsp_imem_read(emitter.compilePC + 1);
|
u16 dest = dsp_imem_read(emitter.m_compile_pc + 1);
|
||||||
const DSPOPCTemplate* opcode = GetOpTemplate(opc);
|
const DSPOPCTemplate* opcode = GetOpTemplate(opc);
|
||||||
|
|
||||||
// If the block is unconditional, attempt to link block
|
// If the block is unconditional, attempt to link block
|
||||||
|
@ -195,14 +195,14 @@ static void r_call(const UDSPInstruction opc, DSPEmitter& emitter)
|
||||||
// NOTE: Cannot use FallBackToInterpreter(opc) here because of the need to write branch exit
|
// NOTE: Cannot use FallBackToInterpreter(opc) here because of the need to write branch exit
|
||||||
void DSPEmitter::call(const UDSPInstruction opc)
|
void DSPEmitter::call(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
MOV(16, M(&(g_dsp.pc)), Imm16(compilePC + 2));
|
MOV(16, M(&(g_dsp.pc)), Imm16(m_compile_pc + 2));
|
||||||
ReJitConditional<r_call>(opc, *this);
|
ReJitConditional<r_call>(opc, *this);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void r_callr(const UDSPInstruction opc, DSPEmitter& emitter)
|
static void r_callr(const UDSPInstruction opc, DSPEmitter& emitter)
|
||||||
{
|
{
|
||||||
u8 reg = (opc >> 5) & 0x7;
|
u8 reg = (opc >> 5) & 0x7;
|
||||||
emitter.MOV(16, R(DX), Imm16(emitter.compilePC + 1));
|
emitter.MOV(16, R(DX), Imm16(emitter.m_compile_pc + 1));
|
||||||
emitter.dsp_reg_store_stack(DSP_STACK_C);
|
emitter.dsp_reg_store_stack(DSP_STACK_C);
|
||||||
emitter.dsp_op_read_reg(reg, RAX, NONE);
|
emitter.dsp_op_read_reg(reg, RAX, NONE);
|
||||||
emitter.MOV(16, M(&g_dsp.pc), R(EAX));
|
emitter.MOV(16, M(&g_dsp.pc), R(EAX));
|
||||||
|
@ -217,13 +217,13 @@ static void r_callr(const UDSPInstruction opc, DSPEmitter& emitter)
|
||||||
// NOTE: Cannot use FallBackToInterpreter(opc) here because of the need to write branch exit
|
// NOTE: Cannot use FallBackToInterpreter(opc) here because of the need to write branch exit
|
||||||
void DSPEmitter::callr(const UDSPInstruction opc)
|
void DSPEmitter::callr(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
MOV(16, M(&g_dsp.pc), Imm16(compilePC + 1));
|
MOV(16, M(&g_dsp.pc), Imm16(m_compile_pc + 1));
|
||||||
ReJitConditional<r_callr>(opc, *this);
|
ReJitConditional<r_callr>(opc, *this);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void r_ifcc(const UDSPInstruction opc, DSPEmitter& emitter)
|
static void r_ifcc(const UDSPInstruction opc, DSPEmitter& emitter)
|
||||||
{
|
{
|
||||||
emitter.MOV(16, M(&g_dsp.pc), Imm16(emitter.compilePC + 1));
|
emitter.MOV(16, M(&g_dsp.pc), Imm16(emitter.m_compile_pc + 1));
|
||||||
}
|
}
|
||||||
// Generic if implementation
|
// Generic if implementation
|
||||||
// IFcc
|
// IFcc
|
||||||
|
@ -232,7 +232,7 @@ static void r_ifcc(const UDSPInstruction opc, DSPEmitter& emitter)
|
||||||
// NOTE: Cannot use FallBackToInterpreter(opc) here because of the need to write branch exit
|
// NOTE: Cannot use FallBackToInterpreter(opc) here because of the need to write branch exit
|
||||||
void DSPEmitter::ifcc(const UDSPInstruction opc)
|
void DSPEmitter::ifcc(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
const u16 address = compilePC + 1;
|
const u16 address = m_compile_pc + 1;
|
||||||
const DSPOPCTemplate* const op_template = GetOpTemplate(dsp_imem_read(address));
|
const DSPOPCTemplate* const op_template = GetOpTemplate(dsp_imem_read(address));
|
||||||
|
|
||||||
MOV(16, M(&g_dsp.pc), Imm16(address + op_template->size));
|
MOV(16, M(&g_dsp.pc), Imm16(address + op_template->size));
|
||||||
|
@ -255,7 +255,7 @@ static void r_ret(const UDSPInstruction opc, DSPEmitter& emitter)
|
||||||
// NOTE: Cannot use FallBackToInterpreter(opc) here because of the need to write branch exit
|
// NOTE: Cannot use FallBackToInterpreter(opc) here because of the need to write branch exit
|
||||||
void DSPEmitter::ret(const UDSPInstruction opc)
|
void DSPEmitter::ret(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
MOV(16, M(&g_dsp.pc), Imm16(compilePC + 1));
|
MOV(16, M(&g_dsp.pc), Imm16(m_compile_pc + 1));
|
||||||
ReJitConditional<r_ret>(opc, *this);
|
ReJitConditional<r_ret>(opc, *this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -298,7 +298,7 @@ void DSPEmitter::HandleLoop()
|
||||||
|
|
||||||
TEST(32, R(RCX), R(RCX));
|
TEST(32, R(RCX), R(RCX));
|
||||||
FixupBranch rLoopCntG = J_CC(CC_LE, true);
|
FixupBranch rLoopCntG = J_CC(CC_LE, true);
|
||||||
CMP(16, R(RAX), Imm16(compilePC - 1));
|
CMP(16, R(RAX), Imm16(m_compile_pc - 1));
|
||||||
FixupBranch rLoopAddrG = J_CC(CC_NE, true);
|
FixupBranch rLoopAddrG = J_CC(CC_NE, true);
|
||||||
|
|
||||||
SUB(16, M(&(g_dsp.r.st[3])), Imm16(1));
|
SUB(16, M(&(g_dsp.r.st[3])), Imm16(1));
|
||||||
|
@ -310,11 +310,11 @@ void DSPEmitter::HandleLoop()
|
||||||
FixupBranch loopUpdated = J(true);
|
FixupBranch loopUpdated = J(true);
|
||||||
|
|
||||||
SetJumpTarget(loadStack);
|
SetJumpTarget(loadStack);
|
||||||
DSPJitRegCache c(gpr);
|
DSPJitRegCache c(m_gpr);
|
||||||
dsp_reg_load_stack(0);
|
dsp_reg_load_stack(0);
|
||||||
dsp_reg_load_stack(2);
|
dsp_reg_load_stack(2);
|
||||||
dsp_reg_load_stack(3);
|
dsp_reg_load_stack(3);
|
||||||
gpr.FlushRegs(c);
|
m_gpr.FlushRegs(c);
|
||||||
|
|
||||||
SetJumpTarget(loopUpdated);
|
SetJumpTarget(loopUpdated);
|
||||||
SetJumpTarget(rLoopAddrG);
|
SetJumpTarget(rLoopAddrG);
|
||||||
|
@ -335,25 +335,25 @@ void DSPEmitter::loop(const UDSPInstruction opc)
|
||||||
// u16 cnt = g_dsp.r[reg];
|
// u16 cnt = g_dsp.r[reg];
|
||||||
// todo: check if we can use normal variant here
|
// todo: check if we can use normal variant here
|
||||||
dsp_op_read_reg_dont_saturate(reg, RDX, ZERO);
|
dsp_op_read_reg_dont_saturate(reg, RDX, ZERO);
|
||||||
u16 loop_pc = compilePC + 1;
|
u16 loop_pc = m_compile_pc + 1;
|
||||||
|
|
||||||
TEST(16, R(EDX), R(EDX));
|
TEST(16, R(EDX), R(EDX));
|
||||||
DSPJitRegCache c(gpr);
|
DSPJitRegCache c(m_gpr);
|
||||||
FixupBranch cnt = J_CC(CC_Z, true);
|
FixupBranch cnt = J_CC(CC_Z, true);
|
||||||
dsp_reg_store_stack(3);
|
dsp_reg_store_stack(3);
|
||||||
MOV(16, R(RDX), Imm16(compilePC + 1));
|
MOV(16, R(RDX), Imm16(m_compile_pc + 1));
|
||||||
dsp_reg_store_stack(0);
|
dsp_reg_store_stack(0);
|
||||||
MOV(16, R(RDX), Imm16(loop_pc));
|
MOV(16, R(RDX), Imm16(loop_pc));
|
||||||
dsp_reg_store_stack(2);
|
dsp_reg_store_stack(2);
|
||||||
gpr.FlushRegs(c);
|
m_gpr.FlushRegs(c);
|
||||||
MOV(16, M(&(g_dsp.pc)), Imm16(compilePC + 1));
|
MOV(16, M(&(g_dsp.pc)), Imm16(m_compile_pc + 1));
|
||||||
FixupBranch exit = J(true);
|
FixupBranch exit = J(true);
|
||||||
|
|
||||||
SetJumpTarget(cnt);
|
SetJumpTarget(cnt);
|
||||||
// dsp_skip_inst();
|
// dsp_skip_inst();
|
||||||
MOV(16, M(&g_dsp.pc), Imm16(loop_pc + GetOpTemplate(dsp_imem_read(loop_pc))->size));
|
MOV(16, M(&g_dsp.pc), Imm16(loop_pc + GetOpTemplate(dsp_imem_read(loop_pc))->size));
|
||||||
WriteBranchExit(*this);
|
WriteBranchExit(*this);
|
||||||
gpr.FlushRegs(c, false);
|
m_gpr.FlushRegs(c, false);
|
||||||
SetJumpTarget(exit);
|
SetJumpTarget(exit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -368,18 +368,18 @@ void DSPEmitter::loop(const UDSPInstruction opc)
|
||||||
void DSPEmitter::loopi(const UDSPInstruction opc)
|
void DSPEmitter::loopi(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u16 cnt = opc & 0xff;
|
u16 cnt = opc & 0xff;
|
||||||
u16 loop_pc = compilePC + 1;
|
u16 loop_pc = m_compile_pc + 1;
|
||||||
|
|
||||||
if (cnt)
|
if (cnt)
|
||||||
{
|
{
|
||||||
MOV(16, R(RDX), Imm16(compilePC + 1));
|
MOV(16, R(RDX), Imm16(m_compile_pc + 1));
|
||||||
dsp_reg_store_stack(0);
|
dsp_reg_store_stack(0);
|
||||||
MOV(16, R(RDX), Imm16(loop_pc));
|
MOV(16, R(RDX), Imm16(loop_pc));
|
||||||
dsp_reg_store_stack(2);
|
dsp_reg_store_stack(2);
|
||||||
MOV(16, R(RDX), Imm16(cnt));
|
MOV(16, R(RDX), Imm16(cnt));
|
||||||
dsp_reg_store_stack(3);
|
dsp_reg_store_stack(3);
|
||||||
|
|
||||||
MOV(16, M(&(g_dsp.pc)), Imm16(compilePC + 1));
|
MOV(16, M(&(g_dsp.pc)), Imm16(m_compile_pc + 1));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -404,18 +404,18 @@ void DSPEmitter::bloop(const UDSPInstruction opc)
|
||||||
// u16 cnt = g_dsp.r[reg];
|
// u16 cnt = g_dsp.r[reg];
|
||||||
// todo: check if we can use normal variant here
|
// todo: check if we can use normal variant here
|
||||||
dsp_op_read_reg_dont_saturate(reg, RDX, ZERO);
|
dsp_op_read_reg_dont_saturate(reg, RDX, ZERO);
|
||||||
u16 loop_pc = dsp_imem_read(compilePC + 1);
|
u16 loop_pc = dsp_imem_read(m_compile_pc + 1);
|
||||||
|
|
||||||
TEST(16, R(EDX), R(EDX));
|
TEST(16, R(EDX), R(EDX));
|
||||||
DSPJitRegCache c(gpr);
|
DSPJitRegCache c(m_gpr);
|
||||||
FixupBranch cnt = J_CC(CC_Z, true);
|
FixupBranch cnt = J_CC(CC_Z, true);
|
||||||
dsp_reg_store_stack(3);
|
dsp_reg_store_stack(3);
|
||||||
MOV(16, R(RDX), Imm16(compilePC + 2));
|
MOV(16, R(RDX), Imm16(m_compile_pc + 2));
|
||||||
dsp_reg_store_stack(0);
|
dsp_reg_store_stack(0);
|
||||||
MOV(16, R(RDX), Imm16(loop_pc));
|
MOV(16, R(RDX), Imm16(loop_pc));
|
||||||
dsp_reg_store_stack(2);
|
dsp_reg_store_stack(2);
|
||||||
MOV(16, M(&(g_dsp.pc)), Imm16(compilePC + 2));
|
MOV(16, M(&(g_dsp.pc)), Imm16(m_compile_pc + 2));
|
||||||
gpr.FlushRegs(c, true);
|
m_gpr.FlushRegs(c, true);
|
||||||
FixupBranch exit = J(true);
|
FixupBranch exit = J(true);
|
||||||
|
|
||||||
SetJumpTarget(cnt);
|
SetJumpTarget(cnt);
|
||||||
|
@ -423,7 +423,7 @@ void DSPEmitter::bloop(const UDSPInstruction opc)
|
||||||
// dsp_skip_inst();
|
// dsp_skip_inst();
|
||||||
MOV(16, M(&g_dsp.pc), Imm16(loop_pc + GetOpTemplate(dsp_imem_read(loop_pc))->size));
|
MOV(16, M(&g_dsp.pc), Imm16(loop_pc + GetOpTemplate(dsp_imem_read(loop_pc))->size));
|
||||||
WriteBranchExit(*this);
|
WriteBranchExit(*this);
|
||||||
gpr.FlushRegs(c, false);
|
m_gpr.FlushRegs(c, false);
|
||||||
SetJumpTarget(exit);
|
SetJumpTarget(exit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -440,18 +440,18 @@ void DSPEmitter::bloopi(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u16 cnt = opc & 0xff;
|
u16 cnt = opc & 0xff;
|
||||||
// u16 loop_pc = dsp_fetch_code();
|
// u16 loop_pc = dsp_fetch_code();
|
||||||
u16 loop_pc = dsp_imem_read(compilePC + 1);
|
u16 loop_pc = dsp_imem_read(m_compile_pc + 1);
|
||||||
|
|
||||||
if (cnt)
|
if (cnt)
|
||||||
{
|
{
|
||||||
MOV(16, R(RDX), Imm16(compilePC + 2));
|
MOV(16, R(RDX), Imm16(m_compile_pc + 2));
|
||||||
dsp_reg_store_stack(0);
|
dsp_reg_store_stack(0);
|
||||||
MOV(16, R(RDX), Imm16(loop_pc));
|
MOV(16, R(RDX), Imm16(loop_pc));
|
||||||
dsp_reg_store_stack(2);
|
dsp_reg_store_stack(2);
|
||||||
MOV(16, R(RDX), Imm16(cnt));
|
MOV(16, R(RDX), Imm16(cnt));
|
||||||
dsp_reg_store_stack(3);
|
dsp_reg_store_stack(3);
|
||||||
|
|
||||||
MOV(16, M(&(g_dsp.pc)), Imm16(compilePC + 2));
|
MOV(16, M(&(g_dsp.pc)), Imm16(m_compile_pc + 2));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,7 +19,7 @@ namespace x86
|
||||||
// Clobbers RDX
|
// Clobbers RDX
|
||||||
void DSPEmitter::Update_SR_Register(Gen::X64Reg val)
|
void DSPEmitter::Update_SR_Register(Gen::X64Reg val)
|
||||||
{
|
{
|
||||||
const OpArg sr_reg = gpr.GetReg(DSP_REG_SR);
|
const OpArg sr_reg = m_gpr.GetReg(DSP_REG_SR);
|
||||||
// // 0x04
|
// // 0x04
|
||||||
// if (_Value == 0) g_dsp.r[DSP_REG_SR] |= SR_ARITH_ZERO;
|
// if (_Value == 0) g_dsp.r[DSP_REG_SR] |= SR_ARITH_ZERO;
|
||||||
TEST(64, R(val), R(val));
|
TEST(64, R(val), R(val));
|
||||||
|
@ -54,7 +54,7 @@ void DSPEmitter::Update_SR_Register(Gen::X64Reg val)
|
||||||
OR(16, sr_reg, Imm16(SR_TOP2BITS));
|
OR(16, sr_reg, Imm16(SR_TOP2BITS));
|
||||||
SetJumpTarget(cC);
|
SetJumpTarget(cC);
|
||||||
SetJumpTarget(end);
|
SetJumpTarget(end);
|
||||||
gpr.PutReg(DSP_REG_SR);
|
m_gpr.PutReg(DSP_REG_SR);
|
||||||
}
|
}
|
||||||
|
|
||||||
// In: RAX: s64 _Value
|
// In: RAX: s64 _Value
|
||||||
|
@ -62,9 +62,9 @@ void DSPEmitter::Update_SR_Register(Gen::X64Reg val)
|
||||||
void DSPEmitter::Update_SR_Register64(Gen::X64Reg val)
|
void DSPEmitter::Update_SR_Register64(Gen::X64Reg val)
|
||||||
{
|
{
|
||||||
// g_dsp.r[DSP_REG_SR] &= ~SR_CMP_MASK;
|
// g_dsp.r[DSP_REG_SR] &= ~SR_CMP_MASK;
|
||||||
const OpArg sr_reg = gpr.GetReg(DSP_REG_SR);
|
const OpArg sr_reg = m_gpr.GetReg(DSP_REG_SR);
|
||||||
AND(16, sr_reg, Imm16(~SR_CMP_MASK));
|
AND(16, sr_reg, Imm16(~SR_CMP_MASK));
|
||||||
gpr.PutReg(DSP_REG_SR);
|
m_gpr.PutReg(DSP_REG_SR);
|
||||||
Update_SR_Register(val);
|
Update_SR_Register(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ void DSPEmitter::Update_SR_Register64(Gen::X64Reg val)
|
||||||
// Clobbers RDX
|
// Clobbers RDX
|
||||||
void DSPEmitter::Update_SR_Register64_Carry(X64Reg val, X64Reg carry_ovfl, bool carry_eq)
|
void DSPEmitter::Update_SR_Register64_Carry(X64Reg val, X64Reg carry_ovfl, bool carry_eq)
|
||||||
{
|
{
|
||||||
const OpArg sr_reg = gpr.GetReg(DSP_REG_SR);
|
const OpArg sr_reg = m_gpr.GetReg(DSP_REG_SR);
|
||||||
// g_dsp.r[DSP_REG_SR] &= ~SR_CMP_MASK;
|
// g_dsp.r[DSP_REG_SR] &= ~SR_CMP_MASK;
|
||||||
AND(16, sr_reg, Imm16(~SR_CMP_MASK));
|
AND(16, sr_reg, Imm16(~SR_CMP_MASK));
|
||||||
|
|
||||||
|
@ -98,7 +98,7 @@ void DSPEmitter::Update_SR_Register64_Carry(X64Reg val, X64Reg carry_ovfl, bool
|
||||||
OR(16, sr_reg, Imm16(SR_OVERFLOW | SR_OVERFLOW_STICKY));
|
OR(16, sr_reg, Imm16(SR_OVERFLOW | SR_OVERFLOW_STICKY));
|
||||||
SetJumpTarget(noOverflow);
|
SetJumpTarget(noOverflow);
|
||||||
|
|
||||||
gpr.PutReg(DSP_REG_SR);
|
m_gpr.PutReg(DSP_REG_SR);
|
||||||
if (carry_eq)
|
if (carry_eq)
|
||||||
{
|
{
|
||||||
Update_SR_Register();
|
Update_SR_Register();
|
||||||
|
@ -112,7 +112,7 @@ void DSPEmitter::Update_SR_Register64_Carry(X64Reg val, X64Reg carry_ovfl, bool
|
||||||
// In: RAX: s64 _Value
|
// In: RAX: s64 _Value
|
||||||
void DSPEmitter::Update_SR_Register16(X64Reg val)
|
void DSPEmitter::Update_SR_Register16(X64Reg val)
|
||||||
{
|
{
|
||||||
const OpArg sr_reg = gpr.GetReg(DSP_REG_SR);
|
const OpArg sr_reg = m_gpr.GetReg(DSP_REG_SR);
|
||||||
AND(16, sr_reg, Imm16(~SR_CMP_MASK));
|
AND(16, sr_reg, Imm16(~SR_CMP_MASK));
|
||||||
|
|
||||||
// // 0x04
|
// // 0x04
|
||||||
|
@ -141,14 +141,14 @@ void DSPEmitter::Update_SR_Register16(X64Reg val)
|
||||||
OR(16, sr_reg, Imm16(SR_TOP2BITS));
|
OR(16, sr_reg, Imm16(SR_TOP2BITS));
|
||||||
SetJumpTarget(notThree);
|
SetJumpTarget(notThree);
|
||||||
SetJumpTarget(end);
|
SetJumpTarget(end);
|
||||||
gpr.PutReg(DSP_REG_SR);
|
m_gpr.PutReg(DSP_REG_SR);
|
||||||
}
|
}
|
||||||
|
|
||||||
// In: RAX: s64 _Value
|
// In: RAX: s64 _Value
|
||||||
// Clobbers RCX
|
// Clobbers RCX
|
||||||
void DSPEmitter::Update_SR_Register16_OverS32(Gen::X64Reg val)
|
void DSPEmitter::Update_SR_Register16_OverS32(Gen::X64Reg val)
|
||||||
{
|
{
|
||||||
const OpArg sr_reg = gpr.GetReg(DSP_REG_SR);
|
const OpArg sr_reg = m_gpr.GetReg(DSP_REG_SR);
|
||||||
AND(16, sr_reg, Imm16(~SR_CMP_MASK));
|
AND(16, sr_reg, Imm16(~SR_CMP_MASK));
|
||||||
|
|
||||||
// // 0x10
|
// // 0x10
|
||||||
|
@ -159,7 +159,7 @@ void DSPEmitter::Update_SR_Register16_OverS32(Gen::X64Reg val)
|
||||||
OR(16, sr_reg, Imm16(SR_OVER_S32));
|
OR(16, sr_reg, Imm16(SR_OVER_S32));
|
||||||
SetJumpTarget(noOverS32);
|
SetJumpTarget(noOverS32);
|
||||||
|
|
||||||
gpr.PutReg(DSP_REG_SR);
|
m_gpr.PutReg(DSP_REG_SR);
|
||||||
// // 0x20 - Checks if top bits of m are equal
|
// // 0x20 - Checks if top bits of m are equal
|
||||||
// if ((((u16)_Value >> 14) == 0) || (((u16)_Value >> 14) == 3))
|
// if ((((u16)_Value >> 14) == 0) || (((u16)_Value >> 14) == 3))
|
||||||
// AND(32, R(val), Imm32(0xc0000000));
|
// AND(32, R(val), Imm32(0xc0000000));
|
||||||
|
|
|
@ -65,7 +65,7 @@ void DSPEmitter::mv(const UDSPInstruction opc)
|
||||||
u8 sreg = (opc & 0x3) + DSP_REG_ACL0;
|
u8 sreg = (opc & 0x3) + DSP_REG_ACL0;
|
||||||
u8 dreg = ((opc >> 2) & 0x3);
|
u8 dreg = ((opc >> 2) & 0x3);
|
||||||
dsp_op_read_reg(sreg, RBX, ZERO);
|
dsp_op_read_reg(sreg, RBX, ZERO);
|
||||||
storeIndex = dreg + DSP_REG_AXL0;
|
m_store_index = dreg + DSP_REG_AXL0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// S @$arD, $acS.S
|
// S @$arD, $acS.S
|
||||||
|
@ -79,13 +79,13 @@ void DSPEmitter::s(const UDSPInstruction opc)
|
||||||
// u16 addr = g_dsp.r[dest];
|
// u16 addr = g_dsp.r[dest];
|
||||||
dsp_op_read_reg(dreg, RAX, ZERO);
|
dsp_op_read_reg(dreg, RAX, ZERO);
|
||||||
|
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
|
|
||||||
dsp_op_read_reg(sreg, tmp1, ZERO);
|
dsp_op_read_reg(sreg, tmp1, ZERO);
|
||||||
// u16 val = g_dsp.r[src];
|
// u16 val = g_dsp.r[src];
|
||||||
dmem_write(tmp1);
|
dmem_write(tmp1);
|
||||||
|
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
|
|
||||||
increment_addr_reg(dreg);
|
increment_addr_reg(dreg);
|
||||||
}
|
}
|
||||||
|
@ -100,12 +100,12 @@ void DSPEmitter::sn(const UDSPInstruction opc)
|
||||||
u8 sreg = ((opc >> 3) & 0x3) + DSP_REG_ACL0;
|
u8 sreg = ((opc >> 3) & 0x3) + DSP_REG_ACL0;
|
||||||
dsp_op_read_reg(dreg, RAX, ZERO);
|
dsp_op_read_reg(dreg, RAX, ZERO);
|
||||||
|
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
|
|
||||||
dsp_op_read_reg(sreg, tmp1, ZERO);
|
dsp_op_read_reg(sreg, tmp1, ZERO);
|
||||||
dmem_write(tmp1);
|
dmem_write(tmp1);
|
||||||
|
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
|
|
||||||
increase_addr_reg(dreg, dreg);
|
increase_addr_reg(dreg, dreg);
|
||||||
}
|
}
|
||||||
|
@ -171,12 +171,12 @@ void DSPEmitter::ls(const UDSPInstruction opc)
|
||||||
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
||||||
dsp_op_read_reg(DSP_REG_AR3, RAX, ZERO);
|
dsp_op_read_reg(DSP_REG_AR3, RAX, ZERO);
|
||||||
|
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
|
|
||||||
dsp_op_read_reg(sreg + DSP_REG_ACM0, tmp1, ZERO);
|
dsp_op_read_reg(sreg + DSP_REG_ACM0, tmp1, ZERO);
|
||||||
dmem_write(tmp1);
|
dmem_write(tmp1);
|
||||||
|
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
|
|
||||||
pushExtValueFromMem(dreg, DSP_REG_AR0);
|
pushExtValueFromMem(dreg, DSP_REG_AR0);
|
||||||
|
|
||||||
|
@ -196,12 +196,12 @@ void DSPEmitter::lsn(const UDSPInstruction opc)
|
||||||
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
||||||
dsp_op_read_reg(DSP_REG_AR3, RAX, ZERO);
|
dsp_op_read_reg(DSP_REG_AR3, RAX, ZERO);
|
||||||
|
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
|
|
||||||
dsp_op_read_reg(sreg + DSP_REG_ACM0, tmp1, ZERO);
|
dsp_op_read_reg(sreg + DSP_REG_ACM0, tmp1, ZERO);
|
||||||
dmem_write(tmp1);
|
dmem_write(tmp1);
|
||||||
|
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
|
|
||||||
pushExtValueFromMem(dreg, DSP_REG_AR0);
|
pushExtValueFromMem(dreg, DSP_REG_AR0);
|
||||||
|
|
||||||
|
@ -221,12 +221,12 @@ void DSPEmitter::lsm(const UDSPInstruction opc)
|
||||||
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
||||||
dsp_op_read_reg(DSP_REG_AR3, RAX, ZERO);
|
dsp_op_read_reg(DSP_REG_AR3, RAX, ZERO);
|
||||||
|
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
|
|
||||||
dsp_op_read_reg(sreg + DSP_REG_ACM0, tmp1, ZERO);
|
dsp_op_read_reg(sreg + DSP_REG_ACM0, tmp1, ZERO);
|
||||||
dmem_write(tmp1);
|
dmem_write(tmp1);
|
||||||
|
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
|
|
||||||
pushExtValueFromMem(dreg, DSP_REG_AR0);
|
pushExtValueFromMem(dreg, DSP_REG_AR0);
|
||||||
|
|
||||||
|
@ -247,12 +247,12 @@ void DSPEmitter::lsnm(const UDSPInstruction opc)
|
||||||
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
||||||
dsp_op_read_reg(DSP_REG_AR3, RAX, ZERO);
|
dsp_op_read_reg(DSP_REG_AR3, RAX, ZERO);
|
||||||
|
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
|
|
||||||
dsp_op_read_reg(sreg + DSP_REG_ACM0, tmp1, ZERO);
|
dsp_op_read_reg(sreg + DSP_REG_ACM0, tmp1, ZERO);
|
||||||
dmem_write(tmp1);
|
dmem_write(tmp1);
|
||||||
|
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
|
|
||||||
pushExtValueFromMem(dreg, DSP_REG_AR0);
|
pushExtValueFromMem(dreg, DSP_REG_AR0);
|
||||||
|
|
||||||
|
@ -271,12 +271,12 @@ void DSPEmitter::sl(const UDSPInstruction opc)
|
||||||
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
||||||
dsp_op_read_reg(DSP_REG_AR0, RAX, ZERO);
|
dsp_op_read_reg(DSP_REG_AR0, RAX, ZERO);
|
||||||
|
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
|
|
||||||
dsp_op_read_reg(sreg + DSP_REG_ACM0, tmp1, ZERO);
|
dsp_op_read_reg(sreg + DSP_REG_ACM0, tmp1, ZERO);
|
||||||
dmem_write(tmp1);
|
dmem_write(tmp1);
|
||||||
|
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
|
|
||||||
pushExtValueFromMem(dreg, DSP_REG_AR3);
|
pushExtValueFromMem(dreg, DSP_REG_AR3);
|
||||||
|
|
||||||
|
@ -296,12 +296,12 @@ void DSPEmitter::sln(const UDSPInstruction opc)
|
||||||
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
||||||
dsp_op_read_reg(DSP_REG_AR0, RAX, ZERO);
|
dsp_op_read_reg(DSP_REG_AR0, RAX, ZERO);
|
||||||
|
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
|
|
||||||
dsp_op_read_reg(sreg + DSP_REG_ACM0, tmp1, ZERO);
|
dsp_op_read_reg(sreg + DSP_REG_ACM0, tmp1, ZERO);
|
||||||
dmem_write(tmp1);
|
dmem_write(tmp1);
|
||||||
|
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
|
|
||||||
pushExtValueFromMem(dreg, DSP_REG_AR3);
|
pushExtValueFromMem(dreg, DSP_REG_AR3);
|
||||||
|
|
||||||
|
@ -321,12 +321,12 @@ void DSPEmitter::slm(const UDSPInstruction opc)
|
||||||
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
||||||
dsp_op_read_reg(DSP_REG_AR0, RAX, ZERO);
|
dsp_op_read_reg(DSP_REG_AR0, RAX, ZERO);
|
||||||
|
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
|
|
||||||
dsp_op_read_reg(sreg + DSP_REG_ACM0, tmp1, ZERO);
|
dsp_op_read_reg(sreg + DSP_REG_ACM0, tmp1, ZERO);
|
||||||
dmem_write(tmp1);
|
dmem_write(tmp1);
|
||||||
|
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
|
|
||||||
pushExtValueFromMem(dreg, DSP_REG_AR3);
|
pushExtValueFromMem(dreg, DSP_REG_AR3);
|
||||||
|
|
||||||
|
@ -346,12 +346,12 @@ void DSPEmitter::slnm(const UDSPInstruction opc)
|
||||||
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
|
||||||
dsp_op_read_reg(DSP_REG_AR0, RAX, ZERO);
|
dsp_op_read_reg(DSP_REG_AR0, RAX, ZERO);
|
||||||
|
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
|
|
||||||
dsp_op_read_reg(sreg + DSP_REG_ACM0, tmp1, ZERO);
|
dsp_op_read_reg(sreg + DSP_REG_ACM0, tmp1, ZERO);
|
||||||
dmem_write(tmp1);
|
dmem_write(tmp1);
|
||||||
|
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
|
|
||||||
pushExtValueFromMem(dreg, DSP_REG_AR3);
|
pushExtValueFromMem(dreg, DSP_REG_AR3);
|
||||||
|
|
||||||
|
@ -378,20 +378,20 @@ void DSPEmitter::ld(const UDSPInstruction opc)
|
||||||
pushExtValueFromMem((dreg << 1) + DSP_REG_AXL0, sreg);
|
pushExtValueFromMem((dreg << 1) + DSP_REG_AXL0, sreg);
|
||||||
|
|
||||||
// if (IsSameMemArea(g_dsp.r[sreg], g_dsp.r[DSP_REG_AR3])) {
|
// if (IsSameMemArea(g_dsp.r[sreg], g_dsp.r[DSP_REG_AR3])) {
|
||||||
X64Reg tmp = gpr.GetFreeXReg();
|
X64Reg tmp = m_gpr.GetFreeXReg();
|
||||||
dsp_op_read_reg(sreg, RCX, NONE);
|
dsp_op_read_reg(sreg, RCX, NONE);
|
||||||
dsp_op_read_reg(DSP_REG_AR3, tmp, NONE);
|
dsp_op_read_reg(DSP_REG_AR3, tmp, NONE);
|
||||||
XOR(16, R(ECX), R(tmp));
|
XOR(16, R(ECX), R(tmp));
|
||||||
gpr.PutXReg(tmp);
|
m_gpr.PutXReg(tmp);
|
||||||
DSPJitRegCache c(gpr);
|
DSPJitRegCache c(m_gpr);
|
||||||
TEST(16, R(ECX), Imm16(0xfc00));
|
TEST(16, R(ECX), Imm16(0xfc00));
|
||||||
FixupBranch not_equal = J_CC(CC_NE, true);
|
FixupBranch not_equal = J_CC(CC_NE, true);
|
||||||
pushExtValueFromMem2((rreg << 1) + DSP_REG_AXL1, sreg);
|
pushExtValueFromMem2((rreg << 1) + DSP_REG_AXL1, sreg);
|
||||||
gpr.FlushRegs(c);
|
m_gpr.FlushRegs(c);
|
||||||
FixupBranch after = J(true);
|
FixupBranch after = J(true);
|
||||||
SetJumpTarget(not_equal); // else
|
SetJumpTarget(not_equal); // else
|
||||||
pushExtValueFromMem2((rreg << 1) + DSP_REG_AXL1, DSP_REG_AR3);
|
pushExtValueFromMem2((rreg << 1) + DSP_REG_AXL1, DSP_REG_AR3);
|
||||||
gpr.FlushRegs(c);
|
m_gpr.FlushRegs(c);
|
||||||
SetJumpTarget(after);
|
SetJumpTarget(after);
|
||||||
|
|
||||||
increment_addr_reg(sreg);
|
increment_addr_reg(sreg);
|
||||||
|
@ -408,21 +408,21 @@ void DSPEmitter::ldax(const UDSPInstruction opc)
|
||||||
|
|
||||||
pushExtValueFromMem(rreg + DSP_REG_AXH0, sreg);
|
pushExtValueFromMem(rreg + DSP_REG_AXH0, sreg);
|
||||||
|
|
||||||
X64Reg tmp = gpr.GetFreeXReg();
|
X64Reg tmp = m_gpr.GetFreeXReg();
|
||||||
// if (IsSameMemArea(g_dsp.r[sreg], g_dsp.r[DSP_REG_AR3])) {
|
// if (IsSameMemArea(g_dsp.r[sreg], g_dsp.r[DSP_REG_AR3])) {
|
||||||
dsp_op_read_reg(sreg, RCX, NONE);
|
dsp_op_read_reg(sreg, RCX, NONE);
|
||||||
dsp_op_read_reg(DSP_REG_AR3, tmp, NONE);
|
dsp_op_read_reg(DSP_REG_AR3, tmp, NONE);
|
||||||
XOR(16, R(ECX), R(tmp));
|
XOR(16, R(ECX), R(tmp));
|
||||||
gpr.PutXReg(tmp);
|
m_gpr.PutXReg(tmp);
|
||||||
DSPJitRegCache c(gpr);
|
DSPJitRegCache c(m_gpr);
|
||||||
TEST(16, R(ECX), Imm16(0xfc00));
|
TEST(16, R(ECX), Imm16(0xfc00));
|
||||||
FixupBranch not_equal = J_CC(CC_NE, true);
|
FixupBranch not_equal = J_CC(CC_NE, true);
|
||||||
pushExtValueFromMem2(rreg + DSP_REG_AXL0, sreg);
|
pushExtValueFromMem2(rreg + DSP_REG_AXL0, sreg);
|
||||||
gpr.FlushRegs(c);
|
m_gpr.FlushRegs(c);
|
||||||
FixupBranch after = J(true); // else
|
FixupBranch after = J(true); // else
|
||||||
SetJumpTarget(not_equal);
|
SetJumpTarget(not_equal);
|
||||||
pushExtValueFromMem2(rreg + DSP_REG_AXL0, DSP_REG_AR3);
|
pushExtValueFromMem2(rreg + DSP_REG_AXL0, DSP_REG_AR3);
|
||||||
gpr.FlushRegs(c);
|
m_gpr.FlushRegs(c);
|
||||||
SetJumpTarget(after);
|
SetJumpTarget(after);
|
||||||
|
|
||||||
increment_addr_reg(sreg);
|
increment_addr_reg(sreg);
|
||||||
|
@ -440,21 +440,21 @@ void DSPEmitter::ldn(const UDSPInstruction opc)
|
||||||
|
|
||||||
pushExtValueFromMem((dreg << 1) + DSP_REG_AXL0, sreg);
|
pushExtValueFromMem((dreg << 1) + DSP_REG_AXL0, sreg);
|
||||||
|
|
||||||
X64Reg tmp = gpr.GetFreeXReg();
|
X64Reg tmp = m_gpr.GetFreeXReg();
|
||||||
// if (IsSameMemArea(g_dsp.r[sreg], g_dsp.r[DSP_REG_AR3])) {
|
// if (IsSameMemArea(g_dsp.r[sreg], g_dsp.r[DSP_REG_AR3])) {
|
||||||
dsp_op_read_reg(sreg, RCX, NONE);
|
dsp_op_read_reg(sreg, RCX, NONE);
|
||||||
dsp_op_read_reg(DSP_REG_AR3, tmp, NONE);
|
dsp_op_read_reg(DSP_REG_AR3, tmp, NONE);
|
||||||
XOR(16, R(ECX), R(tmp));
|
XOR(16, R(ECX), R(tmp));
|
||||||
gpr.PutXReg(tmp);
|
m_gpr.PutXReg(tmp);
|
||||||
DSPJitRegCache c(gpr);
|
DSPJitRegCache c(m_gpr);
|
||||||
TEST(16, R(ECX), Imm16(0xfc00));
|
TEST(16, R(ECX), Imm16(0xfc00));
|
||||||
FixupBranch not_equal = J_CC(CC_NE, true);
|
FixupBranch not_equal = J_CC(CC_NE, true);
|
||||||
pushExtValueFromMem2((rreg << 1) + DSP_REG_AXL1, sreg);
|
pushExtValueFromMem2((rreg << 1) + DSP_REG_AXL1, sreg);
|
||||||
gpr.FlushRegs(c);
|
m_gpr.FlushRegs(c);
|
||||||
FixupBranch after = J(true);
|
FixupBranch after = J(true);
|
||||||
SetJumpTarget(not_equal); // else
|
SetJumpTarget(not_equal); // else
|
||||||
pushExtValueFromMem2((rreg << 1) + DSP_REG_AXL1, DSP_REG_AR3);
|
pushExtValueFromMem2((rreg << 1) + DSP_REG_AXL1, DSP_REG_AR3);
|
||||||
gpr.FlushRegs(c);
|
m_gpr.FlushRegs(c);
|
||||||
SetJumpTarget(after);
|
SetJumpTarget(after);
|
||||||
|
|
||||||
increase_addr_reg(sreg, sreg);
|
increase_addr_reg(sreg, sreg);
|
||||||
|
@ -471,21 +471,21 @@ void DSPEmitter::ldaxn(const UDSPInstruction opc)
|
||||||
|
|
||||||
pushExtValueFromMem(rreg + DSP_REG_AXH0, sreg);
|
pushExtValueFromMem(rreg + DSP_REG_AXH0, sreg);
|
||||||
|
|
||||||
X64Reg tmp = gpr.GetFreeXReg();
|
X64Reg tmp = m_gpr.GetFreeXReg();
|
||||||
// if (IsSameMemArea(g_dsp.r[sreg], g_dsp.r[DSP_REG_AR3])) {
|
// if (IsSameMemArea(g_dsp.r[sreg], g_dsp.r[DSP_REG_AR3])) {
|
||||||
dsp_op_read_reg(sreg, RCX, NONE);
|
dsp_op_read_reg(sreg, RCX, NONE);
|
||||||
dsp_op_read_reg(DSP_REG_AR3, tmp, NONE);
|
dsp_op_read_reg(DSP_REG_AR3, tmp, NONE);
|
||||||
XOR(16, R(ECX), R(tmp));
|
XOR(16, R(ECX), R(tmp));
|
||||||
gpr.PutXReg(tmp);
|
m_gpr.PutXReg(tmp);
|
||||||
DSPJitRegCache c(gpr);
|
DSPJitRegCache c(m_gpr);
|
||||||
TEST(16, R(ECX), Imm16(0xfc00));
|
TEST(16, R(ECX), Imm16(0xfc00));
|
||||||
FixupBranch not_equal = J_CC(CC_NE, true);
|
FixupBranch not_equal = J_CC(CC_NE, true);
|
||||||
pushExtValueFromMem2(rreg + DSP_REG_AXL0, sreg);
|
pushExtValueFromMem2(rreg + DSP_REG_AXL0, sreg);
|
||||||
gpr.FlushRegs(c);
|
m_gpr.FlushRegs(c);
|
||||||
FixupBranch after = J(true); // else
|
FixupBranch after = J(true); // else
|
||||||
SetJumpTarget(not_equal);
|
SetJumpTarget(not_equal);
|
||||||
pushExtValueFromMem2(rreg + DSP_REG_AXL0, DSP_REG_AR3);
|
pushExtValueFromMem2(rreg + DSP_REG_AXL0, DSP_REG_AR3);
|
||||||
gpr.FlushRegs(c);
|
m_gpr.FlushRegs(c);
|
||||||
SetJumpTarget(after);
|
SetJumpTarget(after);
|
||||||
|
|
||||||
increase_addr_reg(sreg, sreg);
|
increase_addr_reg(sreg, sreg);
|
||||||
|
@ -503,21 +503,21 @@ void DSPEmitter::ldm(const UDSPInstruction opc)
|
||||||
|
|
||||||
pushExtValueFromMem((dreg << 1) + DSP_REG_AXL0, sreg);
|
pushExtValueFromMem((dreg << 1) + DSP_REG_AXL0, sreg);
|
||||||
|
|
||||||
X64Reg tmp = gpr.GetFreeXReg();
|
X64Reg tmp = m_gpr.GetFreeXReg();
|
||||||
// if (IsSameMemArea(g_dsp.r[sreg], g_dsp.r[DSP_REG_AR3])) {
|
// if (IsSameMemArea(g_dsp.r[sreg], g_dsp.r[DSP_REG_AR3])) {
|
||||||
dsp_op_read_reg(sreg, RCX, NONE);
|
dsp_op_read_reg(sreg, RCX, NONE);
|
||||||
dsp_op_read_reg(DSP_REG_AR3, tmp, NONE);
|
dsp_op_read_reg(DSP_REG_AR3, tmp, NONE);
|
||||||
XOR(16, R(ECX), R(tmp));
|
XOR(16, R(ECX), R(tmp));
|
||||||
gpr.PutXReg(tmp);
|
m_gpr.PutXReg(tmp);
|
||||||
DSPJitRegCache c(gpr);
|
DSPJitRegCache c(m_gpr);
|
||||||
TEST(16, R(ECX), Imm16(0xfc00));
|
TEST(16, R(ECX), Imm16(0xfc00));
|
||||||
FixupBranch not_equal = J_CC(CC_NE, true);
|
FixupBranch not_equal = J_CC(CC_NE, true);
|
||||||
pushExtValueFromMem2((rreg << 1) + DSP_REG_AXL1, sreg);
|
pushExtValueFromMem2((rreg << 1) + DSP_REG_AXL1, sreg);
|
||||||
gpr.FlushRegs(c);
|
m_gpr.FlushRegs(c);
|
||||||
FixupBranch after = J(true);
|
FixupBranch after = J(true);
|
||||||
SetJumpTarget(not_equal); // else
|
SetJumpTarget(not_equal); // else
|
||||||
pushExtValueFromMem2((rreg << 1) + DSP_REG_AXL1, DSP_REG_AR3);
|
pushExtValueFromMem2((rreg << 1) + DSP_REG_AXL1, DSP_REG_AR3);
|
||||||
gpr.FlushRegs(c);
|
m_gpr.FlushRegs(c);
|
||||||
SetJumpTarget(after);
|
SetJumpTarget(after);
|
||||||
|
|
||||||
increment_addr_reg(sreg);
|
increment_addr_reg(sreg);
|
||||||
|
@ -534,21 +534,21 @@ void DSPEmitter::ldaxm(const UDSPInstruction opc)
|
||||||
|
|
||||||
pushExtValueFromMem(rreg + DSP_REG_AXH0, sreg);
|
pushExtValueFromMem(rreg + DSP_REG_AXH0, sreg);
|
||||||
|
|
||||||
X64Reg tmp = gpr.GetFreeXReg();
|
X64Reg tmp = m_gpr.GetFreeXReg();
|
||||||
// if (IsSameMemArea(g_dsp.r[sreg], g_dsp.r[DSP_REG_AR3])) {
|
// if (IsSameMemArea(g_dsp.r[sreg], g_dsp.r[DSP_REG_AR3])) {
|
||||||
dsp_op_read_reg(sreg, RCX, NONE);
|
dsp_op_read_reg(sreg, RCX, NONE);
|
||||||
dsp_op_read_reg(DSP_REG_AR3, tmp, NONE);
|
dsp_op_read_reg(DSP_REG_AR3, tmp, NONE);
|
||||||
XOR(16, R(ECX), R(tmp));
|
XOR(16, R(ECX), R(tmp));
|
||||||
gpr.PutXReg(tmp);
|
m_gpr.PutXReg(tmp);
|
||||||
DSPJitRegCache c(gpr);
|
DSPJitRegCache c(m_gpr);
|
||||||
TEST(16, R(ECX), Imm16(0xfc00));
|
TEST(16, R(ECX), Imm16(0xfc00));
|
||||||
FixupBranch not_equal = J_CC(CC_NE, true);
|
FixupBranch not_equal = J_CC(CC_NE, true);
|
||||||
pushExtValueFromMem2(rreg + DSP_REG_AXL0, sreg);
|
pushExtValueFromMem2(rreg + DSP_REG_AXL0, sreg);
|
||||||
gpr.FlushRegs(c);
|
m_gpr.FlushRegs(c);
|
||||||
FixupBranch after = J(true); // else
|
FixupBranch after = J(true); // else
|
||||||
SetJumpTarget(not_equal);
|
SetJumpTarget(not_equal);
|
||||||
pushExtValueFromMem2(rreg + DSP_REG_AXL0, DSP_REG_AR3);
|
pushExtValueFromMem2(rreg + DSP_REG_AXL0, DSP_REG_AR3);
|
||||||
gpr.FlushRegs(c);
|
m_gpr.FlushRegs(c);
|
||||||
SetJumpTarget(after);
|
SetJumpTarget(after);
|
||||||
|
|
||||||
increment_addr_reg(sreg);
|
increment_addr_reg(sreg);
|
||||||
|
@ -566,21 +566,21 @@ void DSPEmitter::ldnm(const UDSPInstruction opc)
|
||||||
|
|
||||||
pushExtValueFromMem((dreg << 1) + DSP_REG_AXL0, sreg);
|
pushExtValueFromMem((dreg << 1) + DSP_REG_AXL0, sreg);
|
||||||
|
|
||||||
X64Reg tmp = gpr.GetFreeXReg();
|
X64Reg tmp = m_gpr.GetFreeXReg();
|
||||||
// if (IsSameMemArea(g_dsp.r[sreg], g_dsp.r[DSP_REG_AR3])) {
|
// if (IsSameMemArea(g_dsp.r[sreg], g_dsp.r[DSP_REG_AR3])) {
|
||||||
dsp_op_read_reg(sreg, RCX, NONE);
|
dsp_op_read_reg(sreg, RCX, NONE);
|
||||||
dsp_op_read_reg(DSP_REG_AR3, tmp, NONE);
|
dsp_op_read_reg(DSP_REG_AR3, tmp, NONE);
|
||||||
XOR(16, R(ECX), R(tmp));
|
XOR(16, R(ECX), R(tmp));
|
||||||
gpr.PutXReg(tmp);
|
m_gpr.PutXReg(tmp);
|
||||||
DSPJitRegCache c(gpr);
|
DSPJitRegCache c(m_gpr);
|
||||||
TEST(16, R(ECX), Imm16(0xfc00));
|
TEST(16, R(ECX), Imm16(0xfc00));
|
||||||
FixupBranch not_equal = J_CC(CC_NE, true);
|
FixupBranch not_equal = J_CC(CC_NE, true);
|
||||||
pushExtValueFromMem2((rreg << 1) + DSP_REG_AXL1, sreg);
|
pushExtValueFromMem2((rreg << 1) + DSP_REG_AXL1, sreg);
|
||||||
gpr.FlushRegs(c);
|
m_gpr.FlushRegs(c);
|
||||||
FixupBranch after = J(true);
|
FixupBranch after = J(true);
|
||||||
SetJumpTarget(not_equal); // else
|
SetJumpTarget(not_equal); // else
|
||||||
pushExtValueFromMem2((rreg << 1) + DSP_REG_AXL1, DSP_REG_AR3);
|
pushExtValueFromMem2((rreg << 1) + DSP_REG_AXL1, DSP_REG_AR3);
|
||||||
gpr.FlushRegs(c);
|
m_gpr.FlushRegs(c);
|
||||||
SetJumpTarget(after);
|
SetJumpTarget(after);
|
||||||
|
|
||||||
increase_addr_reg(sreg, sreg);
|
increase_addr_reg(sreg, sreg);
|
||||||
|
@ -597,21 +597,21 @@ void DSPEmitter::ldaxnm(const UDSPInstruction opc)
|
||||||
|
|
||||||
pushExtValueFromMem(rreg + DSP_REG_AXH0, sreg);
|
pushExtValueFromMem(rreg + DSP_REG_AXH0, sreg);
|
||||||
|
|
||||||
X64Reg tmp = gpr.GetFreeXReg();
|
X64Reg tmp = m_gpr.GetFreeXReg();
|
||||||
// if (IsSameMemArea(g_dsp.r[sreg], g_dsp.r[DSP_REG_AR3])) {
|
// if (IsSameMemArea(g_dsp.r[sreg], g_dsp.r[DSP_REG_AR3])) {
|
||||||
dsp_op_read_reg(sreg, RCX, NONE);
|
dsp_op_read_reg(sreg, RCX, NONE);
|
||||||
dsp_op_read_reg(DSP_REG_AR3, tmp, NONE);
|
dsp_op_read_reg(DSP_REG_AR3, tmp, NONE);
|
||||||
XOR(16, R(ECX), R(tmp));
|
XOR(16, R(ECX), R(tmp));
|
||||||
gpr.PutXReg(tmp);
|
m_gpr.PutXReg(tmp);
|
||||||
DSPJitRegCache c(gpr);
|
DSPJitRegCache c(m_gpr);
|
||||||
TEST(16, R(ECX), Imm16(0xfc00));
|
TEST(16, R(ECX), Imm16(0xfc00));
|
||||||
FixupBranch not_equal = J_CC(CC_NE, true);
|
FixupBranch not_equal = J_CC(CC_NE, true);
|
||||||
pushExtValueFromMem2(rreg + DSP_REG_AXL0, sreg);
|
pushExtValueFromMem2(rreg + DSP_REG_AXL0, sreg);
|
||||||
gpr.FlushRegs(c);
|
m_gpr.FlushRegs(c);
|
||||||
FixupBranch after = J(true); // else
|
FixupBranch after = J(true); // else
|
||||||
SetJumpTarget(not_equal);
|
SetJumpTarget(not_equal);
|
||||||
pushExtValueFromMem2(rreg + DSP_REG_AXL0, DSP_REG_AR3);
|
pushExtValueFromMem2(rreg + DSP_REG_AXL0, DSP_REG_AR3);
|
||||||
gpr.FlushRegs(c);
|
m_gpr.FlushRegs(c);
|
||||||
SetJumpTarget(after);
|
SetJumpTarget(after);
|
||||||
|
|
||||||
increase_addr_reg(sreg, sreg);
|
increase_addr_reg(sreg, sreg);
|
||||||
|
@ -625,33 +625,33 @@ void DSPEmitter::pushExtValueFromMem(u16 dreg, u16 sreg)
|
||||||
{
|
{
|
||||||
// u16 addr = g_dsp.r[addr];
|
// u16 addr = g_dsp.r[addr];
|
||||||
|
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
|
|
||||||
dsp_op_read_reg(sreg, tmp1, ZERO);
|
dsp_op_read_reg(sreg, tmp1, ZERO);
|
||||||
dmem_read(tmp1);
|
dmem_read(tmp1);
|
||||||
|
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
|
|
||||||
MOVZX(32, 16, EBX, R(EAX));
|
MOVZX(32, 16, EBX, R(EAX));
|
||||||
|
|
||||||
storeIndex = dreg;
|
m_store_index = dreg;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DSPEmitter::pushExtValueFromMem2(u16 dreg, u16 sreg)
|
void DSPEmitter::pushExtValueFromMem2(u16 dreg, u16 sreg)
|
||||||
{
|
{
|
||||||
// u16 addr = g_dsp.r[addr];
|
// u16 addr = g_dsp.r[addr];
|
||||||
|
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
|
|
||||||
dsp_op_read_reg(sreg, tmp1, ZERO);
|
dsp_op_read_reg(sreg, tmp1, ZERO);
|
||||||
dmem_read(tmp1);
|
dmem_read(tmp1);
|
||||||
|
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
|
|
||||||
SHL(32, R(EAX), Imm8(16));
|
SHL(32, R(EAX), Imm8(16));
|
||||||
OR(32, R(EBX), R(EAX));
|
OR(32, R(EBX), R(EAX));
|
||||||
|
|
||||||
storeIndex2 = dreg;
|
m_store_index2 = dreg;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DSPEmitter::popExtValueToReg()
|
void DSPEmitter::popExtValueToReg()
|
||||||
|
@ -663,14 +663,14 @@ void DSPEmitter::popExtValueToReg()
|
||||||
// nakee wants to keep it clean, so lets do that.
|
// nakee wants to keep it clean, so lets do that.
|
||||||
// [nakeee] the or case never happens in real
|
// [nakeee] the or case never happens in real
|
||||||
// [nakeee] it's just how the hardware works so we added it
|
// [nakeee] it's just how the hardware works so we added it
|
||||||
if (storeIndex != -1)
|
if (m_store_index != -1)
|
||||||
{
|
{
|
||||||
dsp_op_write_reg(storeIndex, RBX);
|
dsp_op_write_reg(m_store_index, RBX);
|
||||||
if (storeIndex >= DSP_REG_ACM0 && storeIndex2 == -1)
|
if (m_store_index >= DSP_REG_ACM0 && m_store_index2 == -1)
|
||||||
{
|
{
|
||||||
TEST(32, R(EBX), Imm32(SR_40_MODE_BIT << 16));
|
TEST(32, R(EBX), Imm32(SR_40_MODE_BIT << 16));
|
||||||
FixupBranch not_40bit = J_CC(CC_Z, true);
|
FixupBranch not_40bit = J_CC(CC_Z, true);
|
||||||
DSPJitRegCache c(gpr);
|
DSPJitRegCache c(m_gpr);
|
||||||
// if (g_dsp.r[DSP_REG_SR] & SR_40_MODE_BIT)
|
// if (g_dsp.r[DSP_REG_SR] & SR_40_MODE_BIT)
|
||||||
//{
|
//{
|
||||||
// Sign extend into whole accum.
|
// Sign extend into whole accum.
|
||||||
|
@ -679,23 +679,23 @@ void DSPEmitter::popExtValueToReg()
|
||||||
SHR(32, R(EAX), Imm8(16));
|
SHR(32, R(EAX), Imm8(16));
|
||||||
// g_dsp.r[reg - DSP_REG_ACM0 + DSP_REG_ACH0] = (val & 0x8000) ? 0xFFFF : 0x0000;
|
// g_dsp.r[reg - DSP_REG_ACM0 + DSP_REG_ACH0] = (val & 0x8000) ? 0xFFFF : 0x0000;
|
||||||
// g_dsp.r[reg - DSP_REG_ACM0 + DSP_REG_ACL0] = 0;
|
// g_dsp.r[reg - DSP_REG_ACM0 + DSP_REG_ACL0] = 0;
|
||||||
set_acc_h(storeIndex - DSP_REG_ACM0, R(RAX));
|
set_acc_h(m_store_index - DSP_REG_ACM0, R(RAX));
|
||||||
set_acc_l(storeIndex - DSP_REG_ACM0, Imm16(0));
|
set_acc_l(m_store_index - DSP_REG_ACM0, Imm16(0));
|
||||||
//}
|
//}
|
||||||
gpr.FlushRegs(c);
|
m_gpr.FlushRegs(c);
|
||||||
SetJumpTarget(not_40bit);
|
SetJumpTarget(not_40bit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
storeIndex = -1;
|
m_store_index = -1;
|
||||||
|
|
||||||
if (storeIndex2 != -1)
|
if (m_store_index2 != -1)
|
||||||
{
|
{
|
||||||
SHR(32, R(EBX), Imm8(16));
|
SHR(32, R(EBX), Imm8(16));
|
||||||
dsp_op_write_reg(storeIndex2, RBX);
|
dsp_op_write_reg(m_store_index2, RBX);
|
||||||
}
|
}
|
||||||
|
|
||||||
storeIndex2 = -1;
|
m_store_index2 = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace x86
|
} // namespace x86
|
||||||
|
|
|
@ -29,7 +29,7 @@ void DSPEmitter::srs(const UDSPInstruction opc)
|
||||||
u8 reg = ((opc >> 8) & 0x7) + 0x18;
|
u8 reg = ((opc >> 8) & 0x7) + 0x18;
|
||||||
// u16 addr = (g_dsp.r.cr << 8) | (opc & 0xFF);
|
// u16 addr = (g_dsp.r.cr << 8) | (opc & 0xFF);
|
||||||
|
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
|
|
||||||
dsp_op_read_reg(reg, tmp1, ZERO);
|
dsp_op_read_reg(reg, tmp1, ZERO);
|
||||||
dsp_op_read_reg(DSP_REG_CR, RAX, ZERO);
|
dsp_op_read_reg(DSP_REG_CR, RAX, ZERO);
|
||||||
|
@ -37,7 +37,7 @@ void DSPEmitter::srs(const UDSPInstruction opc)
|
||||||
OR(16, R(EAX), Imm16(opc & 0xFF));
|
OR(16, R(EAX), Imm16(opc & 0xFF));
|
||||||
dmem_write(tmp1);
|
dmem_write(tmp1);
|
||||||
|
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// LRS $(0x18+D), @M
|
// LRS $(0x18+D), @M
|
||||||
|
@ -49,7 +49,7 @@ void DSPEmitter::lrs(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 reg = ((opc >> 8) & 0x7) + 0x18;
|
u8 reg = ((opc >> 8) & 0x7) + 0x18;
|
||||||
|
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
|
|
||||||
// u16 addr = (g_dsp.r[DSP_REG_CR] << 8) | (opc & 0xFF);
|
// u16 addr = (g_dsp.r[DSP_REG_CR] << 8) | (opc & 0xFF);
|
||||||
dsp_op_read_reg(DSP_REG_CR, tmp1, ZERO);
|
dsp_op_read_reg(DSP_REG_CR, tmp1, ZERO);
|
||||||
|
@ -57,7 +57,7 @@ void DSPEmitter::lrs(const UDSPInstruction opc)
|
||||||
OR(16, R(tmp1), Imm16(opc & 0xFF));
|
OR(16, R(tmp1), Imm16(opc & 0xFF));
|
||||||
dmem_read(tmp1);
|
dmem_read(tmp1);
|
||||||
|
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
|
|
||||||
dsp_op_write_reg(reg, RAX);
|
dsp_op_write_reg(reg, RAX);
|
||||||
dsp_conditional_extend_accum(reg);
|
dsp_conditional_extend_accum(reg);
|
||||||
|
@ -70,7 +70,7 @@ void DSPEmitter::lrs(const UDSPInstruction opc)
|
||||||
void DSPEmitter::lr(const UDSPInstruction opc)
|
void DSPEmitter::lr(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
int reg = opc & 0x1F;
|
int reg = opc & 0x1F;
|
||||||
u16 address = dsp_imem_read(compilePC + 1);
|
u16 address = dsp_imem_read(m_compile_pc + 1);
|
||||||
dmem_read_imm(address);
|
dmem_read_imm(address);
|
||||||
dsp_op_write_reg(reg, EAX);
|
dsp_op_write_reg(reg, EAX);
|
||||||
dsp_conditional_extend_accum(reg);
|
dsp_conditional_extend_accum(reg);
|
||||||
|
@ -83,14 +83,14 @@ void DSPEmitter::lr(const UDSPInstruction opc)
|
||||||
void DSPEmitter::sr(const UDSPInstruction opc)
|
void DSPEmitter::sr(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 reg = opc & 0x1F;
|
u8 reg = opc & 0x1F;
|
||||||
u16 address = dsp_imem_read(compilePC + 1);
|
u16 address = dsp_imem_read(m_compile_pc + 1);
|
||||||
|
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
|
|
||||||
dsp_op_read_reg(reg, tmp1);
|
dsp_op_read_reg(reg, tmp1);
|
||||||
dmem_write_imm(address, tmp1);
|
dmem_write_imm(address, tmp1);
|
||||||
|
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// SI @M, #I
|
// SI @M, #I
|
||||||
|
@ -101,14 +101,14 @@ void DSPEmitter::sr(const UDSPInstruction opc)
|
||||||
void DSPEmitter::si(const UDSPInstruction opc)
|
void DSPEmitter::si(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u16 address = (s8)opc;
|
u16 address = (s8)opc;
|
||||||
u16 imm = dsp_imem_read(compilePC + 1);
|
u16 imm = dsp_imem_read(m_compile_pc + 1);
|
||||||
|
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
|
|
||||||
MOV(32, R(tmp1), Imm32((u32)imm));
|
MOV(32, R(tmp1), Imm32((u32)imm));
|
||||||
dmem_write_imm(address, tmp1);
|
dmem_write_imm(address, tmp1);
|
||||||
|
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// LRR $D, @$S
|
// LRR $D, @$S
|
||||||
|
@ -119,12 +119,12 @@ void DSPEmitter::lrr(const UDSPInstruction opc)
|
||||||
u8 sreg = (opc >> 5) & 0x3;
|
u8 sreg = (opc >> 5) & 0x3;
|
||||||
u8 dreg = opc & 0x1f;
|
u8 dreg = opc & 0x1f;
|
||||||
|
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
|
|
||||||
dsp_op_read_reg(sreg, tmp1);
|
dsp_op_read_reg(sreg, tmp1);
|
||||||
dmem_read(tmp1);
|
dmem_read(tmp1);
|
||||||
|
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
|
|
||||||
dsp_op_write_reg(dreg, EAX);
|
dsp_op_write_reg(dreg, EAX);
|
||||||
dsp_conditional_extend_accum(dreg);
|
dsp_conditional_extend_accum(dreg);
|
||||||
|
@ -139,12 +139,12 @@ void DSPEmitter::lrrd(const UDSPInstruction opc)
|
||||||
u8 sreg = (opc >> 5) & 0x3;
|
u8 sreg = (opc >> 5) & 0x3;
|
||||||
u8 dreg = opc & 0x1f;
|
u8 dreg = opc & 0x1f;
|
||||||
|
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
|
|
||||||
dsp_op_read_reg(sreg, tmp1);
|
dsp_op_read_reg(sreg, tmp1);
|
||||||
dmem_read(tmp1);
|
dmem_read(tmp1);
|
||||||
|
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
|
|
||||||
dsp_op_write_reg(dreg, EAX);
|
dsp_op_write_reg(dreg, EAX);
|
||||||
dsp_conditional_extend_accum(dreg);
|
dsp_conditional_extend_accum(dreg);
|
||||||
|
@ -160,12 +160,12 @@ void DSPEmitter::lrri(const UDSPInstruction opc)
|
||||||
u8 sreg = (opc >> 5) & 0x3;
|
u8 sreg = (opc >> 5) & 0x3;
|
||||||
u8 dreg = opc & 0x1f;
|
u8 dreg = opc & 0x1f;
|
||||||
|
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
|
|
||||||
dsp_op_read_reg(sreg, tmp1);
|
dsp_op_read_reg(sreg, tmp1);
|
||||||
dmem_read(tmp1);
|
dmem_read(tmp1);
|
||||||
|
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
|
|
||||||
dsp_op_write_reg(dreg, EAX);
|
dsp_op_write_reg(dreg, EAX);
|
||||||
dsp_conditional_extend_accum(dreg);
|
dsp_conditional_extend_accum(dreg);
|
||||||
|
@ -181,12 +181,12 @@ void DSPEmitter::lrrn(const UDSPInstruction opc)
|
||||||
u8 sreg = (opc >> 5) & 0x3;
|
u8 sreg = (opc >> 5) & 0x3;
|
||||||
u8 dreg = opc & 0x1f;
|
u8 dreg = opc & 0x1f;
|
||||||
|
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
|
|
||||||
dsp_op_read_reg(sreg, tmp1);
|
dsp_op_read_reg(sreg, tmp1);
|
||||||
dmem_read(tmp1);
|
dmem_read(tmp1);
|
||||||
|
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
|
|
||||||
dsp_op_write_reg(dreg, EAX);
|
dsp_op_write_reg(dreg, EAX);
|
||||||
dsp_conditional_extend_accum(dreg);
|
dsp_conditional_extend_accum(dreg);
|
||||||
|
@ -202,13 +202,13 @@ void DSPEmitter::srr(const UDSPInstruction opc)
|
||||||
u8 dreg = (opc >> 5) & 0x3;
|
u8 dreg = (opc >> 5) & 0x3;
|
||||||
u8 sreg = opc & 0x1f;
|
u8 sreg = opc & 0x1f;
|
||||||
|
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
|
|
||||||
dsp_op_read_reg(sreg, tmp1);
|
dsp_op_read_reg(sreg, tmp1);
|
||||||
dsp_op_read_reg(dreg, RAX, ZERO);
|
dsp_op_read_reg(dreg, RAX, ZERO);
|
||||||
dmem_write(tmp1);
|
dmem_write(tmp1);
|
||||||
|
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// SRRD @$D, $S
|
// SRRD @$D, $S
|
||||||
|
@ -220,13 +220,13 @@ void DSPEmitter::srrd(const UDSPInstruction opc)
|
||||||
u8 dreg = (opc >> 5) & 0x3;
|
u8 dreg = (opc >> 5) & 0x3;
|
||||||
u8 sreg = opc & 0x1f;
|
u8 sreg = opc & 0x1f;
|
||||||
|
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
|
|
||||||
dsp_op_read_reg(sreg, tmp1);
|
dsp_op_read_reg(sreg, tmp1);
|
||||||
dsp_op_read_reg(dreg, RAX, ZERO);
|
dsp_op_read_reg(dreg, RAX, ZERO);
|
||||||
dmem_write(tmp1);
|
dmem_write(tmp1);
|
||||||
|
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
|
|
||||||
decrement_addr_reg(dreg);
|
decrement_addr_reg(dreg);
|
||||||
}
|
}
|
||||||
|
@ -240,13 +240,13 @@ void DSPEmitter::srri(const UDSPInstruction opc)
|
||||||
u8 dreg = (opc >> 5) & 0x3;
|
u8 dreg = (opc >> 5) & 0x3;
|
||||||
u8 sreg = opc & 0x1f;
|
u8 sreg = opc & 0x1f;
|
||||||
|
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
|
|
||||||
dsp_op_read_reg(sreg, tmp1);
|
dsp_op_read_reg(sreg, tmp1);
|
||||||
dsp_op_read_reg(dreg, RAX, ZERO);
|
dsp_op_read_reg(dreg, RAX, ZERO);
|
||||||
dmem_write(tmp1);
|
dmem_write(tmp1);
|
||||||
|
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
|
|
||||||
increment_addr_reg(dreg);
|
increment_addr_reg(dreg);
|
||||||
}
|
}
|
||||||
|
@ -260,13 +260,13 @@ void DSPEmitter::srrn(const UDSPInstruction opc)
|
||||||
u8 dreg = (opc >> 5) & 0x3;
|
u8 dreg = (opc >> 5) & 0x3;
|
||||||
u8 sreg = opc & 0x1f;
|
u8 sreg = opc & 0x1f;
|
||||||
|
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
|
|
||||||
dsp_op_read_reg(sreg, tmp1);
|
dsp_op_read_reg(sreg, tmp1);
|
||||||
dsp_op_read_reg(dreg, RAX, ZERO);
|
dsp_op_read_reg(dreg, RAX, ZERO);
|
||||||
dmem_write(tmp1);
|
dmem_write(tmp1);
|
||||||
|
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
|
|
||||||
increase_addr_reg(dreg, dreg);
|
increase_addr_reg(dreg, dreg);
|
||||||
}
|
}
|
||||||
|
@ -280,12 +280,12 @@ void DSPEmitter::ilrr(const UDSPInstruction opc)
|
||||||
u16 reg = opc & 0x3;
|
u16 reg = opc & 0x3;
|
||||||
u16 dreg = (opc >> 8) & 1;
|
u16 dreg = (opc >> 8) & 1;
|
||||||
|
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
|
|
||||||
dsp_op_read_reg(reg, tmp1, ZERO);
|
dsp_op_read_reg(reg, tmp1, ZERO);
|
||||||
imem_read(tmp1);
|
imem_read(tmp1);
|
||||||
|
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
|
|
||||||
set_acc_m(dreg, R(RAX));
|
set_acc_m(dreg, R(RAX));
|
||||||
dsp_conditional_extend_accum(dreg + DSP_REG_ACM0);
|
dsp_conditional_extend_accum(dreg + DSP_REG_ACM0);
|
||||||
|
@ -300,12 +300,12 @@ void DSPEmitter::ilrrd(const UDSPInstruction opc)
|
||||||
u16 reg = opc & 0x3;
|
u16 reg = opc & 0x3;
|
||||||
u16 dreg = (opc >> 8) & 1;
|
u16 dreg = (opc >> 8) & 1;
|
||||||
|
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
|
|
||||||
dsp_op_read_reg(reg, tmp1, ZERO);
|
dsp_op_read_reg(reg, tmp1, ZERO);
|
||||||
imem_read(tmp1);
|
imem_read(tmp1);
|
||||||
|
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
|
|
||||||
set_acc_m(dreg, R(RAX));
|
set_acc_m(dreg, R(RAX));
|
||||||
dsp_conditional_extend_accum(dreg + DSP_REG_ACM0);
|
dsp_conditional_extend_accum(dreg + DSP_REG_ACM0);
|
||||||
|
@ -321,12 +321,12 @@ void DSPEmitter::ilrri(const UDSPInstruction opc)
|
||||||
u16 reg = opc & 0x3;
|
u16 reg = opc & 0x3;
|
||||||
u16 dreg = (opc >> 8) & 1;
|
u16 dreg = (opc >> 8) & 1;
|
||||||
|
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
|
|
||||||
dsp_op_read_reg(reg, tmp1, ZERO);
|
dsp_op_read_reg(reg, tmp1, ZERO);
|
||||||
imem_read(tmp1);
|
imem_read(tmp1);
|
||||||
|
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
|
|
||||||
set_acc_m(dreg, R(RAX));
|
set_acc_m(dreg, R(RAX));
|
||||||
dsp_conditional_extend_accum(dreg + DSP_REG_ACM0);
|
dsp_conditional_extend_accum(dreg + DSP_REG_ACM0);
|
||||||
|
@ -343,12 +343,12 @@ void DSPEmitter::ilrrn(const UDSPInstruction opc)
|
||||||
u16 reg = opc & 0x3;
|
u16 reg = opc & 0x3;
|
||||||
u16 dreg = (opc >> 8) & 1;
|
u16 dreg = (opc >> 8) & 1;
|
||||||
|
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
|
|
||||||
dsp_op_read_reg(reg, tmp1, ZERO);
|
dsp_op_read_reg(reg, tmp1, ZERO);
|
||||||
imem_read(tmp1);
|
imem_read(tmp1);
|
||||||
|
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
|
|
||||||
set_acc_m(dreg, R(RAX));
|
set_acc_m(dreg, R(RAX));
|
||||||
dsp_conditional_extend_accum(dreg + DSP_REG_ACM0);
|
dsp_conditional_extend_accum(dreg + DSP_REG_ACM0);
|
||||||
|
|
|
@ -41,7 +41,7 @@ void DSPEmitter::mrr(const UDSPInstruction opc)
|
||||||
void DSPEmitter::lri(const UDSPInstruction opc)
|
void DSPEmitter::lri(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 reg = opc & 0x1F;
|
u8 reg = opc & 0x1F;
|
||||||
u16 imm = dsp_imem_read(compilePC + 1);
|
u16 imm = dsp_imem_read(m_compile_pc + 1);
|
||||||
dsp_op_write_reg_imm(reg, imm);
|
dsp_op_write_reg_imm(reg, imm);
|
||||||
dsp_conditional_extend_accum_imm(reg, imm);
|
dsp_conditional_extend_accum_imm(reg, imm);
|
||||||
}
|
}
|
||||||
|
@ -118,21 +118,21 @@ void DSPEmitter::addarn(const UDSPInstruction opc)
|
||||||
void DSPEmitter::setCompileSR(u16 bit)
|
void DSPEmitter::setCompileSR(u16 bit)
|
||||||
{
|
{
|
||||||
// g_dsp.r[DSP_REG_SR] |= bit
|
// g_dsp.r[DSP_REG_SR] |= bit
|
||||||
const OpArg sr_reg = gpr.GetReg(DSP_REG_SR);
|
const OpArg sr_reg = m_gpr.GetReg(DSP_REG_SR);
|
||||||
OR(16, sr_reg, Imm16(bit));
|
OR(16, sr_reg, Imm16(bit));
|
||||||
gpr.PutReg(DSP_REG_SR);
|
m_gpr.PutReg(DSP_REG_SR);
|
||||||
|
|
||||||
compileSR |= bit;
|
m_compile_status_register |= bit;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DSPEmitter::clrCompileSR(u16 bit)
|
void DSPEmitter::clrCompileSR(u16 bit)
|
||||||
{
|
{
|
||||||
// g_dsp.r[DSP_REG_SR] &= bit
|
// g_dsp.r[DSP_REG_SR] &= bit
|
||||||
const OpArg sr_reg = gpr.GetReg(DSP_REG_SR);
|
const OpArg sr_reg = m_gpr.GetReg(DSP_REG_SR);
|
||||||
AND(16, sr_reg, Imm16(~bit));
|
AND(16, sr_reg, Imm16(~bit));
|
||||||
gpr.PutReg(DSP_REG_SR);
|
m_gpr.PutReg(DSP_REG_SR);
|
||||||
|
|
||||||
compileSR &= ~bit;
|
m_compile_status_register &= ~bit;
|
||||||
}
|
}
|
||||||
// SBCLR #I
|
// SBCLR #I
|
||||||
// 0001 0011 aaaa aiii
|
// 0001 0011 aaaa aiii
|
||||||
|
|
|
@ -28,13 +28,13 @@ void DSPEmitter::multiply()
|
||||||
|
|
||||||
// Conditionally multiply by 2.
|
// Conditionally multiply by 2.
|
||||||
// if ((g_dsp.r.sr & SR_MUL_MODIFY) == 0)
|
// if ((g_dsp.r.sr & SR_MUL_MODIFY) == 0)
|
||||||
const OpArg sr_reg = gpr.GetReg(DSP_REG_SR);
|
const OpArg sr_reg = m_gpr.GetReg(DSP_REG_SR);
|
||||||
TEST(16, sr_reg, Imm16(SR_MUL_MODIFY));
|
TEST(16, sr_reg, Imm16(SR_MUL_MODIFY));
|
||||||
FixupBranch noMult2 = J_CC(CC_NZ);
|
FixupBranch noMult2 = J_CC(CC_NZ);
|
||||||
// prod <<= 1;
|
// prod <<= 1;
|
||||||
LEA(64, RAX, MRegSum(RAX, RAX));
|
LEA(64, RAX, MRegSum(RAX, RAX));
|
||||||
SetJumpTarget(noMult2);
|
SetJumpTarget(noMult2);
|
||||||
gpr.PutReg(DSP_REG_SR, false);
|
m_gpr.PutReg(DSP_REG_SR, false);
|
||||||
// return prod;
|
// return prod;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ void DSPEmitter::multiply_mulx(u8 axh0, u8 axh1)
|
||||||
// result = dsp_multiply(val1, val2, 0); // unsigned support OFF if both ax?.h regs are used
|
// result = dsp_multiply(val1, val2, 0); // unsigned support OFF if both ax?.h regs are used
|
||||||
|
|
||||||
// if ((sign == 1) && (g_dsp.r.sr & SR_MUL_UNSIGNED)) //unsigned
|
// if ((sign == 1) && (g_dsp.r.sr & SR_MUL_UNSIGNED)) //unsigned
|
||||||
const OpArg sr_reg = gpr.GetReg(DSP_REG_SR);
|
const OpArg sr_reg = m_gpr.GetReg(DSP_REG_SR);
|
||||||
TEST(16, sr_reg, Imm16(SR_MUL_UNSIGNED));
|
TEST(16, sr_reg, Imm16(SR_MUL_UNSIGNED));
|
||||||
FixupBranch unsignedMul = J_CC(CC_NZ);
|
FixupBranch unsignedMul = J_CC(CC_NZ);
|
||||||
// prod = (s16)a * (s16)b; //signed
|
// prod = (s16)a * (s16)b; //signed
|
||||||
|
@ -89,8 +89,8 @@ void DSPEmitter::multiply_mulx(u8 axh0, u8 axh1)
|
||||||
FixupBranch signedMul = J(true);
|
FixupBranch signedMul = J(true);
|
||||||
|
|
||||||
SetJumpTarget(unsignedMul);
|
SetJumpTarget(unsignedMul);
|
||||||
DSPJitRegCache c(gpr);
|
DSPJitRegCache c(m_gpr);
|
||||||
gpr.PutReg(DSP_REG_SR, false);
|
m_gpr.PutReg(DSP_REG_SR, false);
|
||||||
if ((axh0 == 0) && (axh1 == 0))
|
if ((axh0 == 0) && (axh1 == 0))
|
||||||
{
|
{
|
||||||
// unsigned support ON if both ax?.l regs are used
|
// unsigned support ON if both ax?.l regs are used
|
||||||
|
@ -103,11 +103,11 @@ void DSPEmitter::multiply_mulx(u8 axh0, u8 axh1)
|
||||||
{
|
{
|
||||||
// mixed support ON (u16)axl.0 * (s16)axh.1
|
// mixed support ON (u16)axl.0 * (s16)axh.1
|
||||||
// prod = a * (s16)b;
|
// prod = a * (s16)b;
|
||||||
X64Reg tmp = gpr.GetFreeXReg();
|
X64Reg tmp = m_gpr.GetFreeXReg();
|
||||||
MOV(64, R(tmp), R(RAX));
|
MOV(64, R(tmp), R(RAX));
|
||||||
MOVZX(64, 16, RAX, R(RCX));
|
MOVZX(64, 16, RAX, R(RCX));
|
||||||
IMUL(64, R(tmp));
|
IMUL(64, R(tmp));
|
||||||
gpr.PutXReg(tmp);
|
m_gpr.PutXReg(tmp);
|
||||||
}
|
}
|
||||||
else if ((axh0 == 1) && (axh1 == 0))
|
else if ((axh0 == 1) && (axh1 == 0))
|
||||||
{
|
{
|
||||||
|
@ -124,7 +124,7 @@ void DSPEmitter::multiply_mulx(u8 axh0, u8 axh1)
|
||||||
IMUL(64, R(RCX));
|
IMUL(64, R(RCX));
|
||||||
}
|
}
|
||||||
|
|
||||||
gpr.FlushRegs(c);
|
m_gpr.FlushRegs(c);
|
||||||
SetJumpTarget(signedMul);
|
SetJumpTarget(signedMul);
|
||||||
|
|
||||||
// Conditionally multiply by 2.
|
// Conditionally multiply by 2.
|
||||||
|
@ -134,7 +134,7 @@ void DSPEmitter::multiply_mulx(u8 axh0, u8 axh1)
|
||||||
// prod <<= 1;
|
// prod <<= 1;
|
||||||
LEA(64, RAX, MRegSum(RAX, RAX));
|
LEA(64, RAX, MRegSum(RAX, RAX));
|
||||||
SetJumpTarget(noMult2);
|
SetJumpTarget(noMult2);
|
||||||
gpr.PutReg(DSP_REG_SR, false);
|
m_gpr.PutReg(DSP_REG_SR, false);
|
||||||
// return prod;
|
// return prod;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,7 +249,7 @@ void DSPEmitter::addpaxz(const UDSPInstruction opc)
|
||||||
u8 sreg = (opc >> 9) & 0x1;
|
u8 sreg = (opc >> 9) & 0x1;
|
||||||
|
|
||||||
// s64 ax = dsp_get_long_acx(sreg);
|
// s64 ax = dsp_get_long_acx(sreg);
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
get_long_acx(sreg, tmp1);
|
get_long_acx(sreg, tmp1);
|
||||||
MOV(64, R(RDX), R(tmp1));
|
MOV(64, R(RDX), R(tmp1));
|
||||||
// s64 res = prod + (ax & ~0xffff);
|
// s64 res = prod + (ax & ~0xffff);
|
||||||
|
@ -274,7 +274,7 @@ void DSPEmitter::addpaxz(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
set_long_acc(dreg, RAX);
|
set_long_acc(dreg, RAX);
|
||||||
}
|
}
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
}
|
}
|
||||||
|
|
||||||
//----
|
//----
|
||||||
|
@ -432,7 +432,7 @@ void DSPEmitter::mulxac(const UDSPInstruction opc)
|
||||||
u8 sreg = (opc >> 12) & 0x1;
|
u8 sreg = (opc >> 12) & 0x1;
|
||||||
|
|
||||||
// s64 acc = dsp_get_long_acc(rreg) + dsp_get_long_prod();
|
// s64 acc = dsp_get_long_acc(rreg) + dsp_get_long_prod();
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
get_long_acc(rreg, tmp1);
|
get_long_acc(rreg, tmp1);
|
||||||
get_long_prod();
|
get_long_prod();
|
||||||
ADD(64, R(tmp1), R(RAX));
|
ADD(64, R(tmp1), R(RAX));
|
||||||
|
@ -452,7 +452,7 @@ void DSPEmitter::mulxac(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
Update_SR_Register64(tmp1);
|
Update_SR_Register64(tmp1);
|
||||||
}
|
}
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// MULXMV $ax0.S, $ax1.T, $acR
|
// MULXMV $ax0.S, $ax1.T, $acR
|
||||||
|
@ -469,7 +469,7 @@ void DSPEmitter::mulxmv(const UDSPInstruction opc)
|
||||||
u8 sreg = (opc >> 12) & 0x1;
|
u8 sreg = (opc >> 12) & 0x1;
|
||||||
|
|
||||||
// s64 acc = dsp_get_long_prod();
|
// s64 acc = dsp_get_long_prod();
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
get_long_prod(tmp1);
|
get_long_prod(tmp1);
|
||||||
// u16 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0);
|
// u16 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0);
|
||||||
dsp_op_read_reg(DSP_REG_AXL0 + sreg * 2, RCX, SIGN);
|
dsp_op_read_reg(DSP_REG_AXL0 + sreg * 2, RCX, SIGN);
|
||||||
|
@ -487,7 +487,7 @@ void DSPEmitter::mulxmv(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
Update_SR_Register64(tmp1);
|
Update_SR_Register64(tmp1);
|
||||||
}
|
}
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// MULXMV $ax0.S, $ax1.T, $acR
|
// MULXMV $ax0.S, $ax1.T, $acR
|
||||||
|
@ -505,7 +505,7 @@ void DSPEmitter::mulxmvz(const UDSPInstruction opc)
|
||||||
u8 sreg = (opc >> 12) & 0x1;
|
u8 sreg = (opc >> 12) & 0x1;
|
||||||
|
|
||||||
// s64 acc = dsp_get_long_prod_round_prodl();
|
// s64 acc = dsp_get_long_prod_round_prodl();
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
get_long_prod_round_prodl(tmp1);
|
get_long_prod_round_prodl(tmp1);
|
||||||
// u16 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0);
|
// u16 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0);
|
||||||
dsp_op_read_reg(DSP_REG_AXL0 + sreg * 2, RCX, SIGN);
|
dsp_op_read_reg(DSP_REG_AXL0 + sreg * 2, RCX, SIGN);
|
||||||
|
@ -523,7 +523,7 @@ void DSPEmitter::mulxmvz(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
Update_SR_Register64(tmp1);
|
Update_SR_Register64(tmp1);
|
||||||
}
|
}
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
}
|
}
|
||||||
|
|
||||||
//----
|
//----
|
||||||
|
|
|
@ -28,15 +28,15 @@ void DSPEmitter::dsp_reg_stack_push(int stack_reg)
|
||||||
AND(8, R(AL), Imm8(DSP_STACK_MASK));
|
AND(8, R(AL), Imm8(DSP_STACK_MASK));
|
||||||
MOV(8, M(&g_dsp.reg_stack_ptr[stack_reg]), R(AL));
|
MOV(8, M(&g_dsp.reg_stack_ptr[stack_reg]), R(AL));
|
||||||
|
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
X64Reg tmp2 = gpr.GetFreeXReg();
|
X64Reg tmp2 = m_gpr.GetFreeXReg();
|
||||||
// g_dsp.reg_stack[stack_reg][g_dsp.reg_stack_ptr[stack_reg]] = g_dsp.r[DSP_REG_ST0 + stack_reg];
|
// g_dsp.reg_stack[stack_reg][g_dsp.reg_stack_ptr[stack_reg]] = g_dsp.r[DSP_REG_ST0 + stack_reg];
|
||||||
MOV(16, R(tmp1), M(&g_dsp.r.st[stack_reg]));
|
MOV(16, R(tmp1), M(&g_dsp.r.st[stack_reg]));
|
||||||
MOVZX(64, 8, RAX, R(AL));
|
MOVZX(64, 8, RAX, R(AL));
|
||||||
MOV(64, R(tmp2), ImmPtr(g_dsp.reg_stack[stack_reg]));
|
MOV(64, R(tmp2), ImmPtr(g_dsp.reg_stack[stack_reg]));
|
||||||
MOV(16, MComplex(tmp2, EAX, SCALE_2, 0), R(tmp1));
|
MOV(16, MComplex(tmp2, EAX, SCALE_2, 0), R(tmp1));
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
gpr.PutXReg(tmp2);
|
m_gpr.PutXReg(tmp2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// clobbers:
|
// clobbers:
|
||||||
|
@ -46,14 +46,14 @@ 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]];
|
// g_dsp.r[DSP_REG_ST0 + stack_reg] = g_dsp.reg_stack[stack_reg][g_dsp.reg_stack_ptr[stack_reg]];
|
||||||
MOV(8, R(AL), M(&g_dsp.reg_stack_ptr[stack_reg]));
|
MOV(8, R(AL), M(&g_dsp.reg_stack_ptr[stack_reg]));
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
X64Reg tmp2 = gpr.GetFreeXReg();
|
X64Reg tmp2 = m_gpr.GetFreeXReg();
|
||||||
MOVZX(64, 8, RAX, R(AL));
|
MOVZX(64, 8, RAX, R(AL));
|
||||||
MOV(64, R(tmp2), ImmPtr(g_dsp.reg_stack[stack_reg]));
|
MOV(64, R(tmp2), ImmPtr(g_dsp.reg_stack[stack_reg]));
|
||||||
MOV(16, R(tmp1), MComplex(tmp2, EAX, SCALE_2, 0));
|
MOV(16, R(tmp1), MComplex(tmp2, EAX, SCALE_2, 0));
|
||||||
MOV(16, M(&g_dsp.r.st[stack_reg]), R(tmp1));
|
MOV(16, M(&g_dsp.r.st[stack_reg]), R(tmp1));
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
gpr.PutXReg(tmp2);
|
m_gpr.PutXReg(tmp2);
|
||||||
|
|
||||||
// g_dsp.reg_stack_ptr[stack_reg]--;
|
// g_dsp.reg_stack_ptr[stack_reg]--;
|
||||||
// g_dsp.reg_stack_ptr[stack_reg] &= DSP_STACK_MASK;
|
// g_dsp.reg_stack_ptr[stack_reg] &= DSP_STACK_MASK;
|
||||||
|
@ -98,7 +98,7 @@ void DSPEmitter::dsp_op_write_reg(int reg, Gen::X64Reg host_sreg)
|
||||||
// 8-bit sign extended registers.
|
// 8-bit sign extended registers.
|
||||||
case DSP_REG_ACH0:
|
case DSP_REG_ACH0:
|
||||||
case DSP_REG_ACH1:
|
case DSP_REG_ACH1:
|
||||||
gpr.WriteReg(reg, R(host_sreg));
|
m_gpr.WriteReg(reg, R(host_sreg));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Stack registers.
|
// Stack registers.
|
||||||
|
@ -110,7 +110,7 @@ void DSPEmitter::dsp_op_write_reg(int reg, Gen::X64Reg host_sreg)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
gpr.WriteReg(reg, R(host_sreg));
|
m_gpr.WriteReg(reg, R(host_sreg));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -122,7 +122,7 @@ void DSPEmitter::dsp_op_write_reg_imm(int reg, u16 val)
|
||||||
// 8-bit sign extended registers. Should look at prod.h too...
|
// 8-bit sign extended registers. Should look at prod.h too...
|
||||||
case DSP_REG_ACH0:
|
case DSP_REG_ACH0:
|
||||||
case DSP_REG_ACH1:
|
case DSP_REG_ACH1:
|
||||||
gpr.WriteReg(reg, Imm16((u16)(s16)(s8)(u8)val));
|
m_gpr.WriteReg(reg, Imm16((u16)(s16)(s8)(u8)val));
|
||||||
break;
|
break;
|
||||||
// Stack registers.
|
// Stack registers.
|
||||||
case DSP_REG_ST0:
|
case DSP_REG_ST0:
|
||||||
|
@ -133,7 +133,7 @@ void DSPEmitter::dsp_op_write_reg_imm(int reg, u16 val)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
gpr.WriteReg(reg, Imm16(val));
|
m_gpr.WriteReg(reg, Imm16(val));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -145,8 +145,8 @@ void DSPEmitter::dsp_conditional_extend_accum(int reg)
|
||||||
case DSP_REG_ACM0:
|
case DSP_REG_ACM0:
|
||||||
case DSP_REG_ACM1:
|
case DSP_REG_ACM1:
|
||||||
{
|
{
|
||||||
const OpArg sr_reg = gpr.GetReg(DSP_REG_SR);
|
const OpArg sr_reg = m_gpr.GetReg(DSP_REG_SR);
|
||||||
DSPJitRegCache c(gpr);
|
DSPJitRegCache c(m_gpr);
|
||||||
TEST(16, sr_reg, Imm16(SR_40_MODE_BIT));
|
TEST(16, sr_reg, Imm16(SR_40_MODE_BIT));
|
||||||
FixupBranch not_40bit = J_CC(CC_Z, true);
|
FixupBranch not_40bit = J_CC(CC_Z, true);
|
||||||
// if (g_dsp.r[DSP_REG_SR] & SR_40_MODE_BIT)
|
// if (g_dsp.r[DSP_REG_SR] & SR_40_MODE_BIT)
|
||||||
|
@ -160,9 +160,9 @@ void DSPEmitter::dsp_conditional_extend_accum(int reg)
|
||||||
set_acc_h(reg - DSP_REG_ACM0, R(RAX));
|
set_acc_h(reg - DSP_REG_ACM0, R(RAX));
|
||||||
set_acc_l(reg - DSP_REG_ACM0, Imm16(0));
|
set_acc_l(reg - DSP_REG_ACM0, Imm16(0));
|
||||||
//}
|
//}
|
||||||
gpr.FlushRegs(c);
|
m_gpr.FlushRegs(c);
|
||||||
SetJumpTarget(not_40bit);
|
SetJumpTarget(not_40bit);
|
||||||
gpr.PutReg(DSP_REG_SR, false);
|
m_gpr.PutReg(DSP_REG_SR, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -174,8 +174,8 @@ void DSPEmitter::dsp_conditional_extend_accum_imm(int reg, u16 val)
|
||||||
case DSP_REG_ACM0:
|
case DSP_REG_ACM0:
|
||||||
case DSP_REG_ACM1:
|
case DSP_REG_ACM1:
|
||||||
{
|
{
|
||||||
const OpArg sr_reg = gpr.GetReg(DSP_REG_SR);
|
const OpArg sr_reg = m_gpr.GetReg(DSP_REG_SR);
|
||||||
DSPJitRegCache c(gpr);
|
DSPJitRegCache c(m_gpr);
|
||||||
TEST(16, sr_reg, Imm16(SR_40_MODE_BIT));
|
TEST(16, sr_reg, Imm16(SR_40_MODE_BIT));
|
||||||
FixupBranch not_40bit = J_CC(CC_Z, true);
|
FixupBranch not_40bit = J_CC(CC_Z, true);
|
||||||
// if (g_dsp.r[DSP_REG_SR] & SR_40_MODE_BIT)
|
// if (g_dsp.r[DSP_REG_SR] & SR_40_MODE_BIT)
|
||||||
|
@ -186,9 +186,9 @@ void DSPEmitter::dsp_conditional_extend_accum_imm(int reg, u16 val)
|
||||||
set_acc_h(reg - DSP_REG_ACM0, Imm16((val & 0x8000) ? 0xffff : 0x0000));
|
set_acc_h(reg - DSP_REG_ACM0, Imm16((val & 0x8000) ? 0xffff : 0x0000));
|
||||||
set_acc_l(reg - DSP_REG_ACM0, Imm16(0));
|
set_acc_l(reg - DSP_REG_ACM0, Imm16(0));
|
||||||
//}
|
//}
|
||||||
gpr.FlushRegs(c);
|
m_gpr.FlushRegs(c);
|
||||||
SetJumpTarget(not_40bit);
|
SetJumpTarget(not_40bit);
|
||||||
gpr.PutReg(DSP_REG_SR, false);
|
m_gpr.PutReg(DSP_REG_SR, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -217,7 +217,7 @@ void DSPEmitter::dsp_op_read_reg_dont_saturate(int reg, Gen::X64Reg host_dreg,
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
gpr.ReadReg(reg, host_dreg, extend);
|
m_gpr.ReadReg(reg, host_dreg, extend);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -248,10 +248,10 @@ void DSPEmitter::dsp_op_read_reg(int reg, Gen::X64Reg host_dreg, DSPJitSignExten
|
||||||
case DSP_REG_ACM1:
|
case DSP_REG_ACM1:
|
||||||
{
|
{
|
||||||
// we already know this is ACCM0 or ACCM1
|
// we already know this is ACCM0 or ACCM1
|
||||||
const OpArg acc_reg = gpr.GetReg(reg - DSP_REG_ACM0 + DSP_REG_ACC0_64);
|
const OpArg acc_reg = m_gpr.GetReg(reg - DSP_REG_ACM0 + DSP_REG_ACC0_64);
|
||||||
const OpArg sr_reg = gpr.GetReg(DSP_REG_SR);
|
const OpArg sr_reg = m_gpr.GetReg(DSP_REG_SR);
|
||||||
|
|
||||||
DSPJitRegCache c(gpr);
|
DSPJitRegCache c(m_gpr);
|
||||||
TEST(16, sr_reg, Imm16(SR_40_MODE_BIT));
|
TEST(16, sr_reg, Imm16(SR_40_MODE_BIT));
|
||||||
FixupBranch not_40bit = J_CC(CC_Z, true);
|
FixupBranch not_40bit = J_CC(CC_Z, true);
|
||||||
|
|
||||||
|
@ -282,14 +282,14 @@ void DSPEmitter::dsp_op_read_reg(int reg, Gen::X64Reg host_dreg, DSPJitSignExten
|
||||||
SAR(64, R(host_dreg), Imm8(16));
|
SAR(64, R(host_dreg), Imm8(16));
|
||||||
SetJumpTarget(done_positive);
|
SetJumpTarget(done_positive);
|
||||||
SetJumpTarget(done_negative);
|
SetJumpTarget(done_negative);
|
||||||
gpr.FlushRegs(c);
|
m_gpr.FlushRegs(c);
|
||||||
gpr.PutReg(reg - DSP_REG_ACM0 + DSP_REG_ACC0_64, false);
|
m_gpr.PutReg(reg - DSP_REG_ACM0 + DSP_REG_ACC0_64, false);
|
||||||
|
|
||||||
gpr.PutReg(DSP_REG_SR, false);
|
m_gpr.PutReg(DSP_REG_SR, false);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
gpr.ReadReg(reg, host_dreg, extend);
|
m_gpr.ReadReg(reg, host_dreg, extend);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -307,14 +307,14 @@ void DSPEmitter::dsp_op_read_reg(int reg, Gen::X64Reg host_dreg, DSPJitSignExten
|
||||||
// EDX = g_dsp.r.wr[reg]
|
// EDX = g_dsp.r.wr[reg]
|
||||||
void DSPEmitter::increment_addr_reg(int reg)
|
void DSPEmitter::increment_addr_reg(int reg)
|
||||||
{
|
{
|
||||||
const OpArg wr_reg = gpr.GetReg(DSP_REG_WR0 + reg);
|
const OpArg wr_reg = m_gpr.GetReg(DSP_REG_WR0 + reg);
|
||||||
MOVZX(32, 16, EDX, wr_reg);
|
MOVZX(32, 16, EDX, wr_reg);
|
||||||
gpr.PutReg(DSP_REG_WR0 + reg, false);
|
m_gpr.PutReg(DSP_REG_WR0 + reg, false);
|
||||||
|
|
||||||
const OpArg ar_reg = gpr.GetReg(DSP_REG_AR0 + reg);
|
const OpArg ar_reg = m_gpr.GetReg(DSP_REG_AR0 + reg);
|
||||||
MOVZX(32, 16, EAX, ar_reg);
|
MOVZX(32, 16, EAX, ar_reg);
|
||||||
|
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
// u32 nar = ar + 1;
|
// u32 nar = ar + 1;
|
||||||
MOV(32, R(tmp1), R(EAX));
|
MOV(32, R(tmp1), R(EAX));
|
||||||
ADD(32, R(EAX), Imm8(1));
|
ADD(32, R(EAX), Imm8(1));
|
||||||
|
@ -329,25 +329,25 @@ void DSPEmitter::increment_addr_reg(int reg)
|
||||||
SUB(16, R(AX), R(DX));
|
SUB(16, R(AX), R(DX));
|
||||||
SUB(16, R(AX), Imm8(1));
|
SUB(16, R(AX), Imm8(1));
|
||||||
SetJumpTarget(nowrap);
|
SetJumpTarget(nowrap);
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
// g_dsp.r.ar[reg] = nar;
|
// g_dsp.r.ar[reg] = nar;
|
||||||
|
|
||||||
MOV(16, ar_reg, R(AX));
|
MOV(16, ar_reg, R(AX));
|
||||||
gpr.PutReg(DSP_REG_AR0 + reg);
|
m_gpr.PutReg(DSP_REG_AR0 + reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// EAX = g_dsp.r.ar[reg]
|
// EAX = g_dsp.r.ar[reg]
|
||||||
// EDX = g_dsp.r.wr[reg]
|
// EDX = g_dsp.r.wr[reg]
|
||||||
void DSPEmitter::decrement_addr_reg(int reg)
|
void DSPEmitter::decrement_addr_reg(int reg)
|
||||||
{
|
{
|
||||||
const OpArg wr_reg = gpr.GetReg(DSP_REG_WR0 + reg);
|
const OpArg wr_reg = m_gpr.GetReg(DSP_REG_WR0 + reg);
|
||||||
MOVZX(32, 16, EDX, wr_reg);
|
MOVZX(32, 16, EDX, wr_reg);
|
||||||
gpr.PutReg(DSP_REG_WR0 + reg, false);
|
m_gpr.PutReg(DSP_REG_WR0 + reg, false);
|
||||||
|
|
||||||
const OpArg ar_reg = gpr.GetReg(DSP_REG_AR0 + reg);
|
const OpArg ar_reg = m_gpr.GetReg(DSP_REG_AR0 + reg);
|
||||||
MOVZX(32, 16, EAX, ar_reg);
|
MOVZX(32, 16, EAX, ar_reg);
|
||||||
|
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
// u32 nar = ar + wr;
|
// u32 nar = ar + wr;
|
||||||
// edi = nar
|
// edi = nar
|
||||||
LEA(32, tmp1, MRegSum(EAX, EDX));
|
LEA(32, tmp1, MRegSum(EAX, EDX));
|
||||||
|
@ -366,8 +366,8 @@ void DSPEmitter::decrement_addr_reg(int reg)
|
||||||
// g_dsp.r.ar[reg] = nar;
|
// g_dsp.r.ar[reg] = nar;
|
||||||
|
|
||||||
MOV(16, ar_reg, R(tmp1));
|
MOV(16, ar_reg, R(tmp1));
|
||||||
gpr.PutReg(DSP_REG_AR0 + reg);
|
m_gpr.PutReg(DSP_REG_AR0 + reg);
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Increase addr register according to the correspond ix register
|
// Increase addr register according to the correspond ix register
|
||||||
|
@ -376,18 +376,18 @@ void DSPEmitter::decrement_addr_reg(int reg)
|
||||||
// ECX = g_dsp.r.ix[reg]
|
// ECX = g_dsp.r.ix[reg]
|
||||||
void DSPEmitter::increase_addr_reg(int reg, int _ix_reg)
|
void DSPEmitter::increase_addr_reg(int reg, int _ix_reg)
|
||||||
{
|
{
|
||||||
const OpArg wr_reg = gpr.GetReg(DSP_REG_WR0 + reg);
|
const OpArg wr_reg = m_gpr.GetReg(DSP_REG_WR0 + reg);
|
||||||
MOVZX(32, 16, EDX, wr_reg);
|
MOVZX(32, 16, EDX, wr_reg);
|
||||||
gpr.PutReg(DSP_REG_WR0 + reg, false);
|
m_gpr.PutReg(DSP_REG_WR0 + reg, false);
|
||||||
|
|
||||||
const OpArg ix_reg = gpr.GetReg(DSP_REG_IX0 + _ix_reg);
|
const OpArg ix_reg = m_gpr.GetReg(DSP_REG_IX0 + _ix_reg);
|
||||||
MOVSX(32, 16, ECX, ix_reg);
|
MOVSX(32, 16, ECX, ix_reg);
|
||||||
gpr.PutReg(DSP_REG_IX0 + _ix_reg, false);
|
m_gpr.PutReg(DSP_REG_IX0 + _ix_reg, false);
|
||||||
|
|
||||||
const OpArg ar_reg = gpr.GetReg(DSP_REG_AR0 + reg);
|
const OpArg ar_reg = m_gpr.GetReg(DSP_REG_AR0 + reg);
|
||||||
MOVZX(32, 16, EAX, ar_reg);
|
MOVZX(32, 16, EAX, ar_reg);
|
||||||
|
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
// u32 nar = ar + ix;
|
// u32 nar = ar + ix;
|
||||||
// edi = nar
|
// edi = nar
|
||||||
LEA(32, tmp1, MRegSum(EAX, ECX));
|
LEA(32, tmp1, MRegSum(EAX, ECX));
|
||||||
|
@ -433,8 +433,8 @@ void DSPEmitter::increase_addr_reg(int reg, int _ix_reg)
|
||||||
// g_dsp.r.ar[reg] = nar;
|
// g_dsp.r.ar[reg] = nar;
|
||||||
|
|
||||||
MOV(16, ar_reg, R(tmp1));
|
MOV(16, ar_reg, R(tmp1));
|
||||||
gpr.PutReg(DSP_REG_AR0 + reg);
|
m_gpr.PutReg(DSP_REG_AR0 + reg);
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decrease addr register according to the correspond ix register
|
// Decrease addr register according to the correspond ix register
|
||||||
|
@ -443,20 +443,20 @@ void DSPEmitter::increase_addr_reg(int reg, int _ix_reg)
|
||||||
// ECX = g_dsp.r.ix[reg]
|
// ECX = g_dsp.r.ix[reg]
|
||||||
void DSPEmitter::decrease_addr_reg(int reg)
|
void DSPEmitter::decrease_addr_reg(int reg)
|
||||||
{
|
{
|
||||||
const OpArg wr_reg = gpr.GetReg(DSP_REG_WR0 + reg);
|
const OpArg wr_reg = m_gpr.GetReg(DSP_REG_WR0 + reg);
|
||||||
MOVZX(32, 16, EDX, wr_reg);
|
MOVZX(32, 16, EDX, wr_reg);
|
||||||
gpr.PutReg(DSP_REG_WR0 + reg, false);
|
m_gpr.PutReg(DSP_REG_WR0 + reg, false);
|
||||||
|
|
||||||
const OpArg ix_reg = gpr.GetReg(DSP_REG_IX0 + reg);
|
const OpArg ix_reg = m_gpr.GetReg(DSP_REG_IX0 + reg);
|
||||||
MOVSX(32, 16, ECX, ix_reg);
|
MOVSX(32, 16, ECX, ix_reg);
|
||||||
gpr.PutReg(DSP_REG_IX0 + reg, false);
|
m_gpr.PutReg(DSP_REG_IX0 + reg, false);
|
||||||
|
|
||||||
const OpArg ar_reg = gpr.GetReg(DSP_REG_AR0 + reg);
|
const OpArg ar_reg = m_gpr.GetReg(DSP_REG_AR0 + reg);
|
||||||
MOVZX(32, 16, EAX, ar_reg);
|
MOVZX(32, 16, EAX, ar_reg);
|
||||||
|
|
||||||
NOT(32, R(ECX)); // esi = ~ix
|
NOT(32, R(ECX)); // esi = ~ix
|
||||||
|
|
||||||
X64Reg tmp1 = gpr.GetFreeXReg();
|
X64Reg tmp1 = m_gpr.GetFreeXReg();
|
||||||
// u32 nar = ar - ix; (ar + ~ix + 1)
|
// u32 nar = ar - ix; (ar + ~ix + 1)
|
||||||
LEA(32, tmp1, MComplex(EAX, ECX, SCALE_1, 1));
|
LEA(32, tmp1, MComplex(EAX, ECX, SCALE_1, 1));
|
||||||
|
|
||||||
|
@ -501,8 +501,8 @@ void DSPEmitter::decrease_addr_reg(int reg)
|
||||||
// return nar
|
// return nar
|
||||||
|
|
||||||
MOV(16, ar_reg, R(tmp1));
|
MOV(16, ar_reg, R(tmp1));
|
||||||
gpr.PutReg(DSP_REG_AR0 + reg);
|
m_gpr.PutReg(DSP_REG_AR0 + reg);
|
||||||
gpr.PutXReg(tmp1);
|
m_gpr.PutXReg(tmp1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// EAX - destination address
|
// EAX - destination address
|
||||||
|
@ -522,12 +522,12 @@ void DSPEmitter::dmem_write(X64Reg value)
|
||||||
// else if (saddr == 0xf)
|
// else if (saddr == 0xf)
|
||||||
SetJumpTarget(ifx);
|
SetJumpTarget(ifx);
|
||||||
// Does it mean gdsp_ifx_write needs u32 rather than u16?
|
// Does it mean gdsp_ifx_write needs u32 rather than u16?
|
||||||
DSPJitRegCache c(gpr);
|
DSPJitRegCache c(m_gpr);
|
||||||
X64Reg abisafereg = gpr.MakeABICallSafe(value);
|
X64Reg abisafereg = m_gpr.MakeABICallSafe(value);
|
||||||
gpr.PushRegs();
|
m_gpr.PushRegs();
|
||||||
ABI_CallFunctionRR(gdsp_ifx_write, EAX, abisafereg);
|
ABI_CallFunctionRR(gdsp_ifx_write, EAX, abisafereg);
|
||||||
gpr.PopRegs();
|
m_gpr.PopRegs();
|
||||||
gpr.FlushRegs(c);
|
m_gpr.FlushRegs(c);
|
||||||
SetJumpTarget(end);
|
SetJumpTarget(end);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -543,10 +543,10 @@ void DSPEmitter::dmem_write_imm(u16 address, X64Reg value)
|
||||||
case 0xf: // Fxxx HW regs
|
case 0xf: // Fxxx HW regs
|
||||||
{
|
{
|
||||||
MOV(16, R(EAX), Imm16(address));
|
MOV(16, R(EAX), Imm16(address));
|
||||||
X64Reg abisafereg = gpr.MakeABICallSafe(value);
|
X64Reg abisafereg = m_gpr.MakeABICallSafe(value);
|
||||||
gpr.PushRegs();
|
m_gpr.PushRegs();
|
||||||
ABI_CallFunctionRR(gdsp_ifx_write, EAX, abisafereg);
|
ABI_CallFunctionRR(gdsp_ifx_write, EAX, abisafereg);
|
||||||
gpr.PopRegs();
|
m_gpr.PopRegs();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: // Unmapped/non-existing memory
|
default: // Unmapped/non-existing memory
|
||||||
|
@ -608,12 +608,12 @@ void DSPEmitter::dmem_read(X64Reg address)
|
||||||
SetJumpTarget(ifx);
|
SetJumpTarget(ifx);
|
||||||
// else if (saddr == 0xf)
|
// else if (saddr == 0xf)
|
||||||
// return gdsp_ifx_read(addr);
|
// return gdsp_ifx_read(addr);
|
||||||
DSPJitRegCache c(gpr);
|
DSPJitRegCache c(m_gpr);
|
||||||
X64Reg abisafereg = gpr.MakeABICallSafe(address);
|
X64Reg abisafereg = m_gpr.MakeABICallSafe(address);
|
||||||
gpr.PushRegs();
|
m_gpr.PushRegs();
|
||||||
ABI_CallFunctionR(gdsp_ifx_read, abisafereg);
|
ABI_CallFunctionR(gdsp_ifx_read, abisafereg);
|
||||||
gpr.PopRegs();
|
m_gpr.PopRegs();
|
||||||
gpr.FlushRegs(c);
|
m_gpr.FlushRegs(c);
|
||||||
SetJumpTarget(end);
|
SetJumpTarget(end);
|
||||||
SetJumpTarget(end2);
|
SetJumpTarget(end2);
|
||||||
}
|
}
|
||||||
|
@ -634,9 +634,9 @@ void DSPEmitter::dmem_read_imm(u16 address)
|
||||||
|
|
||||||
case 0xf: // Fxxx HW regs
|
case 0xf: // Fxxx HW regs
|
||||||
{
|
{
|
||||||
gpr.PushRegs();
|
m_gpr.PushRegs();
|
||||||
ABI_CallFunctionC16(gdsp_ifx_read, address);
|
ABI_CallFunctionC16(gdsp_ifx_read, address);
|
||||||
gpr.PopRegs();
|
m_gpr.PopRegs();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: // Unmapped/non-existing memory
|
default: // Unmapped/non-existing memory
|
||||||
|
@ -648,18 +648,18 @@ void DSPEmitter::dmem_read_imm(u16 address)
|
||||||
void DSPEmitter::get_long_prod(X64Reg long_prod)
|
void DSPEmitter::get_long_prod(X64Reg long_prod)
|
||||||
{
|
{
|
||||||
// s64 val = (s8)(u8)g_dsp.r[DSP_REG_PRODH];
|
// s64 val = (s8)(u8)g_dsp.r[DSP_REG_PRODH];
|
||||||
const OpArg prod_reg = gpr.GetReg(DSP_REG_PROD_64);
|
const OpArg prod_reg = m_gpr.GetReg(DSP_REG_PROD_64);
|
||||||
MOV(64, R(long_prod), prod_reg);
|
MOV(64, R(long_prod), prod_reg);
|
||||||
gpr.PutReg(DSP_REG_PROD_64, false);
|
m_gpr.PutReg(DSP_REG_PROD_64, false);
|
||||||
// no use in keeping prod_reg any longer.
|
// no use in keeping prod_reg any longer.
|
||||||
X64Reg tmp = gpr.GetFreeXReg();
|
X64Reg tmp = m_gpr.GetFreeXReg();
|
||||||
MOV(64, R(tmp), R(long_prod));
|
MOV(64, R(tmp), R(long_prod));
|
||||||
SHL(64, R(long_prod), Imm8(64 - 40)); // sign extend
|
SHL(64, R(long_prod), Imm8(64 - 40)); // sign extend
|
||||||
SAR(64, R(long_prod), Imm8(64 - 40));
|
SAR(64, R(long_prod), Imm8(64 - 40));
|
||||||
SHR(64, R(tmp), Imm8(48));
|
SHR(64, R(tmp), Imm8(48));
|
||||||
SHL(64, R(tmp), Imm8(16));
|
SHL(64, R(tmp), Imm8(16));
|
||||||
ADD(64, R(long_prod), R(tmp));
|
ADD(64, R(long_prod), R(tmp));
|
||||||
gpr.PutXReg(tmp);
|
m_gpr.PutXReg(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns s64 in RAX
|
// Returns s64 in RAX
|
||||||
|
@ -669,7 +669,7 @@ void DSPEmitter::get_long_prod_round_prodl(X64Reg long_prod)
|
||||||
// s64 prod = dsp_get_long_prod();
|
// s64 prod = dsp_get_long_prod();
|
||||||
get_long_prod(long_prod);
|
get_long_prod(long_prod);
|
||||||
|
|
||||||
X64Reg tmp = gpr.GetFreeXReg();
|
X64Reg tmp = m_gpr.GetFreeXReg();
|
||||||
// if (prod & 0x10000) prod = (prod + 0x8000) & ~0xffff;
|
// if (prod & 0x10000) prod = (prod + 0x8000) & ~0xffff;
|
||||||
TEST(32, R(long_prod), Imm32(0x10000));
|
TEST(32, R(long_prod), Imm32(0x10000));
|
||||||
FixupBranch jump = J_CC(CC_Z);
|
FixupBranch jump = J_CC(CC_Z);
|
||||||
|
@ -684,7 +684,7 @@ void DSPEmitter::get_long_prod_round_prodl(X64Reg long_prod)
|
||||||
AND(64, R(long_prod), R(tmp));
|
AND(64, R(long_prod), R(tmp));
|
||||||
SetJumpTarget(_ret);
|
SetJumpTarget(_ret);
|
||||||
// return prod;
|
// return prod;
|
||||||
gpr.PutXReg(tmp);
|
m_gpr.PutXReg(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
// For accurate emulation, this is wrong - but the real prod registers behave
|
// For accurate emulation, this is wrong - but the real prod registers behave
|
||||||
|
@ -692,16 +692,16 @@ void DSPEmitter::get_long_prod_round_prodl(X64Reg long_prod)
|
||||||
// In: RAX = s64 val
|
// In: RAX = s64 val
|
||||||
void DSPEmitter::set_long_prod()
|
void DSPEmitter::set_long_prod()
|
||||||
{
|
{
|
||||||
X64Reg tmp = gpr.GetFreeXReg();
|
X64Reg tmp = m_gpr.GetFreeXReg();
|
||||||
|
|
||||||
MOV(64, R(tmp), Imm64(0x000000ffffffffffULL));
|
MOV(64, R(tmp), Imm64(0x000000ffffffffffULL));
|
||||||
AND(64, R(RAX), R(tmp));
|
AND(64, R(RAX), R(tmp));
|
||||||
gpr.PutXReg(tmp);
|
m_gpr.PutXReg(tmp);
|
||||||
const OpArg prod_reg = gpr.GetReg(DSP_REG_PROD_64, false);
|
const OpArg prod_reg = m_gpr.GetReg(DSP_REG_PROD_64, false);
|
||||||
// g_dsp.r[DSP_REG_PRODL] = (u16)val;
|
// g_dsp.r[DSP_REG_PRODL] = (u16)val;
|
||||||
MOV(64, prod_reg, R(RAX));
|
MOV(64, prod_reg, R(RAX));
|
||||||
|
|
||||||
gpr.PutReg(DSP_REG_PROD_64, true);
|
m_gpr.PutReg(DSP_REG_PROD_64, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns s64 in RAX
|
// Returns s64 in RAX
|
||||||
|
@ -727,79 +727,79 @@ void DSPEmitter::round_long_acc(X64Reg long_acc)
|
||||||
// Returns s64 in acc
|
// Returns s64 in acc
|
||||||
void DSPEmitter::get_long_acc(int _reg, X64Reg acc)
|
void DSPEmitter::get_long_acc(int _reg, X64Reg acc)
|
||||||
{
|
{
|
||||||
const OpArg reg = gpr.GetReg(DSP_REG_ACC0_64 + _reg);
|
const OpArg reg = m_gpr.GetReg(DSP_REG_ACC0_64 + _reg);
|
||||||
MOV(64, R(acc), reg);
|
MOV(64, R(acc), reg);
|
||||||
gpr.PutReg(DSP_REG_ACC0_64 + _reg, false);
|
m_gpr.PutReg(DSP_REG_ACC0_64 + _reg, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// In: acc = s64 val
|
// In: acc = s64 val
|
||||||
void DSPEmitter::set_long_acc(int _reg, X64Reg acc)
|
void DSPEmitter::set_long_acc(int _reg, X64Reg acc)
|
||||||
{
|
{
|
||||||
const OpArg reg = gpr.GetReg(DSP_REG_ACC0_64 + _reg, false);
|
const OpArg reg = m_gpr.GetReg(DSP_REG_ACC0_64 + _reg, false);
|
||||||
MOV(64, reg, R(acc));
|
MOV(64, reg, R(acc));
|
||||||
gpr.PutReg(DSP_REG_ACC0_64 + _reg);
|
m_gpr.PutReg(DSP_REG_ACC0_64 + _reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns s16 in AX
|
// Returns s16 in AX
|
||||||
void DSPEmitter::get_acc_l(int _reg, X64Reg acl, bool sign)
|
void DSPEmitter::get_acc_l(int _reg, X64Reg acl, bool sign)
|
||||||
{
|
{
|
||||||
// return g_dsp.r[DSP_REG_ACM0 + _reg];
|
// return g_dsp.r[DSP_REG_ACM0 + _reg];
|
||||||
gpr.ReadReg(_reg + DSP_REG_ACL0, acl, sign ? SIGN : ZERO);
|
m_gpr.ReadReg(_reg + DSP_REG_ACL0, acl, sign ? SIGN : ZERO);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DSPEmitter::set_acc_l(int _reg, const OpArg& arg)
|
void DSPEmitter::set_acc_l(int _reg, const OpArg& arg)
|
||||||
{
|
{
|
||||||
// return g_dsp.r[DSP_REG_ACM0 + _reg];
|
// return g_dsp.r[DSP_REG_ACM0 + _reg];
|
||||||
gpr.WriteReg(_reg + DSP_REG_ACL0, arg);
|
m_gpr.WriteReg(_reg + DSP_REG_ACL0, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns s16 in AX
|
// Returns s16 in AX
|
||||||
void DSPEmitter::get_acc_m(int _reg, X64Reg acm, bool sign)
|
void DSPEmitter::get_acc_m(int _reg, X64Reg acm, bool sign)
|
||||||
{
|
{
|
||||||
// return g_dsp.r[DSP_REG_ACM0 + _reg];
|
// return g_dsp.r[DSP_REG_ACM0 + _reg];
|
||||||
gpr.ReadReg(_reg + DSP_REG_ACM0, acm, sign ? SIGN : ZERO);
|
m_gpr.ReadReg(_reg + DSP_REG_ACM0, acm, sign ? SIGN : ZERO);
|
||||||
}
|
}
|
||||||
|
|
||||||
// In: s16 in AX
|
// In: s16 in AX
|
||||||
void DSPEmitter::set_acc_m(int _reg, const OpArg& arg)
|
void DSPEmitter::set_acc_m(int _reg, const OpArg& arg)
|
||||||
{
|
{
|
||||||
// return g_dsp.r.ac[_reg].m;
|
// return g_dsp.r.ac[_reg].m;
|
||||||
gpr.WriteReg(_reg + DSP_REG_ACM0, arg);
|
m_gpr.WriteReg(_reg + DSP_REG_ACM0, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns s16 in AX
|
// Returns s16 in AX
|
||||||
void DSPEmitter::get_acc_h(int _reg, X64Reg ach, bool sign)
|
void DSPEmitter::get_acc_h(int _reg, X64Reg ach, bool sign)
|
||||||
{
|
{
|
||||||
// return g_dsp.r.ac[_reg].h;
|
// return g_dsp.r.ac[_reg].h;
|
||||||
gpr.ReadReg(_reg + DSP_REG_ACH0, ach, sign ? SIGN : ZERO);
|
m_gpr.ReadReg(_reg + DSP_REG_ACH0, ach, sign ? SIGN : ZERO);
|
||||||
}
|
}
|
||||||
|
|
||||||
// In: s16 in AX
|
// In: s16 in AX
|
||||||
void DSPEmitter::set_acc_h(int _reg, const OpArg& arg)
|
void DSPEmitter::set_acc_h(int _reg, const OpArg& arg)
|
||||||
{
|
{
|
||||||
// return g_dsp.r[DSP_REG_ACM0 + _reg];
|
// return g_dsp.r[DSP_REG_ACM0 + _reg];
|
||||||
gpr.WriteReg(_reg + DSP_REG_ACH0, arg);
|
m_gpr.WriteReg(_reg + DSP_REG_ACH0, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns u32 in EAX
|
// Returns u32 in EAX
|
||||||
void DSPEmitter::get_long_acx(int _reg, X64Reg acx)
|
void DSPEmitter::get_long_acx(int _reg, X64Reg acx)
|
||||||
{
|
{
|
||||||
// return ((u32)g_dsp.r[DSP_REG_AXH0 + _reg] << 16) | g_dsp.r[DSP_REG_AXL0 + _reg];
|
// return ((u32)g_dsp.r[DSP_REG_AXH0 + _reg] << 16) | g_dsp.r[DSP_REG_AXL0 + _reg];
|
||||||
gpr.ReadReg(_reg + DSP_REG_AX0_32, acx, SIGN);
|
m_gpr.ReadReg(_reg + DSP_REG_AX0_32, acx, SIGN);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns s16 in EAX
|
// Returns s16 in EAX
|
||||||
void DSPEmitter::get_ax_l(int _reg, X64Reg axl)
|
void DSPEmitter::get_ax_l(int _reg, X64Reg axl)
|
||||||
{
|
{
|
||||||
// return (s16)g_dsp.r[DSP_REG_AXL0 + _reg];
|
// return (s16)g_dsp.r[DSP_REG_AXL0 + _reg];
|
||||||
gpr.ReadReg(_reg + DSP_REG_AXL0, axl, SIGN);
|
m_gpr.ReadReg(_reg + DSP_REG_AXL0, axl, SIGN);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns s16 in EAX
|
// Returns s16 in EAX
|
||||||
void DSPEmitter::get_ax_h(int _reg, X64Reg axh)
|
void DSPEmitter::get_ax_h(int _reg, X64Reg axh)
|
||||||
{
|
{
|
||||||
// return (s16)g_dsp.r[DSP_REG_AXH0 + _reg];
|
// return (s16)g_dsp.r[DSP_REG_AXH0 + _reg];
|
||||||
gpr.ReadReg(_reg + DSP_REG_AXH0, axh, SIGN);
|
m_gpr.ReadReg(_reg + DSP_REG_AXH0, axh, SIGN);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace x86
|
} // namespace x86
|
||||||
|
|
Loading…
Reference in New Issue