summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorhrydgard <hrydgard@gmail.com>2008-12-20 12:10:59 +0000
committerhrydgard <hrydgard@gmail.com>2008-12-20 12:10:59 +0000
commit614dc1069e08366828f6d97818812eda1ad0dc91 (patch)
tree42cbbb9c7678a594f14338f4b27817454b6447c9 /Source/Core
parentf0bb8f430af0c480dca20199756ba9be87ba7cd8 (diff)
More code reorganization.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@1605 8ced0084-cf51-0410-be5f-012b33b47a6e
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/Src/Console.cpp14
-rw-r--r--Source/Core/Core/Src/Debugger/Debugger_BreakPoints.cpp13
-rw-r--r--Source/Core/Core/Src/Debugger/Debugger_BreakPoints.h2
-rw-r--r--Source/Core/Core/Src/HW/Memmap.cpp4
-rw-r--r--Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_LoadStore.cpp2
-rw-r--r--Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp43
-rw-r--r--Source/Core/Core/Src/PowerPC/Jit64/Jit.h76
-rw-r--r--Source/Core/Core/Src/PowerPC/Jit64/JitAsm.cpp4
-rw-r--r--Source/Core/Core/Src/PowerPC/Jit64/JitBackpatch.cpp2
-rw-r--r--Source/Core/Core/Src/PowerPC/Jit64/JitCache.cpp98
-rw-r--r--Source/Core/Core/Src/PowerPC/Jit64/JitCache.h81
-rw-r--r--Source/Core/Core/Src/PowerPC/Jit64/Jit_Integer.cpp12
-rw-r--r--Source/Core/Core/Src/PowerPC/Profiler.cpp13
-rw-r--r--Source/Core/Core/Src/State.cpp13
-rw-r--r--Source/Core/DebuggerWX/Src/CodeWindow.cpp13
-rw-r--r--Source/Core/DebuggerWX/Src/JitWindow.cpp10
16 files changed, 202 insertions, 198 deletions
diff --git a/Source/Core/Core/Src/Console.cpp b/Source/Core/Core/Src/Console.cpp
index ebf99d92a1..3af897edec 100644
--- a/Source/Core/Core/Src/Console.cpp
+++ b/Source/Core/Core/Src/Console.cpp
@@ -35,12 +35,6 @@
void Console_Submit(const char *cmd)
{
- CASE1("jits")
- {
-#ifdef _M_X64
- jit.PrintStats();
-#endif
- }
CASE1("r")
{
Core::StartTrace(false);
@@ -57,7 +51,7 @@ void Console_Submit(const char *cmd)
u32 addr;
sscanf(cmd, "%s %08x", temp, &addr);
- if (addr!=0)
+ if (addr)
{
#ifdef LOGGING
u32 EA =
@@ -75,7 +69,7 @@ void Console_Submit(const char *cmd)
TCHAR temp[256];
u32 addr;
sscanf(cmd, "%s %08x", temp, &addr);
- if (addr!=0)
+ if (addr)
{
g_symbolDB.PrintCalls(addr);
}
@@ -89,7 +83,7 @@ void Console_Submit(const char *cmd)
TCHAR temp[256];
u32 addr;
sscanf(cmd, "%s %08x", temp, &addr);
- if (addr!=0)
+ if (addr)
{
g_symbolDB.PrintCallers(addr);
}
@@ -111,7 +105,7 @@ void Console_Submit(const char *cmd)
sscanf(cmd, "%s %08x %08x %s", temp, &start, &end, filename);
FILE *f = fopen(filename, "wb");
- for (u32 i=start; i<end; i++)
+ for (u32 i = start; i < end; i++)
{
u8 b = Memory::ReadUnchecked_U8(i);
fputc(b,f);
diff --git a/Source/Core/Core/Src/Debugger/Debugger_BreakPoints.cpp b/Source/Core/Core/Src/Debugger/Debugger_BreakPoints.cpp
index bdcc7ccb82..e4e5ae4247 100644
--- a/Source/Core/Core/Src/Debugger/Debugger_BreakPoints.cpp
+++ b/Source/Core/Core/Src/Debugger/Debugger_BreakPoints.cpp
@@ -28,6 +28,7 @@
#include "../HW/CPU.h"
#include "../Host.h"
#include "../PowerPC/SymbolDB.h"
+#include "../PowerPC/Jit64/Jit.h"
#include "Debugger_BreakPoints.h"
CBreakPoints::TBreakPoints CBreakPoints::m_BreakPoints;
@@ -90,7 +91,7 @@ TMemCheck *CBreakPoints::GetMemCheck(u32 address)
}
else
{
- if ((*iter).StartAddress==address)
+ if ((*iter).StartAddress == address)
return &(*iter);
}
}
@@ -99,16 +100,17 @@ TMemCheck *CBreakPoints::GetMemCheck(u32 address)
return 0;
}
-void CBreakPoints::AddBreakPoint(u32 _iAddress, bool temp)
+void CBreakPoints::AddBreakPoint(u32 em_address, bool temp)
{
- if (!IsAddressBreakPoint(_iAddress)) // only add new addresses
+ if (!IsAddressBreakPoint(em_address)) // only add new addresses
{
TBreakPoint pt; // breakpoint settings
pt.bOn = true;
pt.bTemporary = temp;
- pt.iAddress = _iAddress;
+ pt.iAddress = em_address;
m_BreakPoints.push_back(pt);
+ // jit.NotifyBreakpoint(em_address, true);
}
}
@@ -121,11 +123,10 @@ void CBreakPoints::RemoveBreakPoint(u32 _iAddress)
if ((*iter).iAddress == _iAddress)
{
m_BreakPoints.erase(iter);
+ // jit.NotifyBreakpoint(em_address, false);
break;
}
}
-
- Host_UpdateBreakPointView();
}
void CBreakPoints::ClearAllBreakPoints()
diff --git a/Source/Core/Core/Src/Debugger/Debugger_BreakPoints.h b/Source/Core/Core/Src/Debugger/Debugger_BreakPoints.h
index 92e746807c..28248ab525 100644
--- a/Source/Core/Core/Src/Debugger/Debugger_BreakPoints.h
+++ b/Source/Core/Core/Src/Debugger/Debugger_BreakPoints.h
@@ -72,7 +72,7 @@ public:
static bool IsTempBreakPoint(u32 _iAddress);
// AddBreakPoint
- static void AddBreakPoint(u32 _iAddress, bool temp=false);
+ static void AddBreakPoint(u32 em_address, bool temp=false);
// Remove Breakpoint
static void RemoveBreakPoint(u32 _iAddress);
diff --git a/Source/Core/Core/Src/HW/Memmap.cpp b/Source/Core/Core/Src/HW/Memmap.cpp
index 0dd15705b3..bda446bb58 100644
--- a/Source/Core/Core/Src/HW/Memmap.cpp
+++ b/Source/Core/Core/Src/HW/Memmap.cpp
@@ -757,9 +757,9 @@ bool AreMemoryBreakpointsActivated()
}
-u32 Read_Instruction(const u32 _Address)
+u32 Read_Instruction(const u32 em_address)
{
- return jit.GetOriginalCode(_Address);
+ return jit.GetBlockCache()->GetOriginalCode(em_address);
}
u32 Read_Opcode(const u32 _Address)
diff --git a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_LoadStore.cpp b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_LoadStore.cpp
index c9945f789a..2653771c35 100644
--- a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_LoadStore.cpp
+++ b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_LoadStore.cpp
@@ -340,7 +340,7 @@ void icbi(UGeckoInstruction _inst)
// VERY IMPORTANT when we start linking blocks
// There are a TON of these so hopefully we can make this mechanism
// fast in the JIT
- jit.InvalidateCodeRange(address, 0x20);
+ jit.GetBlockCache()->InvalidateCodeRange(address, 0x20);
}
void lbzux(UGeckoInstruction _inst)
diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp
index 3f7d753a3a..956a3d5da8 100644
--- a/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp
+++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp
@@ -196,20 +196,28 @@ namespace CPUCompare
trampolines.Init();
AllocCodeSpace(CODE_SIZE);
- InitCache();
+
+ blocks.Init();
asm_routines.Init();
}
void Jit64::Shutdown()
{
FreeCodeSpace();
- ShutdownCache();
+ blocks.Shutdown();
trampolines.Shutdown();
asm_routines.Shutdown();
}
- void Jit64::WriteCallInterpreter(UGeckoInstruction _inst)
+ void Jit64::EnterFastRun()
+ {
+ CompiledCode pExecAddr = (CompiledCode)asm_routines.enterCode;
+ pExecAddr();
+ //Will return when PowerPC::state changes
+ }
+
+ void Jit64::WriteCallInterpreter(UGeckoInstruction inst)
{
gpr.Flush(FLUSH_ALL);
fpr.Flush(FLUSH_ALL);
@@ -218,8 +226,14 @@ namespace CPUCompare
MOV(32, M(&PC), Imm32(js.compilerPC));
MOV(32, M(&NPC), Imm32(js.compilerPC + 4));
}
- Interpreter::_interpreterInstruction instr = GetInterpreterOp(_inst);
- ABI_CallFunctionC((void*)instr, _inst.hex);
+ Interpreter::_interpreterInstruction instr = GetInterpreterOp(inst);
+ ABI_CallFunctionC((void*)instr, inst.hex);
+ }
+
+ void Jit64::unknown_instruction(UGeckoInstruction inst)
+ {
+ // CCPU::Break();
+ PanicAlert("unknown_instruction %08x - Fix me ;)", inst.hex);
}
void Jit64::Default(UGeckoInstruction _inst)
@@ -286,11 +300,11 @@ namespace CPUCompare
b->exitPtrs[exit_num] = GetWritableCodePtr();
// Link opportunity!
- int block = GetBlockNumberFromAddress(destination);
+ int block = blocks.GetBlockNumberFromAddress(destination);
if (block >= 0 && jo.enableBlocklink)
{
// It exists! Joy of joy!
- JMP(GetBlock(block)->checkedEntry, true);
+ JMP(blocks.GetBlock(block)->checkedEntry, true);
b->linkStatus[exit_num] = true;
}
else
@@ -323,6 +337,21 @@ namespace CPUCompare
MOV(32, M(&PC), Imm32(js.compilerPC + 4));
JMP(asm_routines.testExceptions, true);
}
+
+ const u8 *Jit64::Jit(u32 em_address)
+ {
+ if (GetSpaceLeft() < 0x10000 || blocks.IsFull())
+ {
+ LOG(DYNA_REC, "JIT cache full - clearing.")
+ if (Core::g_CoreStartupParameter.bJITUnlimitedCache)
+ {
+ PanicAlert("What? JIT cache still full - clearing.");
+ }
+ ClearCache();
+ }
+
+ return blocks.Jit(em_address);
+ }
const u8* Jit64::DoJit(u32 emaddress, JitBlock &b)
{
diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit.h b/Source/Core/Core/Src/PowerPC/Jit64/Jit.h
index ef858c94a9..a73b677600 100644
--- a/Source/Core/Core/Src/PowerPC/Jit64/Jit.h
+++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit.h
@@ -71,37 +71,7 @@ public:
class Jit64 : public Gen::XCodeBlock
{
-public:
- // TODO(ector) - optimize this struct for size
- struct JitBlock
- {
- u32 exitAddress[2]; // 0xFFFFFFFF == unknown
- u8 *exitPtrs[2]; // to be able to rewrite the exit jump
- bool linkStatus[2];
-
- u32 originalAddress;
- u32 originalFirstOpcode; //to be able to restore
- u32 codeSize;
- u32 originalSize;
- int runCount; // for profiling.
-#ifdef _WIN32
- // we don't really need to save start and stop
- // TODO (mb2): ticStart and ticStop -> "local var" mean "in block" ... low priority ;)
- LARGE_INTEGER ticStart; // for profiling - time.
- LARGE_INTEGER ticStop; // for profiling - time.
- LARGE_INTEGER ticCounter; // for profiling - time.
-#endif
- const u8 *checkedEntry;
- bool invalid;
- int flags;
- };
private:
- enum BlockFlag
- {
- BLOCK_USE_GQR0 = 0x1, BLOCK_USE_GQR1 = 0x2, BLOCK_USE_GQR2 = 0x4, BLOCK_USE_GQR3 = 0x8,
- BLOCK_USE_GQR4 = 0x10, BLOCK_USE_GQR5 = 0x20, BLOCK_USE_GQR6 = 0x40, BLOCK_USE_GQR7 = 0x80,
- };
-
struct JitState
{
u32 compilerPC;
@@ -139,20 +109,14 @@ private:
bool accurateSinglePrecision;
};
-
+ JitBlockCache blocks;
TrampolineCache trampolines;
GPRRegCache gpr;
FPURegCache fpr;
- u8 **blockCodePointers;
-
- std::multimap<u32, int> links_to;
-
- JitBlock *blocks;
- int numBlocks;
-
public:
- typedef void (*CompiledCode)();
+ Jit64() {blocks.SetJit(this);}
+ ~Jit64() {}
JitState js;
JitOptions jo;
@@ -162,40 +126,24 @@ public:
void Init();
void Shutdown();
- void PrintStats();
-
// Jit!
- const u8* Jit(u32 emaddress);
+ const u8 *Jit(u32 emAddress); // calls blocks.Jit, which in turn calls DoJit below after setting up a block.
const u8* DoJit(u32 emaddress, JitBlock &b);
+ JitBlockCache *GetBlockCache() { return &blocks; }
+
+ void ClearCache()
+ {
+ blocks.Clear();
+ trampolines.ClearCodeSpace();
+ }
+
// Run!
void EnterFastRun();
const u8 *BackPatch(u8 *codePtr, int accessType, u32 emAddress, CONTEXT *ctx);
- // Code Cache
-
- u32 GetOriginalCode(u32 address);
- JitBlock *GetBlock(int no);
- void InvalidateCodeRange(u32 address, u32 length);
- int GetBlockNumberFromAddress(u32 address);
- CompiledCode GetCompiledCode(u32 address);
- CompiledCode GetCompiledCodeFromBlock(int blockNumber);
- int GetCodeSize();
- int GetNumBlocks();
- u8 **GetCodePointers();
- void DestroyBlocksWithFlag(BlockFlag death_flag);
- void LinkBlocks();
- void LinkBlockExits(int i);
- void LinkBlock(int i);
- void ClearCache();
- void InitCache();
- void ShutdownCache();
- void ResetCache();
- void DestroyBlock(int blocknum, bool invalidate);
- bool RangeIntersect(int s1, int e1, int s2, int e2) const;
-
#define JIT_OPCODE 0
// Utilities for use by opcodes
diff --git a/Source/Core/Core/Src/PowerPC/Jit64/JitAsm.cpp b/Source/Core/Core/Src/PowerPC/Jit64/JitAsm.cpp
index 0877ab9a05..17d2b508fb 100644
--- a/Source/Core/Core/Src/PowerPC/Jit64/JitAsm.cpp
+++ b/Source/Core/Core/Src/PowerPC/Jit64/JitAsm.cpp
@@ -169,10 +169,8 @@ void AsmRoutineManager::Generate()
ABI_PushAllCalleeSavedRegsAndAdjustStack();
- if (!jit.GetCodePointers() || !Memory::base)
- PanicAlert("Memory::base and jit.GetCodePointers() must return valid values");
MOV(64, R(RBX), Imm64((u64)Memory::base));
- MOV(64, R(R15), Imm64((u64)jit.GetCodePointers())); //It's below 2GB so 32 bits are good enough
+ MOV(64, R(R15), Imm64((u64)jit.GetBlockCache()->GetCodePointers())); //It's below 2GB so 32 bits are good enough
const u8 *outerLoop = GetCodePtr();
CALL((void *)&CoreTiming::Advance);
diff --git a/Source/Core/Core/Src/PowerPC/Jit64/JitBackpatch.cpp b/Source/Core/Core/Src/PowerPC/Jit64/JitBackpatch.cpp
index 569c2f4d73..65e5bbdea2 100644
--- a/Source/Core/Core/Src/PowerPC/Jit64/JitBackpatch.cpp
+++ b/Source/Core/Core/Src/PowerPC/Jit64/JitBackpatch.cpp
@@ -204,7 +204,7 @@ const u8 *Jit64::BackPatch(u8 *codePtr, int accessType, u32 emAddress, CONTEXT *
if (info.instructionSize < 3)
PanicAlert("instruction too small");
// We entered here with a BSWAP-ed EAX. We'll have to swap it back.
- ctx->Rax = Common::swap32(ctx->Rax);
+ ctx->Rax = Common::swap32((u32)ctx->Rax);
return codePtr - 2;
}
return 0;
diff --git a/Source/Core/Core/Src/PowerPC/Jit64/JitCache.cpp b/Source/Core/Core/Src/PowerPC/Jit64/JitCache.cpp
index 1c03f52efe..18a3df758a 100644
--- a/Source/Core/Core/Src/PowerPC/Jit64/JitCache.cpp
+++ b/Source/Core/Core/Src/PowerPC/Jit64/JitCache.cpp
@@ -24,8 +24,6 @@
//#define OPROFILE_REPORT
-#include <map>
-
#include "Common.h"
#include "../../Core.h"
#include "MemoryUtil.h"
@@ -50,31 +48,23 @@
#include <opagent.h>
#endif
-using namespace Gen;
-
#ifdef OPROFILE_REPORT
op_agent_t agent;
#endif
-#define INVALID_EXIT 0xFFFFFFFF
-
- enum
- {
- TRAMPOLINE_SIZE = 1024*1024,
- };
+using namespace Gen;
- int MAX_NUM_BLOCKS = 65536*2;
+#define INVALID_EXIT 0xFFFFFFFF
- void Jit64::PrintStats()
+ bool JitBlockCache::IsFull() const
{
- LOG(DYNA_REC, "JIT Statistics =======================");
- LOG(DYNA_REC, "Number of blocks currently: %i", numBlocks);
- LOG(DYNA_REC, "======================================");
+ return GetNumBlocks() >= MAX_NUM_BLOCKS - 1;
}
- void Jit64::InitCache()
+ void JitBlockCache::Init()
{
+ MAX_NUM_BLOCKS = 65536*2;
if (Core::g_CoreStartupParameter.bJITUnlimitedCache)
{
MAX_NUM_BLOCKS = 65536*8;
@@ -86,10 +76,10 @@ using namespace Gen;
blocks = new JitBlock[MAX_NUM_BLOCKS];
blockCodePointers = new u8*[MAX_NUM_BLOCKS];
- ClearCache();
+ Clear();
}
- void Jit64::ShutdownCache()
+ void JitBlockCache::Shutdown()
{
delete [] blocks;
delete [] blockCodePointers;
@@ -103,7 +93,7 @@ using namespace Gen;
// This clears the JIT cache. It's called from JitCache.cpp when the JIT cache
// is full and when saving and loading states.
- void Jit64::ClearCache()
+ void JitBlockCache::Clear()
{
Core::DisplayMessage("Cleared code cache.", 3000);
// Is destroying the blocks really necessary?
@@ -114,11 +104,9 @@ using namespace Gen;
links_to.clear();
numBlocks = 0;
memset(blockCodePointers, 0, sizeof(u8*)*MAX_NUM_BLOCKS);
-
- trampolines.ClearCodeSpace();
}
- void Jit64::DestroyBlocksWithFlag(BlockFlag death_flag)
+ void JitBlockCache::DestroyBlocksWithFlag(BlockFlag death_flag)
{
for (int i = 0; i < numBlocks; i++)
{
@@ -129,23 +117,23 @@ using namespace Gen;
}
}
- void Jit64::ResetCache()
+ void JitBlockCache::Reset()
{
- ShutdownCache();
- InitCache();
+ Shutdown();
+ Init();
}
- Jit64::JitBlock *Jit64::GetBlock(int no)
+ JitBlock *JitBlockCache::GetBlock(int no)
{
return &blocks[no];
}
- int Jit64::GetNumBlocks()
+ int JitBlockCache::GetNumBlocks() const
{
return numBlocks;
}
- bool Jit64::RangeIntersect(int s1, int e1, int s2, int e2) const
+ bool JitBlockCache::RangeIntersect(int s1, int e1, int s2, int e2) const
{
// check if any endpoint is inside the other range
if ( (s1 >= s2 && s1 <= e2) ||
@@ -162,18 +150,8 @@ using namespace Gen;
return jit.Jit(emAddress);
}
- const u8 *Jit64::Jit(u32 emAddress)
+ const u8 *JitBlockCache::Jit(u32 emAddress)
{
- if (GetSpaceLeft() < 0x10000 || numBlocks >= MAX_NUM_BLOCKS - 1)
- {
- LOG(DYNA_REC, "JIT cache full - clearing.")
- if (Core::g_CoreStartupParameter.bJITUnlimitedCache)
- {
- PanicAlert("What? JIT cache still full - clearing.");
- }
- ClearCache();
- }
-
JitBlock &b = blocks[numBlocks];
b.invalid = false;
b.originalAddress = emAddress;
@@ -185,10 +163,10 @@ using namespace Gen;
b.linkStatus[0] = false;
b.linkStatus[1] = false;
- blockCodePointers[numBlocks] = (u8*)DoJit(emAddress, b); //cast away const
+ blockCodePointers[numBlocks] = (u8*)jit->DoJit(emAddress, b); //cast away const
Memory::WriteUnchecked_U32((JIT_OPCODE << 26) | numBlocks, emAddress);
- if (jo.enableBlocklink) {
+ if (jit->jo.enableBlocklink) {
for (int i = 0; i < 2; i++) {
if (b.exitAddress[i] != INVALID_EXIT) {
links_to.insert(std::pair<u32, int>(b.exitAddress[i], numBlocks));
@@ -211,26 +189,12 @@ using namespace Gen;
return 0;
}
- void Jit64::unknown_instruction(UGeckoInstruction _inst)
- {
- // CCPU::Break();
- PanicAlert("unknown_instruction Jit64 - Fix me ;)");
- _dbg_assert_(DYNA_REC, 0);
- }
-
- u8 **Jit64::GetCodePointers()
+ u8 **JitBlockCache::GetCodePointers()
{
return blockCodePointers;
}
- void Jit64::EnterFastRun()
- {
- CompiledCode pExecAddr = (CompiledCode)asm_routines.enterCode;
- pExecAddr();
- //Will return when PowerPC::state changes
- }
-
- int Jit64::GetBlockNumberFromAddress(u32 addr)
+ int JitBlockCache::GetBlockNumberFromAddress(u32 addr)
{
if (!blocks)
return -1;
@@ -256,7 +220,7 @@ using namespace Gen;
}
}
- u32 Jit64::GetOriginalCode(u32 address)
+ u32 JitBlockCache::GetOriginalCode(u32 address)
{
int num = GetBlockNumberFromAddress(address);
if (num == -1)
@@ -265,7 +229,7 @@ using namespace Gen;
return blocks[num].originalFirstOpcode;
}
- Jit64::CompiledCode Jit64::GetCompiledCode(u32 address)
+ CompiledCode JitBlockCache::GetCompiledCode(u32 address)
{
int num = GetBlockNumberFromAddress(address);
if (num == -1)
@@ -274,7 +238,7 @@ using namespace Gen;
return (CompiledCode)blockCodePointers[num];
}
- Jit64::CompiledCode Jit64::GetCompiledCodeFromBlock(int blockNumber)
+ CompiledCode JitBlockCache::GetCompiledCodeFromBlock(int blockNumber)
{
return (CompiledCode)blockCodePointers[blockNumber];
}
@@ -285,7 +249,7 @@ using namespace Gen;
//Can be faster by doing a queue for blocks to link up, and only process those
//Should probably be done
- void Jit64::LinkBlockExits(int i)
+ void JitBlockCache::LinkBlockExits(int i)
{
JitBlock &b = blocks[i];
if (b.invalid)
@@ -310,10 +274,10 @@ using namespace Gen;
using namespace std;
- void Jit64::LinkBlock(int i)
+ void JitBlockCache::LinkBlock(int i)
{
LinkBlockExits(i);
- Jit64::JitBlock &b = blocks[i];
+ JitBlock &b = blocks[i];
std::map<u32, int>::iterator iter;
pair<multimap<u32, int>::iterator, multimap<u32, int>::iterator> ppp;
// equal_range(b) returns pair<iterator,iterator> representing the range
@@ -327,10 +291,10 @@ using namespace Gen;
}
}
- void Jit64::DestroyBlock(int blocknum, bool invalidate)
+ void JitBlockCache::DestroyBlock(int blocknum, bool invalidate)
{
u32 codebytes = (JIT_OPCODE << 26) | blocknum; //generate from i
- Jit64::JitBlock &b = blocks[blocknum];
+ JitBlock &b = blocks[blocknum];
b.invalid = 1;
if (codebytes == Memory::ReadFast32(b.originalAddress))
{
@@ -363,9 +327,9 @@ using namespace Gen;
}
- void Jit64::InvalidateCodeRange(u32 address, u32 length)
+ void JitBlockCache::InvalidateCodeRange(u32 address, u32 length)
{
- if (!jo.enableBlocklink)
+ if (!jit->jo.enableBlocklink)
return;
return;
//This is slow but should be safe (zelda needs it for block linking)
diff --git a/Source/Core/Core/Src/PowerPC/Jit64/JitCache.h b/Source/Core/Core/Src/PowerPC/Jit64/JitCache.h
index 49f865fde4..e3818e965f 100644
--- a/Source/Core/Core/Src/PowerPC/Jit64/JitCache.h
+++ b/Source/Core/Core/Src/PowerPC/Jit64/JitCache.h
@@ -17,8 +17,87 @@
#ifndef _JITCACHE_H
#define _JITCACHE_H
+#include <map>
+
#include "../Gekko.h"
-// Will soon introduce the JitBlockCache class here.
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
+enum BlockFlag
+{
+ BLOCK_USE_GQR0 = 0x1, BLOCK_USE_GQR1 = 0x2, BLOCK_USE_GQR2 = 0x4, BLOCK_USE_GQR3 = 0x8,
+ BLOCK_USE_GQR4 = 0x10, BLOCK_USE_GQR5 = 0x20, BLOCK_USE_GQR6 = 0x40, BLOCK_USE_GQR7 = 0x80,
+};
+
+// TODO(ector) - optimize this struct for size
+struct JitBlock
+{
+ u32 exitAddress[2]; // 0xFFFFFFFF == unknown
+ u8 *exitPtrs[2]; // to be able to rewrite the exit jump
+ bool linkStatus[2];
+
+ u32 originalAddress;
+ u32 originalFirstOpcode; //to be able to restore
+ u32 codeSize;
+ u32 originalSize;
+ int runCount; // for profiling.
+
+#ifdef _WIN32
+ // we don't really need to save start and stop
+ // TODO (mb2): ticStart and ticStop -> "local var" mean "in block" ... low priority ;)
+ LARGE_INTEGER ticStart; // for profiling - time.
+ LARGE_INTEGER ticStop; // for profiling - time.
+ LARGE_INTEGER ticCounter; // for profiling - time.
+#endif
+ const u8 *checkedEntry;
+ bool invalid;
+ int flags;
+};
+
+class Jit64;
+
+typedef void (*CompiledCode)();
+
+class JitBlockCache
+{
+ Jit64 *jit;
+
+ u8 **blockCodePointers;
+ JitBlock *blocks;
+ int numBlocks;
+ std::multimap<u32, int> links_to;
+
+ int MAX_NUM_BLOCKS;
+
+public:
+ JitBlockCache() {}
+
+ void SetJit(Jit64 *jit_) { jit = jit_; }
+
+ const u8* Jit(u32 emaddress);
+ void Clear();
+ void Init();
+ void Shutdown();
+ void Reset();
+
+ bool IsFull() const;
+ // Code Cache
+ u32 GetOriginalCode(u32 address);
+ JitBlock *GetBlock(int no);
+ void InvalidateCodeRange(u32 address, u32 length);
+ int GetBlockNumberFromAddress(u32 address);
+ CompiledCode GetCompiledCode(u32 address);
+ CompiledCode GetCompiledCodeFromBlock(int blockNumber);
+ int GetNumBlocks() const;
+ u8 **GetCodePointers();
+ void DestroyBlocksWithFlag(BlockFlag death_flag);
+ void LinkBlocks();
+ void LinkBlockExits(int i);
+ void LinkBlock(int i);
+ void DestroyBlock(int blocknum, bool invalidate);
+ bool RangeIntersect(int s1, int e1, int s2, int e2) const;
+};
#endif
diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit_Integer.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit_Integer.cpp
index 6891fe5987..81ae7beec7 100644
--- a/Source/Core/Core/Src/PowerPC/Jit64/Jit_Integer.cpp
+++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit_Integer.cpp
@@ -131,18 +131,6 @@
}
}
- /*
-
- if (js.next_inst.OPCD == 16) { // bcx
- if (!js.next_inst.LK && (js.next_inst.BO & BO_DONT_DECREMENT_FLAG))
- {
- // it's clear there's plenty of opportunity.
- //PanicAlert("merge");
- }
- }
- */
-
- // unsigned
void Jit64::cmpXX(UGeckoInstruction inst)
{
// USES_CR
diff --git a/Source/Core/Core/Src/PowerPC/Profiler.cpp b/Source/Core/Core/Src/PowerPC/Profiler.cpp
index 2d5a7c2dc1..1cd46c21e4 100644
--- a/Source/Core/Core/Src/PowerPC/Profiler.cpp
+++ b/Source/Core/Core/Src/PowerPC/Profiler.cpp
@@ -41,16 +41,16 @@ struct BlockStat
void WriteProfileResults(const char *filename) {
std::vector<BlockStat> stats;
- stats.reserve(jit.GetNumBlocks());
+ stats.reserve(jit.GetBlockCache()->GetNumBlocks());
u64 cost_sum = 0;
#ifdef _WIN32
u64 timecost_sum = 0;
LARGE_INTEGER countsPerSec;
QueryPerformanceFrequency(&countsPerSec);
#endif
- for (int i = 0; i < jit.GetNumBlocks(); i++)
+ for (int i = 0; i < jit.GetBlockCache()->GetNumBlocks(); i++)
{
- const Jit64::JitBlock *block = jit.GetBlock(i);
+ const JitBlock *block = jit.GetBlockCache()->GetBlock(i);
u64 cost = (block->originalSize / 4) * block->runCount; // rough heuristic. mem instructions should cost more.
#ifdef _WIN32
u64 timecost = block->ticCounter.QuadPart; // Indeed ;)
@@ -73,8 +73,9 @@ void WriteProfileResults(const char *filename) {
fprintf(f, "origAddr\tblkName\tcost\ttimeCost\tpercent\ttimePercent\tOvAllinBlkTime(ms)\tblkCodeSize\n");
for (unsigned int i = 0; i < stats.size(); i++)
{
- const Jit64::JitBlock *block = jit.GetBlock(stats[i].blockNum);
- if (block) {
+ const JitBlock *block = jit.GetBlockCache()->GetBlock(stats[i].blockNum);
+ if (block)
+ {
std::string name = g_symbolDB.GetDescription(block->originalAddress);
double percent = 100.0 * (double)stats[i].cost / (double)cost_sum;
#ifdef _WIN32
@@ -90,4 +91,4 @@ void WriteProfileResults(const char *filename) {
fclose(f);
}
-}
+} // namespace
diff --git a/Source/Core/Core/Src/State.cpp b/Source/Core/Core/Src/State.cpp
index dd238ed5d1..d6dc4ceea6 100644
--- a/Source/Core/Core/Src/State.cpp
+++ b/Source/Core/Core/Src/State.cpp
@@ -97,7 +97,7 @@ void SaveStateCallback(u64 userdata, int cyclesLate)
p.SetMode(PointerWrap::MODE_WRITE);
DoState(p);
- if(bCompressed) {
+ if (bCompressed) {
fwrite(&sz, sizeof(int), 1, f);
} else {
int zero = 0;
@@ -105,7 +105,7 @@ void SaveStateCallback(u64 userdata, int cyclesLate)
}
- if(bCompressed) {
+ if (bCompressed) {
if (lzo_init() != LZO_E_OK)
PanicAlert("Internal LZO Error - lzo_init() failed");
else {
@@ -163,15 +163,15 @@ void LoadStateCallback(u64 userdata, int cyclesLate)
bCompressedState = (sz != 0);
- if(bCompressedState) {
+ if (bCompressedState) {
if (lzo_init() != LZO_E_OK)
PanicAlert("Internal LZO Error - lzo_init() failed");
else {
lzo_uint i = 0;
buffer = new u8[sz];
- for(;;) {
- if(fread(&cur_len, 1, sizeof(int), f) == 0)
+ for (;;) {
+ if (fread(&cur_len, 1, sizeof(int), f) == 0)
break;
fread(out, 1, cur_len, f);
@@ -216,7 +216,8 @@ void State_Shutdown()
// nothing to do, here for consistency.
}
-std::string MakeStateFilename(int state_number) {
+std::string MakeStateFilename(int state_number)
+{
return StringFromFormat(FULL_STATESAVES_DIR "%s.s%02i", Core::GetStartupParameter().GetUniqueID().c_str(), state_number);
}
diff --git a/Source/Core/DebuggerWX/Src/CodeWindow.cpp b/Source/Core/DebuggerWX/Src/CodeWindow.cpp
index 4931c090b1..c1cd760bca 100644
--- a/Source/Core/DebuggerWX/Src/CodeWindow.cpp
+++ b/Source/Core/DebuggerWX/Src/CodeWindow.cpp
@@ -496,7 +496,9 @@ void CCodeWindow::OnJITOff(wxCommandEvent& event)
// creates the SCoreStartupParameter as a game is loaded
GetMenuBar()->Check(event.GetId(),!event.IsChecked());
wxMessageBox(_T("Please start a game before changing mode."));
- } else {
+ }
+ else
+ {
if (Core::GetState() != Core::CORE_RUN)
{
switch (event.GetId())
@@ -504,9 +506,8 @@ void CCodeWindow::OnJITOff(wxCommandEvent& event)
case IDM_JITUNLIMITED:
Core::g_CoreStartupParameter.bJITUnlimitedCache = event.IsChecked();
jit.ClearCache(); // allow InitCache() even after the game has started
- jit.InitCache();
GetMenuBar()->Enable(event.GetId(),!event.IsChecked());
- break;
+ return; // avoid a second jit.ClearCache
case IDM_JITOFF:
Core::g_CoreStartupParameter.bJITOff = event.IsChecked(); break;
case IDM_JITLSOFF:
@@ -531,15 +532,15 @@ void CCodeWindow::OnJITOff(wxCommandEvent& event)
Core::g_CoreStartupParameter.bJITSystemRegistersOff = event.IsChecked(); break;
}
jit.ClearCache();
- } else {
+ }
+ else
+ {
//event.Skip(); // this doesn't work
GetMenuBar()->Check(event.GetId(),!event.IsChecked());
wxMessageBox(_T("Please pause the emulator before changing mode."));
}
}
}
-// ==============
-
void CCodeWindow::OnJitMenu(wxCommandEvent& event)
{
diff --git a/Source/Core/DebuggerWX/Src/JitWindow.cpp b/Source/Core/DebuggerWX/Src/JitWindow.cpp
index 81c57e7328..4405b8b7fc 100644
--- a/Source/Core/DebuggerWX/Src/JitWindow.cpp
+++ b/Source/Core/DebuggerWX/Src/JitWindow.cpp
@@ -138,16 +138,16 @@ void CJitWindow::Compare(u32 em_address)
disassembler x64disasm;
x64disasm.set_syntax_intel();
- int block_num = jit.GetBlockNumberFromAddress(em_address);
+ int block_num = jit.GetBlockCache()->GetBlockNumberFromAddress(em_address);
if (block_num < 0)
{
for (int i = 0; i < 500; i++) {
- block_num = jit.GetBlockNumberFromAddress(em_address - 4 * i);
+ block_num = jit.GetBlockCache()->GetBlockNumberFromAddress(em_address - 4 * i);
if (block_num >= 0)
break;
}
if (block_num >= 0) {
- Jit64::JitBlock *block = jit.GetBlock(block_num);
+ JitBlock *block = jit.GetBlockCache()->GetBlock(block_num);
if (!(block->originalAddress <= em_address && block->originalSize + block->originalAddress >= em_address))
block_num = -1;
}
@@ -158,13 +158,13 @@ void CJitWindow::Compare(u32 em_address)
return;
}
}
- Jit64::JitBlock *block = jit.GetBlock(block_num);
+ JitBlock *block = jit.GetBlockCache()->GetBlock(block_num);
// 800031f0
// == Fill in x86 box
memset(xDis, 0, 65536);
- const u8 *code = (const u8 *)jit.GetCompiledCodeFromBlock(block_num);
+ const u8 *code = (const u8 *)jit.GetBlockCache()->GetCompiledCodeFromBlock(block_num);
u64 disasmPtr = (u64)code;
int size = block->codeSize;
const u8 *end = code + size;