diff --git a/Source/Core/Core/CMakeLists.txt b/Source/Core/Core/CMakeLists.txt
index a1bb58f238..5629e21f86 100644
--- a/Source/Core/Core/CMakeLists.txt
+++ b/Source/Core/Core/CMakeLists.txt
@@ -167,6 +167,8 @@ set(SRCS ActionReplay.cpp
PowerPC/SignatureDB/DSYSignatureDB.cpp
PowerPC/SignatureDB/SignatureDB.cpp
PowerPC/JitInterface.cpp
+ PowerPC/CachedInterpreter/CachedInterpreter.cpp
+ PowerPC/CachedInterpreter/InterpreterBlockCache.cpp
PowerPC/Interpreter/Interpreter_Branch.cpp
PowerPC/Interpreter/Interpreter.cpp
PowerPC/Interpreter/Interpreter_FloatingPoint.cpp
@@ -179,7 +181,6 @@ set(SRCS ActionReplay.cpp
PowerPC/JitCommon/JitAsmCommon.cpp
PowerPC/JitCommon/JitBase.cpp
PowerPC/JitCommon/JitCache.cpp
- PowerPC/CachedInterpreter.cpp
PowerPC/JitILCommon/IR.cpp
PowerPC/JitILCommon/JitILBase_Branch.cpp
PowerPC/JitILCommon/JitILBase_LoadStore.cpp
diff --git a/Source/Core/Core/Core.vcxproj b/Source/Core/Core/Core.vcxproj
index 13492f654f..944085b82b 100644
--- a/Source/Core/Core/Core.vcxproj
+++ b/Source/Core/Core/Core.vcxproj
@@ -204,6 +204,8 @@
+
+
@@ -251,7 +253,6 @@
-
@@ -424,6 +425,8 @@
+
+
@@ -451,7 +454,6 @@
-
diff --git a/Source/Core/Core/Core.vcxproj.filters b/Source/Core/Core/Core.vcxproj.filters
index 00023e98f4..fb6c05b4cc 100644
--- a/Source/Core/Core/Core.vcxproj.filters
+++ b/Source/Core/Core/Core.vcxproj.filters
@@ -31,6 +31,9 @@
{ebd24590-dfdc-433e-a411-21723e4b7cb5}
+
+ {d6410c05-51f9-422a-83d5-f0723e34b607}
+
{523f8d77-4aa6-4762-8f27-96f02b5070b4}
@@ -273,6 +276,12 @@
HLE
+
+ PowerPC\Cached Interpreter
+
+
+ PowerPC\Cached Interpreter
+
PowerPC\Interpreter
@@ -624,9 +633,6 @@
HW %28Flipper/Hollywood%29\Wiimote
-
- PowerPC
-
PowerPC
@@ -869,6 +875,12 @@
HLE
+
+ PowerPC\Cached Interpreter
+
+
+ PowerPC\Cached Interpreter
+
PowerPC\Interpreter
@@ -1229,9 +1241,6 @@
PowerPC
-
- PowerPC
-
PowerPC
diff --git a/Source/Core/Core/PowerPC/CachedInterpreter.cpp b/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp
similarity index 92%
rename from Source/Core/Core/PowerPC/CachedInterpreter.cpp
rename to Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp
index a1f3c7ce08..44bf711e90 100644
--- a/Source/Core/Core/PowerPC/CachedInterpreter.cpp
+++ b/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp
@@ -2,7 +2,7 @@
// Licensed under GPLv2+
// Refer to the license.txt file included.
-#include "Core/PowerPC/CachedInterpreter.h"
+#include "Core/PowerPC/CachedInterpreter/CachedInterpreter.h"
#include "Common/CommonTypes.h"
#include "Common/Logging/Log.h"
#include "Core/ConfigManager.h"
@@ -20,7 +20,7 @@ void CachedInterpreter::Init()
jo.enableBlocklink = false;
- JitBaseBlockCache::Init();
+ m_block_cache.Init();
UpdateMemoryOptions();
code_block.m_stats = &js.st;
@@ -30,12 +30,12 @@ void CachedInterpreter::Init()
void CachedInterpreter::Shutdown()
{
- JitBaseBlockCache::Shutdown();
+ m_block_cache.Shutdown();
}
void CachedInterpreter::ExecuteOneBlock()
{
- const u8* normal_entry = JitBaseBlockCache::Dispatch();
+ const u8* normal_entry = m_block_cache.Dispatch();
const Instruction* code = reinterpret_cast(normal_entry);
for (; code->type != Instruction::INSTRUCTION_ABORT; ++code)
@@ -123,7 +123,7 @@ static bool CheckDSI(u32 data)
void CachedInterpreter::Jit(u32 address)
{
- if (m_code.size() >= CODE_SIZE / sizeof(Instruction) - 0x1000 || IsFull() ||
+ if (m_code.size() >= CODE_SIZE / sizeof(Instruction) - 0x1000 || m_block_cache.IsFull() ||
SConfig::GetInstance().bJITNoBlockCache)
{
ClearCache();
@@ -140,8 +140,8 @@ void CachedInterpreter::Jit(u32 address)
return;
}
- int block_num = AllocateBlock(PC);
- JitBlock* b = GetBlock(block_num);
+ int block_num = m_block_cache.AllocateBlock(PC);
+ JitBlock* b = m_block_cache.GetBlock(block_num);
js.blockStart = PC;
js.firstFPInstructionFound = false;
@@ -212,12 +212,12 @@ void CachedInterpreter::Jit(u32 address)
b->codeSize = (u32)(GetCodePtr() - b->checkedEntry);
b->originalSize = code_block.m_num_instructions;
- FinalizeBlock(block_num, jo.enableBlocklink, b->checkedEntry);
+ m_block_cache.FinalizeBlock(block_num, jo.enableBlocklink, b->checkedEntry);
}
void CachedInterpreter::ClearCache()
{
m_code.clear();
- JitBaseBlockCache::Clear();
+ m_block_cache.Clear();
UpdateMemoryOptions();
}
diff --git a/Source/Core/Core/PowerPC/CachedInterpreter.h b/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.h
similarity index 88%
rename from Source/Core/Core/PowerPC/CachedInterpreter.h
rename to Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.h
index 42291fe509..4aade83ba2 100644
--- a/Source/Core/Core/PowerPC/CachedInterpreter.h
+++ b/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.h
@@ -7,10 +7,11 @@
#include
#include "Common/CommonTypes.h"
+#include "Core/PowerPC/CachedInterpreter/InterpreterBlockCache.h"
#include "Core/PowerPC/JitCommon/JitBase.h"
#include "Core/PowerPC/PPCAnalyst.h"
-class CachedInterpreter : public JitBase, JitBaseBlockCache
+class CachedInterpreter : public JitBase
{
public:
CachedInterpreter() : code_buffer(32000) {}
@@ -26,9 +27,8 @@ public:
void Jit(u32 address) override;
- JitBaseBlockCache* GetBlockCache() override { return this; }
+ JitBaseBlockCache* GetBlockCache() override { return &m_block_cache; }
const char* GetName() override { return "Cached Interpreter"; }
- void WriteLinkBlock(const JitBlock::LinkData& source, const JitBlock* dest) override {}
const CommonAsmRoutinesBase* GetAsmRoutines() override { return nullptr; }
private:
struct Instruction
@@ -59,6 +59,7 @@ private:
const u8* GetCodePtr() { return (u8*)(m_code.data() + m_code.size()); }
void ExecuteOneBlock();
+ BlockCache m_block_cache{*this};
std::vector m_code;
PPCAnalyst::CodeBuffer code_buffer;
};
diff --git a/Source/Core/Core/PowerPC/CachedInterpreter/InterpreterBlockCache.cpp b/Source/Core/Core/PowerPC/CachedInterpreter/InterpreterBlockCache.cpp
new file mode 100644
index 0000000000..f5ed742744
--- /dev/null
+++ b/Source/Core/Core/PowerPC/CachedInterpreter/InterpreterBlockCache.cpp
@@ -0,0 +1,14 @@
+// Copyright 2016 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#include "Core/PowerPC/CachedInterpreter/InterpreterBlockCache.h"
+#include "Core/PowerPC/JitCommon/JitBase.h"
+
+BlockCache::BlockCache(JitBase& jit) : JitBaseBlockCache{jit}
+{
+}
+
+void BlockCache::WriteLinkBlock(const JitBlock::LinkData& source, const JitBlock* dest)
+{
+}
diff --git a/Source/Core/Core/PowerPC/CachedInterpreter/InterpreterBlockCache.h b/Source/Core/Core/PowerPC/CachedInterpreter/InterpreterBlockCache.h
new file mode 100644
index 0000000000..0dea8227c7
--- /dev/null
+++ b/Source/Core/Core/PowerPC/CachedInterpreter/InterpreterBlockCache.h
@@ -0,0 +1,18 @@
+// Copyright 2016 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "Core/PowerPC/JitCommon/JitCache.h"
+
+class JitBase;
+
+class BlockCache final : public JitBaseBlockCache
+{
+public:
+ explicit BlockCache(JitBase& jit);
+
+private:
+ void WriteLinkBlock(const JitBlock::LinkData& source, const JitBlock* dest) override;
+};
diff --git a/Source/Core/Core/PowerPC/Jit64Common/BlockCache.cpp b/Source/Core/Core/PowerPC/Jit64Common/BlockCache.cpp
index ec06a5ec6e..4c9f27df6c 100644
--- a/Source/Core/Core/PowerPC/Jit64Common/BlockCache.cpp
+++ b/Source/Core/Core/PowerPC/Jit64Common/BlockCache.cpp
@@ -8,10 +8,14 @@
#include "Common/x64Emitter.h"
#include "Core/PowerPC/JitCommon/JitBase.h"
+JitBlockCache::JitBlockCache(JitBase& jit) : JitBaseBlockCache{jit}
+{
+}
+
void JitBlockCache::WriteLinkBlock(const JitBlock::LinkData& source, const JitBlock* dest)
{
u8* location = source.exitPtrs;
- const u8* address = dest ? dest->checkedEntry : g_jit->GetAsmRoutines()->dispatcher;
+ const u8* address = dest ? dest->checkedEntry : m_jit.GetAsmRoutines()->dispatcher;
Gen::XEmitter emit(location);
if (*location == 0xE8)
{
diff --git a/Source/Core/Core/PowerPC/Jit64Common/BlockCache.h b/Source/Core/Core/PowerPC/Jit64Common/BlockCache.h
index 3d3f884e26..a5b096a076 100644
--- a/Source/Core/Core/PowerPC/Jit64Common/BlockCache.h
+++ b/Source/Core/Core/PowerPC/Jit64Common/BlockCache.h
@@ -6,8 +6,13 @@
#include "Core/PowerPC/JitCommon/JitCache.h"
+class JitBase;
+
class JitBlockCache : public JitBaseBlockCache
{
+public:
+ explicit JitBlockCache(JitBase& jit);
+
private:
void WriteLinkBlock(const JitBlock::LinkData& source, const JitBlock* dest) override;
void WriteDestroyBlock(const JitBlock& block) override;
diff --git a/Source/Core/Core/PowerPC/Jit64Common/Jit64Base.h b/Source/Core/Core/PowerPC/Jit64Common/Jit64Base.h
index 9638cd60ab..49f4e52a9f 100644
--- a/Source/Core/Core/PowerPC/Jit64Common/Jit64Base.h
+++ b/Source/Core/Core/PowerPC/Jit64Common/Jit64Base.h
@@ -39,7 +39,7 @@ class Jitx86Base : public JitBase, public QuantizedMemoryRoutines
{
protected:
bool BackPatch(u32 emAddress, SContext* ctx);
- JitBlockCache blocks;
+ JitBlockCache blocks{*this};
TrampolineCache trampolines;
public:
diff --git a/Source/Core/Core/PowerPC/JitArm64/Jit.h b/Source/Core/Core/PowerPC/JitArm64/Jit.h
index d0975db561..5e2685c6a9 100644
--- a/Source/Core/Core/PowerPC/JitArm64/Jit.h
+++ b/Source/Core/Core/PowerPC/JitArm64/Jit.h
@@ -178,7 +178,7 @@ private:
Arm64GPRCache gpr;
Arm64FPRCache fpr;
- JitArm64BlockCache blocks;
+ JitArm64BlockCache blocks{*this};
PPCAnalyst::CodeBuffer code_buffer;
diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64Cache.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64Cache.cpp
index f366ce3f8e..0672488181 100644
--- a/Source/Core/Core/PowerPC/JitArm64/JitArm64Cache.cpp
+++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64Cache.cpp
@@ -5,8 +5,13 @@
#include "Core/PowerPC/JitArm64/Jit.h"
#include "Common/CommonTypes.h"
#include "Core/PowerPC/JitArm64/JitArm64Cache.h"
+#include "Core/PowerPC/JitCommon/JitBase.h"
#include "Core/PowerPC/JitInterface.h"
+JitArm64BlockCache::JitArm64BlockCache(JitBase& jit) : JitBaseBlockCache{jit}
+{
+}
+
void JitArm64BlockCache::WriteLinkBlock(const JitBlock::LinkData& source, const JitBlock* dest)
{
u8* location = source.exitPtrs;
@@ -28,7 +33,7 @@ void JitArm64BlockCache::WriteLinkBlock(const JitBlock::LinkData& source, const
else
{
emit.MOVI2R(DISPATCHER_PC, source.exitAddress);
- emit.B(g_jit->GetAsmRoutines()->dispatcher);
+ emit.B(m_jit.GetAsmRoutines()->dispatcher);
}
emit.FlushIcache();
}
diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64Cache.h b/Source/Core/Core/PowerPC/JitArm64/JitArm64Cache.h
index 7d5ee9fb49..f4b1b3af7f 100644
--- a/Source/Core/Core/PowerPC/JitArm64/JitArm64Cache.h
+++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64Cache.h
@@ -6,10 +6,15 @@
#include "Core/PowerPC/JitCommon/JitCache.h"
+class JitBase;
+
typedef void (*CompiledCode)();
class JitArm64BlockCache : public JitBaseBlockCache
{
+public:
+ explicit JitArm64BlockCache(JitBase& jit);
+
private:
void WriteLinkBlock(const JitBlock::LinkData& source, const JitBlock* dest) override;
void WriteDestroyBlock(const JitBlock& block) override;
diff --git a/Source/Core/Core/PowerPC/JitCommon/JitCache.cpp b/Source/Core/Core/PowerPC/JitCommon/JitCache.cpp
index 016e214fd4..265bef38d9 100644
--- a/Source/Core/Core/PowerPC/JitCommon/JitCache.cpp
+++ b/Source/Core/Core/PowerPC/JitCommon/JitCache.cpp
@@ -35,11 +35,12 @@ static void ClearCacheThreadSafe(u64 userdata, s64 cyclesdata)
JitInterface::ClearCache();
}
-bool JitBaseBlockCache::IsFull() const
+JitBaseBlockCache::JitBaseBlockCache(JitBase& jit) : m_jit{jit}
{
- return GetNumBlocks() >= MAX_NUM_BLOCKS - 1;
}
+JitBaseBlockCache::~JitBaseBlockCache() = default;
+
void JitBaseBlockCache::Init()
{
s_clear_jit_cache_thread_safe = CoreTiming::RegisterEvent("clearJitCache", ClearCacheThreadSafe);
@@ -66,8 +67,8 @@ void JitBaseBlockCache::Clear()
else
Core::DisplayMessage("Clearing code cache.", 3000);
#endif
- g_jit->js.fifoWriteAddresses.clear();
- g_jit->js.pairedQuantizeAddresses.clear();
+ m_jit.js.fifoWriteAddresses.clear();
+ m_jit.js.pairedQuantizeAddresses.clear();
for (int i = 1; i < num_blocks; i++)
{
DestroyBlock(i, false);
@@ -82,15 +83,20 @@ void JitBaseBlockCache::Clear()
blocks[0].invalid = true;
}
+void JitBaseBlockCache::Reset()
+{
+ Shutdown();
+ Init();
+}
+
void JitBaseBlockCache::SchedulateClearCacheThreadSafe()
{
CoreTiming::ScheduleEvent(0, s_clear_jit_cache_thread_safe, 0, CoreTiming::FromThread::NON_CPU);
}
-void JitBaseBlockCache::Reset()
+bool JitBaseBlockCache::IsFull() const
{
- Shutdown();
- Init();
+ return GetNumBlocks() >= MAX_NUM_BLOCKS - 1;
}
JitBlock* JitBaseBlockCache::GetBlock(int no)
@@ -98,11 +104,21 @@ JitBlock* JitBaseBlockCache::GetBlock(int no)
return &blocks[no];
}
+JitBlock* JitBaseBlockCache::GetBlocks()
+{
+ return blocks.data();
+}
+
int JitBaseBlockCache::GetNumBlocks() const
{
return num_blocks;
}
+int* JitBaseBlockCache::GetICache()
+{
+ return iCache.data();
+}
+
int JitBaseBlockCache::AllocateBlock(u32 em_address)
{
JitBlock& b = blocks[num_blocks];
@@ -180,20 +196,6 @@ int JitBaseBlockCache::GetBlockNumberFromStartAddress(u32 addr, u32 msr)
return block_num;
}
-void JitBaseBlockCache::MoveBlockIntoFastCache(u32 addr, u32 msr)
-{
- int block_num = GetBlockNumberFromStartAddress(addr, msr);
- if (block_num < 0)
- {
- Jit(addr);
- }
- else
- {
- FastLookupEntryForAddress(addr) = block_num;
- LinkBlock(block_num);
- }
-}
-
const u8* JitBaseBlockCache::Dispatch()
{
int block_num = FastLookupEntryForAddress(PC);
@@ -208,6 +210,59 @@ const u8* JitBaseBlockCache::Dispatch()
return blocks[block_num].normalEntry;
}
+void JitBaseBlockCache::InvalidateICache(u32 address, const u32 length, bool forced)
+{
+ auto translated = PowerPC::JitCache_TranslateAddress(address);
+ if (!translated.valid)
+ return;
+ u32 pAddr = translated.address;
+
+ // Optimize the common case of length == 32 which is used by Interpreter::dcb*
+ bool destroy_block = true;
+ if (length == 32)
+ {
+ if (!valid_block.Test(pAddr / 32))
+ destroy_block = false;
+ else
+ valid_block.Clear(pAddr / 32);
+ }
+
+ // destroy JIT blocks
+ // !! this works correctly under assumption that any two overlapping blocks end at the same
+ // address
+ if (destroy_block)
+ {
+ auto it = block_map.lower_bound(std::make_pair(pAddr, 0));
+ while (it != block_map.end() && it->first.second < pAddr + length)
+ {
+ DestroyBlock(it->second, true);
+ it = block_map.erase(it);
+ }
+
+ // If the code was actually modified, we need to clear the relevant entries from the
+ // FIFO write address cache, so we don't end up with FIFO checks in places they shouldn't
+ // be (this can clobber flags, and thus break any optimization that relies on flags
+ // being in the right place between instructions).
+ if (!forced)
+ {
+ for (u32 i = address; i < address + length; i += 4)
+ {
+ m_jit.js.fifoWriteAddresses.erase(i);
+ m_jit.js.pairedQuantizeAddresses.erase(i);
+ }
+ }
+ }
+}
+
+u32* JitBaseBlockCache::GetBlockBitSet() const
+{
+ return valid_block.m_valid_block.get();
+}
+
+void JitBaseBlockCache::WriteDestroyBlock(const JitBlock& block)
+{
+}
+
// Block linker
// Make sure to have as many blocks as possible compiled before calling this
// It's O(N), so it's fast :)
@@ -309,46 +364,21 @@ void JitBaseBlockCache::DestroyBlock(int block_num, bool invalidate)
WriteDestroyBlock(b);
}
-void JitBaseBlockCache::InvalidateICache(u32 address, const u32 length, bool forced)
+void JitBaseBlockCache::MoveBlockIntoFastCache(u32 addr, u32 msr)
{
- auto translated = PowerPC::JitCache_TranslateAddress(address);
- if (!translated.valid)
- return;
- u32 pAddr = translated.address;
-
- // Optimize the common case of length == 32 which is used by Interpreter::dcb*
- bool destroy_block = true;
- if (length == 32)
+ int block_num = GetBlockNumberFromStartAddress(addr, msr);
+ if (block_num < 0)
{
- if (!valid_block.Test(pAddr / 32))
- destroy_block = false;
- else
- valid_block.Clear(pAddr / 32);
+ Jit(addr);
}
-
- // destroy JIT blocks
- // !! this works correctly under assumption that any two overlapping blocks end at the same
- // address
- if (destroy_block)
+ else
{
- auto it = block_map.lower_bound(std::make_pair(pAddr, 0));
- while (it != block_map.end() && it->first.second < pAddr + length)
- {
- DestroyBlock(it->second, true);
- it = block_map.erase(it);
- }
-
- // If the code was actually modified, we need to clear the relevant entries from the
- // FIFO write address cache, so we don't end up with FIFO checks in places they shouldn't
- // be (this can clobber flags, and thus break any optimization that relies on flags
- // being in the right place between instructions).
- if (!forced)
- {
- for (u32 i = address; i < address + length; i += 4)
- {
- g_jit->js.fifoWriteAddresses.erase(i);
- g_jit->js.pairedQuantizeAddresses.erase(i);
- }
- }
+ FastLookupEntryForAddress(addr) = block_num;
+ LinkBlock(block_num);
}
}
+
+int& JitBaseBlockCache::FastLookupEntryForAddress(u32 address)
+{
+ return iCache[(address >> 2) & iCache_Mask];
+}
diff --git a/Source/Core/Core/PowerPC/JitCommon/JitCache.h b/Source/Core/Core/PowerPC/JitCommon/JitCache.h
index 0694400177..0b1f23482e 100644
--- a/Source/Core/Core/PowerPC/JitCommon/JitCache.h
+++ b/Source/Core/Core/PowerPC/JitCommon/JitCache.h
@@ -12,6 +12,8 @@
#include "Common/CommonTypes.h"
+class JitBase;
+
// A JitBlock is block of compiled code which corresponds to the PowerPC
// code at a given address.
//
@@ -112,11 +114,61 @@ public:
static constexpr u32 iCache_Num_Elements = 0x10000;
static constexpr u32 iCache_Mask = iCache_Num_Elements - 1;
+ explicit JitBaseBlockCache(JitBase& jit);
+ virtual ~JitBaseBlockCache();
+
+ void Init();
+ void Shutdown();
+ void Clear();
+ void Reset();
+ void SchedulateClearCacheThreadSafe();
+
+ bool IsFull() const;
+
+ // Code Cache
+ JitBlock* GetBlock(int block_num);
+ JitBlock* GetBlocks();
+ int GetNumBlocks() const;
+ int* GetICache();
+
+ int AllocateBlock(u32 em_address);
+ void FinalizeBlock(int block_num, bool block_link, const u8* code_ptr);
+
+ // Look for the block in the slow but accurate way.
+ // This function shall be used if FastLookupEntryForAddress() failed.
+ int GetBlockNumberFromStartAddress(u32 em_address, u32 msr);
+
+ // Get the normal entry for the block associated with the current program
+ // counter. This will JIT code if necessary. (This is the reference
+ // implementation; high-performance JITs will want to use a custom
+ // assembly version.)
+ const u8* Dispatch();
+
+ void InvalidateICache(u32 address, const u32 length, bool forced);
+
+ u32* GetBlockBitSet() const;
+
+protected:
+ JitBase& m_jit;
+
private:
+ virtual void WriteLinkBlock(const JitBlock::LinkData& source, const JitBlock* dest) = 0;
+ virtual void WriteDestroyBlock(const JitBlock& block);
+
+ void LinkBlockExits(int i);
+ void LinkBlock(int i);
+ void UnlinkBlock(int i);
+ void DestroyBlock(int block_num, bool invalidate);
+
+ void MoveBlockIntoFastCache(u32 em_address, u32 msr);
+
+ // Fast but risky block lookup based on iCache.
+ int& FastLookupEntryForAddress(u32 address);
+
// We store the metadata of all blocks in a linear way within this array.
// Note: blocks[0] must not be used as it is referenced as invalid block in iCache.
std::array blocks; // number -> JitBlock
- int num_blocks;
+ int num_blocks = 1;
// links_to hold all exit points of all valid blocks in a reverse way.
// It is used to query all blocks which links to an address.
@@ -138,51 +190,4 @@ private:
// This array is indexed with the masked PC and likely holds the correct block id.
// This is used as a fast cache of start_block_map used in the assembly dispatcher.
std::array iCache; // start_addr & mask -> number
-
- void LinkBlockExits(int i);
- void LinkBlock(int i);
- void UnlinkBlock(int i);
-
- void DestroyBlock(int block_num, bool invalidate);
-
- void MoveBlockIntoFastCache(u32 em_address, u32 msr);
-
- // Fast but risky block lookup based on iCache.
- int& FastLookupEntryForAddress(u32 address) { return iCache[(address >> 2) & iCache_Mask]; }
- // Virtual for overloaded
- virtual void WriteLinkBlock(const JitBlock::LinkData& source, const JitBlock* dest) = 0;
- virtual void WriteDestroyBlock(const JitBlock& block) {}
-public:
- JitBaseBlockCache() : num_blocks(1) {}
- virtual ~JitBaseBlockCache() {}
- int AllocateBlock(u32 em_address);
- void FinalizeBlock(int block_num, bool block_link, const u8* code_ptr);
-
- void Clear();
- void SchedulateClearCacheThreadSafe();
- void Init();
- void Shutdown();
- void Reset();
-
- bool IsFull() const;
-
- // Code Cache
- JitBlock* GetBlock(int block_num);
- JitBlock* GetBlocks() { return blocks.data(); }
- int* GetICache() { return iCache.data(); }
- int GetNumBlocks() const;
-
- // Look for the block in the slow but accurate way.
- // This function shall be used if FastLookupEntryForAddress() failed.
- int GetBlockNumberFromStartAddress(u32 em_address, u32 msr);
-
- // Get the normal entry for the block associated with the current program
- // counter. This will JIT code if necessary. (This is the reference
- // implementation; high-performance JITs will want to use a custom
- // assembly version.)
- const u8* Dispatch();
-
- void InvalidateICache(u32 address, const u32 length, bool forced);
-
- u32* GetBlockBitSet() const { return valid_block.m_valid_block.get(); }
};
diff --git a/Source/Core/Core/PowerPC/JitInterface.cpp b/Source/Core/Core/PowerPC/JitInterface.cpp
index e22a9a4e11..d02377264c 100644
--- a/Source/Core/Core/PowerPC/JitInterface.cpp
+++ b/Source/Core/Core/PowerPC/JitInterface.cpp
@@ -13,7 +13,7 @@
#endif
#include "Core/Core.h"
-#include "Core/PowerPC/CachedInterpreter.h"
+#include "Core/PowerPC/CachedInterpreter/CachedInterpreter.h"
#include "Core/PowerPC/JitCommon/JitBase.h"
#include "Core/PowerPC/JitInterface.h"
#include "Core/PowerPC/PPCSymbolDB.h"