JitArm64: Far Code Cache
This commit is contained in:
parent
b30ae1b9f8
commit
b8dd68beef
|
@ -271,8 +271,8 @@ bool IsImmLogical(uint64_t value, unsigned int width, unsigned int *n, unsigned
|
|||
void ARM64XEmitter::SetCodePtr(u8* ptr)
|
||||
{
|
||||
m_code = ptr;
|
||||
m_startcode = m_code;
|
||||
m_lastCacheFlushEnd = ptr;
|
||||
if (!m_lastCacheFlushEnd)
|
||||
m_lastCacheFlushEnd = ptr;
|
||||
}
|
||||
|
||||
const u8* ARM64XEmitter::GetCodePtr() const
|
||||
|
@ -315,6 +315,9 @@ void ARM64XEmitter::FlushIcache()
|
|||
|
||||
void ARM64XEmitter::FlushIcacheSection(u8* start, u8* end)
|
||||
{
|
||||
if (start == end)
|
||||
return;
|
||||
|
||||
#if defined(IOS)
|
||||
// Header file says this is equivalent to: sys_icache_invalidate(start, end - start);
|
||||
sys_cache_control(kCacheFunctionPrepareForExecution, start, end - start);
|
||||
|
|
|
@ -324,7 +324,6 @@ class ARM64XEmitter
|
|||
|
||||
private:
|
||||
u8* m_code;
|
||||
u8* m_startcode;
|
||||
u8* m_lastCacheFlushEnd;
|
||||
|
||||
void EncodeCompareBranchInst(u32 op, ARM64Reg Rt, const void* ptr);
|
||||
|
@ -365,14 +364,13 @@ protected:
|
|||
|
||||
public:
|
||||
ARM64XEmitter()
|
||||
: m_code(nullptr), m_startcode(nullptr), m_lastCacheFlushEnd(nullptr)
|
||||
: m_code(nullptr), m_lastCacheFlushEnd(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
ARM64XEmitter(u8* code_ptr) {
|
||||
m_code = code_ptr;
|
||||
m_lastCacheFlushEnd = code_ptr;
|
||||
m_startcode = code_ptr;
|
||||
}
|
||||
|
||||
virtual ~ARM64XEmitter()
|
||||
|
|
|
@ -17,6 +17,7 @@ using namespace Arm64Gen;
|
|||
void JitArm64::Init()
|
||||
{
|
||||
AllocCodeSpace(CODE_SIZE);
|
||||
farcode.Init(SConfig::GetInstance().bMMU ? FARCODE_SIZE_MMU : FARCODE_SIZE);
|
||||
jo.enableBlocklink = true;
|
||||
jo.optimizeGatherPipe = true;
|
||||
UpdateMemoryOptions();
|
||||
|
@ -36,6 +37,7 @@ void JitArm64::Init()
|
|||
void JitArm64::ClearCache()
|
||||
{
|
||||
ClearCodeSpace();
|
||||
farcode.ClearCodeSpace();
|
||||
blocks.Clear();
|
||||
UpdateMemoryOptions();
|
||||
}
|
||||
|
@ -43,6 +45,7 @@ void JitArm64::ClearCache()
|
|||
void JitArm64::Shutdown()
|
||||
{
|
||||
FreeCodeSpace();
|
||||
farcode.Shutdown();
|
||||
blocks.Shutdown();
|
||||
asm_routines.Shutdown();
|
||||
}
|
||||
|
@ -276,7 +279,8 @@ void JitArm64::SingleStep()
|
|||
|
||||
void JitArm64::Jit(u32)
|
||||
{
|
||||
if (GetSpaceLeft() < 0x10000 || blocks.IsFull() || SConfig::GetInstance().bJITNoBlockCache)
|
||||
if (GetSpaceLeft() < 0x10000 || farcode.GetSpaceLeft() < 0x10000 || blocks.IsFull() ||
|
||||
SConfig::GetInstance().bJITNoBlockCache)
|
||||
{
|
||||
ClearCache();
|
||||
}
|
||||
|
@ -450,5 +454,6 @@ const u8* JitArm64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitB
|
|||
b->originalSize = code_block.m_num_instructions;
|
||||
|
||||
FlushIcache();
|
||||
farcode.FlushIcache();
|
||||
return start;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,15 @@
|
|||
|
||||
#define PPCSTATE_OFF(elem) (offsetof(PowerPC::PowerPCState, elem))
|
||||
|
||||
// A place to throw blocks of code we don't want polluting the cache, e.g. rarely taken
|
||||
// exception branches.
|
||||
class FarCodeCacheArm64 : public Arm64Gen::ARM64CodeBlock
|
||||
{
|
||||
public:
|
||||
void Init(int size) { AllocCodeSpace(size); }
|
||||
void Shutdown() { FreeCodeSpace(); }
|
||||
};
|
||||
|
||||
// Some asserts to make sure we will be able to load everything
|
||||
static_assert(PPCSTATE_OFF(spr[1023]) <= 16380, "LDR(32bit) can't reach the last SPR");
|
||||
static_assert((PPCSTATE_OFF(ps[0][0]) % 8) == 0, "LDR(64bit VFP) requires FPRs to be 8 byte aligned");
|
||||
|
@ -185,6 +194,22 @@ private:
|
|||
|
||||
ARM64FloatEmitter m_float_emit;
|
||||
|
||||
FarCodeCacheArm64 farcode;
|
||||
u8* nearcode; // Backed up when we switch to far code.
|
||||
|
||||
// Simple functions to switch between near and far code emitting
|
||||
void SwitchToFarCode()
|
||||
{
|
||||
nearcode = GetWritableCodePtr();
|
||||
SetCodePtr(farcode.GetWritableCodePtr());
|
||||
}
|
||||
|
||||
void SwitchToNearCode()
|
||||
{
|
||||
farcode.SetCodePtr(GetWritableCodePtr());
|
||||
SetCodePtr(nearcode);
|
||||
}
|
||||
|
||||
// Dump a memory range of code
|
||||
void DumpCode(const u8* start, const u8* end);
|
||||
|
||||
|
|
Loading…
Reference in New Issue