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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

View File

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

View File

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

View File

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

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, 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;

View File

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

View File

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