CPU/Recompiler: Add unconditional EmitBranch
This commit is contained in:
parent
4f2c1e1a6b
commit
390b6da0b8
|
@ -78,6 +78,9 @@ public:
|
||||||
Value EmitLoadGuestMemory(const Value& address, RegSize size);
|
Value EmitLoadGuestMemory(const Value& address, RegSize size);
|
||||||
void EmitStoreGuestMemory(const Value& address, const Value& value);
|
void EmitStoreGuestMemory(const Value& address, const Value& value);
|
||||||
|
|
||||||
|
// Unconditional branch to pointer. May allocate a scratch register.
|
||||||
|
void EmitBranch(const void* address, bool allow_scratch = true);
|
||||||
|
|
||||||
// Branching, generates two paths.
|
// Branching, generates two paths.
|
||||||
void EmitBranch(Condition condition, Reg lr_reg, Value&& branch_target);
|
void EmitBranch(Condition condition, Reg lr_reg, Value&& branch_target);
|
||||||
void EmitBranchIfBitClear(HostReg reg, RegSize size, u8 bit, LabelType* label);
|
void EmitBranchIfBitClear(HostReg reg, RegSize size, u8 bit, LabelType* label);
|
||||||
|
|
|
@ -1390,6 +1390,24 @@ void CodeGenerator::EmitCancelInterpreterLoadDelayForReg(Reg reg)
|
||||||
m_emit->Bind(&skip_cancel);
|
m_emit->Bind(&skip_cancel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CodeGenerator::EmitBranch(const void* address, bool allow_scratch)
|
||||||
|
{
|
||||||
|
const s64 jump_distance =
|
||||||
|
static_cast<s64>(reinterpret_cast<intptr_t>(address) - reinterpret_cast<intptr_t>(GetCurrentCodePointer()));
|
||||||
|
Assert(Common::IsAligned(jump_distance, 4));
|
||||||
|
if (a64::Instruction::IsValidImmPCOffset(a64::UncondBranchType, jump_distance >> 2))
|
||||||
|
{
|
||||||
|
m_emit->b(jump_distance >> 2);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert(allow_scratch);
|
||||||
|
|
||||||
|
Value temp = m_register_cache.AllocateScratch(RegSize_64);
|
||||||
|
m_emit->Mov(GetHostReg64(temp), reinterpret_cast<uintptr_t>(address));
|
||||||
|
m_emit->br(GetHostReg64(temp));
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static void EmitConditionalJump(Condition condition, bool invert, a64::MacroAssembler* emit, const T& label)
|
static void EmitConditionalJump(Condition condition, bool invert, a64::MacroAssembler* emit, const T& label)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1792,6 +1792,21 @@ void CodeGenerator::EmitCancelInterpreterLoadDelayForReg(Reg reg)
|
||||||
m_emit->L(skip_cancel);
|
m_emit->L(skip_cancel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CodeGenerator::EmitBranch(const void* address, bool allow_scratch)
|
||||||
|
{
|
||||||
|
if (Xbyak::inner::IsInInt32(reinterpret_cast<uintptr_t>(address)))
|
||||||
|
{
|
||||||
|
m_emit->jmp(address);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert(allow_scratch);
|
||||||
|
|
||||||
|
Value temp = m_register_cache.AllocateScratch(RegSize_64);
|
||||||
|
m_emit->mov(GetHostReg64(temp), reinterpret_cast<uintptr_t>(address));
|
||||||
|
m_emit->jmp(GetHostReg64(temp));
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static void EmitConditionalJump(Condition condition, bool invert, Xbyak::CodeGenerator* emit, const T& label)
|
static void EmitConditionalJump(Condition condition, bool invert, Xbyak::CodeGenerator* emit, const T& label)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue