Merge pull request #4753 from lioncash/dspjit

DSPEmitter: Amend member variable naming
This commit is contained in:
Markus Wick 2017-01-26 10:33:03 +01:00 committed by GitHub
commit 0a07df13d2
11 changed files with 434 additions and 437 deletions

View File

@ -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;
} }
} }

View File

@ -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));

View File

@ -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);

View File

@ -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);
} }
//---- //----

View File

@ -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
{ {

View File

@ -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));

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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);
} }
//---- //----

View File

@ -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