|
|
@@ -25,6 +25,7 @@
|
|
|
|
#include "../../Core.h"
|
|
|
|
#include "../../Core.h"
|
|
|
|
#include "../../PatchEngine.h"
|
|
|
|
#include "../../PatchEngine.h"
|
|
|
|
#include "../../CoreTiming.h"
|
|
|
|
#include "../../CoreTiming.h"
|
|
|
|
|
|
|
|
#include "../../ConfigManager.h"
|
|
|
|
#include "../PowerPC.h"
|
|
|
|
#include "../PowerPC.h"
|
|
|
|
#include "../Profiler.h"
|
|
|
|
#include "../Profiler.h"
|
|
|
|
#include "../PPCTables.h"
|
|
|
|
#include "../PPCTables.h"
|
|
|
@@ -152,8 +153,7 @@ ps_adds1
|
|
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
//#define ENABLE_JITIL_PROFILING
|
|
|
|
#ifdef _WIN32
|
|
|
|
#ifdef ENABLE_JITIL_PROFILING
|
|
|
|
|
|
|
|
// For profiling
|
|
|
|
// For profiling
|
|
|
|
// FIXME: This is currently for windows only.
|
|
|
|
// FIXME: This is currently for windows only.
|
|
|
|
#include <unordered_map>
|
|
|
|
#include <unordered_map>
|
|
|
@@ -170,13 +170,13 @@ namespace JitILProfiler {
|
|
|
|
static std::tr1::unordered_map<u64, Performance> profiledData;
|
|
|
|
static std::tr1::unordered_map<u64, Performance> profiledData;
|
|
|
|
// These functions need to be static function
|
|
|
|
// These functions need to be static function
|
|
|
|
// because they are called with ABI_CallFunction().
|
|
|
|
// because they are called with ABI_CallFunction().
|
|
|
|
static void begin(u32 higher, u32 lower) {
|
|
|
|
static void Begin(u32 higher, u32 lower) {
|
|
|
|
hash = (((u64)higher) << 32) | lower;
|
|
|
|
hash = (((u64)higher) << 32) | lower;
|
|
|
|
LARGE_INTEGER largeInteger;
|
|
|
|
LARGE_INTEGER largeInteger;
|
|
|
|
QueryPerformanceCounter(&largeInteger);
|
|
|
|
QueryPerformanceCounter(&largeInteger);
|
|
|
|
beginTime = largeInteger.QuadPart;
|
|
|
|
beginTime = largeInteger.QuadPart;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
static void end() {
|
|
|
|
static void End() {
|
|
|
|
LARGE_INTEGER largeInteger;
|
|
|
|
LARGE_INTEGER largeInteger;
|
|
|
|
QueryPerformanceCounter(&largeInteger);
|
|
|
|
QueryPerformanceCounter(&largeInteger);
|
|
|
|
const u64 endTime = largeInteger.QuadPart;
|
|
|
|
const u64 endTime = largeInteger.QuadPart;
|
|
|
@@ -202,7 +202,22 @@ namespace JitILProfiler {
|
|
|
|
fclose(file);
|
|
|
|
fclose(file);
|
|
|
|
file = NULL;
|
|
|
|
file = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} finalizer; // Is this a bad manner?
|
|
|
|
};
|
|
|
|
|
|
|
|
std::auto_ptr<JitILProfilerFinalizer> finalizer;
|
|
|
|
|
|
|
|
static void Init() {
|
|
|
|
|
|
|
|
finalizer = std::auto_ptr<JitILProfilerFinalizer>(new JitILProfilerFinalizer);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
static void Shutdown() {
|
|
|
|
|
|
|
|
finalizer.reset();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
namespace JitILProfiler {
|
|
|
|
|
|
|
|
// FIXME: Dummy functions for linux. Please implement them.
|
|
|
|
|
|
|
|
static void Begin(u32 higher, u32 lower) { }
|
|
|
|
|
|
|
|
static void End() { }
|
|
|
|
|
|
|
|
static void Init() { }
|
|
|
|
|
|
|
|
static void Shutdown() { }
|
|
|
|
};
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
@@ -248,6 +263,10 @@ void JitIL::Init()
|
|
|
|
|
|
|
|
|
|
|
|
blocks.Init();
|
|
|
|
blocks.Init();
|
|
|
|
asm_routines.Init();
|
|
|
|
asm_routines.Init();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bJITILTimeProfiling) {
|
|
|
|
|
|
|
|
JitILProfiler::Init();
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void JitIL::ClearCache()
|
|
|
|
void JitIL::ClearCache()
|
|
|
@@ -259,6 +278,10 @@ void JitIL::ClearCache()
|
|
|
|
|
|
|
|
|
|
|
|
void JitIL::Shutdown()
|
|
|
|
void JitIL::Shutdown()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bJITILTimeProfiling) {
|
|
|
|
|
|
|
|
JitILProfiler::Shutdown();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
FreeCodeSpace();
|
|
|
|
FreeCodeSpace();
|
|
|
|
|
|
|
|
|
|
|
|
blocks.Shutdown();
|
|
|
|
blocks.Shutdown();
|
|
|
@@ -346,9 +369,9 @@ void JitIL::Cleanup()
|
|
|
|
void JitIL::WriteExit(u32 destination, int exit_num)
|
|
|
|
void JitIL::WriteExit(u32 destination, int exit_num)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
Cleanup();
|
|
|
|
Cleanup();
|
|
|
|
#ifdef ENABLE_JITIL_PROFILING
|
|
|
|
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bJITILTimeProfiling) {
|
|
|
|
ABI_CallFunction(JitILProfiler::end);
|
|
|
|
ABI_CallFunction(JitILProfiler::End);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
SUB(32, M(&CoreTiming::downcount), js.downcountAmount > 127 ? Imm32(js.downcountAmount) : Imm8(js.downcountAmount));
|
|
|
|
SUB(32, M(&CoreTiming::downcount), js.downcountAmount > 127 ? Imm32(js.downcountAmount) : Imm8(js.downcountAmount));
|
|
|
|
|
|
|
|
|
|
|
|
//If nobody has taken care of this yet (this can be removed when all branches are done)
|
|
|
|
//If nobody has taken care of this yet (this can be removed when all branches are done)
|
|
|
@@ -375,9 +398,9 @@ void JitIL::WriteExitDestInOpArg(const Gen::OpArg& arg)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
MOV(32, M(&PC), arg);
|
|
|
|
MOV(32, M(&PC), arg);
|
|
|
|
Cleanup();
|
|
|
|
Cleanup();
|
|
|
|
#ifdef ENABLE_JITIL_PROFILING
|
|
|
|
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bJITILTimeProfiling) {
|
|
|
|
ABI_CallFunction(JitILProfiler::end);
|
|
|
|
ABI_CallFunction(JitILProfiler::End);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
SUB(32, M(&CoreTiming::downcount), js.downcountAmount > 127 ? Imm32(js.downcountAmount) : Imm8(js.downcountAmount));
|
|
|
|
SUB(32, M(&CoreTiming::downcount), js.downcountAmount > 127 ? Imm32(js.downcountAmount) : Imm8(js.downcountAmount));
|
|
|
|
JMP(asm_routines.dispatcher, true);
|
|
|
|
JMP(asm_routines.dispatcher, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
@@ -386,9 +409,9 @@ void JitIL::WriteRfiExitDestInOpArg(const Gen::OpArg& arg)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
MOV(32, M(&PC), arg);
|
|
|
|
MOV(32, M(&PC), arg);
|
|
|
|
Cleanup();
|
|
|
|
Cleanup();
|
|
|
|
#ifdef ENABLE_JITIL_PROFILING
|
|
|
|
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bJITILTimeProfiling) {
|
|
|
|
ABI_CallFunction(JitILProfiler::end);
|
|
|
|
ABI_CallFunction(JitILProfiler::End);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
SUB(32, M(&CoreTiming::downcount), js.downcountAmount > 127 ? Imm32(js.downcountAmount) : Imm8(js.downcountAmount));
|
|
|
|
SUB(32, M(&CoreTiming::downcount), js.downcountAmount > 127 ? Imm32(js.downcountAmount) : Imm8(js.downcountAmount));
|
|
|
|
JMP(asm_routines.testExceptions, true);
|
|
|
|
JMP(asm_routines.testExceptions, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
@@ -396,9 +419,9 @@ void JitIL::WriteRfiExitDestInOpArg(const Gen::OpArg& arg)
|
|
|
|
void JitIL::WriteExceptionExit()
|
|
|
|
void JitIL::WriteExceptionExit()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
Cleanup();
|
|
|
|
Cleanup();
|
|
|
|
#ifdef ENABLE_JITIL_PROFILING
|
|
|
|
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bJITILTimeProfiling) {
|
|
|
|
ABI_CallFunction(JitILProfiler::end);
|
|
|
|
ABI_CallFunction(JitILProfiler::End);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
SUB(32, M(&CoreTiming::downcount), js.downcountAmount > 127 ? Imm32(js.downcountAmount) : Imm8(js.downcountAmount));
|
|
|
|
SUB(32, M(&CoreTiming::downcount), js.downcountAmount > 127 ? Imm32(js.downcountAmount) : Imm8(js.downcountAmount));
|
|
|
|
JMP(asm_routines.testExceptions, true);
|
|
|
|
JMP(asm_routines.testExceptions, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
@@ -533,7 +556,7 @@ const u8* JitIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
|
|
|
|
|
|
|
|
|
|
|
|
js.rewriteStart = (u8*)GetCodePtr();
|
|
|
|
js.rewriteStart = (u8*)GetCodePtr();
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef ENABLE_JITIL_PROFILING
|
|
|
|
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bJITILTimeProfiling) {
|
|
|
|
// For profiling
|
|
|
|
// For profiling
|
|
|
|
u64 codeHash = -1;
|
|
|
|
u64 codeHash = -1;
|
|
|
|
for (int i = 0; i < (int)size; i++)
|
|
|
|
for (int i = 0; i < (int)size; i++)
|
|
|
@@ -542,8 +565,8 @@ const u8* JitIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
|
|
|
|
// Ported from boost::hash
|
|
|
|
// Ported from boost::hash
|
|
|
|
codeHash ^= inst + (codeHash << 6) + (codeHash >> 2);
|
|
|
|
codeHash ^= inst + (codeHash << 6) + (codeHash >> 2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ABI_CallFunctionCC(JitILProfiler::begin, (u32)(codeHash >> 32), (u32)codeHash);
|
|
|
|
ABI_CallFunctionCC(JitILProfiler::Begin, (u32)(codeHash >> 32), (u32)codeHash);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Start up IR builder (structure that collects the
|
|
|
|
// Start up IR builder (structure that collects the
|
|
|
|
// instruction processed by the JIT routines)
|
|
|
|
// instruction processed by the JIT routines)
|
|
|
|