summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authordegasus <wickmarkus@web.de>2015-07-11 12:22:13 +0200
committerdegasus <wickmarkus@web.de>2015-07-12 09:41:32 +0200
commitb8dd68beef384f2717a70d5d5d0235ee13701e98 (patch)
treeab07ccab5955edb877188778b76f8514bf6b4dc2 /Source/Core
parentb30ae1b9f8a49b0b19e2802ce4f91f6505cd0682 (diff)
JitArm64: Far Code Cache
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Common/Arm64Emitter.cpp7
-rw-r--r--Source/Core/Common/Arm64Emitter.h4
-rw-r--r--Source/Core/Core/PowerPC/JitArm64/Jit.cpp7
-rw-r--r--Source/Core/Core/PowerPC/JitArm64/Jit.h25
4 files changed, 37 insertions, 6 deletions
diff --git a/Source/Core/Common/Arm64Emitter.cpp b/Source/Core/Common/Arm64Emitter.cpp
index 6eaa4fdfca..f5b00de3cc 100644
--- a/Source/Core/Common/Arm64Emitter.cpp
+++ b/Source/Core/Common/Arm64Emitter.cpp
@@ -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);
diff --git a/Source/Core/Common/Arm64Emitter.h b/Source/Core/Common/Arm64Emitter.h
index 6939984308..c4ce6ab253 100644
--- a/Source/Core/Common/Arm64Emitter.h
+++ b/Source/Core/Common/Arm64Emitter.h
@@ -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()
diff --git a/Source/Core/Core/PowerPC/JitArm64/Jit.cpp b/Source/Core/Core/PowerPC/JitArm64/Jit.cpp
index c1bf82b05d..e346ea198e 100644
--- a/Source/Core/Core/PowerPC/JitArm64/Jit.cpp
+++ b/Source/Core/Core/PowerPC/JitArm64/Jit.cpp
@@ -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;
}
diff --git a/Source/Core/Core/PowerPC/JitArm64/Jit.h b/Source/Core/Core/PowerPC/JitArm64/Jit.h
index 6b2d0c3fe8..476af4c3d8 100644
--- a/Source/Core/Core/PowerPC/JitArm64/Jit.h
+++ b/Source/Core/Core/PowerPC/JitArm64/Jit.h
@@ -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);