XEmitter: Add enum class Jump
Replace the bool parameter force5bytes in J, JMP, and J_CC with an enum class Jump::Short/Near. Many callers set that parameter to the literal 'true', which was unclear if you didn't already know what it did.
This commit is contained in:
parent
c8559a7933
commit
4c2759f541
|
@ -432,14 +432,14 @@ void XEmitter::Rex(int w, int r, int x, int b)
|
||||||
Write8(rx);
|
Write8(rx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void XEmitter::JMP(const u8* addr, bool force5Bytes)
|
void XEmitter::JMP(const u8* addr, const Jump jump)
|
||||||
{
|
{
|
||||||
u64 fn = (u64)addr;
|
u64 fn = (u64)addr;
|
||||||
if (!force5Bytes)
|
if (jump == Jump::Short)
|
||||||
{
|
{
|
||||||
s64 distance = (s64)(fn - ((u64)code + 2));
|
s64 distance = (s64)(fn - ((u64)code + 2));
|
||||||
ASSERT_MSG(DYNA_REC, distance >= -0x80 && distance < 0x80,
|
ASSERT_MSG(DYNA_REC, distance >= -0x80 && distance < 0x80,
|
||||||
"Jump target too far away ({}), needs force5Bytes = true", distance);
|
"Jump::Short target too far away ({}), needs Jump::Near", distance);
|
||||||
// 8 bits will do
|
// 8 bits will do
|
||||||
Write8(0xEB);
|
Write8(0xEB);
|
||||||
Write8((u8)(s8)distance);
|
Write8((u8)(s8)distance);
|
||||||
|
@ -449,7 +449,7 @@ void XEmitter::JMP(const u8* addr, bool force5Bytes)
|
||||||
s64 distance = (s64)(fn - ((u64)code + 5));
|
s64 distance = (s64)(fn - ((u64)code + 5));
|
||||||
|
|
||||||
ASSERT_MSG(DYNA_REC, distance >= -0x80000000LL && distance < 0x80000000LL,
|
ASSERT_MSG(DYNA_REC, distance >= -0x80000000LL && distance < 0x80000000LL,
|
||||||
"Jump target too far away ({}), needs indirect register", distance);
|
"Jump::Near target too far away ({}), needs indirect register", distance);
|
||||||
Write8(0xE9);
|
Write8(0xE9);
|
||||||
Write32((u32)(s32)distance);
|
Write32((u32)(s32)distance);
|
||||||
}
|
}
|
||||||
|
@ -510,12 +510,13 @@ FixupBranch XEmitter::CALL()
|
||||||
return branch;
|
return branch;
|
||||||
}
|
}
|
||||||
|
|
||||||
FixupBranch XEmitter::J(bool force5bytes)
|
FixupBranch XEmitter::J(const Jump jump)
|
||||||
{
|
{
|
||||||
FixupBranch branch;
|
FixupBranch branch;
|
||||||
branch.type = force5bytes ? FixupBranch::Type::Branch32Bit : FixupBranch::Type::Branch8Bit;
|
const bool is_near_jump = jump == Jump::Near;
|
||||||
branch.ptr = code + (force5bytes ? 5 : 2);
|
branch.type = is_near_jump ? FixupBranch::Type::Branch32Bit : FixupBranch::Type::Branch8Bit;
|
||||||
if (!force5bytes)
|
branch.ptr = code + (is_near_jump ? 5 : 2);
|
||||||
|
if (!is_near_jump)
|
||||||
{
|
{
|
||||||
// 8 bits will do
|
// 8 bits will do
|
||||||
Write8(0xEB);
|
Write8(0xEB);
|
||||||
|
@ -536,12 +537,13 @@ FixupBranch XEmitter::J(bool force5bytes)
|
||||||
return branch;
|
return branch;
|
||||||
}
|
}
|
||||||
|
|
||||||
FixupBranch XEmitter::J_CC(CCFlags conditionCode, bool force5bytes)
|
FixupBranch XEmitter::J_CC(CCFlags conditionCode, const Jump jump)
|
||||||
{
|
{
|
||||||
FixupBranch branch;
|
FixupBranch branch;
|
||||||
branch.type = force5bytes ? FixupBranch::Type::Branch32Bit : FixupBranch::Type::Branch8Bit;
|
const bool is_near_jump = jump == Jump::Near;
|
||||||
branch.ptr = code + (force5bytes ? 6 : 2);
|
branch.type = is_near_jump ? FixupBranch::Type::Branch32Bit : FixupBranch::Type::Branch8Bit;
|
||||||
if (!force5bytes)
|
branch.ptr = code + (is_near_jump ? 6 : 2);
|
||||||
|
if (!is_near_jump)
|
||||||
{
|
{
|
||||||
// 8 bits will do
|
// 8 bits will do
|
||||||
Write8(0x70 + conditionCode);
|
Write8(0x70 + conditionCode);
|
||||||
|
@ -592,14 +594,14 @@ void XEmitter::SetJumpTarget(const FixupBranch& branch)
|
||||||
{
|
{
|
||||||
s64 distance = (s64)(code - branch.ptr);
|
s64 distance = (s64)(code - branch.ptr);
|
||||||
ASSERT_MSG(DYNA_REC, distance >= -0x80 && distance < 0x80,
|
ASSERT_MSG(DYNA_REC, distance >= -0x80 && distance < 0x80,
|
||||||
"Jump target too far away ({}), needs force5Bytes = true", distance);
|
"Jump::Short target too far away ({}), needs Jump::Near", distance);
|
||||||
branch.ptr[-1] = (u8)(s8)distance;
|
branch.ptr[-1] = (u8)(s8)distance;
|
||||||
}
|
}
|
||||||
else if (branch.type == FixupBranch::Type::Branch32Bit)
|
else if (branch.type == FixupBranch::Type::Branch32Bit)
|
||||||
{
|
{
|
||||||
s64 distance = (s64)(code - branch.ptr);
|
s64 distance = (s64)(code - branch.ptr);
|
||||||
ASSERT_MSG(DYNA_REC, distance >= -0x80000000LL && distance < 0x80000000LL,
|
ASSERT_MSG(DYNA_REC, distance >= -0x80000000LL && distance < 0x80000000LL,
|
||||||
"Jump target too far away ({}), needs indirect register", distance);
|
"Jump::Near target too far away ({}), needs indirect register", distance);
|
||||||
|
|
||||||
s32 valid_distance = static_cast<s32>(distance);
|
s32 valid_distance = static_cast<s32>(distance);
|
||||||
std::memcpy(&branch.ptr[-4], &valid_distance, sizeof(s32));
|
std::memcpy(&branch.ptr[-4], &valid_distance, sizeof(s32));
|
||||||
|
|
|
@ -440,13 +440,19 @@ public:
|
||||||
void PUSHF();
|
void PUSHF();
|
||||||
void POPF();
|
void POPF();
|
||||||
|
|
||||||
|
enum class Jump
|
||||||
|
{
|
||||||
|
Short,
|
||||||
|
Near,
|
||||||
|
};
|
||||||
|
|
||||||
// Flow control
|
// Flow control
|
||||||
void RET();
|
void RET();
|
||||||
void RET_FAST();
|
void RET_FAST();
|
||||||
void UD2();
|
void UD2();
|
||||||
FixupBranch J(bool force5bytes = false);
|
FixupBranch J(Jump jump = Jump::Short);
|
||||||
|
|
||||||
void JMP(const u8* addr, bool force5Bytes = false);
|
void JMP(const u8* addr, Jump jump = Jump::Short);
|
||||||
void JMPptr(const OpArg& arg);
|
void JMPptr(const OpArg& arg);
|
||||||
void JMPself(); // infinite loop!
|
void JMPself(); // infinite loop!
|
||||||
#ifdef CALL
|
#ifdef CALL
|
||||||
|
@ -456,7 +462,7 @@ public:
|
||||||
FixupBranch CALL();
|
FixupBranch CALL();
|
||||||
void CALLptr(OpArg arg);
|
void CALLptr(OpArg arg);
|
||||||
|
|
||||||
FixupBranch J_CC(CCFlags conditionCode, bool force5bytes = false);
|
FixupBranch J_CC(CCFlags conditionCode, Jump jump = Jump::Short);
|
||||||
void J_CC(CCFlags conditionCode, const u8* addr);
|
void J_CC(CCFlags conditionCode, const u8* addr);
|
||||||
|
|
||||||
void SetJumpTarget(const FixupBranch& branch);
|
void SetJumpTarget(const FixupBranch& branch);
|
||||||
|
|
|
@ -109,7 +109,7 @@ void DSPEmitter::checkExceptions(u32 retval)
|
||||||
{
|
{
|
||||||
// Check for interrupts and exceptions
|
// Check for interrupts and exceptions
|
||||||
TEST(8, M_SDSP_exceptions(), Imm8(0xff));
|
TEST(8, M_SDSP_exceptions(), Imm8(0xff));
|
||||||
FixupBranch skipCheck = J_CC(CC_Z, true);
|
FixupBranch skipCheck = J_CC(CC_Z, Jump::Near);
|
||||||
|
|
||||||
MOV(16, M_SDSP_pc(), Imm16(m_compile_pc));
|
MOV(16, M_SDSP_pc(), Imm16(m_compile_pc));
|
||||||
|
|
||||||
|
@ -117,7 +117,7 @@ void DSPEmitter::checkExceptions(u32 retval)
|
||||||
m_gpr.SaveRegs();
|
m_gpr.SaveRegs();
|
||||||
ABI_CallFunctionP(CheckExceptionsThunk, &m_dsp_core);
|
ABI_CallFunctionP(CheckExceptionsThunk, &m_dsp_core);
|
||||||
MOV(32, R(EAX), Imm32(retval));
|
MOV(32, R(EAX), Imm32(retval));
|
||||||
JMP(m_return_dispatcher, true);
|
JMP(m_return_dispatcher, Jump::Near);
|
||||||
m_gpr.LoadRegs(false);
|
m_gpr.LoadRegs(false);
|
||||||
m_gpr.FlushRegs(c, false);
|
m_gpr.FlushRegs(c, false);
|
||||||
|
|
||||||
|
@ -265,11 +265,11 @@ void DSPEmitter::Compile(u16 start_addr)
|
||||||
{
|
{
|
||||||
MOVZX(32, 16, EAX, M_SDSP_r_st(2));
|
MOVZX(32, 16, EAX, M_SDSP_r_st(2));
|
||||||
TEST(32, R(EAX), R(EAX));
|
TEST(32, R(EAX), R(EAX));
|
||||||
FixupBranch rLoopAddressExit = J_CC(CC_LE, true);
|
FixupBranch rLoopAddressExit = J_CC(CC_LE, Jump::Near);
|
||||||
|
|
||||||
MOVZX(32, 16, EAX, M_SDSP_r_st(3));
|
MOVZX(32, 16, EAX, M_SDSP_r_st(3));
|
||||||
TEST(32, R(EAX), R(EAX));
|
TEST(32, R(EAX), R(EAX));
|
||||||
FixupBranch rLoopCounterExit = J_CC(CC_LE, true);
|
FixupBranch rLoopCounterExit = J_CC(CC_LE, Jump::Near);
|
||||||
|
|
||||||
if (!opcode->branch)
|
if (!opcode->branch)
|
||||||
{
|
{
|
||||||
|
@ -290,7 +290,7 @@ void DSPEmitter::Compile(u16 start_addr)
|
||||||
{
|
{
|
||||||
MOV(16, R(EAX), Imm16(m_block_size[start_addr]));
|
MOV(16, R(EAX), Imm16(m_block_size[start_addr]));
|
||||||
}
|
}
|
||||||
JMP(m_return_dispatcher, true);
|
JMP(m_return_dispatcher, Jump::Near);
|
||||||
m_gpr.LoadRegs(false);
|
m_gpr.LoadRegs(false);
|
||||||
m_gpr.FlushRegs(c, false);
|
m_gpr.FlushRegs(c, false);
|
||||||
|
|
||||||
|
@ -313,7 +313,7 @@ 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_SDSP_pc());
|
MOV(16, R(AX), M_SDSP_pc());
|
||||||
CMP(16, R(AX), Imm16(m_compile_pc));
|
CMP(16, R(AX), Imm16(m_compile_pc));
|
||||||
FixupBranch rNoBranch = J_CC(CC_Z, true);
|
FixupBranch rNoBranch = J_CC(CC_Z, Jump::Near);
|
||||||
|
|
||||||
DSPJitRegCache c(m_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
|
||||||
|
@ -326,7 +326,7 @@ void DSPEmitter::Compile(u16 start_addr)
|
||||||
{
|
{
|
||||||
MOV(16, R(EAX), Imm16(m_block_size[start_addr]));
|
MOV(16, R(EAX), Imm16(m_block_size[start_addr]));
|
||||||
}
|
}
|
||||||
JMP(m_return_dispatcher, true);
|
JMP(m_return_dispatcher, Jump::Near);
|
||||||
m_gpr.LoadRegs(false);
|
m_gpr.LoadRegs(false);
|
||||||
m_gpr.FlushRegs(c, false);
|
m_gpr.FlushRegs(c, false);
|
||||||
|
|
||||||
|
@ -389,7 +389,7 @@ void DSPEmitter::Compile(u16 start_addr)
|
||||||
{
|
{
|
||||||
MOV(16, R(EAX), Imm16(m_block_size[start_addr]));
|
MOV(16, R(EAX), Imm16(m_block_size[start_addr]));
|
||||||
}
|
}
|
||||||
JMP(m_return_dispatcher, true);
|
JMP(m_return_dispatcher, Jump::Near);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DSPEmitter::CompileCurrent(DSPEmitter& emitter)
|
void DSPEmitter::CompileCurrent(DSPEmitter& emitter)
|
||||||
|
|
|
@ -91,7 +91,7 @@ void DSPEmitter::ReJitConditional(const UDSPInstruction opc,
|
||||||
flag = CC_NZ;
|
flag = CC_NZ;
|
||||||
else // Odd conditions run if the bit IS NOT zero, so jump if it IS zero
|
else // Odd conditions run if the bit IS NOT zero, so jump if it IS zero
|
||||||
flag = CC_Z;
|
flag = CC_Z;
|
||||||
FixupBranch skip_code = J_CC(flag, true);
|
FixupBranch skip_code = J_CC(flag, Jump::Near);
|
||||||
(this->*conditional_fn)(opc);
|
(this->*conditional_fn)(opc);
|
||||||
m_gpr.FlushRegs(c1);
|
m_gpr.FlushRegs(c1);
|
||||||
SetJumpTarget(skip_code);
|
SetJumpTarget(skip_code);
|
||||||
|
@ -109,7 +109,7 @@ void DSPEmitter::WriteBranchExit()
|
||||||
{
|
{
|
||||||
MOV(16, R(EAX), Imm16(m_block_size[m_start_address]));
|
MOV(16, R(EAX), Imm16(m_block_size[m_start_address]));
|
||||||
}
|
}
|
||||||
JMP(m_return_dispatcher, true);
|
JMP(m_return_dispatcher, Jump::Near);
|
||||||
m_gpr.LoadRegs(false);
|
m_gpr.LoadRegs(false);
|
||||||
m_gpr.FlushRegs(c, false);
|
m_gpr.FlushRegs(c, false);
|
||||||
}
|
}
|
||||||
|
@ -130,7 +130,7 @@ void DSPEmitter::WriteBlockLink(u16 dest)
|
||||||
|
|
||||||
SUB(16, R(ECX), Imm16(m_block_size[m_start_address]));
|
SUB(16, R(ECX), Imm16(m_block_size[m_start_address]));
|
||||||
MOV(16, MatR(RAX), R(ECX));
|
MOV(16, MatR(RAX), R(ECX));
|
||||||
JMP(m_block_links[dest], true);
|
JMP(m_block_links[dest], Jump::Near);
|
||||||
SetJumpTarget(notEnoughCycles);
|
SetJumpTarget(notEnoughCycles);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -322,17 +322,17 @@ void DSPEmitter::HandleLoop()
|
||||||
MOVZX(32, 16, ECX, M_SDSP_r_st(3));
|
MOVZX(32, 16, ECX, M_SDSP_r_st(3));
|
||||||
|
|
||||||
TEST(32, R(RCX), R(RCX));
|
TEST(32, R(RCX), R(RCX));
|
||||||
FixupBranch rLoopCntG = J_CC(CC_E, true);
|
FixupBranch rLoopCntG = J_CC(CC_E, Jump::Near);
|
||||||
CMP(16, R(RAX), Imm16(m_compile_pc - 1));
|
CMP(16, R(RAX), Imm16(m_compile_pc - 1));
|
||||||
FixupBranch rLoopAddrG = J_CC(CC_NE, true);
|
FixupBranch rLoopAddrG = J_CC(CC_NE, Jump::Near);
|
||||||
|
|
||||||
SUB(16, M_SDSP_r_st(3), Imm16(1));
|
SUB(16, M_SDSP_r_st(3), Imm16(1));
|
||||||
CMP(16, M_SDSP_r_st(3), Imm16(0));
|
CMP(16, M_SDSP_r_st(3), Imm16(0));
|
||||||
|
|
||||||
FixupBranch loadStack = J_CC(CC_E, true);
|
FixupBranch loadStack = J_CC(CC_E, Jump::Near);
|
||||||
MOVZX(32, 16, ECX, M_SDSP_r_st(0));
|
MOVZX(32, 16, ECX, M_SDSP_r_st(0));
|
||||||
MOV(16, M_SDSP_pc(), R(RCX));
|
MOV(16, M_SDSP_pc(), R(RCX));
|
||||||
FixupBranch loopUpdated = J(true);
|
FixupBranch loopUpdated = J(Jump::Near);
|
||||||
|
|
||||||
SetJumpTarget(loadStack);
|
SetJumpTarget(loadStack);
|
||||||
DSPJitRegCache c(m_gpr);
|
DSPJitRegCache c(m_gpr);
|
||||||
|
@ -363,7 +363,7 @@ void DSPEmitter::loop(const UDSPInstruction opc)
|
||||||
|
|
||||||
TEST(16, R(EDX), R(EDX));
|
TEST(16, R(EDX), R(EDX));
|
||||||
DSPJitRegCache c(m_gpr);
|
DSPJitRegCache c(m_gpr);
|
||||||
FixupBranch cnt = J_CC(CC_Z, true);
|
FixupBranch cnt = J_CC(CC_Z, Jump::Near);
|
||||||
dsp_reg_store_stack(StackRegister::LoopCounter);
|
dsp_reg_store_stack(StackRegister::LoopCounter);
|
||||||
MOV(16, R(RDX), Imm16(m_compile_pc + 1));
|
MOV(16, R(RDX), Imm16(m_compile_pc + 1));
|
||||||
dsp_reg_store_stack(StackRegister::Call);
|
dsp_reg_store_stack(StackRegister::Call);
|
||||||
|
@ -371,7 +371,7 @@ void DSPEmitter::loop(const UDSPInstruction opc)
|
||||||
dsp_reg_store_stack(StackRegister::LoopAddress);
|
dsp_reg_store_stack(StackRegister::LoopAddress);
|
||||||
m_gpr.FlushRegs(c);
|
m_gpr.FlushRegs(c);
|
||||||
MOV(16, M_SDSP_pc(), Imm16(m_compile_pc + 1));
|
MOV(16, M_SDSP_pc(), Imm16(m_compile_pc + 1));
|
||||||
FixupBranch exit = J(true);
|
FixupBranch exit = J(Jump::Near);
|
||||||
|
|
||||||
SetJumpTarget(cnt);
|
SetJumpTarget(cnt);
|
||||||
// dsp_skip_inst();
|
// dsp_skip_inst();
|
||||||
|
@ -433,7 +433,7 @@ void DSPEmitter::bloop(const UDSPInstruction opc)
|
||||||
|
|
||||||
TEST(16, R(EDX), R(EDX));
|
TEST(16, R(EDX), R(EDX));
|
||||||
DSPJitRegCache c(m_gpr);
|
DSPJitRegCache c(m_gpr);
|
||||||
FixupBranch cnt = J_CC(CC_Z, true);
|
FixupBranch cnt = J_CC(CC_Z, Jump::Near);
|
||||||
dsp_reg_store_stack(StackRegister::LoopCounter);
|
dsp_reg_store_stack(StackRegister::LoopCounter);
|
||||||
MOV(16, R(RDX), Imm16(m_compile_pc + 2));
|
MOV(16, R(RDX), Imm16(m_compile_pc + 2));
|
||||||
dsp_reg_store_stack(StackRegister::Call);
|
dsp_reg_store_stack(StackRegister::Call);
|
||||||
|
@ -441,7 +441,7 @@ void DSPEmitter::bloop(const UDSPInstruction opc)
|
||||||
dsp_reg_store_stack(StackRegister::LoopAddress);
|
dsp_reg_store_stack(StackRegister::LoopAddress);
|
||||||
MOV(16, M_SDSP_pc(), Imm16(m_compile_pc + 2));
|
MOV(16, M_SDSP_pc(), Imm16(m_compile_pc + 2));
|
||||||
m_gpr.FlushRegs(c, true);
|
m_gpr.FlushRegs(c, true);
|
||||||
FixupBranch exit = J(true);
|
FixupBranch exit = J(Jump::Near);
|
||||||
|
|
||||||
SetJumpTarget(cnt);
|
SetJumpTarget(cnt);
|
||||||
// g_dsp.pc = loop_pc;
|
// g_dsp.pc = loop_pc;
|
||||||
|
|
|
@ -383,10 +383,10 @@ void DSPEmitter::ld(const UDSPInstruction opc)
|
||||||
m_gpr.PutXReg(tmp);
|
m_gpr.PutXReg(tmp);
|
||||||
DSPJitRegCache c(m_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, Jump::Near);
|
||||||
pushExtValueFromMem2((rreg << 1) + DSP_REG_AXL1, sreg);
|
pushExtValueFromMem2((rreg << 1) + DSP_REG_AXL1, sreg);
|
||||||
m_gpr.FlushRegs(c);
|
m_gpr.FlushRegs(c);
|
||||||
FixupBranch after = J(true);
|
FixupBranch after = J(Jump::Near);
|
||||||
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);
|
||||||
m_gpr.FlushRegs(c);
|
m_gpr.FlushRegs(c);
|
||||||
|
@ -417,10 +417,10 @@ void DSPEmitter::ldax(const UDSPInstruction opc)
|
||||||
m_gpr.PutXReg(tmp);
|
m_gpr.PutXReg(tmp);
|
||||||
DSPJitRegCache c(m_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, Jump::Near);
|
||||||
pushExtValueFromMem2(rreg + DSP_REG_AXL0, sreg);
|
pushExtValueFromMem2(rreg + DSP_REG_AXL0, sreg);
|
||||||
m_gpr.FlushRegs(c);
|
m_gpr.FlushRegs(c);
|
||||||
FixupBranch after = J(true); // else
|
FixupBranch after = J(Jump::Near); // else
|
||||||
SetJumpTarget(not_equal);
|
SetJumpTarget(not_equal);
|
||||||
pushExtValueFromMem2(rreg + DSP_REG_AXL0, DSP_REG_AR3);
|
pushExtValueFromMem2(rreg + DSP_REG_AXL0, DSP_REG_AR3);
|
||||||
m_gpr.FlushRegs(c);
|
m_gpr.FlushRegs(c);
|
||||||
|
@ -449,10 +449,10 @@ void DSPEmitter::ldn(const UDSPInstruction opc)
|
||||||
m_gpr.PutXReg(tmp);
|
m_gpr.PutXReg(tmp);
|
||||||
DSPJitRegCache c(m_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, Jump::Near);
|
||||||
pushExtValueFromMem2((rreg << 1) + DSP_REG_AXL1, sreg);
|
pushExtValueFromMem2((rreg << 1) + DSP_REG_AXL1, sreg);
|
||||||
m_gpr.FlushRegs(c);
|
m_gpr.FlushRegs(c);
|
||||||
FixupBranch after = J(true);
|
FixupBranch after = J(Jump::Near);
|
||||||
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);
|
||||||
m_gpr.FlushRegs(c);
|
m_gpr.FlushRegs(c);
|
||||||
|
@ -480,10 +480,10 @@ void DSPEmitter::ldaxn(const UDSPInstruction opc)
|
||||||
m_gpr.PutXReg(tmp);
|
m_gpr.PutXReg(tmp);
|
||||||
DSPJitRegCache c(m_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, Jump::Near);
|
||||||
pushExtValueFromMem2(rreg + DSP_REG_AXL0, sreg);
|
pushExtValueFromMem2(rreg + DSP_REG_AXL0, sreg);
|
||||||
m_gpr.FlushRegs(c);
|
m_gpr.FlushRegs(c);
|
||||||
FixupBranch after = J(true); // else
|
FixupBranch after = J(Jump::Near); // else
|
||||||
SetJumpTarget(not_equal);
|
SetJumpTarget(not_equal);
|
||||||
pushExtValueFromMem2(rreg + DSP_REG_AXL0, DSP_REG_AR3);
|
pushExtValueFromMem2(rreg + DSP_REG_AXL0, DSP_REG_AR3);
|
||||||
m_gpr.FlushRegs(c);
|
m_gpr.FlushRegs(c);
|
||||||
|
@ -512,10 +512,10 @@ void DSPEmitter::ldm(const UDSPInstruction opc)
|
||||||
m_gpr.PutXReg(tmp);
|
m_gpr.PutXReg(tmp);
|
||||||
DSPJitRegCache c(m_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, Jump::Near);
|
||||||
pushExtValueFromMem2((rreg << 1) + DSP_REG_AXL1, sreg);
|
pushExtValueFromMem2((rreg << 1) + DSP_REG_AXL1, sreg);
|
||||||
m_gpr.FlushRegs(c);
|
m_gpr.FlushRegs(c);
|
||||||
FixupBranch after = J(true);
|
FixupBranch after = J(Jump::Near);
|
||||||
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);
|
||||||
m_gpr.FlushRegs(c);
|
m_gpr.FlushRegs(c);
|
||||||
|
@ -543,10 +543,10 @@ void DSPEmitter::ldaxm(const UDSPInstruction opc)
|
||||||
m_gpr.PutXReg(tmp);
|
m_gpr.PutXReg(tmp);
|
||||||
DSPJitRegCache c(m_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, Jump::Near);
|
||||||
pushExtValueFromMem2(rreg + DSP_REG_AXL0, sreg);
|
pushExtValueFromMem2(rreg + DSP_REG_AXL0, sreg);
|
||||||
m_gpr.FlushRegs(c);
|
m_gpr.FlushRegs(c);
|
||||||
FixupBranch after = J(true); // else
|
FixupBranch after = J(Jump::Near); // else
|
||||||
SetJumpTarget(not_equal);
|
SetJumpTarget(not_equal);
|
||||||
pushExtValueFromMem2(rreg + DSP_REG_AXL0, DSP_REG_AR3);
|
pushExtValueFromMem2(rreg + DSP_REG_AXL0, DSP_REG_AR3);
|
||||||
m_gpr.FlushRegs(c);
|
m_gpr.FlushRegs(c);
|
||||||
|
@ -575,10 +575,10 @@ void DSPEmitter::ldnm(const UDSPInstruction opc)
|
||||||
m_gpr.PutXReg(tmp);
|
m_gpr.PutXReg(tmp);
|
||||||
DSPJitRegCache c(m_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, Jump::Near);
|
||||||
pushExtValueFromMem2((rreg << 1) + DSP_REG_AXL1, sreg);
|
pushExtValueFromMem2((rreg << 1) + DSP_REG_AXL1, sreg);
|
||||||
m_gpr.FlushRegs(c);
|
m_gpr.FlushRegs(c);
|
||||||
FixupBranch after = J(true);
|
FixupBranch after = J(Jump::Near);
|
||||||
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);
|
||||||
m_gpr.FlushRegs(c);
|
m_gpr.FlushRegs(c);
|
||||||
|
@ -606,10 +606,10 @@ void DSPEmitter::ldaxnm(const UDSPInstruction opc)
|
||||||
m_gpr.PutXReg(tmp);
|
m_gpr.PutXReg(tmp);
|
||||||
DSPJitRegCache c(m_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, Jump::Near);
|
||||||
pushExtValueFromMem2(rreg + DSP_REG_AXL0, sreg);
|
pushExtValueFromMem2(rreg + DSP_REG_AXL0, sreg);
|
||||||
m_gpr.FlushRegs(c);
|
m_gpr.FlushRegs(c);
|
||||||
FixupBranch after = J(true); // else
|
FixupBranch after = J(Jump::Near); // else
|
||||||
SetJumpTarget(not_equal);
|
SetJumpTarget(not_equal);
|
||||||
pushExtValueFromMem2(rreg + DSP_REG_AXL0, DSP_REG_AR3);
|
pushExtValueFromMem2(rreg + DSP_REG_AXL0, DSP_REG_AR3);
|
||||||
m_gpr.FlushRegs(c);
|
m_gpr.FlushRegs(c);
|
||||||
|
@ -670,7 +670,7 @@ void DSPEmitter::popExtValueToReg()
|
||||||
if (m_store_index >= DSP_REG_ACM0 && m_store_index2 == -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, Jump::Near);
|
||||||
DSPJitRegCache c(m_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)
|
||||||
//{
|
//{
|
||||||
|
|
|
@ -84,7 +84,7 @@ void DSPEmitter::multiply_mulx(u8 axh0, u8 axh1)
|
||||||
// prod = (s16)a * (s16)b; //signed
|
// prod = (s16)a * (s16)b; //signed
|
||||||
MOVSX(64, 16, RAX, R(RAX));
|
MOVSX(64, 16, RAX, R(RAX));
|
||||||
IMUL(64, R(RCX));
|
IMUL(64, R(RCX));
|
||||||
FixupBranch signedMul = J(true);
|
FixupBranch signedMul = J(Jump::Near);
|
||||||
|
|
||||||
SetJumpTarget(unsignedMul);
|
SetJumpTarget(unsignedMul);
|
||||||
DSPJitRegCache c(m_gpr);
|
DSPJitRegCache c(m_gpr);
|
||||||
|
|
|
@ -151,7 +151,7 @@ void DSPEmitter::dsp_conditional_extend_accum(int reg)
|
||||||
const OpArg sr_reg = m_gpr.GetReg(DSP_REG_SR);
|
const OpArg sr_reg = m_gpr.GetReg(DSP_REG_SR);
|
||||||
DSPJitRegCache c(m_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, Jump::Near);
|
||||||
// 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.
|
||||||
|
@ -180,7 +180,7 @@ void DSPEmitter::dsp_conditional_extend_accum_imm(int reg, u16 val)
|
||||||
const OpArg sr_reg = m_gpr.GetReg(DSP_REG_SR);
|
const OpArg sr_reg = m_gpr.GetReg(DSP_REG_SR);
|
||||||
DSPJitRegCache c(m_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, Jump::Near);
|
||||||
// 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.
|
||||||
|
@ -227,7 +227,7 @@ void DSPEmitter::dsp_op_read_reg(int reg, Gen::X64Reg host_dreg, RegisterExtensi
|
||||||
|
|
||||||
DSPJitRegCache c(m_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, Jump::Near);
|
||||||
|
|
||||||
MOVSX(64, 32, host_dreg, acc_reg);
|
MOVSX(64, 32, host_dreg, acc_reg);
|
||||||
CMP(64, R(host_dreg), acc_reg);
|
CMP(64, R(host_dreg), acc_reg);
|
||||||
|
@ -491,7 +491,7 @@ void DSPEmitter::dmem_write(X64Reg value)
|
||||||
MOV(64, R(ECX), ImmPtr(m_dsp_core.DSPState().dram));
|
MOV(64, R(ECX), ImmPtr(m_dsp_core.DSPState().dram));
|
||||||
MOV(16, MComplex(ECX, EAX, SCALE_2, 0), R(value));
|
MOV(16, MComplex(ECX, EAX, SCALE_2, 0), R(value));
|
||||||
|
|
||||||
FixupBranch end = J(true);
|
FixupBranch end = J(Jump::Near);
|
||||||
// else if (saddr == 0xf)
|
// else if (saddr == 0xf)
|
||||||
SetJumpTarget(ifx);
|
SetJumpTarget(ifx);
|
||||||
DSPJitRegCache c(m_gpr);
|
DSPJitRegCache c(m_gpr);
|
||||||
|
@ -566,7 +566,7 @@ void DSPEmitter::dmem_read(X64Reg address)
|
||||||
MOV(64, R(ECX), ImmPtr(m_dsp_core.DSPState().dram));
|
MOV(64, R(ECX), ImmPtr(m_dsp_core.DSPState().dram));
|
||||||
MOV(16, R(EAX), MComplex(ECX, address, SCALE_2, 0));
|
MOV(16, R(EAX), MComplex(ECX, address, SCALE_2, 0));
|
||||||
|
|
||||||
FixupBranch end = J(true);
|
FixupBranch end = J(Jump::Near);
|
||||||
SetJumpTarget(dram);
|
SetJumpTarget(dram);
|
||||||
// else if (saddr == 0x1)
|
// else if (saddr == 0x1)
|
||||||
CMP(16, R(address), Imm16(0x1fff));
|
CMP(16, R(address), Imm16(0x1fff));
|
||||||
|
@ -576,7 +576,7 @@ void DSPEmitter::dmem_read(X64Reg address)
|
||||||
MOV(64, R(ECX), ImmPtr(m_dsp_core.DSPState().coef));
|
MOV(64, R(ECX), ImmPtr(m_dsp_core.DSPState().coef));
|
||||||
MOV(16, R(EAX), MComplex(ECX, address, SCALE_2, 0));
|
MOV(16, R(EAX), MComplex(ECX, address, SCALE_2, 0));
|
||||||
|
|
||||||
FixupBranch end2 = J(true);
|
FixupBranch end2 = J(Jump::Near);
|
||||||
SetJumpTarget(ifx);
|
SetJumpTarget(ifx);
|
||||||
// else if (saddr == 0xf)
|
// else if (saddr == 0xf)
|
||||||
// return gdsp_ifx_read(addr);
|
// return gdsp_ifx_read(addr);
|
||||||
|
|
|
@ -203,7 +203,7 @@ bool Jit64::BackPatch(SContext* ctx)
|
||||||
|
|
||||||
// Patch the original memory operation.
|
// Patch the original memory operation.
|
||||||
XEmitter emitter(start, start + info.len);
|
XEmitter emitter(start, start + info.len);
|
||||||
emitter.JMP(trampoline, true);
|
emitter.JMP(trampoline, Jump::Near);
|
||||||
// NOPs become dead code
|
// NOPs become dead code
|
||||||
const u8* end = info.start + info.len;
|
const u8* end = info.start + info.len;
|
||||||
for (const u8* i = emitter.GetCodePtr(); i < end; ++i)
|
for (const u8* i = emitter.GetCodePtr(); i < end; ++i)
|
||||||
|
@ -373,7 +373,7 @@ void Jit64::FallBackToInterpreter(UGeckoInstruction inst)
|
||||||
else if (ShouldHandleFPExceptionForInstruction(js.op))
|
else if (ShouldHandleFPExceptionForInstruction(js.op))
|
||||||
{
|
{
|
||||||
TEST(32, PPCSTATE(Exceptions), Imm32(EXCEPTION_PROGRAM));
|
TEST(32, PPCSTATE(Exceptions), Imm32(EXCEPTION_PROGRAM));
|
||||||
FixupBranch exception = J_CC(CC_NZ, true);
|
FixupBranch exception = J_CC(CC_NZ, Jump::Near);
|
||||||
|
|
||||||
SwitchToFarCode();
|
SwitchToFarCode();
|
||||||
SetJumpTarget(exception);
|
SetJumpTarget(exception);
|
||||||
|
@ -521,11 +521,11 @@ void Jit64::JustWriteExit(u32 destination, bool bl, u32 after)
|
||||||
// Perform downcount flag check, followed by the requested exit
|
// Perform downcount flag check, followed by the requested exit
|
||||||
if (bl)
|
if (bl)
|
||||||
{
|
{
|
||||||
FixupBranch do_timing = J_CC(CC_LE, true);
|
FixupBranch do_timing = J_CC(CC_LE, Jump::Near);
|
||||||
SwitchToFarCode();
|
SwitchToFarCode();
|
||||||
SetJumpTarget(do_timing);
|
SetJumpTarget(do_timing);
|
||||||
CALL(asm_routines.do_timing);
|
CALL(asm_routines.do_timing);
|
||||||
FixupBranch after_fixup = J(true);
|
FixupBranch after_fixup = J(Jump::Near);
|
||||||
SwitchToNearCode();
|
SwitchToNearCode();
|
||||||
|
|
||||||
linkData.exitPtrs = GetWritableCodePtr();
|
linkData.exitPtrs = GetWritableCodePtr();
|
||||||
|
@ -540,7 +540,7 @@ void Jit64::JustWriteExit(u32 destination, bool bl, u32 after)
|
||||||
J_CC(CC_LE, asm_routines.do_timing);
|
J_CC(CC_LE, asm_routines.do_timing);
|
||||||
|
|
||||||
linkData.exitPtrs = GetWritableCodePtr();
|
linkData.exitPtrs = GetWritableCodePtr();
|
||||||
JMP(asm_routines.dispatcher_no_timing_check, true);
|
JMP(asm_routines.dispatcher_no_timing_check, Jump::Near);
|
||||||
}
|
}
|
||||||
|
|
||||||
b->linkData.push_back(linkData);
|
b->linkData.push_back(linkData);
|
||||||
|
@ -568,7 +568,7 @@ void Jit64::WriteExitDestInRSCRATCH(bool bl, u32 after)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
JMP(asm_routines.dispatcher, true);
|
JMP(asm_routines.dispatcher, Jump::Near);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -599,7 +599,7 @@ void Jit64::WriteRfiExitDestInRSCRATCH()
|
||||||
ABI_CallFunctionP(PowerPC::CheckExceptionsFromJIT, &m_system.GetPowerPC());
|
ABI_CallFunctionP(PowerPC::CheckExceptionsFromJIT, &m_system.GetPowerPC());
|
||||||
ABI_PopRegistersAndAdjustStack({}, 0);
|
ABI_PopRegistersAndAdjustStack({}, 0);
|
||||||
SUB(32, PPCSTATE(downcount), Imm32(js.downcountAmount));
|
SUB(32, PPCSTATE(downcount), Imm32(js.downcountAmount));
|
||||||
JMP(asm_routines.dispatcher, true);
|
JMP(asm_routines.dispatcher, Jump::Near);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Jit64::WriteIdleExit(u32 destination)
|
void Jit64::WriteIdleExit(u32 destination)
|
||||||
|
@ -620,7 +620,7 @@ void Jit64::WriteExceptionExit()
|
||||||
ABI_CallFunctionP(PowerPC::CheckExceptionsFromJIT, &m_system.GetPowerPC());
|
ABI_CallFunctionP(PowerPC::CheckExceptionsFromJIT, &m_system.GetPowerPC());
|
||||||
ABI_PopRegistersAndAdjustStack({}, 0);
|
ABI_PopRegistersAndAdjustStack({}, 0);
|
||||||
SUB(32, PPCSTATE(downcount), Imm32(js.downcountAmount));
|
SUB(32, PPCSTATE(downcount), Imm32(js.downcountAmount));
|
||||||
JMP(asm_routines.dispatcher, true);
|
JMP(asm_routines.dispatcher, Jump::Near);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Jit64::WriteExternalExceptionExit()
|
void Jit64::WriteExternalExceptionExit()
|
||||||
|
@ -632,7 +632,7 @@ void Jit64::WriteExternalExceptionExit()
|
||||||
ABI_CallFunctionP(PowerPC::CheckExternalExceptionsFromJIT, &m_system.GetPowerPC());
|
ABI_CallFunctionP(PowerPC::CheckExternalExceptionsFromJIT, &m_system.GetPowerPC());
|
||||||
ABI_PopRegistersAndAdjustStack({}, 0);
|
ABI_PopRegistersAndAdjustStack({}, 0);
|
||||||
SUB(32, PPCSTATE(downcount), Imm32(js.downcountAmount));
|
SUB(32, PPCSTATE(downcount), Imm32(js.downcountAmount));
|
||||||
JMP(asm_routines.dispatcher, true);
|
JMP(asm_routines.dispatcher, Jump::Near);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Jit64::Run()
|
void Jit64::Run()
|
||||||
|
@ -883,7 +883,7 @@ bool Jit64::DoJit(u32 em_address, JitBlock* b, u32 nextPC)
|
||||||
ABI_CallFunctionPC(JitInterface::CompileExceptionCheckFromJIT, &m_system.GetJitInterface(),
|
ABI_CallFunctionPC(JitInterface::CompileExceptionCheckFromJIT, &m_system.GetJitInterface(),
|
||||||
static_cast<u32>(JitInterface::ExceptionType::PairedQuantize));
|
static_cast<u32>(JitInterface::ExceptionType::PairedQuantize));
|
||||||
ABI_PopRegistersAndAdjustStack({}, 0);
|
ABI_PopRegistersAndAdjustStack({}, 0);
|
||||||
JMP(asm_routines.dispatcher_no_check, true);
|
JMP(asm_routines.dispatcher_no_check, Jump::Near);
|
||||||
SwitchToNearCode();
|
SwitchToNearCode();
|
||||||
|
|
||||||
// Insert a check that the GQRs are still the value we expect at
|
// Insert a check that the GQRs are still the value we expect at
|
||||||
|
@ -950,17 +950,17 @@ bool Jit64::DoJit(u32 em_address, JitBlock* b, u32 nextPC)
|
||||||
if (gatherPipeIntCheck)
|
if (gatherPipeIntCheck)
|
||||||
{
|
{
|
||||||
TEST(32, PPCSTATE(Exceptions), Imm32(EXCEPTION_EXTERNAL_INT));
|
TEST(32, PPCSTATE(Exceptions), Imm32(EXCEPTION_EXTERNAL_INT));
|
||||||
FixupBranch extException = J_CC(CC_NZ, true);
|
FixupBranch extException = J_CC(CC_NZ, Jump::Near);
|
||||||
|
|
||||||
SwitchToFarCode();
|
SwitchToFarCode();
|
||||||
SetJumpTarget(extException);
|
SetJumpTarget(extException);
|
||||||
TEST(32, PPCSTATE(msr), Imm32(0x0008000));
|
TEST(32, PPCSTATE(msr), Imm32(0x0008000));
|
||||||
FixupBranch noExtIntEnable = J_CC(CC_Z, true);
|
FixupBranch noExtIntEnable = J_CC(CC_Z, Jump::Near);
|
||||||
MOV(64, R(RSCRATCH), ImmPtr(&m_system.GetProcessorInterface().m_interrupt_cause));
|
MOV(64, R(RSCRATCH), ImmPtr(&m_system.GetProcessorInterface().m_interrupt_cause));
|
||||||
TEST(32, MatR(RSCRATCH),
|
TEST(32, MatR(RSCRATCH),
|
||||||
Imm32(ProcessorInterface::INT_CAUSE_CP | ProcessorInterface::INT_CAUSE_PE_TOKEN |
|
Imm32(ProcessorInterface::INT_CAUSE_CP | ProcessorInterface::INT_CAUSE_PE_TOKEN |
|
||||||
ProcessorInterface::INT_CAUSE_PE_FINISH));
|
ProcessorInterface::INT_CAUSE_PE_FINISH));
|
||||||
FixupBranch noCPInt = J_CC(CC_Z, true);
|
FixupBranch noCPInt = J_CC(CC_Z, Jump::Near);
|
||||||
|
|
||||||
{
|
{
|
||||||
RCForkGuard gpr_guard = gpr.Fork();
|
RCForkGuard gpr_guard = gpr.Fork();
|
||||||
|
@ -986,7 +986,7 @@ bool Jit64::DoJit(u32 em_address, JitBlock* b, u32 nextPC)
|
||||||
{
|
{
|
||||||
// This instruction uses FPU - needs to add FP exception bailout
|
// This instruction uses FPU - needs to add FP exception bailout
|
||||||
TEST(32, PPCSTATE(msr), Imm32(1 << 13)); // Test FP enabled bit
|
TEST(32, PPCSTATE(msr), Imm32(1 << 13)); // Test FP enabled bit
|
||||||
FixupBranch b1 = J_CC(CC_Z, true);
|
FixupBranch b1 = J_CC(CC_Z, Jump::Near);
|
||||||
|
|
||||||
SwitchToFarCode();
|
SwitchToFarCode();
|
||||||
SetJumpTarget(b1);
|
SetJumpTarget(b1);
|
||||||
|
@ -1027,7 +1027,7 @@ bool Jit64::DoJit(u32 em_address, JitBlock* b, u32 nextPC)
|
||||||
Cleanup();
|
Cleanup();
|
||||||
MOV(32, PPCSTATE(npc), Imm32(op.address));
|
MOV(32, PPCSTATE(npc), Imm32(op.address));
|
||||||
SUB(32, PPCSTATE(downcount), Imm32(js.downcountAmount));
|
SUB(32, PPCSTATE(downcount), Imm32(js.downcountAmount));
|
||||||
JMP(asm_routines.dispatcher_exit, true);
|
JMP(asm_routines.dispatcher_exit, Jump::Near);
|
||||||
|
|
||||||
SetJumpTarget(noBreakpoint);
|
SetJumpTarget(noBreakpoint);
|
||||||
}
|
}
|
||||||
|
@ -1065,7 +1065,7 @@ bool Jit64::DoJit(u32 em_address, JitBlock* b, u32 nextPC)
|
||||||
if (!js.fastmemLoadStore && !js.fixupExceptionHandler)
|
if (!js.fastmemLoadStore && !js.fixupExceptionHandler)
|
||||||
{
|
{
|
||||||
TEST(32, PPCSTATE(Exceptions), Imm32(EXCEPTION_DSI));
|
TEST(32, PPCSTATE(Exceptions), Imm32(EXCEPTION_DSI));
|
||||||
memException = J_CC(CC_NZ, true);
|
memException = J_CC(CC_NZ, Jump::Near);
|
||||||
}
|
}
|
||||||
|
|
||||||
SwitchToFarCode();
|
SwitchToFarCode();
|
||||||
|
@ -1201,7 +1201,7 @@ void Jit64::IntializeSpeculativeConstants()
|
||||||
ABI_CallFunctionPC(JitInterface::CompileExceptionCheckFromJIT, &m_system.GetJitInterface(),
|
ABI_CallFunctionPC(JitInterface::CompileExceptionCheckFromJIT, &m_system.GetJitInterface(),
|
||||||
static_cast<u32>(JitInterface::ExceptionType::SpeculativeConstants));
|
static_cast<u32>(JitInterface::ExceptionType::SpeculativeConstants));
|
||||||
ABI_PopRegistersAndAdjustStack({}, 0);
|
ABI_PopRegistersAndAdjustStack({}, 0);
|
||||||
JMP(asm_routines.dispatcher_no_check, true);
|
JMP(asm_routines.dispatcher_no_check, Jump::Near);
|
||||||
SwitchToNearCode();
|
SwitchToNearCode();
|
||||||
}
|
}
|
||||||
CMP(32, PPCSTATE_GPR(i), Imm32(compileTimeValue));
|
CMP(32, PPCSTATE_GPR(i), Imm32(compileTimeValue));
|
||||||
|
|
|
@ -64,7 +64,10 @@ void Jit64AsmRoutineManager::Generate()
|
||||||
ABI_PushRegistersAndAdjustStack({}, 0);
|
ABI_PushRegistersAndAdjustStack({}, 0);
|
||||||
ABI_CallFunction(CoreTiming::GlobalAdvance);
|
ABI_CallFunction(CoreTiming::GlobalAdvance);
|
||||||
ABI_PopRegistersAndAdjustStack({}, 0);
|
ABI_PopRegistersAndAdjustStack({}, 0);
|
||||||
FixupBranch skipToRealDispatch = J(enable_debugging); // skip the sync and compare first time
|
|
||||||
|
// skip the sync and compare first time
|
||||||
|
FixupBranch skipToRealDispatch = J(enable_debugging ? Jump::Near : Jump::Short);
|
||||||
|
|
||||||
dispatcher_mispredicted_blr = GetCodePtr();
|
dispatcher_mispredicted_blr = GetCodePtr();
|
||||||
AND(32, PPCSTATE(pc), Imm32(0xFFFFFFFC));
|
AND(32, PPCSTATE(pc), Imm32(0xFFFFFFFC));
|
||||||
|
|
||||||
|
@ -83,7 +86,7 @@ void Jit64AsmRoutineManager::Generate()
|
||||||
|
|
||||||
// Expected result of SUB(32, PPCSTATE(downcount), Imm32(block_cycles)) is in RFLAGS.
|
// Expected result of SUB(32, PPCSTATE(downcount), Imm32(block_cycles)) is in RFLAGS.
|
||||||
// Branch if downcount is <= 0 (signed).
|
// Branch if downcount is <= 0 (signed).
|
||||||
FixupBranch bail = J_CC(CC_LE, true);
|
FixupBranch bail = J_CC(CC_LE, Jump::Near);
|
||||||
|
|
||||||
dispatcher_no_timing_check = GetCodePtr();
|
dispatcher_no_timing_check = GetCodePtr();
|
||||||
|
|
||||||
|
@ -94,7 +97,7 @@ void Jit64AsmRoutineManager::Generate()
|
||||||
{
|
{
|
||||||
MOV(64, R(RSCRATCH), ImmPtr(system.GetCPU().GetStatePtr()));
|
MOV(64, R(RSCRATCH), ImmPtr(system.GetCPU().GetStatePtr()));
|
||||||
TEST(32, MatR(RSCRATCH), Imm32(0xFFFFFFFF));
|
TEST(32, MatR(RSCRATCH), Imm32(0xFFFFFFFF));
|
||||||
dbg_exit = J_CC(CC_NZ, true);
|
dbg_exit = J_CC(CC_NZ, Jump::Near);
|
||||||
}
|
}
|
||||||
|
|
||||||
SetJumpTarget(skipToRealDispatch);
|
SetJumpTarget(skipToRealDispatch);
|
||||||
|
@ -209,7 +212,7 @@ void Jit64AsmRoutineManager::Generate()
|
||||||
ABI_CallFunction(JitTrampoline);
|
ABI_CallFunction(JitTrampoline);
|
||||||
ABI_PopRegistersAndAdjustStack({}, 0);
|
ABI_PopRegistersAndAdjustStack({}, 0);
|
||||||
|
|
||||||
JMP(dispatcher_no_check, true);
|
JMP(dispatcher_no_check, Jump::Near);
|
||||||
|
|
||||||
SetJumpTarget(bail);
|
SetJumpTarget(bail);
|
||||||
do_timing = GetCodePtr();
|
do_timing = GetCodePtr();
|
||||||
|
|
|
@ -116,9 +116,9 @@ void Jit64::bcx(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
SUB(32, PPCSTATE_CTR, Imm8(1));
|
SUB(32, PPCSTATE_CTR, Imm8(1));
|
||||||
if (inst.BO & BO_BRANCH_IF_CTR_0)
|
if (inst.BO & BO_BRANCH_IF_CTR_0)
|
||||||
pCTRDontBranch = J_CC(CC_NZ, true);
|
pCTRDontBranch = J_CC(CC_NZ, Jump::Near);
|
||||||
else
|
else
|
||||||
pCTRDontBranch = J_CC(CC_Z, true);
|
pCTRDontBranch = J_CC(CC_Z, Jump::Near);
|
||||||
}
|
}
|
||||||
|
|
||||||
FixupBranch pConditionDontBranch;
|
FixupBranch pConditionDontBranch;
|
||||||
|
@ -243,9 +243,9 @@ void Jit64::bclrx(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
SUB(32, PPCSTATE_CTR, Imm8(1));
|
SUB(32, PPCSTATE_CTR, Imm8(1));
|
||||||
if (inst.BO & BO_BRANCH_IF_CTR_0)
|
if (inst.BO & BO_BRANCH_IF_CTR_0)
|
||||||
pCTRDontBranch = J_CC(CC_NZ, true);
|
pCTRDontBranch = J_CC(CC_NZ, Jump::Near);
|
||||||
else
|
else
|
||||||
pCTRDontBranch = J_CC(CC_Z, true);
|
pCTRDontBranch = J_CC(CC_Z, Jump::Near);
|
||||||
}
|
}
|
||||||
|
|
||||||
FixupBranch pConditionDontBranch;
|
FixupBranch pConditionDontBranch;
|
||||||
|
|
|
@ -114,7 +114,7 @@ void Jit64::HandleNaNs(UGeckoInstruction inst, X64Reg xmm, X64Reg clobber, std::
|
||||||
// not paired-single
|
// not paired-single
|
||||||
|
|
||||||
UCOMISD(xmm, R(xmm));
|
UCOMISD(xmm, R(xmm));
|
||||||
FixupBranch handle_nan = J_CC(CC_P, true);
|
FixupBranch handle_nan = J_CC(CC_P, Jump::Near);
|
||||||
SwitchToFarCode();
|
SwitchToFarCode();
|
||||||
SetJumpTarget(handle_nan);
|
SetJumpTarget(handle_nan);
|
||||||
|
|
||||||
|
@ -140,7 +140,7 @@ void Jit64::HandleNaNs(UGeckoInstruction inst, X64Reg xmm, X64Reg clobber, std::
|
||||||
SetJumpTarget(fixup);
|
SetJumpTarget(fixup);
|
||||||
ORPD(xmm, MConst(psGeneratedQNaN));
|
ORPD(xmm, MConst(psGeneratedQNaN));
|
||||||
|
|
||||||
FixupBranch done = J(true);
|
FixupBranch done = J(Jump::Near);
|
||||||
SwitchToNearCode();
|
SwitchToNearCode();
|
||||||
SetJumpTarget(done);
|
SetJumpTarget(done);
|
||||||
}
|
}
|
||||||
|
@ -152,7 +152,7 @@ void Jit64::HandleNaNs(UGeckoInstruction inst, X64Reg xmm, X64Reg clobber, std::
|
||||||
{
|
{
|
||||||
avx_op(&XEmitter::VCMPPD, &XEmitter::CMPPD, clobber, R(xmm), R(xmm), CMP_UNORD);
|
avx_op(&XEmitter::VCMPPD, &XEmitter::CMPPD, clobber, R(xmm), R(xmm), CMP_UNORD);
|
||||||
PTEST(clobber, R(clobber));
|
PTEST(clobber, R(clobber));
|
||||||
FixupBranch handle_nan = J_CC(CC_NZ, true);
|
FixupBranch handle_nan = J_CC(CC_NZ, Jump::Near);
|
||||||
SwitchToFarCode();
|
SwitchToFarCode();
|
||||||
SetJumpTarget(handle_nan);
|
SetJumpTarget(handle_nan);
|
||||||
|
|
||||||
|
@ -182,7 +182,7 @@ void Jit64::HandleNaNs(UGeckoInstruction inst, X64Reg xmm, X64Reg clobber, std::
|
||||||
CMPPD(clobber, R(clobber), CMP_UNORD);
|
CMPPD(clobber, R(clobber), CMP_UNORD);
|
||||||
MOVMSKPD(RSCRATCH, R(clobber));
|
MOVMSKPD(RSCRATCH, R(clobber));
|
||||||
TEST(32, R(RSCRATCH), R(RSCRATCH));
|
TEST(32, R(RSCRATCH), R(RSCRATCH));
|
||||||
FixupBranch handle_nan = J_CC(CC_NZ, true);
|
FixupBranch handle_nan = J_CC(CC_NZ, Jump::Near);
|
||||||
SwitchToFarCode();
|
SwitchToFarCode();
|
||||||
SetJumpTarget(handle_nan);
|
SetJumpTarget(handle_nan);
|
||||||
|
|
||||||
|
@ -215,7 +215,7 @@ void Jit64::HandleNaNs(UGeckoInstruction inst, X64Reg xmm, X64Reg clobber, std::
|
||||||
ANDPD(clobber, MConst(psGeneratedQNaN));
|
ANDPD(clobber, MConst(psGeneratedQNaN));
|
||||||
ORPD(xmm, R(clobber));
|
ORPD(xmm, R(clobber));
|
||||||
|
|
||||||
FixupBranch done = J(true);
|
FixupBranch done = J(Jump::Near);
|
||||||
SwitchToNearCode();
|
SwitchToNearCode();
|
||||||
SetJumpTarget(done);
|
SetJumpTarget(done);
|
||||||
}
|
}
|
||||||
|
|
|
@ -444,13 +444,25 @@ void Jit64::DoMergedBranchCondition()
|
||||||
|
|
||||||
FixupBranch pDontBranch;
|
FixupBranch pDontBranch;
|
||||||
if (test_bit & 8)
|
if (test_bit & 8)
|
||||||
pDontBranch = J_CC(condition ? CC_GE : CC_L, true); // Test < 0, so jump over if >= 0.
|
{
|
||||||
|
// Test < 0, so jump over if >= 0.
|
||||||
|
pDontBranch = J_CC(condition ? CC_GE : CC_L, Jump::Near);
|
||||||
|
}
|
||||||
else if (test_bit & 4)
|
else if (test_bit & 4)
|
||||||
pDontBranch = J_CC(condition ? CC_LE : CC_G, true); // Test > 0, so jump over if <= 0.
|
{
|
||||||
|
// Test > 0, so jump over if <= 0.
|
||||||
|
pDontBranch = J_CC(condition ? CC_LE : CC_G, Jump::Near);
|
||||||
|
}
|
||||||
else if (test_bit & 2)
|
else if (test_bit & 2)
|
||||||
pDontBranch = J_CC(condition ? CC_NE : CC_E, true); // Test = 0, so jump over if != 0.
|
{
|
||||||
else // SO bit, do not branch (we don't emulate SO for cmp).
|
// Test = 0, so jump over if != 0.
|
||||||
pDontBranch = J(true);
|
pDontBranch = J_CC(condition ? CC_NE : CC_E, Jump::Near);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// SO bit, do not branch (we don't emulate SO for cmp).
|
||||||
|
pDontBranch = J(Jump::Near);
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
RCForkGuard gpr_guard = gpr.Fork();
|
RCForkGuard gpr_guard = gpr.Fork();
|
||||||
|
@ -2717,7 +2729,7 @@ void Jit64::twX(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
if (inst.TO & (1 << i))
|
if (inst.TO & (1 << i))
|
||||||
{
|
{
|
||||||
FixupBranch f = J_CC(conditions[i], true);
|
FixupBranch f = J_CC(conditions[i], Jump::Near);
|
||||||
fixups.push_back(f);
|
fixups.push_back(f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -338,7 +338,7 @@ void Jit64::dcbx(UGeckoInstruction inst)
|
||||||
MOV(32, R(tmp), R(effective_address));
|
MOV(32, R(tmp), R(effective_address));
|
||||||
SHR(32, R(tmp), Imm8(5));
|
SHR(32, R(tmp), Imm8(5));
|
||||||
BT(32, R(addr), R(tmp));
|
BT(32, R(addr), R(tmp));
|
||||||
FixupBranch invalidate_needed = J_CC(CC_C, true);
|
FixupBranch invalidate_needed = J_CC(CC_C, Jump::Near);
|
||||||
|
|
||||||
if (make_loop)
|
if (make_loop)
|
||||||
{
|
{
|
||||||
|
@ -372,7 +372,7 @@ void Jit64::dcbx(UGeckoInstruction inst)
|
||||||
ABI_PopRegistersAndAdjustStack(registersInUse, 0);
|
ABI_PopRegistersAndAdjustStack(registersInUse, 0);
|
||||||
asm_routines.ResetStack(*this);
|
asm_routines.ResetStack(*this);
|
||||||
|
|
||||||
FixupBranch done = J(true);
|
FixupBranch done = J(Jump::Near);
|
||||||
SwitchToNearCode();
|
SwitchToNearCode();
|
||||||
SetJumpTarget(done);
|
SetJumpTarget(done);
|
||||||
}
|
}
|
||||||
|
@ -432,7 +432,7 @@ void Jit64::dcbz(UGeckoInstruction inst)
|
||||||
SHR(32, R(RSCRATCH), Imm8(PowerPC::BAT_INDEX_SHIFT));
|
SHR(32, R(RSCRATCH), Imm8(PowerPC::BAT_INDEX_SHIFT));
|
||||||
TEST(32, MComplex(RSCRATCH2, RSCRATCH, SCALE_4, 0), Imm32(PowerPC::BAT_PHYSICAL_BIT));
|
TEST(32, MComplex(RSCRATCH2, RSCRATCH, SCALE_4, 0), Imm32(PowerPC::BAT_PHYSICAL_BIT));
|
||||||
POP(RSCRATCH);
|
POP(RSCRATCH);
|
||||||
FixupBranch slow = J_CC(CC_Z, true);
|
FixupBranch slow = J_CC(CC_Z, Jump::Near);
|
||||||
|
|
||||||
// Fast path: compute full address, then zero out 32 bytes of memory.
|
// Fast path: compute full address, then zero out 32 bytes of memory.
|
||||||
XORPS(XMM0, R(XMM0));
|
XORPS(XMM0, R(XMM0));
|
||||||
|
@ -451,7 +451,7 @@ void Jit64::dcbz(UGeckoInstruction inst)
|
||||||
|
|
||||||
if (emit_fast_path)
|
if (emit_fast_path)
|
||||||
{
|
{
|
||||||
FixupBranch end_far_code = J(true);
|
FixupBranch end_far_code = J(Jump::Near);
|
||||||
SwitchToNearCode();
|
SwitchToNearCode();
|
||||||
SetJumpTarget(end_far_code);
|
SetJumpTarget(end_far_code);
|
||||||
}
|
}
|
||||||
|
|
|
@ -167,19 +167,19 @@ FixupBranch Jit64::JumpIfCRFieldBit(int field, int bit, bool jump_if_set)
|
||||||
{
|
{
|
||||||
case PowerPC::CR_SO_BIT: // check bit 59 set
|
case PowerPC::CR_SO_BIT: // check bit 59 set
|
||||||
BT(64, CROffset(field), Imm8(PowerPC::CR_EMU_SO_BIT));
|
BT(64, CROffset(field), Imm8(PowerPC::CR_EMU_SO_BIT));
|
||||||
return J_CC(jump_if_set ? CC_C : CC_NC, true);
|
return J_CC(jump_if_set ? CC_C : CC_NC, Jump::Near);
|
||||||
|
|
||||||
case PowerPC::CR_EQ_BIT: // check bits 31-0 == 0
|
case PowerPC::CR_EQ_BIT: // check bits 31-0 == 0
|
||||||
CMP(32, CROffset(field), Imm8(0));
|
CMP(32, CROffset(field), Imm8(0));
|
||||||
return J_CC(jump_if_set ? CC_Z : CC_NZ, true);
|
return J_CC(jump_if_set ? CC_Z : CC_NZ, Jump::Near);
|
||||||
|
|
||||||
case PowerPC::CR_GT_BIT: // check val > 0
|
case PowerPC::CR_GT_BIT: // check val > 0
|
||||||
CMP(64, CROffset(field), Imm8(0));
|
CMP(64, CROffset(field), Imm8(0));
|
||||||
return J_CC(jump_if_set ? CC_G : CC_LE, true);
|
return J_CC(jump_if_set ? CC_G : CC_LE, Jump::Near);
|
||||||
|
|
||||||
case PowerPC::CR_LT_BIT: // check bit 62 set
|
case PowerPC::CR_LT_BIT: // check bit 62 set
|
||||||
BT(64, CROffset(field), Imm8(PowerPC::CR_EMU_LT_BIT));
|
BT(64, CROffset(field), Imm8(PowerPC::CR_EMU_LT_BIT));
|
||||||
return J_CC(jump_if_set ? CC_C : CC_NC, true);
|
return J_CC(jump_if_set ? CC_C : CC_NC, Jump::Near);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ASSERT_MSG(DYNA_REC, false, "Invalid CR bit");
|
ASSERT_MSG(DYNA_REC, false, "Invalid CR bit");
|
||||||
|
@ -450,16 +450,16 @@ void Jit64::mtmsr(UGeckoInstruction inst)
|
||||||
// external exceptions when going out of mtmsr in order to execute delayed
|
// external exceptions when going out of mtmsr in order to execute delayed
|
||||||
// interrupts as soon as possible.
|
// interrupts as soon as possible.
|
||||||
TEST(32, PPCSTATE(msr), Imm32(0x8000));
|
TEST(32, PPCSTATE(msr), Imm32(0x8000));
|
||||||
FixupBranch eeDisabled = J_CC(CC_Z, true);
|
FixupBranch eeDisabled = J_CC(CC_Z, Jump::Near);
|
||||||
|
|
||||||
TEST(32, PPCSTATE(Exceptions),
|
TEST(32, PPCSTATE(Exceptions),
|
||||||
Imm32(EXCEPTION_EXTERNAL_INT | EXCEPTION_PERFORMANCE_MONITOR | EXCEPTION_DECREMENTER));
|
Imm32(EXCEPTION_EXTERNAL_INT | EXCEPTION_PERFORMANCE_MONITOR | EXCEPTION_DECREMENTER));
|
||||||
FixupBranch noExceptionsPending = J_CC(CC_Z, true);
|
FixupBranch noExceptionsPending = J_CC(CC_Z, Jump::Near);
|
||||||
|
|
||||||
// Check if a CP interrupt is waiting and keep the GPU emulation in sync (issue 4336)
|
// Check if a CP interrupt is waiting and keep the GPU emulation in sync (issue 4336)
|
||||||
MOV(64, R(RSCRATCH), ImmPtr(&m_system.GetProcessorInterface().m_interrupt_cause));
|
MOV(64, R(RSCRATCH), ImmPtr(&m_system.GetProcessorInterface().m_interrupt_cause));
|
||||||
TEST(32, MatR(RSCRATCH), Imm32(ProcessorInterface::INT_CAUSE_CP));
|
TEST(32, MatR(RSCRATCH), Imm32(ProcessorInterface::INT_CAUSE_CP));
|
||||||
FixupBranch cpInt = J_CC(CC_NZ, true);
|
FixupBranch cpInt = J_CC(CC_NZ, Jump::Near);
|
||||||
|
|
||||||
MOV(32, PPCSTATE(pc), Imm32(js.compilerPC + 4));
|
MOV(32, PPCSTATE(pc), Imm32(js.compilerPC + 4));
|
||||||
WriteExternalExceptionExit();
|
WriteExternalExceptionExit();
|
||||||
|
|
|
@ -35,7 +35,7 @@ void JitBlockCache::WriteLinkBlock(const JitBlock::LinkData& source, const JitBl
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Gen::XEmitter emit(location, location + 5);
|
Gen::XEmitter emit(location, location + 5);
|
||||||
emit.JMP(address, true);
|
emit.JMP(address, Gen::XEmitter::Jump::Near);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,7 +61,7 @@ void EmuCodeBlock::MemoryExceptionCheck()
|
||||||
if (js.trampolineExceptionHandler)
|
if (js.trampolineExceptionHandler)
|
||||||
{
|
{
|
||||||
TEST(32, PPCSTATE(Exceptions), Gen::Imm32(EXCEPTION_DSI));
|
TEST(32, PPCSTATE(Exceptions), Gen::Imm32(EXCEPTION_DSI));
|
||||||
J_CC(CC_NZ, js.trampolineExceptionHandler);
|
J_CC(CC_NZ, js.trampolineExceptionHandler ? Jump::Near : Jump::Short);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,7 @@ void EmuCodeBlock::MemoryExceptionCheck()
|
||||||
if (m_jit.jo.memcheck && !js.fastmemLoadStore && !js.fixupExceptionHandler)
|
if (m_jit.jo.memcheck && !js.fastmemLoadStore && !js.fixupExceptionHandler)
|
||||||
{
|
{
|
||||||
TEST(32, PPCSTATE(Exceptions), Gen::Imm32(EXCEPTION_DSI));
|
TEST(32, PPCSTATE(Exceptions), Gen::Imm32(EXCEPTION_DSI));
|
||||||
js.exceptionHandler = J_CC(Gen::CC_NZ, true);
|
js.exceptionHandler = J_CC(Gen::CC_NZ, Jump::Near);
|
||||||
js.fixupExceptionHandler = true;
|
js.fixupExceptionHandler = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -99,7 +99,7 @@ FixupBranch EmuCodeBlock::BATAddressLookup(X64Reg addr, X64Reg tmp, const void*
|
||||||
MOV(32, R(addr), MComplex(tmp, addr, SCALE_4, 0));
|
MOV(32, R(addr), MComplex(tmp, addr, SCALE_4, 0));
|
||||||
BT(32, R(addr), Imm8(MathUtil::IntLog2(PowerPC::BAT_MAPPED_BIT)));
|
BT(32, R(addr), Imm8(MathUtil::IntLog2(PowerPC::BAT_MAPPED_BIT)));
|
||||||
|
|
||||||
return J_CC(CC_NC, m_far_code.Enabled());
|
return J_CC(CC_NC, m_far_code.Enabled() ? Jump::Near : Jump::Short);
|
||||||
}
|
}
|
||||||
|
|
||||||
FixupBranch EmuCodeBlock::CheckIfSafeAddress(const OpArg& reg_value, X64Reg reg_addr,
|
FixupBranch EmuCodeBlock::CheckIfSafeAddress(const OpArg& reg_value, X64Reg reg_addr,
|
||||||
|
@ -128,7 +128,7 @@ FixupBranch EmuCodeBlock::CheckIfSafeAddress(const OpArg& reg_value, X64Reg reg_
|
||||||
if (registers_in_use[RSCRATCH])
|
if (registers_in_use[RSCRATCH])
|
||||||
POP(RSCRATCH);
|
POP(RSCRATCH);
|
||||||
|
|
||||||
return J_CC(CC_Z, m_far_code.Enabled());
|
return J_CC(CC_Z, m_far_code.Enabled() ? Jump::Near : Jump::Short);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuCodeBlock::UnsafeWriteRegToReg(OpArg reg_value, X64Reg reg_addr, int accessSize, s32 offset,
|
void EmuCodeBlock::UnsafeWriteRegToReg(OpArg reg_value, X64Reg reg_addr, int accessSize, s32 offset,
|
||||||
|
@ -380,7 +380,7 @@ void EmuCodeBlock::SafeLoadToReg(X64Reg reg_value, const Gen::OpArg& opAddress,
|
||||||
if (m_far_code.Enabled())
|
if (m_far_code.Enabled())
|
||||||
SwitchToFarCode();
|
SwitchToFarCode();
|
||||||
else
|
else
|
||||||
exit = J(true);
|
exit = J(Jump::Near);
|
||||||
SetJumpTarget(slow);
|
SetJumpTarget(slow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -425,7 +425,7 @@ void EmuCodeBlock::SafeLoadToReg(X64Reg reg_value, const Gen::OpArg& opAddress,
|
||||||
{
|
{
|
||||||
if (m_far_code.Enabled())
|
if (m_far_code.Enabled())
|
||||||
{
|
{
|
||||||
exit = J(true);
|
exit = J(Jump::Near);
|
||||||
SwitchToNearCode();
|
SwitchToNearCode();
|
||||||
}
|
}
|
||||||
SetJumpTarget(exit);
|
SetJumpTarget(exit);
|
||||||
|
@ -549,7 +549,7 @@ void EmuCodeBlock::SafeWriteRegToReg(OpArg reg_value, X64Reg reg_addr, int acces
|
||||||
if (m_far_code.Enabled())
|
if (m_far_code.Enabled())
|
||||||
SwitchToFarCode();
|
SwitchToFarCode();
|
||||||
else
|
else
|
||||||
exit = J(true);
|
exit = J(Jump::Near);
|
||||||
SetJumpTarget(slow);
|
SetJumpTarget(slow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -601,7 +601,7 @@ void EmuCodeBlock::SafeWriteRegToReg(OpArg reg_value, X64Reg reg_addr, int acces
|
||||||
{
|
{
|
||||||
if (m_far_code.Enabled())
|
if (m_far_code.Enabled())
|
||||||
{
|
{
|
||||||
exit = J(true);
|
exit = J(Jump::Near);
|
||||||
SwitchToNearCode();
|
SwitchToNearCode();
|
||||||
}
|
}
|
||||||
SetJumpTarget(exit);
|
SetJumpTarget(exit);
|
||||||
|
@ -866,14 +866,14 @@ void EmuCodeBlock::ConvertSingleToDouble(X64Reg dst, X64Reg src, bool src_is_gpr
|
||||||
|
|
||||||
UCOMISS(dst, R(dst));
|
UCOMISS(dst, R(dst));
|
||||||
CVTSS2SD(dst, R(dst));
|
CVTSS2SD(dst, R(dst));
|
||||||
FixupBranch nanConversion = J_CC(CC_P, true);
|
FixupBranch nanConversion = J_CC(CC_P, Jump::Near);
|
||||||
|
|
||||||
SwitchToFarCode();
|
SwitchToFarCode();
|
||||||
SetJumpTarget(nanConversion);
|
SetJumpTarget(nanConversion);
|
||||||
TEST(32, R(gprsrc), Imm32(0x00400000));
|
TEST(32, R(gprsrc), Imm32(0x00400000));
|
||||||
FixupBranch continue1 = J_CC(CC_NZ, true);
|
FixupBranch continue1 = J_CC(CC_NZ, Jump::Near);
|
||||||
ANDPD(dst, MConst(double_qnan_bit));
|
ANDPD(dst, MConst(double_qnan_bit));
|
||||||
FixupBranch continue2 = J(true);
|
FixupBranch continue2 = J(Jump::Near);
|
||||||
SwitchToNearCode();
|
SwitchToNearCode();
|
||||||
|
|
||||||
SetJumpTarget(continue1);
|
SetJumpTarget(continue1);
|
||||||
|
|
|
@ -128,7 +128,7 @@ void CommonAsmRoutines::GenFrsqrte()
|
||||||
// Negatives, zeros, denormals, infinities and NaNs take the complex path.
|
// Negatives, zeros, denormals, infinities and NaNs take the complex path.
|
||||||
LEA(32, RSCRATCH2, MDisp(RSCRATCH_EXTRA, -1));
|
LEA(32, RSCRATCH2, MDisp(RSCRATCH_EXTRA, -1));
|
||||||
CMP(32, R(RSCRATCH2), Imm32(0x7FE));
|
CMP(32, R(RSCRATCH2), Imm32(0x7FE));
|
||||||
FixupBranch complex = J_CC(CC_AE, true);
|
FixupBranch complex = J_CC(CC_AE, Jump::Near);
|
||||||
|
|
||||||
SUB(32, R(RSCRATCH_EXTRA), Imm32(0x3FD));
|
SUB(32, R(RSCRATCH_EXTRA), Imm32(0x3FD));
|
||||||
SAR(32, R(RSCRATCH_EXTRA), Imm8(1));
|
SAR(32, R(RSCRATCH_EXTRA), Imm8(1));
|
||||||
|
|
|
@ -46,7 +46,7 @@ const u8* TrampolineCache::GenerateReadTrampoline(const TrampolineInfo& info)
|
||||||
SafeLoadToReg(info.op_reg, info.op_arg, info.accessSize << 3, info.offset, info.registersInUse,
|
SafeLoadToReg(info.op_reg, info.op_arg, info.accessSize << 3, info.offset, info.registersInUse,
|
||||||
info.signExtend, info.flags | SAFE_LOADSTORE_FORCE_SLOWMEM);
|
info.signExtend, info.flags | SAFE_LOADSTORE_FORCE_SLOWMEM);
|
||||||
|
|
||||||
JMP(info.start + info.len, true);
|
JMP(info.start + info.len, Jump::Near);
|
||||||
|
|
||||||
Common::JitRegister::Register(trampoline, GetCodePtr(), "JIT_ReadTrampoline_{:x}", info.pc);
|
Common::JitRegister::Register(trampoline, GetCodePtr(), "JIT_ReadTrampoline_{:x}", info.pc);
|
||||||
return trampoline;
|
return trampoline;
|
||||||
|
@ -65,7 +65,7 @@ const u8* TrampolineCache::GenerateWriteTrampoline(const TrampolineInfo& info)
|
||||||
SafeWriteRegToReg(info.op_arg, info.op_reg, info.accessSize << 3, info.offset,
|
SafeWriteRegToReg(info.op_arg, info.op_reg, info.accessSize << 3, info.offset,
|
||||||
info.registersInUse, info.flags | SAFE_LOADSTORE_FORCE_SLOWMEM);
|
info.registersInUse, info.flags | SAFE_LOADSTORE_FORCE_SLOWMEM);
|
||||||
|
|
||||||
JMP(info.start + info.len, true);
|
JMP(info.start + info.len, Jump::Near);
|
||||||
|
|
||||||
Common::JitRegister::Register(trampoline, GetCodePtr(), "JIT_WriteTrampoline_{:x}", info.pc);
|
Common::JitRegister::Register(trampoline, GetCodePtr(), "JIT_WriteTrampoline_{:x}", info.pc);
|
||||||
return trampoline;
|
return trampoline;
|
||||||
|
|
|
@ -66,7 +66,7 @@ OpArg VertexLoaderX64::GetVertexAddr(CPArray array, VertexComponentFormat attrib
|
||||||
if (array == CPArray::Position)
|
if (array == CPArray::Position)
|
||||||
{
|
{
|
||||||
CMP(bits, R(scratch1), Imm8(-1));
|
CMP(bits, R(scratch1), Imm8(-1));
|
||||||
m_skip_vertex = J_CC(CC_E, true);
|
m_skip_vertex = J_CC(CC_E, Jump::Near);
|
||||||
}
|
}
|
||||||
IMUL(32, scratch1, MPIC(&g_main_cp_state.array_strides[array]));
|
IMUL(32, scratch1, MPIC(&g_main_cp_state.array_strides[array]));
|
||||||
MOV(64, R(scratch2), MPIC(&VertexLoaderManager::cached_arraybases[array]));
|
MOV(64, R(scratch2), MPIC(&VertexLoaderManager::cached_arraybases[array]));
|
||||||
|
|
|
@ -292,7 +292,7 @@ TEST_F(x64EmitterTest, JMP)
|
||||||
"jmp .-8");
|
"jmp .-8");
|
||||||
|
|
||||||
emitter->NOP(6);
|
emitter->NOP(6);
|
||||||
emitter->JMP(code_buffer, true);
|
emitter->JMP(code_buffer, XEmitter::Jump::Near);
|
||||||
ExpectDisassembly("multibyte nop "
|
ExpectDisassembly("multibyte nop "
|
||||||
"jmp .-11");
|
"jmp .-11");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue