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;
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();
if (g_dsp.reset_dspjit_codespace)
@ -325,11 +325,11 @@ void CompileCurrent()
retry = false;
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);
if (!g_dsp_jit->unresolvedJumps[i].empty())
if (!g_dsp_jit->m_unresolved_jumps[i].empty())
retry = true;
}
}

View File

@ -31,16 +31,16 @@ constexpr size_t MAX_BLOCK_SIZE = 250;
constexpr u16 DSP_IDLE_SKIP_CYCLES = 0x1000;
DSPEmitter::DSPEmitter()
: blockLinks(MAX_BLOCKS), blockSize(MAX_BLOCKS), blocks(MAX_BLOCKS),
compileSR{SR_INT_ENABLE | SR_EXT_INT_ENABLE}
: m_block_links(MAX_BLOCKS), m_block_size(MAX_BLOCKS), m_blocks(MAX_BLOCKS),
m_compile_status_register{SR_INT_ENABLE | SR_EXT_INT_ENABLE}
{
AllocCodeSpace(COMPILED_CODE_SIZE);
CompileDispatcher();
stubEntryPoint = CompileStub();
m_stub_entry_point = CompileStub();
// 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()
@ -52,10 +52,10 @@ void DSPEmitter::ClearIRAM()
{
for (int i = 0x0000; i < 0x1000; i++)
{
blocks[i] = (DSPCompiledCode)stubEntryPoint;
blockLinks[i] = nullptr;
blockSize[i] = 0;
unresolvedJumps[i].clear();
m_blocks[i] = (DSPCompiledCode)m_stub_entry_point;
m_block_links[i] = nullptr;
m_block_size[i] = 0;
m_unresolved_jumps[i].clear();
}
g_dsp.reset_dspjit_codespace = true;
}
@ -64,14 +64,14 @@ void DSPEmitter::ClearIRAMandDSPJITCodespaceReset()
{
ClearCodeSpace();
CompileDispatcher();
stubEntryPoint = CompileStub();
m_stub_entry_point = CompileStub();
for (int i = 0x0000; i < 0x10000; i++)
{
blocks[i] = (DSPCompiledCode)stubEntryPoint;
blockLinks[i] = nullptr;
blockSize[i] = 0;
unresolvedJumps[i].clear();
m_blocks[i] = (DSPCompiledCode)m_stub_entry_point;
m_block_links[i] = nullptr;
m_block_size[i] = 0;
m_unresolved_jumps[i].clear();
}
g_dsp.reset_dspjit_codespace = false;
}
@ -83,22 +83,22 @@ void DSPEmitter::checkExceptions(u32 retval)
TEST(8, M(&g_dsp.exceptions), Imm8(0xff));
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);
gpr.SaveRegs();
DSPJitRegCache c(m_gpr);
m_gpr.SaveRegs();
ABI_CallFunction(DSPCore_CheckExceptions);
MOV(32, R(EAX), Imm32(retval));
JMP(returnDispatcher, true);
gpr.LoadRegs(false);
gpr.FlushRegs(c, false);
JMP(m_return_dispatcher, true);
m_gpr.LoadRegs(false);
m_gpr.FlushRegs(c, false);
SetJumpTarget(skipCheck);
}
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);
}
@ -113,14 +113,14 @@ void DSPEmitter::FallBackToInterpreter(UDSPInstruction inst)
// of block.
// 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
gpr.PushRegs();
m_gpr.PushRegs();
_assert_msg_(DSPLLE, op_template->intFunc, "No function for %04x", inst);
ABI_CallFunctionC16(op_template->intFunc, inst);
gpr.PopRegs();
m_gpr.PopRegs();
}
void DSPEmitter::EmitInstruction(UDSPInstruction inst)
@ -136,9 +136,9 @@ void DSPEmitter::EmitInstruction(UDSPInstruction inst)
if (!ext_op_template->jitFunc)
{
// Fall back to interpreter
gpr.PushRegs();
m_gpr.PushRegs();
ABI_CallFunctionC16(ext_op_template->intFunc, inst);
gpr.PopRegs();
m_gpr.PopRegs();
INFO_LOG(DSPLLE, "Instruction not JITed(ext part): %04x", inst);
ext_is_jit = false;
}
@ -167,9 +167,9 @@ void DSPEmitter::EmitInstruction(UDSPInstruction inst)
{
// need to call the online cleanup function because
// the writeBackLog gets populated at runtime
gpr.PushRegs();
m_gpr.PushRegs();
ABI_CallFunction(applyWriteBackLog);
gpr.PopRegs();
m_gpr.PopRegs();
}
else
{
@ -181,8 +181,8 @@ void DSPEmitter::EmitInstruction(UDSPInstruction inst)
void DSPEmitter::Compile(u16 start_addr)
{
// Remember the current block address for later
startAddr = start_addr;
unresolvedJumps[start_addr].clear();
m_start_address = start_addr;
m_unresolved_jumps[start_addr].clear();
const u8* entryPoint = AlignCode16();
@ -195,35 +195,35 @@ void DSPEmitter::Compile(u16 start_addr)
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;
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)
checkExceptions(blockSize[start_addr]);
if (Analyzer::GetCodeFlags(m_compile_pc) & Analyzer::CODE_CHECK_INT)
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);
EmitInstruction(inst);
blockSize[start_addr]++;
compilePC += opcode->size;
m_block_size[start_addr]++;
m_compile_pc += opcode->size;
// 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;
// Handle loop condition, only if current instruction was flagged as a loop destination
// 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])));
TEST(32, R(EAX), R(EAX));
@ -236,25 +236,25 @@ void DSPEmitter::Compile(u16 start_addr)
if (!opcode->branch)
{
// 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
// end of each block and in this order
DSPJitRegCache c(gpr);
DSPJitRegCache c(m_gpr);
HandleLoop();
gpr.SaveRegs();
m_gpr.SaveRegs();
if (!Host::OnThread() && Analyzer::GetCodeFlags(start_addr) & Analyzer::CODE_IDLE_SKIP)
{
MOV(16, R(EAX), Imm16(DSP_IDLE_SKIP_CYCLES));
}
else
{
MOV(16, R(EAX), Imm16(blockSize[start_addr]));
MOV(16, R(EAX), Imm16(m_block_size[start_addr]));
}
JMP(returnDispatcher, true);
gpr.LoadRegs(false);
gpr.FlushRegs(c, false);
JMP(m_return_dispatcher, true);
m_gpr.LoadRegs(false);
m_gpr.FlushRegs(c, false);
SetJumpTarget(rLoopAddressExit);
SetJumpTarget(rLoopCounterExit);
@ -272,30 +272,30 @@ void DSPEmitter::Compile(u16 start_addr)
{
// look at g_dsp.pc if we actually branched
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);
DSPJitRegCache c(gpr);
DSPJitRegCache c(m_gpr);
// 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)
{
MOV(16, R(EAX), Imm16(DSP_IDLE_SKIP_CYCLES));
}
else
{
MOV(16, R(EAX), Imm16(blockSize[start_addr]));
MOV(16, R(EAX), Imm16(m_block_size[start_addr]));
}
JMP(returnDispatcher, true);
gpr.LoadRegs(false);
gpr.FlushRegs(c, false);
JMP(m_return_dispatcher, true);
m_gpr.LoadRegs(false);
m_gpr.FlushRegs(c, false);
SetJumpTarget(rNoBranch);
}
}
// 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;
}
@ -303,53 +303,53 @@ void DSPEmitter::Compile(u16 start_addr)
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
// 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)
{
if (!unresolvedJumps[i].empty())
if (!m_unresolved_jumps[i].empty())
{
// Check if there were any blocks waiting for this block to be linkable
size_t size = unresolvedJumps[i].size();
unresolvedJumps[i].remove(start_addr);
if (unresolvedJumps[i].size() < size)
size_t size = m_unresolved_jumps[i].size();
m_unresolved_jumps[i].remove(start_addr);
if (m_unresolved_jumps[i].size() < size)
{
// Mark the block to be recompiled again
blocks[i] = (DSPCompiledCode)stubEntryPoint;
blockLinks[i] = nullptr;
blockSize[i] = 0;
m_blocks[i] = (DSPCompiledCode)m_stub_entry_point;
m_block_links[i] = nullptr;
m_block_size[i] = 0;
}
}
}
}
if (blockSize[start_addr] == 0)
if (m_block_size[start_addr] == 0)
{
// just a safeguard, should never happen anymore.
// if it does we might get stuck over in RunForCycles.
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)
{
MOV(16, R(EAX), Imm16(DSP_IDLE_SKIP_CYCLES));
}
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()
@ -357,13 +357,13 @@ const u8* DSPEmitter::CompileStub()
const u8* entryPoint = AlignCode16();
ABI_CallFunction(CompileCurrent);
XOR(32, R(EAX), R(EAX)); // Return 0 cycles executed
JMP(returnDispatcher);
JMP(m_return_dispatcher);
return entryPoint;
}
void DSPEmitter::CompileDispatcher()
{
enterDispatcher = AlignCode16();
m_enter_dispatcher = AlignCode16();
// We don't use floating point (high 16 bits).
BitSet32 registers_used = ABI_ALL_CALLEE_SAVED & BitSet32(0xffff);
ABI_PushRegistersAndAdjustStack(registers_used, 8);
@ -383,10 +383,10 @@ void DSPEmitter::CompileDispatcher()
// Execute block. Cycles executed returned in EAX.
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));
returnDispatcher = GetCodePtr();
m_return_dispatcher = GetCodePtr();
// Decrement cyclesLeft
SUB(16, M(&g_cycles_left), R(EAX));

View File

@ -245,29 +245,26 @@ public:
void msub(const UDSPInstruction opc);
// CALL this to start the dispatcher
const u8* enterDispatcher;
const u8* reenterDispatcher;
const u8* stubEntryPoint;
const u8* returnDispatcher;
u16 compilePC;
u16 startAddr;
std::vector<Block> blockLinks;
std::vector<u16> blockSize;
std::list<u16> unresolvedJumps[MAX_BLOCKS];
const u8* m_enter_dispatcher;
const u8* m_reenter_dispatcher;
const u8* m_stub_entry_point;
const u8* m_return_dispatcher;
u16 m_compile_pc;
u16 m_start_address;
std::vector<Block> m_block_links;
std::vector<u16> m_block_size;
std::list<u16> m_unresolved_jumps[MAX_BLOCKS];
DSPJitRegCache gpr{*this};
DSPJitRegCache m_gpr{*this};
private:
std::vector<DSPCompiledCode> blocks;
Block blockLinkEntry;
u16 compileSR;
std::vector<DSPCompiledCode> m_blocks;
Block m_block_link_entry;
u16 m_compile_status_register;
// The index of the last stored ext value (compile time).
int storeIndex = -1;
int storeIndex2 = -1;
// Counts down.
// int cycles;
int m_store_index = -1;
int m_store_index2 = -1;
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;
// 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);
get_acc_m(reg);
// 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;
// else
// 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));
CMP(16, R(RAX), Imm16(imm));
FixupBranch notLogicZero = J_CC(CC_NE);
@ -88,7 +88,7 @@ void DSPEmitter::andcf(const UDSPInstruction opc)
SetJumpTarget(notLogicZero);
AND(16, sr_reg, Imm16(~SR_LOGIC_ZERO));
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;
// 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);
get_acc_m(reg);
// 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;
// else
// 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));
FixupBranch notLogicZero = J_CC(CC_NE);
OR(16, sr_reg, Imm16(SR_LOGIC_ZERO));
@ -122,7 +122,7 @@ void DSPEmitter::andf(const UDSPInstruction opc)
SetJumpTarget(notLogicZero);
AND(16, sr_reg, Imm16(~SR_LOGIC_ZERO));
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())
{
X64Reg tmp1 = gpr.GetFreeXReg();
X64Reg tmp1 = m_gpr.GetFreeXReg();
// s64 acc0 = dsp_get_long_acc(0);
get_long_acc(0, tmp1);
MOV(64, R(RAX), R(tmp1));
@ -185,7 +185,7 @@ void DSPEmitter::cmp(const UDSPInstruction opc)
// influence on ABS/0xa100
NEG(64, R(RDX));
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 sreg = (opc >> 11) & 0x1;
X64Reg tmp1 = gpr.GetFreeXReg();
X64Reg tmp1 = m_gpr.GetFreeXReg();
// s64 sr = dsp_get_long_acc(sreg);
get_long_acc(sreg, 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));
NEG(64, R(RDX));
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())
{
u8 reg = (opc >> 8) & 0x1;
X64Reg tmp1 = gpr.GetFreeXReg();
X64Reg tmp1 = m_gpr.GetFreeXReg();
// s64 val = dsp_get_long_acc(reg);
get_long_acc(reg, tmp1);
MOV(64, R(RAX), R(tmp1));
// s64 imm = (s64)(s16)dsp_fetch_code() << 16; // Immediate is considered to be at M level in
// 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));
// s64 res = dsp_convert_long_acc(val - imm);
SUB(64, R(RAX), R(RDX));
// Update_SR_Register64(res, isCarry2(val, res), isOverflow(val, -imm, res));
NEG(64, R(RDX));
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;
// s64 acc = dsp_get_long_acc(areg);
X64Reg tmp1 = gpr.GetFreeXReg();
X64Reg tmp1 = m_gpr.GetFreeXReg();
get_long_acc(areg, tmp1);
MOV(64, R(RAX), R(tmp1));
// 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));
NEG(64, R(RDX));
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;
// 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;
get_acc_m(reg, RAX);
XOR(16, R(RAX), Imm16(imm));
@ -480,7 +480,7 @@ void DSPEmitter::andi(const UDSPInstruction opc)
{
u8 reg = (opc >> 8) & 0x1;
// 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;
get_acc_m(reg, RAX);
AND(16, R(RAX), Imm16(imm));
@ -503,7 +503,7 @@ void DSPEmitter::ori(const UDSPInstruction opc)
{
u8 reg = (opc >> 8) & 0x1;
// 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;
get_acc_m(reg, RAX);
OR(16, R(RAX), Imm16(imm));
@ -529,7 +529,7 @@ void DSPEmitter::addr(const UDSPInstruction opc)
u8 sreg = ((opc >> 9) & 0x3) + DSP_REG_AXL0;
// s64 acc = dsp_get_long_acc(dreg);
X64Reg tmp1 = gpr.GetFreeXReg();
X64Reg tmp1 = m_gpr.GetFreeXReg();
get_long_acc(dreg, tmp1);
MOV(64, R(RAX), R(tmp1));
// s64 ax = (s16)g_dsp.r[sreg];
@ -550,7 +550,7 @@ void DSPEmitter::addr(const UDSPInstruction opc)
{
set_long_acc(dreg, RAX);
}
gpr.PutXReg(tmp1);
m_gpr.PutXReg(tmp1);
}
// ADDAX $acD, $axS
@ -563,7 +563,7 @@ void DSPEmitter::addax(const UDSPInstruction opc)
u8 dreg = (opc >> 8) & 0x1;
u8 sreg = (opc >> 9) & 0x1;
X64Reg tmp1 = gpr.GetFreeXReg();
X64Reg tmp1 = m_gpr.GetFreeXReg();
// s64 acc = dsp_get_long_acc(dreg);
get_long_acc(dreg, tmp1);
MOV(64, R(RAX), R(tmp1));
@ -584,7 +584,7 @@ void DSPEmitter::addax(const UDSPInstruction opc)
{
set_long_acc(dreg, RAX);
}
gpr.PutXReg(tmp1);
m_gpr.PutXReg(tmp1);
}
// ADD $acD, $ac(1-D)
@ -596,7 +596,7 @@ void DSPEmitter::add(const UDSPInstruction opc)
{
u8 dreg = (opc >> 8) & 0x1;
X64Reg tmp1 = gpr.GetFreeXReg();
X64Reg tmp1 = m_gpr.GetFreeXReg();
// s64 acc0 = dsp_get_long_acc(dreg);
get_long_acc(dreg, tmp1);
MOV(64, R(RAX), R(tmp1));
@ -617,7 +617,7 @@ void DSPEmitter::add(const UDSPInstruction opc)
{
set_long_acc(dreg, RAX);
}
gpr.PutXReg(tmp1);
m_gpr.PutXReg(tmp1);
}
// ADDP $acD
@ -629,7 +629,7 @@ void DSPEmitter::addp(const UDSPInstruction opc)
{
u8 dreg = (opc >> 8) & 0x1;
X64Reg tmp1 = gpr.GetFreeXReg();
X64Reg tmp1 = m_gpr.GetFreeXReg();
// s64 acc = dsp_get_long_acc(dreg);
get_long_acc(dreg, tmp1);
MOV(64, R(RAX), R(tmp1));
@ -650,7 +650,7 @@ void DSPEmitter::addp(const UDSPInstruction opc)
{
set_long_acc(dreg, RAX);
}
gpr.PutXReg(tmp1);
m_gpr.PutXReg(tmp1);
}
// ADDAXL $acD, $axS.l
@ -664,7 +664,7 @@ void DSPEmitter::addaxl(const UDSPInstruction opc)
u8 sreg = (opc >> 9) & 0x1;
u8 dreg = (opc >> 8) & 0x1;
X64Reg tmp1 = gpr.GetFreeXReg();
X64Reg tmp1 = m_gpr.GetFreeXReg();
// u64 acc = dsp_get_long_acc(dreg);
get_long_acc(dreg, tmp1);
MOV(64, R(RAX), R(tmp1));
@ -686,7 +686,7 @@ void DSPEmitter::addaxl(const UDSPInstruction opc)
{
set_long_acc(dreg, RAX);
}
gpr.PutXReg(tmp1);
m_gpr.PutXReg(tmp1);
}
// ADDI $amR, #I
@ -698,12 +698,12 @@ void DSPEmitter::addaxl(const UDSPInstruction opc)
void DSPEmitter::addi(const UDSPInstruction opc)
{
u8 areg = (opc >> 8) & 0x1;
X64Reg tmp1 = gpr.GetFreeXReg();
X64Reg tmp1 = m_gpr.GetFreeXReg();
// s64 acc = dsp_get_long_acc(areg);
get_long_acc(areg, tmp1);
MOV(64, R(RAX), R(tmp1));
// s64 imm = (s16)dsp_fetch_code();
s16 imm = dsp_imem_read(compilePC + 1);
s16 imm = dsp_imem_read(m_compile_pc + 1);
// imm <<= 16;
MOV(16, R(RDX), Imm16(imm));
MOVSX(64, 16, RDX, R(RDX));
@ -723,7 +723,7 @@ void DSPEmitter::addi(const UDSPInstruction opc)
{
set_long_acc(areg, RAX);
}
gpr.PutXReg(tmp1);
m_gpr.PutXReg(tmp1);
}
// ADDIS $acD, #I
@ -735,7 +735,7 @@ void DSPEmitter::addis(const UDSPInstruction opc)
{
u8 dreg = (opc >> 8) & 0x1;
X64Reg tmp1 = gpr.GetFreeXReg();
X64Reg tmp1 = m_gpr.GetFreeXReg();
// s64 acc = dsp_get_long_acc(dreg);
get_long_acc(dreg, tmp1);
MOV(64, R(RAX), R(tmp1));
@ -759,7 +759,7 @@ void DSPEmitter::addis(const UDSPInstruction opc)
{
set_long_acc(dreg, RAX);
}
gpr.PutXReg(tmp1);
m_gpr.PutXReg(tmp1);
}
// INCM $acsD
@ -771,7 +771,7 @@ void DSPEmitter::incm(const UDSPInstruction opc)
{
u8 dreg = (opc >> 8) & 0x1;
s64 subtract = 0x10000;
X64Reg tmp1 = gpr.GetFreeXReg();
X64Reg tmp1 = m_gpr.GetFreeXReg();
// s64 acc = dsp_get_long_acc(dreg);
get_long_acc(dreg, tmp1);
MOV(64, R(RAX), R(tmp1));
@ -791,7 +791,7 @@ void DSPEmitter::incm(const UDSPInstruction opc)
{
set_long_acc(dreg);
}
gpr.PutXReg(tmp1);
m_gpr.PutXReg(tmp1);
}
// INC $acD
@ -802,7 +802,7 @@ void DSPEmitter::incm(const UDSPInstruction opc)
void DSPEmitter::inc(const UDSPInstruction opc)
{
u8 dreg = (opc >> 8) & 0x1;
X64Reg tmp1 = gpr.GetFreeXReg();
X64Reg tmp1 = m_gpr.GetFreeXReg();
// s64 acc = dsp_get_long_acc(dreg);
get_long_acc(dreg, tmp1);
MOV(64, R(RAX), R(tmp1));
@ -822,7 +822,7 @@ void DSPEmitter::inc(const UDSPInstruction opc)
{
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 sreg = ((opc >> 9) & 0x3) + DSP_REG_AXL0;
X64Reg tmp1 = gpr.GetFreeXReg();
X64Reg tmp1 = m_gpr.GetFreeXReg();
// s64 acc = dsp_get_long_acc(dreg);
get_long_acc(dreg, tmp1);
MOV(64, R(RAX), R(tmp1));
@ -861,7 +861,7 @@ void DSPEmitter::subr(const UDSPInstruction opc)
{
set_long_acc(dreg, RAX);
}
gpr.PutXReg(tmp1);
m_gpr.PutXReg(tmp1);
}
// SUBAX $acD, $axS
@ -874,7 +874,7 @@ void DSPEmitter::subax(const UDSPInstruction opc)
u8 dreg = (opc >> 8) & 0x1;
u8 sreg = (opc >> 9) & 0x1;
X64Reg tmp1 = gpr.GetFreeXReg();
X64Reg tmp1 = m_gpr.GetFreeXReg();
// s64 acc = dsp_get_long_acc(dreg);
get_long_acc(dreg, tmp1);
MOV(64, R(RAX), R(tmp1));
@ -896,7 +896,7 @@ void DSPEmitter::subax(const UDSPInstruction opc)
{
set_long_acc(dreg, RAX);
}
gpr.PutXReg(tmp1);
m_gpr.PutXReg(tmp1);
}
// SUB $acD, $ac(1-D)
@ -907,7 +907,7 @@ void DSPEmitter::subax(const UDSPInstruction opc)
void DSPEmitter::sub(const UDSPInstruction opc)
{
u8 dreg = (opc >> 8) & 0x1;
X64Reg tmp1 = gpr.GetFreeXReg();
X64Reg tmp1 = m_gpr.GetFreeXReg();
// s64 acc1 = dsp_get_long_acc(dreg);
get_long_acc(dreg, tmp1);
MOV(64, R(RAX), R(tmp1));
@ -929,7 +929,7 @@ void DSPEmitter::sub(const UDSPInstruction opc)
{
set_long_acc(dreg, RAX);
}
gpr.PutXReg(tmp1);
m_gpr.PutXReg(tmp1);
}
// SUBP $acD
@ -940,7 +940,7 @@ void DSPEmitter::sub(const UDSPInstruction opc)
void DSPEmitter::subp(const UDSPInstruction opc)
{
u8 dreg = (opc >> 8) & 0x1;
X64Reg tmp1 = gpr.GetFreeXReg();
X64Reg tmp1 = m_gpr.GetFreeXReg();
// s64 acc = dsp_get_long_acc(dreg);
get_long_acc(dreg, tmp1);
MOV(64, R(RAX), R(tmp1));
@ -962,7 +962,7 @@ void DSPEmitter::subp(const UDSPInstruction opc)
{
set_long_acc(dreg, RAX);
}
gpr.PutXReg(tmp1);
m_gpr.PutXReg(tmp1);
}
// DECM $acsD
@ -974,7 +974,7 @@ void DSPEmitter::decm(const UDSPInstruction opc)
{
u8 dreg = (opc >> 8) & 0x01;
s64 subtract = 0x10000;
X64Reg tmp1 = gpr.GetFreeXReg();
X64Reg tmp1 = m_gpr.GetFreeXReg();
// s64 acc = dsp_get_long_acc(dreg);
get_long_acc(dreg, tmp1);
MOV(64, R(RAX), R(tmp1));
@ -994,7 +994,7 @@ void DSPEmitter::decm(const UDSPInstruction opc)
{
set_long_acc(dreg, RAX);
}
gpr.PutXReg(tmp1);
m_gpr.PutXReg(tmp1);
}
// DEC $acD
@ -1005,7 +1005,7 @@ void DSPEmitter::decm(const UDSPInstruction opc)
void DSPEmitter::dec(const UDSPInstruction opc)
{
u8 dreg = (opc >> 8) & 0x01;
X64Reg tmp1 = gpr.GetFreeXReg();
X64Reg tmp1 = m_gpr.GetFreeXReg();
// s64 acc = dsp_get_long_acc(dreg);
get_long_acc(dreg, tmp1);
MOV(64, R(RAX), R(tmp1));
@ -1025,7 +1025,7 @@ void DSPEmitter::dec(const UDSPInstruction opc)
{
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));
break;
}
DSPJitRegCache c1(emitter.gpr);
DSPJitRegCache c1(emitter.m_gpr);
FixupBranch skipCode =
cond == 0xe ? emitter.J_CC(CC_E, true) : emitter.J_CC((CCFlags)(CC_NE - (cond & 1)), true);
jitCode(opc, emitter);
emitter.gpr.FlushRegs(c1);
emitter.m_gpr.FlushRegs(c1);
emitter.SetJumpTarget(skipCode);
}
static void WriteBranchExit(DSPEmitter& emitter)
{
DSPJitRegCache c(emitter.gpr);
emitter.gpr.SaveRegs();
if (Analyzer::GetCodeFlags(emitter.startAddr) & Analyzer::CODE_IDLE_SKIP)
DSPJitRegCache c(emitter.m_gpr);
emitter.m_gpr.SaveRegs();
if (Analyzer::GetCodeFlags(emitter.m_start_address) & Analyzer::CODE_IDLE_SKIP)
{
emitter.MOV(16, R(EAX), Imm16(0x1000));
}
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.gpr.LoadRegs(false);
emitter.gpr.FlushRegs(c, false);
emitter.JMP(emitter.m_return_dispatcher, true);
emitter.m_gpr.LoadRegs(false);
emitter.m_gpr.FlushRegs(c, false);
}
static void WriteBlockLink(DSPEmitter& emitter, u16 dest)
{
// 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
emitter.MOV(16, R(ECX), M(&g_cycles_left));
emitter.CMP(16, R(ECX),
Imm16(emitter.blockSize[emitter.startAddr] + emitter.blockSize[dest]));
emitter.CMP(16, R(ECX), Imm16(emitter.m_block_size[emitter.m_start_address] +
emitter.m_block_size[dest]));
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.JMP(emitter.blockLinks[dest], true);
emitter.JMP(emitter.m_block_links[dest], true);
emitter.SetJumpTarget(notEnoughCycles);
}
else
{
// The destination has not been compiled yet. Add it to the list
// 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)
{
u16 dest = dsp_imem_read(emitter.compilePC + 1);
u16 dest = dsp_imem_read(emitter.m_compile_pc + 1);
const DSPOPCTemplate* opcode = GetOpTemplate(opc);
// 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
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);
}
@ -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
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);
}
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);
u16 dest = dsp_imem_read(emitter.compilePC + 1);
u16 dest = dsp_imem_read(emitter.m_compile_pc + 1);
const DSPOPCTemplate* opcode = GetOpTemplate(opc);
// 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
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);
}
static void r_callr(const UDSPInstruction opc, DSPEmitter& emitter)
{
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_op_read_reg(reg, RAX, NONE);
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
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);
}
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
// 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
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));
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
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);
}
@ -298,7 +298,7 @@ void DSPEmitter::HandleLoop()
TEST(32, R(RCX), R(RCX));
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);
SUB(16, M(&(g_dsp.r.st[3])), Imm16(1));
@ -310,11 +310,11 @@ void DSPEmitter::HandleLoop()
FixupBranch loopUpdated = J(true);
SetJumpTarget(loadStack);
DSPJitRegCache c(gpr);
DSPJitRegCache c(m_gpr);
dsp_reg_load_stack(0);
dsp_reg_load_stack(2);
dsp_reg_load_stack(3);
gpr.FlushRegs(c);
m_gpr.FlushRegs(c);
SetJumpTarget(loopUpdated);
SetJumpTarget(rLoopAddrG);
@ -335,25 +335,25 @@ void DSPEmitter::loop(const UDSPInstruction opc)
// u16 cnt = g_dsp.r[reg];
// todo: check if we can use normal variant here
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));
DSPJitRegCache c(gpr);
DSPJitRegCache c(m_gpr);
FixupBranch cnt = J_CC(CC_Z, true);
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);
MOV(16, R(RDX), Imm16(loop_pc));
dsp_reg_store_stack(2);
gpr.FlushRegs(c);
MOV(16, M(&(g_dsp.pc)), Imm16(compilePC + 1));
m_gpr.FlushRegs(c);
MOV(16, M(&(g_dsp.pc)), Imm16(m_compile_pc + 1));
FixupBranch exit = J(true);
SetJumpTarget(cnt);
// dsp_skip_inst();
MOV(16, M(&g_dsp.pc), Imm16(loop_pc + GetOpTemplate(dsp_imem_read(loop_pc))->size));
WriteBranchExit(*this);
gpr.FlushRegs(c, false);
m_gpr.FlushRegs(c, false);
SetJumpTarget(exit);
}
@ -368,18 +368,18 @@ void DSPEmitter::loop(const UDSPInstruction opc)
void DSPEmitter::loopi(const UDSPInstruction opc)
{
u16 cnt = opc & 0xff;
u16 loop_pc = compilePC + 1;
u16 loop_pc = m_compile_pc + 1;
if (cnt)
{
MOV(16, R(RDX), Imm16(compilePC + 1));
MOV(16, R(RDX), Imm16(m_compile_pc + 1));
dsp_reg_store_stack(0);
MOV(16, R(RDX), Imm16(loop_pc));
dsp_reg_store_stack(2);
MOV(16, R(RDX), Imm16(cnt));
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
{
@ -404,18 +404,18 @@ void DSPEmitter::bloop(const UDSPInstruction opc)
// u16 cnt = g_dsp.r[reg];
// todo: check if we can use normal variant here
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));
DSPJitRegCache c(gpr);
DSPJitRegCache c(m_gpr);
FixupBranch cnt = J_CC(CC_Z, true);
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);
MOV(16, R(RDX), Imm16(loop_pc));
dsp_reg_store_stack(2);
MOV(16, M(&(g_dsp.pc)), Imm16(compilePC + 2));
gpr.FlushRegs(c, true);
MOV(16, M(&(g_dsp.pc)), Imm16(m_compile_pc + 2));
m_gpr.FlushRegs(c, true);
FixupBranch exit = J(true);
SetJumpTarget(cnt);
@ -423,7 +423,7 @@ void DSPEmitter::bloop(const UDSPInstruction opc)
// dsp_skip_inst();
MOV(16, M(&g_dsp.pc), Imm16(loop_pc + GetOpTemplate(dsp_imem_read(loop_pc))->size));
WriteBranchExit(*this);
gpr.FlushRegs(c, false);
m_gpr.FlushRegs(c, false);
SetJumpTarget(exit);
}
@ -440,18 +440,18 @@ void DSPEmitter::bloopi(const UDSPInstruction opc)
{
u16 cnt = opc & 0xff;
// 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)
{
MOV(16, R(RDX), Imm16(compilePC + 2));
MOV(16, R(RDX), Imm16(m_compile_pc + 2));
dsp_reg_store_stack(0);
MOV(16, R(RDX), Imm16(loop_pc));
dsp_reg_store_stack(2);
MOV(16, R(RDX), Imm16(cnt));
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
{

View File

@ -19,7 +19,7 @@ namespace x86
// Clobbers RDX
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
// if (_Value == 0) g_dsp.r[DSP_REG_SR] |= SR_ARITH_ZERO;
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));
SetJumpTarget(cC);
SetJumpTarget(end);
gpr.PutReg(DSP_REG_SR);
m_gpr.PutReg(DSP_REG_SR);
}
// In: RAX: s64 _Value
@ -62,9 +62,9 @@ void DSPEmitter::Update_SR_Register(Gen::X64Reg val)
void DSPEmitter::Update_SR_Register64(Gen::X64Reg val)
{
// 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));
gpr.PutReg(DSP_REG_SR);
m_gpr.PutReg(DSP_REG_SR);
Update_SR_Register(val);
}
@ -73,7 +73,7 @@ void DSPEmitter::Update_SR_Register64(Gen::X64Reg val)
// Clobbers RDX
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;
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));
SetJumpTarget(noOverflow);
gpr.PutReg(DSP_REG_SR);
m_gpr.PutReg(DSP_REG_SR);
if (carry_eq)
{
Update_SR_Register();
@ -112,7 +112,7 @@ void DSPEmitter::Update_SR_Register64_Carry(X64Reg val, X64Reg carry_ovfl, bool
// In: RAX: s64 _Value
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));
// // 0x04
@ -141,14 +141,14 @@ void DSPEmitter::Update_SR_Register16(X64Reg val)
OR(16, sr_reg, Imm16(SR_TOP2BITS));
SetJumpTarget(notThree);
SetJumpTarget(end);
gpr.PutReg(DSP_REG_SR);
m_gpr.PutReg(DSP_REG_SR);
}
// In: RAX: s64 _Value
// Clobbers RCX
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));
// // 0x10
@ -159,7 +159,7 @@ void DSPEmitter::Update_SR_Register16_OverS32(Gen::X64Reg val)
OR(16, sr_reg, Imm16(SR_OVER_S32));
SetJumpTarget(noOverS32);
gpr.PutReg(DSP_REG_SR);
m_gpr.PutReg(DSP_REG_SR);
// // 0x20 - Checks if top bits of m are equal
// if ((((u16)_Value >> 14) == 0) || (((u16)_Value >> 14) == 3))
// 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 dreg = ((opc >> 2) & 0x3);
dsp_op_read_reg(sreg, RBX, ZERO);
storeIndex = dreg + DSP_REG_AXL0;
m_store_index = dreg + DSP_REG_AXL0;
}
// S @$arD, $acS.S
@ -79,13 +79,13 @@ void DSPEmitter::s(const UDSPInstruction opc)
// u16 addr = g_dsp.r[dest];
dsp_op_read_reg(dreg, RAX, ZERO);
X64Reg tmp1 = gpr.GetFreeXReg();
X64Reg tmp1 = m_gpr.GetFreeXReg();
dsp_op_read_reg(sreg, tmp1, ZERO);
// u16 val = g_dsp.r[src];
dmem_write(tmp1);
gpr.PutXReg(tmp1);
m_gpr.PutXReg(tmp1);
increment_addr_reg(dreg);
}
@ -100,12 +100,12 @@ void DSPEmitter::sn(const UDSPInstruction opc)
u8 sreg = ((opc >> 3) & 0x3) + DSP_REG_ACL0;
dsp_op_read_reg(dreg, RAX, ZERO);
X64Reg tmp1 = gpr.GetFreeXReg();
X64Reg tmp1 = m_gpr.GetFreeXReg();
dsp_op_read_reg(sreg, tmp1, ZERO);
dmem_write(tmp1);
gpr.PutXReg(tmp1);
m_gpr.PutXReg(tmp1);
increase_addr_reg(dreg, dreg);
}
@ -171,12 +171,12 @@ void DSPEmitter::ls(const UDSPInstruction opc)
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
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);
dmem_write(tmp1);
gpr.PutXReg(tmp1);
m_gpr.PutXReg(tmp1);
pushExtValueFromMem(dreg, DSP_REG_AR0);
@ -196,12 +196,12 @@ void DSPEmitter::lsn(const UDSPInstruction opc)
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
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);
dmem_write(tmp1);
gpr.PutXReg(tmp1);
m_gpr.PutXReg(tmp1);
pushExtValueFromMem(dreg, DSP_REG_AR0);
@ -221,12 +221,12 @@ void DSPEmitter::lsm(const UDSPInstruction opc)
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
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);
dmem_write(tmp1);
gpr.PutXReg(tmp1);
m_gpr.PutXReg(tmp1);
pushExtValueFromMem(dreg, DSP_REG_AR0);
@ -247,12 +247,12 @@ void DSPEmitter::lsnm(const UDSPInstruction opc)
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
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);
dmem_write(tmp1);
gpr.PutXReg(tmp1);
m_gpr.PutXReg(tmp1);
pushExtValueFromMem(dreg, DSP_REG_AR0);
@ -271,12 +271,12 @@ void DSPEmitter::sl(const UDSPInstruction opc)
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
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);
dmem_write(tmp1);
gpr.PutXReg(tmp1);
m_gpr.PutXReg(tmp1);
pushExtValueFromMem(dreg, DSP_REG_AR3);
@ -296,12 +296,12 @@ void DSPEmitter::sln(const UDSPInstruction opc)
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
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);
dmem_write(tmp1);
gpr.PutXReg(tmp1);
m_gpr.PutXReg(tmp1);
pushExtValueFromMem(dreg, DSP_REG_AR3);
@ -321,12 +321,12 @@ void DSPEmitter::slm(const UDSPInstruction opc)
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
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);
dmem_write(tmp1);
gpr.PutXReg(tmp1);
m_gpr.PutXReg(tmp1);
pushExtValueFromMem(dreg, DSP_REG_AR3);
@ -346,12 +346,12 @@ void DSPEmitter::slnm(const UDSPInstruction opc)
u8 dreg = ((opc >> 4) & 0x3) + DSP_REG_AXL0;
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);
dmem_write(tmp1);
gpr.PutXReg(tmp1);
m_gpr.PutXReg(tmp1);
pushExtValueFromMem(dreg, DSP_REG_AR3);
@ -378,20 +378,20 @@ void DSPEmitter::ld(const UDSPInstruction opc)
pushExtValueFromMem((dreg << 1) + DSP_REG_AXL0, sreg);
// 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(DSP_REG_AR3, tmp, NONE);
XOR(16, R(ECX), R(tmp));
gpr.PutXReg(tmp);
DSPJitRegCache c(gpr);
m_gpr.PutXReg(tmp);
DSPJitRegCache c(m_gpr);
TEST(16, R(ECX), Imm16(0xfc00));
FixupBranch not_equal = J_CC(CC_NE, true);
pushExtValueFromMem2((rreg << 1) + DSP_REG_AXL1, sreg);
gpr.FlushRegs(c);
m_gpr.FlushRegs(c);
FixupBranch after = J(true);
SetJumpTarget(not_equal); // else
pushExtValueFromMem2((rreg << 1) + DSP_REG_AXL1, DSP_REG_AR3);
gpr.FlushRegs(c);
m_gpr.FlushRegs(c);
SetJumpTarget(after);
increment_addr_reg(sreg);
@ -408,21 +408,21 @@ void DSPEmitter::ldax(const UDSPInstruction opc)
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])) {
dsp_op_read_reg(sreg, RCX, NONE);
dsp_op_read_reg(DSP_REG_AR3, tmp, NONE);
XOR(16, R(ECX), R(tmp));
gpr.PutXReg(tmp);
DSPJitRegCache c(gpr);
m_gpr.PutXReg(tmp);
DSPJitRegCache c(m_gpr);
TEST(16, R(ECX), Imm16(0xfc00));
FixupBranch not_equal = J_CC(CC_NE, true);
pushExtValueFromMem2(rreg + DSP_REG_AXL0, sreg);
gpr.FlushRegs(c);
m_gpr.FlushRegs(c);
FixupBranch after = J(true); // else
SetJumpTarget(not_equal);
pushExtValueFromMem2(rreg + DSP_REG_AXL0, DSP_REG_AR3);
gpr.FlushRegs(c);
m_gpr.FlushRegs(c);
SetJumpTarget(after);
increment_addr_reg(sreg);
@ -440,21 +440,21 @@ void DSPEmitter::ldn(const UDSPInstruction opc)
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])) {
dsp_op_read_reg(sreg, RCX, NONE);
dsp_op_read_reg(DSP_REG_AR3, tmp, NONE);
XOR(16, R(ECX), R(tmp));
gpr.PutXReg(tmp);
DSPJitRegCache c(gpr);
m_gpr.PutXReg(tmp);
DSPJitRegCache c(m_gpr);
TEST(16, R(ECX), Imm16(0xfc00));
FixupBranch not_equal = J_CC(CC_NE, true);
pushExtValueFromMem2((rreg << 1) + DSP_REG_AXL1, sreg);
gpr.FlushRegs(c);
m_gpr.FlushRegs(c);
FixupBranch after = J(true);
SetJumpTarget(not_equal); // else
pushExtValueFromMem2((rreg << 1) + DSP_REG_AXL1, DSP_REG_AR3);
gpr.FlushRegs(c);
m_gpr.FlushRegs(c);
SetJumpTarget(after);
increase_addr_reg(sreg, sreg);
@ -471,21 +471,21 @@ void DSPEmitter::ldaxn(const UDSPInstruction opc)
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])) {
dsp_op_read_reg(sreg, RCX, NONE);
dsp_op_read_reg(DSP_REG_AR3, tmp, NONE);
XOR(16, R(ECX), R(tmp));
gpr.PutXReg(tmp);
DSPJitRegCache c(gpr);
m_gpr.PutXReg(tmp);
DSPJitRegCache c(m_gpr);
TEST(16, R(ECX), Imm16(0xfc00));
FixupBranch not_equal = J_CC(CC_NE, true);
pushExtValueFromMem2(rreg + DSP_REG_AXL0, sreg);
gpr.FlushRegs(c);
m_gpr.FlushRegs(c);
FixupBranch after = J(true); // else
SetJumpTarget(not_equal);
pushExtValueFromMem2(rreg + DSP_REG_AXL0, DSP_REG_AR3);
gpr.FlushRegs(c);
m_gpr.FlushRegs(c);
SetJumpTarget(after);
increase_addr_reg(sreg, sreg);
@ -503,21 +503,21 @@ void DSPEmitter::ldm(const UDSPInstruction opc)
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])) {
dsp_op_read_reg(sreg, RCX, NONE);
dsp_op_read_reg(DSP_REG_AR3, tmp, NONE);
XOR(16, R(ECX), R(tmp));
gpr.PutXReg(tmp);
DSPJitRegCache c(gpr);
m_gpr.PutXReg(tmp);
DSPJitRegCache c(m_gpr);
TEST(16, R(ECX), Imm16(0xfc00));
FixupBranch not_equal = J_CC(CC_NE, true);
pushExtValueFromMem2((rreg << 1) + DSP_REG_AXL1, sreg);
gpr.FlushRegs(c);
m_gpr.FlushRegs(c);
FixupBranch after = J(true);
SetJumpTarget(not_equal); // else
pushExtValueFromMem2((rreg << 1) + DSP_REG_AXL1, DSP_REG_AR3);
gpr.FlushRegs(c);
m_gpr.FlushRegs(c);
SetJumpTarget(after);
increment_addr_reg(sreg);
@ -534,21 +534,21 @@ void DSPEmitter::ldaxm(const UDSPInstruction opc)
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])) {
dsp_op_read_reg(sreg, RCX, NONE);
dsp_op_read_reg(DSP_REG_AR3, tmp, NONE);
XOR(16, R(ECX), R(tmp));
gpr.PutXReg(tmp);
DSPJitRegCache c(gpr);
m_gpr.PutXReg(tmp);
DSPJitRegCache c(m_gpr);
TEST(16, R(ECX), Imm16(0xfc00));
FixupBranch not_equal = J_CC(CC_NE, true);
pushExtValueFromMem2(rreg + DSP_REG_AXL0, sreg);
gpr.FlushRegs(c);
m_gpr.FlushRegs(c);
FixupBranch after = J(true); // else
SetJumpTarget(not_equal);
pushExtValueFromMem2(rreg + DSP_REG_AXL0, DSP_REG_AR3);
gpr.FlushRegs(c);
m_gpr.FlushRegs(c);
SetJumpTarget(after);
increment_addr_reg(sreg);
@ -566,21 +566,21 @@ void DSPEmitter::ldnm(const UDSPInstruction opc)
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])) {
dsp_op_read_reg(sreg, RCX, NONE);
dsp_op_read_reg(DSP_REG_AR3, tmp, NONE);
XOR(16, R(ECX), R(tmp));
gpr.PutXReg(tmp);
DSPJitRegCache c(gpr);
m_gpr.PutXReg(tmp);
DSPJitRegCache c(m_gpr);
TEST(16, R(ECX), Imm16(0xfc00));
FixupBranch not_equal = J_CC(CC_NE, true);
pushExtValueFromMem2((rreg << 1) + DSP_REG_AXL1, sreg);
gpr.FlushRegs(c);
m_gpr.FlushRegs(c);
FixupBranch after = J(true);
SetJumpTarget(not_equal); // else
pushExtValueFromMem2((rreg << 1) + DSP_REG_AXL1, DSP_REG_AR3);
gpr.FlushRegs(c);
m_gpr.FlushRegs(c);
SetJumpTarget(after);
increase_addr_reg(sreg, sreg);
@ -597,21 +597,21 @@ void DSPEmitter::ldaxnm(const UDSPInstruction opc)
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])) {
dsp_op_read_reg(sreg, RCX, NONE);
dsp_op_read_reg(DSP_REG_AR3, tmp, NONE);
XOR(16, R(ECX), R(tmp));
gpr.PutXReg(tmp);
DSPJitRegCache c(gpr);
m_gpr.PutXReg(tmp);
DSPJitRegCache c(m_gpr);
TEST(16, R(ECX), Imm16(0xfc00));
FixupBranch not_equal = J_CC(CC_NE, true);
pushExtValueFromMem2(rreg + DSP_REG_AXL0, sreg);
gpr.FlushRegs(c);
m_gpr.FlushRegs(c);
FixupBranch after = J(true); // else
SetJumpTarget(not_equal);
pushExtValueFromMem2(rreg + DSP_REG_AXL0, DSP_REG_AR3);
gpr.FlushRegs(c);
m_gpr.FlushRegs(c);
SetJumpTarget(after);
increase_addr_reg(sreg, sreg);
@ -625,33 +625,33 @@ void DSPEmitter::pushExtValueFromMem(u16 dreg, u16 sreg)
{
// u16 addr = g_dsp.r[addr];
X64Reg tmp1 = gpr.GetFreeXReg();
X64Reg tmp1 = m_gpr.GetFreeXReg();
dsp_op_read_reg(sreg, tmp1, ZERO);
dmem_read(tmp1);
gpr.PutXReg(tmp1);
m_gpr.PutXReg(tmp1);
MOVZX(32, 16, EBX, R(EAX));
storeIndex = dreg;
m_store_index = dreg;
}
void DSPEmitter::pushExtValueFromMem2(u16 dreg, u16 sreg)
{
// u16 addr = g_dsp.r[addr];
X64Reg tmp1 = gpr.GetFreeXReg();
X64Reg tmp1 = m_gpr.GetFreeXReg();
dsp_op_read_reg(sreg, tmp1, ZERO);
dmem_read(tmp1);
gpr.PutXReg(tmp1);
m_gpr.PutXReg(tmp1);
SHL(32, R(EAX), Imm8(16));
OR(32, R(EBX), R(EAX));
storeIndex2 = dreg;
m_store_index2 = dreg;
}
void DSPEmitter::popExtValueToReg()
@ -663,14 +663,14 @@ void DSPEmitter::popExtValueToReg()
// nakee wants to keep it clean, so lets do that.
// [nakeee] the or case never happens in real
// [nakeee] it's just how the hardware works so we added it
if (storeIndex != -1)
if (m_store_index != -1)
{
dsp_op_write_reg(storeIndex, RBX);
if (storeIndex >= DSP_REG_ACM0 && storeIndex2 == -1)
dsp_op_write_reg(m_store_index, RBX);
if (m_store_index >= DSP_REG_ACM0 && m_store_index2 == -1)
{
TEST(32, R(EBX), Imm32(SR_40_MODE_BIT << 16));
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)
//{
// Sign extend into whole accum.
@ -679,23 +679,23 @@ void DSPEmitter::popExtValueToReg()
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_ACL0] = 0;
set_acc_h(storeIndex - DSP_REG_ACM0, R(RAX));
set_acc_l(storeIndex - DSP_REG_ACM0, Imm16(0));
set_acc_h(m_store_index - DSP_REG_ACM0, R(RAX));
set_acc_l(m_store_index - DSP_REG_ACM0, Imm16(0));
//}
gpr.FlushRegs(c);
m_gpr.FlushRegs(c);
SetJumpTarget(not_40bit);
}
}
storeIndex = -1;
m_store_index = -1;
if (storeIndex2 != -1)
if (m_store_index2 != -1)
{
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

View File

@ -29,7 +29,7 @@ void DSPEmitter::srs(const UDSPInstruction opc)
u8 reg = ((opc >> 8) & 0x7) + 0x18;
// 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(DSP_REG_CR, RAX, ZERO);
@ -37,7 +37,7 @@ void DSPEmitter::srs(const UDSPInstruction opc)
OR(16, R(EAX), Imm16(opc & 0xFF));
dmem_write(tmp1);
gpr.PutXReg(tmp1);
m_gpr.PutXReg(tmp1);
}
// LRS $(0x18+D), @M
@ -49,7 +49,7 @@ void DSPEmitter::lrs(const UDSPInstruction opc)
{
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);
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));
dmem_read(tmp1);
gpr.PutXReg(tmp1);
m_gpr.PutXReg(tmp1);
dsp_op_write_reg(reg, RAX);
dsp_conditional_extend_accum(reg);
@ -70,7 +70,7 @@ void DSPEmitter::lrs(const UDSPInstruction opc)
void DSPEmitter::lr(const UDSPInstruction opc)
{
int reg = opc & 0x1F;
u16 address = dsp_imem_read(compilePC + 1);
u16 address = dsp_imem_read(m_compile_pc + 1);
dmem_read_imm(address);
dsp_op_write_reg(reg, EAX);
dsp_conditional_extend_accum(reg);
@ -83,14 +83,14 @@ void DSPEmitter::lr(const UDSPInstruction opc)
void DSPEmitter::sr(const UDSPInstruction opc)
{
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);
dmem_write_imm(address, tmp1);
gpr.PutXReg(tmp1);
m_gpr.PutXReg(tmp1);
}
// SI @M, #I
@ -101,14 +101,14 @@ void DSPEmitter::sr(const UDSPInstruction opc)
void DSPEmitter::si(const UDSPInstruction 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));
dmem_write_imm(address, tmp1);
gpr.PutXReg(tmp1);
m_gpr.PutXReg(tmp1);
}
// LRR $D, @$S
@ -119,12 +119,12 @@ void DSPEmitter::lrr(const UDSPInstruction opc)
u8 sreg = (opc >> 5) & 0x3;
u8 dreg = opc & 0x1f;
X64Reg tmp1 = gpr.GetFreeXReg();
X64Reg tmp1 = m_gpr.GetFreeXReg();
dsp_op_read_reg(sreg, tmp1);
dmem_read(tmp1);
gpr.PutXReg(tmp1);
m_gpr.PutXReg(tmp1);
dsp_op_write_reg(dreg, EAX);
dsp_conditional_extend_accum(dreg);
@ -139,12 +139,12 @@ void DSPEmitter::lrrd(const UDSPInstruction opc)
u8 sreg = (opc >> 5) & 0x3;
u8 dreg = opc & 0x1f;
X64Reg tmp1 = gpr.GetFreeXReg();
X64Reg tmp1 = m_gpr.GetFreeXReg();
dsp_op_read_reg(sreg, tmp1);
dmem_read(tmp1);
gpr.PutXReg(tmp1);
m_gpr.PutXReg(tmp1);
dsp_op_write_reg(dreg, EAX);
dsp_conditional_extend_accum(dreg);
@ -160,12 +160,12 @@ void DSPEmitter::lrri(const UDSPInstruction opc)
u8 sreg = (opc >> 5) & 0x3;
u8 dreg = opc & 0x1f;
X64Reg tmp1 = gpr.GetFreeXReg();
X64Reg tmp1 = m_gpr.GetFreeXReg();
dsp_op_read_reg(sreg, tmp1);
dmem_read(tmp1);
gpr.PutXReg(tmp1);
m_gpr.PutXReg(tmp1);
dsp_op_write_reg(dreg, EAX);
dsp_conditional_extend_accum(dreg);
@ -181,12 +181,12 @@ void DSPEmitter::lrrn(const UDSPInstruction opc)
u8 sreg = (opc >> 5) & 0x3;
u8 dreg = opc & 0x1f;
X64Reg tmp1 = gpr.GetFreeXReg();
X64Reg tmp1 = m_gpr.GetFreeXReg();
dsp_op_read_reg(sreg, tmp1);
dmem_read(tmp1);
gpr.PutXReg(tmp1);
m_gpr.PutXReg(tmp1);
dsp_op_write_reg(dreg, EAX);
dsp_conditional_extend_accum(dreg);
@ -202,13 +202,13 @@ void DSPEmitter::srr(const UDSPInstruction opc)
u8 dreg = (opc >> 5) & 0x3;
u8 sreg = opc & 0x1f;
X64Reg tmp1 = gpr.GetFreeXReg();
X64Reg tmp1 = m_gpr.GetFreeXReg();
dsp_op_read_reg(sreg, tmp1);
dsp_op_read_reg(dreg, RAX, ZERO);
dmem_write(tmp1);
gpr.PutXReg(tmp1);
m_gpr.PutXReg(tmp1);
}
// SRRD @$D, $S
@ -220,13 +220,13 @@ void DSPEmitter::srrd(const UDSPInstruction opc)
u8 dreg = (opc >> 5) & 0x3;
u8 sreg = opc & 0x1f;
X64Reg tmp1 = gpr.GetFreeXReg();
X64Reg tmp1 = m_gpr.GetFreeXReg();
dsp_op_read_reg(sreg, tmp1);
dsp_op_read_reg(dreg, RAX, ZERO);
dmem_write(tmp1);
gpr.PutXReg(tmp1);
m_gpr.PutXReg(tmp1);
decrement_addr_reg(dreg);
}
@ -240,13 +240,13 @@ void DSPEmitter::srri(const UDSPInstruction opc)
u8 dreg = (opc >> 5) & 0x3;
u8 sreg = opc & 0x1f;
X64Reg tmp1 = gpr.GetFreeXReg();
X64Reg tmp1 = m_gpr.GetFreeXReg();
dsp_op_read_reg(sreg, tmp1);
dsp_op_read_reg(dreg, RAX, ZERO);
dmem_write(tmp1);
gpr.PutXReg(tmp1);
m_gpr.PutXReg(tmp1);
increment_addr_reg(dreg);
}
@ -260,13 +260,13 @@ void DSPEmitter::srrn(const UDSPInstruction opc)
u8 dreg = (opc >> 5) & 0x3;
u8 sreg = opc & 0x1f;
X64Reg tmp1 = gpr.GetFreeXReg();
X64Reg tmp1 = m_gpr.GetFreeXReg();
dsp_op_read_reg(sreg, tmp1);
dsp_op_read_reg(dreg, RAX, ZERO);
dmem_write(tmp1);
gpr.PutXReg(tmp1);
m_gpr.PutXReg(tmp1);
increase_addr_reg(dreg, dreg);
}
@ -280,12 +280,12 @@ void DSPEmitter::ilrr(const UDSPInstruction opc)
u16 reg = opc & 0x3;
u16 dreg = (opc >> 8) & 1;
X64Reg tmp1 = gpr.GetFreeXReg();
X64Reg tmp1 = m_gpr.GetFreeXReg();
dsp_op_read_reg(reg, tmp1, ZERO);
imem_read(tmp1);
gpr.PutXReg(tmp1);
m_gpr.PutXReg(tmp1);
set_acc_m(dreg, R(RAX));
dsp_conditional_extend_accum(dreg + DSP_REG_ACM0);
@ -300,12 +300,12 @@ void DSPEmitter::ilrrd(const UDSPInstruction opc)
u16 reg = opc & 0x3;
u16 dreg = (opc >> 8) & 1;
X64Reg tmp1 = gpr.GetFreeXReg();
X64Reg tmp1 = m_gpr.GetFreeXReg();
dsp_op_read_reg(reg, tmp1, ZERO);
imem_read(tmp1);
gpr.PutXReg(tmp1);
m_gpr.PutXReg(tmp1);
set_acc_m(dreg, R(RAX));
dsp_conditional_extend_accum(dreg + DSP_REG_ACM0);
@ -321,12 +321,12 @@ void DSPEmitter::ilrri(const UDSPInstruction opc)
u16 reg = opc & 0x3;
u16 dreg = (opc >> 8) & 1;
X64Reg tmp1 = gpr.GetFreeXReg();
X64Reg tmp1 = m_gpr.GetFreeXReg();
dsp_op_read_reg(reg, tmp1, ZERO);
imem_read(tmp1);
gpr.PutXReg(tmp1);
m_gpr.PutXReg(tmp1);
set_acc_m(dreg, R(RAX));
dsp_conditional_extend_accum(dreg + DSP_REG_ACM0);
@ -343,12 +343,12 @@ void DSPEmitter::ilrrn(const UDSPInstruction opc)
u16 reg = opc & 0x3;
u16 dreg = (opc >> 8) & 1;
X64Reg tmp1 = gpr.GetFreeXReg();
X64Reg tmp1 = m_gpr.GetFreeXReg();
dsp_op_read_reg(reg, tmp1, ZERO);
imem_read(tmp1);
gpr.PutXReg(tmp1);
m_gpr.PutXReg(tmp1);
set_acc_m(dreg, R(RAX));
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)
{
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_conditional_extend_accum_imm(reg, imm);
}
@ -118,21 +118,21 @@ void DSPEmitter::addarn(const UDSPInstruction opc)
void DSPEmitter::setCompileSR(u16 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));
gpr.PutReg(DSP_REG_SR);
m_gpr.PutReg(DSP_REG_SR);
compileSR |= bit;
m_compile_status_register |= bit;
}
void DSPEmitter::clrCompileSR(u16 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));
gpr.PutReg(DSP_REG_SR);
m_gpr.PutReg(DSP_REG_SR);
compileSR &= ~bit;
m_compile_status_register &= ~bit;
}
// SBCLR #I
// 0001 0011 aaaa aiii

View File

@ -28,13 +28,13 @@ void DSPEmitter::multiply()
// Conditionally multiply by 2.
// 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));
FixupBranch noMult2 = J_CC(CC_NZ);
// prod <<= 1;
LEA(64, RAX, MRegSum(RAX, RAX));
SetJumpTarget(noMult2);
gpr.PutReg(DSP_REG_SR, false);
m_gpr.PutReg(DSP_REG_SR, false);
// 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
// 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));
FixupBranch unsignedMul = J_CC(CC_NZ);
// prod = (s16)a * (s16)b; //signed
@ -89,8 +89,8 @@ void DSPEmitter::multiply_mulx(u8 axh0, u8 axh1)
FixupBranch signedMul = J(true);
SetJumpTarget(unsignedMul);
DSPJitRegCache c(gpr);
gpr.PutReg(DSP_REG_SR, false);
DSPJitRegCache c(m_gpr);
m_gpr.PutReg(DSP_REG_SR, false);
if ((axh0 == 0) && (axh1 == 0))
{
// 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
// prod = a * (s16)b;
X64Reg tmp = gpr.GetFreeXReg();
X64Reg tmp = m_gpr.GetFreeXReg();
MOV(64, R(tmp), R(RAX));
MOVZX(64, 16, RAX, R(RCX));
IMUL(64, R(tmp));
gpr.PutXReg(tmp);
m_gpr.PutXReg(tmp);
}
else if ((axh0 == 1) && (axh1 == 0))
{
@ -124,7 +124,7 @@ void DSPEmitter::multiply_mulx(u8 axh0, u8 axh1)
IMUL(64, R(RCX));
}
gpr.FlushRegs(c);
m_gpr.FlushRegs(c);
SetJumpTarget(signedMul);
// Conditionally multiply by 2.
@ -134,7 +134,7 @@ void DSPEmitter::multiply_mulx(u8 axh0, u8 axh1)
// prod <<= 1;
LEA(64, RAX, MRegSum(RAX, RAX));
SetJumpTarget(noMult2);
gpr.PutReg(DSP_REG_SR, false);
m_gpr.PutReg(DSP_REG_SR, false);
// return prod;
}
@ -249,7 +249,7 @@ void DSPEmitter::addpaxz(const UDSPInstruction opc)
u8 sreg = (opc >> 9) & 0x1;
// s64 ax = dsp_get_long_acx(sreg);
X64Reg tmp1 = gpr.GetFreeXReg();
X64Reg tmp1 = m_gpr.GetFreeXReg();
get_long_acx(sreg, tmp1);
MOV(64, R(RDX), R(tmp1));
// s64 res = prod + (ax & ~0xffff);
@ -274,7 +274,7 @@ void DSPEmitter::addpaxz(const UDSPInstruction opc)
{
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;
// 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_prod();
ADD(64, R(tmp1), R(RAX));
@ -452,7 +452,7 @@ void DSPEmitter::mulxac(const UDSPInstruction opc)
{
Update_SR_Register64(tmp1);
}
gpr.PutXReg(tmp1);
m_gpr.PutXReg(tmp1);
}
// MULXMV $ax0.S, $ax1.T, $acR
@ -469,7 +469,7 @@ void DSPEmitter::mulxmv(const UDSPInstruction opc)
u8 sreg = (opc >> 12) & 0x1;
// s64 acc = dsp_get_long_prod();
X64Reg tmp1 = gpr.GetFreeXReg();
X64Reg tmp1 = m_gpr.GetFreeXReg();
get_long_prod(tmp1);
// 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);
@ -487,7 +487,7 @@ void DSPEmitter::mulxmv(const UDSPInstruction opc)
{
Update_SR_Register64(tmp1);
}
gpr.PutXReg(tmp1);
m_gpr.PutXReg(tmp1);
}
// MULXMV $ax0.S, $ax1.T, $acR
@ -505,7 +505,7 @@ void DSPEmitter::mulxmvz(const UDSPInstruction opc)
u8 sreg = (opc >> 12) & 0x1;
// s64 acc = dsp_get_long_prod_round_prodl();
X64Reg tmp1 = gpr.GetFreeXReg();
X64Reg tmp1 = m_gpr.GetFreeXReg();
get_long_prod_round_prodl(tmp1);
// 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);
@ -523,7 +523,7 @@ void DSPEmitter::mulxmvz(const UDSPInstruction opc)
{
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));
MOV(8, M(&g_dsp.reg_stack_ptr[stack_reg]), R(AL));
X64Reg tmp1 = gpr.GetFreeXReg();
X64Reg tmp2 = gpr.GetFreeXReg();
X64Reg tmp1 = m_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];
MOV(16, R(tmp1), M(&g_dsp.r.st[stack_reg]));
MOVZX(64, 8, RAX, R(AL));
MOV(64, R(tmp2), ImmPtr(g_dsp.reg_stack[stack_reg]));
MOV(16, MComplex(tmp2, EAX, SCALE_2, 0), R(tmp1));
gpr.PutXReg(tmp1);
gpr.PutXReg(tmp2);
m_gpr.PutXReg(tmp1);
m_gpr.PutXReg(tmp2);
}
// 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]];
MOV(8, R(AL), M(&g_dsp.reg_stack_ptr[stack_reg]));
X64Reg tmp1 = gpr.GetFreeXReg();
X64Reg tmp2 = gpr.GetFreeXReg();
X64Reg tmp1 = m_gpr.GetFreeXReg();
X64Reg tmp2 = m_gpr.GetFreeXReg();
MOVZX(64, 8, RAX, R(AL));
MOV(64, R(tmp2), ImmPtr(g_dsp.reg_stack[stack_reg]));
MOV(16, R(tmp1), MComplex(tmp2, EAX, SCALE_2, 0));
MOV(16, M(&g_dsp.r.st[stack_reg]), R(tmp1));
gpr.PutXReg(tmp1);
gpr.PutXReg(tmp2);
m_gpr.PutXReg(tmp1);
m_gpr.PutXReg(tmp2);
// g_dsp.reg_stack_ptr[stack_reg]--;
// 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.
case DSP_REG_ACH0:
case DSP_REG_ACH1:
gpr.WriteReg(reg, R(host_sreg));
m_gpr.WriteReg(reg, R(host_sreg));
break;
// Stack registers.
@ -110,7 +110,7 @@ void DSPEmitter::dsp_op_write_reg(int reg, Gen::X64Reg host_sreg)
break;
default:
gpr.WriteReg(reg, R(host_sreg));
m_gpr.WriteReg(reg, R(host_sreg));
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...
case DSP_REG_ACH0:
case DSP_REG_ACH1:
gpr.WriteReg(reg, Imm16((u16)(s16)(s8)(u8)val));
m_gpr.WriteReg(reg, Imm16((u16)(s16)(s8)(u8)val));
break;
// Stack registers.
case DSP_REG_ST0:
@ -133,7 +133,7 @@ void DSPEmitter::dsp_op_write_reg_imm(int reg, u16 val)
break;
default:
gpr.WriteReg(reg, Imm16(val));
m_gpr.WriteReg(reg, Imm16(val));
break;
}
}
@ -145,8 +145,8 @@ void DSPEmitter::dsp_conditional_extend_accum(int reg)
case DSP_REG_ACM0:
case DSP_REG_ACM1:
{
const OpArg sr_reg = gpr.GetReg(DSP_REG_SR);
DSPJitRegCache c(gpr);
const OpArg sr_reg = m_gpr.GetReg(DSP_REG_SR);
DSPJitRegCache c(m_gpr);
TEST(16, sr_reg, Imm16(SR_40_MODE_BIT));
FixupBranch not_40bit = J_CC(CC_Z, true);
// 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_l(reg - DSP_REG_ACM0, Imm16(0));
//}
gpr.FlushRegs(c);
m_gpr.FlushRegs(c);
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_ACM1:
{
const OpArg sr_reg = gpr.GetReg(DSP_REG_SR);
DSPJitRegCache c(gpr);
const OpArg sr_reg = m_gpr.GetReg(DSP_REG_SR);
DSPJitRegCache c(m_gpr);
TEST(16, sr_reg, Imm16(SR_40_MODE_BIT));
FixupBranch not_40bit = J_CC(CC_Z, true);
// 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_l(reg - DSP_REG_ACM0, Imm16(0));
//}
gpr.FlushRegs(c);
m_gpr.FlushRegs(c);
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;
default:
gpr.ReadReg(reg, host_dreg, extend);
m_gpr.ReadReg(reg, host_dreg, extend);
return;
}
}
@ -248,10 +248,10 @@ void DSPEmitter::dsp_op_read_reg(int reg, Gen::X64Reg host_dreg, DSPJitSignExten
case DSP_REG_ACM1:
{
// we already know this is ACCM0 or ACCM1
const OpArg acc_reg = gpr.GetReg(reg - DSP_REG_ACM0 + DSP_REG_ACC0_64);
const OpArg sr_reg = gpr.GetReg(DSP_REG_SR);
const OpArg acc_reg = m_gpr.GetReg(reg - DSP_REG_ACM0 + DSP_REG_ACC0_64);
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));
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));
SetJumpTarget(done_positive);
SetJumpTarget(done_negative);
gpr.FlushRegs(c);
gpr.PutReg(reg - DSP_REG_ACM0 + DSP_REG_ACC0_64, false);
m_gpr.FlushRegs(c);
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;
default:
gpr.ReadReg(reg, host_dreg, extend);
m_gpr.ReadReg(reg, host_dreg, extend);
return;
}
}
@ -307,14 +307,14 @@ void DSPEmitter::dsp_op_read_reg(int reg, Gen::X64Reg host_dreg, DSPJitSignExten
// EDX = g_dsp.r.wr[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);
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);
X64Reg tmp1 = gpr.GetFreeXReg();
X64Reg tmp1 = m_gpr.GetFreeXReg();
// u32 nar = ar + 1;
MOV(32, R(tmp1), R(EAX));
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), Imm8(1));
SetJumpTarget(nowrap);
gpr.PutXReg(tmp1);
m_gpr.PutXReg(tmp1);
// g_dsp.r.ar[reg] = nar;
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]
// EDX = g_dsp.r.wr[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);
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);
X64Reg tmp1 = gpr.GetFreeXReg();
X64Reg tmp1 = m_gpr.GetFreeXReg();
// u32 nar = ar + wr;
// edi = nar
LEA(32, tmp1, MRegSum(EAX, EDX));
@ -366,8 +366,8 @@ void DSPEmitter::decrement_addr_reg(int reg)
// g_dsp.r.ar[reg] = nar;
MOV(16, ar_reg, R(tmp1));
gpr.PutReg(DSP_REG_AR0 + reg);
gpr.PutXReg(tmp1);
m_gpr.PutReg(DSP_REG_AR0 + reg);
m_gpr.PutXReg(tmp1);
}
// 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]
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);
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);
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);
X64Reg tmp1 = gpr.GetFreeXReg();
X64Reg tmp1 = m_gpr.GetFreeXReg();
// u32 nar = ar + ix;
// edi = nar
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;
MOV(16, ar_reg, R(tmp1));
gpr.PutReg(DSP_REG_AR0 + reg);
gpr.PutXReg(tmp1);
m_gpr.PutReg(DSP_REG_AR0 + reg);
m_gpr.PutXReg(tmp1);
}
// 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]
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);
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);
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);
NOT(32, R(ECX)); // esi = ~ix
X64Reg tmp1 = gpr.GetFreeXReg();
X64Reg tmp1 = m_gpr.GetFreeXReg();
// u32 nar = ar - ix; (ar + ~ix + 1)
LEA(32, tmp1, MComplex(EAX, ECX, SCALE_1, 1));
@ -501,8 +501,8 @@ void DSPEmitter::decrease_addr_reg(int reg)
// return nar
MOV(16, ar_reg, R(tmp1));
gpr.PutReg(DSP_REG_AR0 + reg);
gpr.PutXReg(tmp1);
m_gpr.PutReg(DSP_REG_AR0 + reg);
m_gpr.PutXReg(tmp1);
}
// EAX - destination address
@ -522,12 +522,12 @@ void DSPEmitter::dmem_write(X64Reg value)
// else if (saddr == 0xf)
SetJumpTarget(ifx);
// Does it mean gdsp_ifx_write needs u32 rather than u16?
DSPJitRegCache c(gpr);
X64Reg abisafereg = gpr.MakeABICallSafe(value);
gpr.PushRegs();
DSPJitRegCache c(m_gpr);
X64Reg abisafereg = m_gpr.MakeABICallSafe(value);
m_gpr.PushRegs();
ABI_CallFunctionRR(gdsp_ifx_write, EAX, abisafereg);
gpr.PopRegs();
gpr.FlushRegs(c);
m_gpr.PopRegs();
m_gpr.FlushRegs(c);
SetJumpTarget(end);
}
@ -543,10 +543,10 @@ void DSPEmitter::dmem_write_imm(u16 address, X64Reg value)
case 0xf: // Fxxx HW regs
{
MOV(16, R(EAX), Imm16(address));
X64Reg abisafereg = gpr.MakeABICallSafe(value);
gpr.PushRegs();
X64Reg abisafereg = m_gpr.MakeABICallSafe(value);
m_gpr.PushRegs();
ABI_CallFunctionRR(gdsp_ifx_write, EAX, abisafereg);
gpr.PopRegs();
m_gpr.PopRegs();
break;
}
default: // Unmapped/non-existing memory
@ -608,12 +608,12 @@ void DSPEmitter::dmem_read(X64Reg address)
SetJumpTarget(ifx);
// else if (saddr == 0xf)
// return gdsp_ifx_read(addr);
DSPJitRegCache c(gpr);
X64Reg abisafereg = gpr.MakeABICallSafe(address);
gpr.PushRegs();
DSPJitRegCache c(m_gpr);
X64Reg abisafereg = m_gpr.MakeABICallSafe(address);
m_gpr.PushRegs();
ABI_CallFunctionR(gdsp_ifx_read, abisafereg);
gpr.PopRegs();
gpr.FlushRegs(c);
m_gpr.PopRegs();
m_gpr.FlushRegs(c);
SetJumpTarget(end);
SetJumpTarget(end2);
}
@ -634,9 +634,9 @@ void DSPEmitter::dmem_read_imm(u16 address)
case 0xf: // Fxxx HW regs
{
gpr.PushRegs();
m_gpr.PushRegs();
ABI_CallFunctionC16(gdsp_ifx_read, address);
gpr.PopRegs();
m_gpr.PopRegs();
break;
}
default: // Unmapped/non-existing memory
@ -648,18 +648,18 @@ void DSPEmitter::dmem_read_imm(u16 address)
void DSPEmitter::get_long_prod(X64Reg long_prod)
{
// 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);
gpr.PutReg(DSP_REG_PROD_64, false);
m_gpr.PutReg(DSP_REG_PROD_64, false);
// no use in keeping prod_reg any longer.
X64Reg tmp = gpr.GetFreeXReg();
X64Reg tmp = m_gpr.GetFreeXReg();
MOV(64, R(tmp), R(long_prod));
SHL(64, R(long_prod), Imm8(64 - 40)); // sign extend
SAR(64, R(long_prod), Imm8(64 - 40));
SHR(64, R(tmp), Imm8(48));
SHL(64, R(tmp), Imm8(16));
ADD(64, R(long_prod), R(tmp));
gpr.PutXReg(tmp);
m_gpr.PutXReg(tmp);
}
// Returns s64 in RAX
@ -669,7 +669,7 @@ void DSPEmitter::get_long_prod_round_prodl(X64Reg long_prod)
// s64 prod = dsp_get_long_prod();
get_long_prod(long_prod);
X64Reg tmp = gpr.GetFreeXReg();
X64Reg tmp = m_gpr.GetFreeXReg();
// if (prod & 0x10000) prod = (prod + 0x8000) & ~0xffff;
TEST(32, R(long_prod), Imm32(0x10000));
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));
SetJumpTarget(_ret);
// return prod;
gpr.PutXReg(tmp);
m_gpr.PutXReg(tmp);
}
// 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
void DSPEmitter::set_long_prod()
{
X64Reg tmp = gpr.GetFreeXReg();
X64Reg tmp = m_gpr.GetFreeXReg();
MOV(64, R(tmp), Imm64(0x000000ffffffffffULL));
AND(64, R(RAX), R(tmp));
gpr.PutXReg(tmp);
const OpArg prod_reg = gpr.GetReg(DSP_REG_PROD_64, false);
m_gpr.PutXReg(tmp);
const OpArg prod_reg = m_gpr.GetReg(DSP_REG_PROD_64, false);
// g_dsp.r[DSP_REG_PRODL] = (u16)val;
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
@ -727,79 +727,79 @@ void DSPEmitter::round_long_acc(X64Reg long_acc)
// Returns s64 in 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);
gpr.PutReg(DSP_REG_ACC0_64 + _reg, false);
m_gpr.PutReg(DSP_REG_ACC0_64 + _reg, false);
}
// In: acc = s64 val
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));
gpr.PutReg(DSP_REG_ACC0_64 + _reg);
m_gpr.PutReg(DSP_REG_ACC0_64 + _reg);
}
// Returns s16 in AX
void DSPEmitter::get_acc_l(int _reg, X64Reg acl, bool sign)
{
// 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)
{
// 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
void DSPEmitter::get_acc_m(int _reg, X64Reg acm, bool sign)
{
// 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
void DSPEmitter::set_acc_m(int _reg, const OpArg& arg)
{
// 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
void DSPEmitter::get_acc_h(int _reg, X64Reg ach, bool sign)
{
// 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
void DSPEmitter::set_acc_h(int _reg, const OpArg& arg)
{
// 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
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];
gpr.ReadReg(_reg + DSP_REG_AX0_32, acx, SIGN);
m_gpr.ReadReg(_reg + DSP_REG_AX0_32, acx, SIGN);
}
// Returns s16 in EAX
void DSPEmitter::get_ax_l(int _reg, X64Reg axl)
{
// 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
void DSPEmitter::get_ax_h(int _reg, X64Reg axh)
{
// 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