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:
Dentomologist 2023-05-21 15:10:11 -07:00
parent c8559a7933
commit 4c2759f541
20 changed files with 147 additions and 124 deletions

View File

@ -432,14 +432,14 @@ void XEmitter::Rex(int w, int r, int x, int b)
Write8(rx);
}
void XEmitter::JMP(const u8* addr, bool force5Bytes)
void XEmitter::JMP(const u8* addr, const Jump jump)
{
u64 fn = (u64)addr;
if (!force5Bytes)
if (jump == Jump::Short)
{
s64 distance = (s64)(fn - ((u64)code + 2));
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
Write8(0xEB);
Write8((u8)(s8)distance);
@ -449,7 +449,7 @@ void XEmitter::JMP(const u8* addr, bool force5Bytes)
s64 distance = (s64)(fn - ((u64)code + 5));
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);
Write32((u32)(s32)distance);
}
@ -510,12 +510,13 @@ FixupBranch XEmitter::CALL()
return branch;
}
FixupBranch XEmitter::J(bool force5bytes)
FixupBranch XEmitter::J(const Jump jump)
{
FixupBranch branch;
branch.type = force5bytes ? FixupBranch::Type::Branch32Bit : FixupBranch::Type::Branch8Bit;
branch.ptr = code + (force5bytes ? 5 : 2);
if (!force5bytes)
const bool is_near_jump = jump == Jump::Near;
branch.type = is_near_jump ? FixupBranch::Type::Branch32Bit : FixupBranch::Type::Branch8Bit;
branch.ptr = code + (is_near_jump ? 5 : 2);
if (!is_near_jump)
{
// 8 bits will do
Write8(0xEB);
@ -536,12 +537,13 @@ FixupBranch XEmitter::J(bool force5bytes)
return branch;
}
FixupBranch XEmitter::J_CC(CCFlags conditionCode, bool force5bytes)
FixupBranch XEmitter::J_CC(CCFlags conditionCode, const Jump jump)
{
FixupBranch branch;
branch.type = force5bytes ? FixupBranch::Type::Branch32Bit : FixupBranch::Type::Branch8Bit;
branch.ptr = code + (force5bytes ? 6 : 2);
if (!force5bytes)
const bool is_near_jump = jump == Jump::Near;
branch.type = is_near_jump ? FixupBranch::Type::Branch32Bit : FixupBranch::Type::Branch8Bit;
branch.ptr = code + (is_near_jump ? 6 : 2);
if (!is_near_jump)
{
// 8 bits will do
Write8(0x70 + conditionCode);
@ -592,14 +594,14 @@ void XEmitter::SetJumpTarget(const FixupBranch& branch)
{
s64 distance = (s64)(code - branch.ptr);
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;
}
else if (branch.type == FixupBranch::Type::Branch32Bit)
{
s64 distance = (s64)(code - branch.ptr);
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);
std::memcpy(&branch.ptr[-4], &valid_distance, sizeof(s32));

View File

@ -440,13 +440,19 @@ public:
void PUSHF();
void POPF();
enum class Jump
{
Short,
Near,
};
// Flow control
void RET();
void RET_FAST();
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 JMPself(); // infinite loop!
#ifdef CALL
@ -456,7 +462,7 @@ public:
FixupBranch CALL();
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 SetJumpTarget(const FixupBranch& branch);

View File

@ -109,7 +109,7 @@ void DSPEmitter::checkExceptions(u32 retval)
{
// Check for interrupts and exceptions
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));
@ -117,7 +117,7 @@ void DSPEmitter::checkExceptions(u32 retval)
m_gpr.SaveRegs();
ABI_CallFunctionP(CheckExceptionsThunk, &m_dsp_core);
MOV(32, R(EAX), Imm32(retval));
JMP(m_return_dispatcher, true);
JMP(m_return_dispatcher, Jump::Near);
m_gpr.LoadRegs(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));
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));
TEST(32, R(EAX), R(EAX));
FixupBranch rLoopCounterExit = J_CC(CC_LE, true);
FixupBranch rLoopCounterExit = J_CC(CC_LE, Jump::Near);
if (!opcode->branch)
{
@ -290,7 +290,7 @@ void DSPEmitter::Compile(u16 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.FlushRegs(c, false);
@ -313,7 +313,7 @@ void DSPEmitter::Compile(u16 start_addr)
// look at g_dsp.pc if we actually branched
MOV(16, R(AX), M_SDSP_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);
// 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]));
}
JMP(m_return_dispatcher, true);
JMP(m_return_dispatcher, Jump::Near);
m_gpr.LoadRegs(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]));
}
JMP(m_return_dispatcher, true);
JMP(m_return_dispatcher, Jump::Near);
}
void DSPEmitter::CompileCurrent(DSPEmitter& emitter)

View File

@ -91,7 +91,7 @@ void DSPEmitter::ReJitConditional(const UDSPInstruction opc,
flag = CC_NZ;
else // Odd conditions run if the bit IS NOT zero, so jump if it IS zero
flag = CC_Z;
FixupBranch skip_code = J_CC(flag, true);
FixupBranch skip_code = J_CC(flag, Jump::Near);
(this->*conditional_fn)(opc);
m_gpr.FlushRegs(c1);
SetJumpTarget(skip_code);
@ -109,7 +109,7 @@ void DSPEmitter::WriteBranchExit()
{
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.FlushRegs(c, false);
}
@ -130,7 +130,7 @@ void DSPEmitter::WriteBlockLink(u16 dest)
SUB(16, R(ECX), Imm16(m_block_size[m_start_address]));
MOV(16, MatR(RAX), R(ECX));
JMP(m_block_links[dest], true);
JMP(m_block_links[dest], Jump::Near);
SetJumpTarget(notEnoughCycles);
}
else
@ -322,17 +322,17 @@ void DSPEmitter::HandleLoop()
MOVZX(32, 16, ECX, M_SDSP_r_st(3));
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));
FixupBranch rLoopAddrG = J_CC(CC_NE, true);
FixupBranch rLoopAddrG = J_CC(CC_NE, Jump::Near);
SUB(16, M_SDSP_r_st(3), Imm16(1));
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));
MOV(16, M_SDSP_pc(), R(RCX));
FixupBranch loopUpdated = J(true);
FixupBranch loopUpdated = J(Jump::Near);
SetJumpTarget(loadStack);
DSPJitRegCache c(m_gpr);
@ -363,7 +363,7 @@ void DSPEmitter::loop(const UDSPInstruction opc)
TEST(16, R(EDX), R(EDX));
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);
MOV(16, R(RDX), Imm16(m_compile_pc + 1));
dsp_reg_store_stack(StackRegister::Call);
@ -371,7 +371,7 @@ void DSPEmitter::loop(const UDSPInstruction opc)
dsp_reg_store_stack(StackRegister::LoopAddress);
m_gpr.FlushRegs(c);
MOV(16, M_SDSP_pc(), Imm16(m_compile_pc + 1));
FixupBranch exit = J(true);
FixupBranch exit = J(Jump::Near);
SetJumpTarget(cnt);
// dsp_skip_inst();
@ -433,7 +433,7 @@ void DSPEmitter::bloop(const UDSPInstruction opc)
TEST(16, R(EDX), R(EDX));
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);
MOV(16, R(RDX), Imm16(m_compile_pc + 2));
dsp_reg_store_stack(StackRegister::Call);
@ -441,7 +441,7 @@ void DSPEmitter::bloop(const UDSPInstruction opc)
dsp_reg_store_stack(StackRegister::LoopAddress);
MOV(16, M_SDSP_pc(), Imm16(m_compile_pc + 2));
m_gpr.FlushRegs(c, true);
FixupBranch exit = J(true);
FixupBranch exit = J(Jump::Near);
SetJumpTarget(cnt);
// g_dsp.pc = loop_pc;

View File

@ -383,10 +383,10 @@ void DSPEmitter::ld(const UDSPInstruction opc)
m_gpr.PutXReg(tmp);
DSPJitRegCache c(m_gpr);
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);
m_gpr.FlushRegs(c);
FixupBranch after = J(true);
FixupBranch after = J(Jump::Near);
SetJumpTarget(not_equal); // else
pushExtValueFromMem2((rreg << 1) + DSP_REG_AXL1, DSP_REG_AR3);
m_gpr.FlushRegs(c);
@ -417,10 +417,10 @@ void DSPEmitter::ldax(const UDSPInstruction opc)
m_gpr.PutXReg(tmp);
DSPJitRegCache c(m_gpr);
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);
m_gpr.FlushRegs(c);
FixupBranch after = J(true); // else
FixupBranch after = J(Jump::Near); // else
SetJumpTarget(not_equal);
pushExtValueFromMem2(rreg + DSP_REG_AXL0, DSP_REG_AR3);
m_gpr.FlushRegs(c);
@ -449,10 +449,10 @@ void DSPEmitter::ldn(const UDSPInstruction opc)
m_gpr.PutXReg(tmp);
DSPJitRegCache c(m_gpr);
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);
m_gpr.FlushRegs(c);
FixupBranch after = J(true);
FixupBranch after = J(Jump::Near);
SetJumpTarget(not_equal); // else
pushExtValueFromMem2((rreg << 1) + DSP_REG_AXL1, DSP_REG_AR3);
m_gpr.FlushRegs(c);
@ -480,10 +480,10 @@ void DSPEmitter::ldaxn(const UDSPInstruction opc)
m_gpr.PutXReg(tmp);
DSPJitRegCache c(m_gpr);
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);
m_gpr.FlushRegs(c);
FixupBranch after = J(true); // else
FixupBranch after = J(Jump::Near); // else
SetJumpTarget(not_equal);
pushExtValueFromMem2(rreg + DSP_REG_AXL0, DSP_REG_AR3);
m_gpr.FlushRegs(c);
@ -512,10 +512,10 @@ void DSPEmitter::ldm(const UDSPInstruction opc)
m_gpr.PutXReg(tmp);
DSPJitRegCache c(m_gpr);
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);
m_gpr.FlushRegs(c);
FixupBranch after = J(true);
FixupBranch after = J(Jump::Near);
SetJumpTarget(not_equal); // else
pushExtValueFromMem2((rreg << 1) + DSP_REG_AXL1, DSP_REG_AR3);
m_gpr.FlushRegs(c);
@ -543,10 +543,10 @@ void DSPEmitter::ldaxm(const UDSPInstruction opc)
m_gpr.PutXReg(tmp);
DSPJitRegCache c(m_gpr);
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);
m_gpr.FlushRegs(c);
FixupBranch after = J(true); // else
FixupBranch after = J(Jump::Near); // else
SetJumpTarget(not_equal);
pushExtValueFromMem2(rreg + DSP_REG_AXL0, DSP_REG_AR3);
m_gpr.FlushRegs(c);
@ -575,10 +575,10 @@ void DSPEmitter::ldnm(const UDSPInstruction opc)
m_gpr.PutXReg(tmp);
DSPJitRegCache c(m_gpr);
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);
m_gpr.FlushRegs(c);
FixupBranch after = J(true);
FixupBranch after = J(Jump::Near);
SetJumpTarget(not_equal); // else
pushExtValueFromMem2((rreg << 1) + DSP_REG_AXL1, DSP_REG_AR3);
m_gpr.FlushRegs(c);
@ -606,10 +606,10 @@ void DSPEmitter::ldaxnm(const UDSPInstruction opc)
m_gpr.PutXReg(tmp);
DSPJitRegCache c(m_gpr);
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);
m_gpr.FlushRegs(c);
FixupBranch after = J(true); // else
FixupBranch after = J(Jump::Near); // else
SetJumpTarget(not_equal);
pushExtValueFromMem2(rreg + DSP_REG_AXL0, DSP_REG_AR3);
m_gpr.FlushRegs(c);
@ -670,7 +670,7 @@ void DSPEmitter::popExtValueToReg()
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);
FixupBranch not_40bit = J_CC(CC_Z, Jump::Near);
DSPJitRegCache c(m_gpr);
// if (g_dsp.r[DSP_REG_SR] & SR_40_MODE_BIT)
//{

View File

@ -84,7 +84,7 @@ void DSPEmitter::multiply_mulx(u8 axh0, u8 axh1)
// prod = (s16)a * (s16)b; //signed
MOVSX(64, 16, RAX, R(RAX));
IMUL(64, R(RCX));
FixupBranch signedMul = J(true);
FixupBranch signedMul = J(Jump::Near);
SetJumpTarget(unsignedMul);
DSPJitRegCache c(m_gpr);

View File

@ -151,7 +151,7 @@ void DSPEmitter::dsp_conditional_extend_accum(int reg)
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);
FixupBranch not_40bit = J_CC(CC_Z, Jump::Near);
// if (g_dsp.r[DSP_REG_SR] & SR_40_MODE_BIT)
//{
// 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);
DSPJitRegCache c(m_gpr);
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)
//{
// 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);
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);
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(16, MComplex(ECX, EAX, SCALE_2, 0), R(value));
FixupBranch end = J(true);
FixupBranch end = J(Jump::Near);
// else if (saddr == 0xf)
SetJumpTarget(ifx);
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(16, R(EAX), MComplex(ECX, address, SCALE_2, 0));
FixupBranch end = J(true);
FixupBranch end = J(Jump::Near);
SetJumpTarget(dram);
// else if (saddr == 0x1)
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(16, R(EAX), MComplex(ECX, address, SCALE_2, 0));
FixupBranch end2 = J(true);
FixupBranch end2 = J(Jump::Near);
SetJumpTarget(ifx);
// else if (saddr == 0xf)
// return gdsp_ifx_read(addr);

View File

@ -203,7 +203,7 @@ bool Jit64::BackPatch(SContext* ctx)
// Patch the original memory operation.
XEmitter emitter(start, start + info.len);
emitter.JMP(trampoline, true);
emitter.JMP(trampoline, Jump::Near);
// NOPs become dead code
const u8* end = info.start + info.len;
for (const u8* i = emitter.GetCodePtr(); i < end; ++i)
@ -373,7 +373,7 @@ void Jit64::FallBackToInterpreter(UGeckoInstruction inst)
else if (ShouldHandleFPExceptionForInstruction(js.op))
{
TEST(32, PPCSTATE(Exceptions), Imm32(EXCEPTION_PROGRAM));
FixupBranch exception = J_CC(CC_NZ, true);
FixupBranch exception = J_CC(CC_NZ, Jump::Near);
SwitchToFarCode();
SetJumpTarget(exception);
@ -521,11 +521,11 @@ void Jit64::JustWriteExit(u32 destination, bool bl, u32 after)
// Perform downcount flag check, followed by the requested exit
if (bl)
{
FixupBranch do_timing = J_CC(CC_LE, true);
FixupBranch do_timing = J_CC(CC_LE, Jump::Near);
SwitchToFarCode();
SetJumpTarget(do_timing);
CALL(asm_routines.do_timing);
FixupBranch after_fixup = J(true);
FixupBranch after_fixup = J(Jump::Near);
SwitchToNearCode();
linkData.exitPtrs = GetWritableCodePtr();
@ -540,7 +540,7 @@ void Jit64::JustWriteExit(u32 destination, bool bl, u32 after)
J_CC(CC_LE, asm_routines.do_timing);
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);
@ -568,7 +568,7 @@ void Jit64::WriteExitDestInRSCRATCH(bool bl, u32 after)
}
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_PopRegistersAndAdjustStack({}, 0);
SUB(32, PPCSTATE(downcount), Imm32(js.downcountAmount));
JMP(asm_routines.dispatcher, true);
JMP(asm_routines.dispatcher, Jump::Near);
}
void Jit64::WriteIdleExit(u32 destination)
@ -620,7 +620,7 @@ void Jit64::WriteExceptionExit()
ABI_CallFunctionP(PowerPC::CheckExceptionsFromJIT, &m_system.GetPowerPC());
ABI_PopRegistersAndAdjustStack({}, 0);
SUB(32, PPCSTATE(downcount), Imm32(js.downcountAmount));
JMP(asm_routines.dispatcher, true);
JMP(asm_routines.dispatcher, Jump::Near);
}
void Jit64::WriteExternalExceptionExit()
@ -632,7 +632,7 @@ void Jit64::WriteExternalExceptionExit()
ABI_CallFunctionP(PowerPC::CheckExternalExceptionsFromJIT, &m_system.GetPowerPC());
ABI_PopRegistersAndAdjustStack({}, 0);
SUB(32, PPCSTATE(downcount), Imm32(js.downcountAmount));
JMP(asm_routines.dispatcher, true);
JMP(asm_routines.dispatcher, Jump::Near);
}
void Jit64::Run()
@ -883,7 +883,7 @@ bool Jit64::DoJit(u32 em_address, JitBlock* b, u32 nextPC)
ABI_CallFunctionPC(JitInterface::CompileExceptionCheckFromJIT, &m_system.GetJitInterface(),
static_cast<u32>(JitInterface::ExceptionType::PairedQuantize));
ABI_PopRegistersAndAdjustStack({}, 0);
JMP(asm_routines.dispatcher_no_check, true);
JMP(asm_routines.dispatcher_no_check, Jump::Near);
SwitchToNearCode();
// 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)
{
TEST(32, PPCSTATE(Exceptions), Imm32(EXCEPTION_EXTERNAL_INT));
FixupBranch extException = J_CC(CC_NZ, true);
FixupBranch extException = J_CC(CC_NZ, Jump::Near);
SwitchToFarCode();
SetJumpTarget(extException);
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));
TEST(32, MatR(RSCRATCH),
Imm32(ProcessorInterface::INT_CAUSE_CP | ProcessorInterface::INT_CAUSE_PE_TOKEN |
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();
@ -986,7 +986,7 @@ bool Jit64::DoJit(u32 em_address, JitBlock* b, u32 nextPC)
{
// This instruction uses FPU - needs to add FP exception bailout
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();
SetJumpTarget(b1);
@ -1027,7 +1027,7 @@ bool Jit64::DoJit(u32 em_address, JitBlock* b, u32 nextPC)
Cleanup();
MOV(32, PPCSTATE(npc), Imm32(op.address));
SUB(32, PPCSTATE(downcount), Imm32(js.downcountAmount));
JMP(asm_routines.dispatcher_exit, true);
JMP(asm_routines.dispatcher_exit, Jump::Near);
SetJumpTarget(noBreakpoint);
}
@ -1065,7 +1065,7 @@ bool Jit64::DoJit(u32 em_address, JitBlock* b, u32 nextPC)
if (!js.fastmemLoadStore && !js.fixupExceptionHandler)
{
TEST(32, PPCSTATE(Exceptions), Imm32(EXCEPTION_DSI));
memException = J_CC(CC_NZ, true);
memException = J_CC(CC_NZ, Jump::Near);
}
SwitchToFarCode();
@ -1201,7 +1201,7 @@ void Jit64::IntializeSpeculativeConstants()
ABI_CallFunctionPC(JitInterface::CompileExceptionCheckFromJIT, &m_system.GetJitInterface(),
static_cast<u32>(JitInterface::ExceptionType::SpeculativeConstants));
ABI_PopRegistersAndAdjustStack({}, 0);
JMP(asm_routines.dispatcher_no_check, true);
JMP(asm_routines.dispatcher_no_check, Jump::Near);
SwitchToNearCode();
}
CMP(32, PPCSTATE_GPR(i), Imm32(compileTimeValue));

View File

@ -64,7 +64,10 @@ void Jit64AsmRoutineManager::Generate()
ABI_PushRegistersAndAdjustStack({}, 0);
ABI_CallFunction(CoreTiming::GlobalAdvance);
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();
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.
// 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();
@ -94,7 +97,7 @@ void Jit64AsmRoutineManager::Generate()
{
MOV(64, R(RSCRATCH), ImmPtr(system.GetCPU().GetStatePtr()));
TEST(32, MatR(RSCRATCH), Imm32(0xFFFFFFFF));
dbg_exit = J_CC(CC_NZ, true);
dbg_exit = J_CC(CC_NZ, Jump::Near);
}
SetJumpTarget(skipToRealDispatch);
@ -209,7 +212,7 @@ void Jit64AsmRoutineManager::Generate()
ABI_CallFunction(JitTrampoline);
ABI_PopRegistersAndAdjustStack({}, 0);
JMP(dispatcher_no_check, true);
JMP(dispatcher_no_check, Jump::Near);
SetJumpTarget(bail);
do_timing = GetCodePtr();

View File

@ -116,9 +116,9 @@ void Jit64::bcx(UGeckoInstruction inst)
{
SUB(32, PPCSTATE_CTR, Imm8(1));
if (inst.BO & BO_BRANCH_IF_CTR_0)
pCTRDontBranch = J_CC(CC_NZ, true);
pCTRDontBranch = J_CC(CC_NZ, Jump::Near);
else
pCTRDontBranch = J_CC(CC_Z, true);
pCTRDontBranch = J_CC(CC_Z, Jump::Near);
}
FixupBranch pConditionDontBranch;
@ -243,9 +243,9 @@ void Jit64::bclrx(UGeckoInstruction inst)
{
SUB(32, PPCSTATE_CTR, Imm8(1));
if (inst.BO & BO_BRANCH_IF_CTR_0)
pCTRDontBranch = J_CC(CC_NZ, true);
pCTRDontBranch = J_CC(CC_NZ, Jump::Near);
else
pCTRDontBranch = J_CC(CC_Z, true);
pCTRDontBranch = J_CC(CC_Z, Jump::Near);
}
FixupBranch pConditionDontBranch;

View File

@ -114,7 +114,7 @@ void Jit64::HandleNaNs(UGeckoInstruction inst, X64Reg xmm, X64Reg clobber, std::
// not paired-single
UCOMISD(xmm, R(xmm));
FixupBranch handle_nan = J_CC(CC_P, true);
FixupBranch handle_nan = J_CC(CC_P, Jump::Near);
SwitchToFarCode();
SetJumpTarget(handle_nan);
@ -140,7 +140,7 @@ void Jit64::HandleNaNs(UGeckoInstruction inst, X64Reg xmm, X64Reg clobber, std::
SetJumpTarget(fixup);
ORPD(xmm, MConst(psGeneratedQNaN));
FixupBranch done = J(true);
FixupBranch done = J(Jump::Near);
SwitchToNearCode();
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);
PTEST(clobber, R(clobber));
FixupBranch handle_nan = J_CC(CC_NZ, true);
FixupBranch handle_nan = J_CC(CC_NZ, Jump::Near);
SwitchToFarCode();
SetJumpTarget(handle_nan);
@ -182,7 +182,7 @@ void Jit64::HandleNaNs(UGeckoInstruction inst, X64Reg xmm, X64Reg clobber, std::
CMPPD(clobber, R(clobber), CMP_UNORD);
MOVMSKPD(RSCRATCH, R(clobber));
TEST(32, R(RSCRATCH), R(RSCRATCH));
FixupBranch handle_nan = J_CC(CC_NZ, true);
FixupBranch handle_nan = J_CC(CC_NZ, Jump::Near);
SwitchToFarCode();
SetJumpTarget(handle_nan);
@ -215,7 +215,7 @@ void Jit64::HandleNaNs(UGeckoInstruction inst, X64Reg xmm, X64Reg clobber, std::
ANDPD(clobber, MConst(psGeneratedQNaN));
ORPD(xmm, R(clobber));
FixupBranch done = J(true);
FixupBranch done = J(Jump::Near);
SwitchToNearCode();
SetJumpTarget(done);
}

View File

@ -444,13 +444,25 @@ void Jit64::DoMergedBranchCondition()
FixupBranch pDontBranch;
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)
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)
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).
pDontBranch = J(true);
{
// Test = 0, so jump over if != 0.
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();
@ -2717,7 +2729,7 @@ void Jit64::twX(UGeckoInstruction inst)
{
if (inst.TO & (1 << i))
{
FixupBranch f = J_CC(conditions[i], true);
FixupBranch f = J_CC(conditions[i], Jump::Near);
fixups.push_back(f);
}
}

View File

@ -338,7 +338,7 @@ void Jit64::dcbx(UGeckoInstruction inst)
MOV(32, R(tmp), R(effective_address));
SHR(32, R(tmp), Imm8(5));
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)
{
@ -372,7 +372,7 @@ void Jit64::dcbx(UGeckoInstruction inst)
ABI_PopRegistersAndAdjustStack(registersInUse, 0);
asm_routines.ResetStack(*this);
FixupBranch done = J(true);
FixupBranch done = J(Jump::Near);
SwitchToNearCode();
SetJumpTarget(done);
}
@ -432,7 +432,7 @@ void Jit64::dcbz(UGeckoInstruction inst)
SHR(32, R(RSCRATCH), Imm8(PowerPC::BAT_INDEX_SHIFT));
TEST(32, MComplex(RSCRATCH2, RSCRATCH, SCALE_4, 0), Imm32(PowerPC::BAT_PHYSICAL_BIT));
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.
XORPS(XMM0, R(XMM0));
@ -451,7 +451,7 @@ void Jit64::dcbz(UGeckoInstruction inst)
if (emit_fast_path)
{
FixupBranch end_far_code = J(true);
FixupBranch end_far_code = J(Jump::Near);
SwitchToNearCode();
SetJumpTarget(end_far_code);
}

View File

@ -167,19 +167,19 @@ FixupBranch Jit64::JumpIfCRFieldBit(int field, int bit, bool jump_if_set)
{
case PowerPC::CR_SO_BIT: // check bit 59 set
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
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
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
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:
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
// interrupts as soon as possible.
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),
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)
MOV(64, R(RSCRATCH), ImmPtr(&m_system.GetProcessorInterface().m_interrupt_cause));
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));
WriteExternalExceptionExit();

View File

@ -35,7 +35,7 @@ void JitBlockCache::WriteLinkBlock(const JitBlock::LinkData& source, const JitBl
else
{
Gen::XEmitter emit(location, location + 5);
emit.JMP(address, true);
emit.JMP(address, Gen::XEmitter::Jump::Near);
}
}
}

View File

@ -61,7 +61,7 @@ void EmuCodeBlock::MemoryExceptionCheck()
if (js.trampolineExceptionHandler)
{
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;
}
@ -72,7 +72,7 @@ void EmuCodeBlock::MemoryExceptionCheck()
if (m_jit.jo.memcheck && !js.fastmemLoadStore && !js.fixupExceptionHandler)
{
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;
}
}
@ -99,7 +99,7 @@ FixupBranch EmuCodeBlock::BATAddressLookup(X64Reg addr, X64Reg tmp, const void*
MOV(32, R(addr), MComplex(tmp, addr, SCALE_4, 0));
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,
@ -128,7 +128,7 @@ FixupBranch EmuCodeBlock::CheckIfSafeAddress(const OpArg& reg_value, X64Reg reg_
if (registers_in_use[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,
@ -380,7 +380,7 @@ void EmuCodeBlock::SafeLoadToReg(X64Reg reg_value, const Gen::OpArg& opAddress,
if (m_far_code.Enabled())
SwitchToFarCode();
else
exit = J(true);
exit = J(Jump::Near);
SetJumpTarget(slow);
}
@ -425,7 +425,7 @@ void EmuCodeBlock::SafeLoadToReg(X64Reg reg_value, const Gen::OpArg& opAddress,
{
if (m_far_code.Enabled())
{
exit = J(true);
exit = J(Jump::Near);
SwitchToNearCode();
}
SetJumpTarget(exit);
@ -549,7 +549,7 @@ void EmuCodeBlock::SafeWriteRegToReg(OpArg reg_value, X64Reg reg_addr, int acces
if (m_far_code.Enabled())
SwitchToFarCode();
else
exit = J(true);
exit = J(Jump::Near);
SetJumpTarget(slow);
}
@ -601,7 +601,7 @@ void EmuCodeBlock::SafeWriteRegToReg(OpArg reg_value, X64Reg reg_addr, int acces
{
if (m_far_code.Enabled())
{
exit = J(true);
exit = J(Jump::Near);
SwitchToNearCode();
}
SetJumpTarget(exit);
@ -866,14 +866,14 @@ void EmuCodeBlock::ConvertSingleToDouble(X64Reg dst, X64Reg src, bool src_is_gpr
UCOMISS(dst, R(dst));
CVTSS2SD(dst, R(dst));
FixupBranch nanConversion = J_CC(CC_P, true);
FixupBranch nanConversion = J_CC(CC_P, Jump::Near);
SwitchToFarCode();
SetJumpTarget(nanConversion);
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));
FixupBranch continue2 = J(true);
FixupBranch continue2 = J(Jump::Near);
SwitchToNearCode();
SetJumpTarget(continue1);

View File

@ -128,7 +128,7 @@ void CommonAsmRoutines::GenFrsqrte()
// Negatives, zeros, denormals, infinities and NaNs take the complex path.
LEA(32, RSCRATCH2, MDisp(RSCRATCH_EXTRA, -1));
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));
SAR(32, R(RSCRATCH_EXTRA), Imm8(1));

View File

@ -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,
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);
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,
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);
return trampoline;

View File

@ -66,7 +66,7 @@ OpArg VertexLoaderX64::GetVertexAddr(CPArray array, VertexComponentFormat attrib
if (array == CPArray::Position)
{
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]));
MOV(64, R(scratch2), MPIC(&VertexLoaderManager::cached_arraybases[array]));

View File

@ -292,7 +292,7 @@ TEST_F(x64EmitterTest, JMP)
"jmp .-8");
emitter->NOP(6);
emitter->JMP(code_buffer, true);
emitter->JMP(code_buffer, XEmitter::Jump::Near);
ExpectDisassembly("multibyte nop "
"jmp .-11");
}