diff --git a/Source/Core/Core/PowerPC/JitArm64/Jit.cpp b/Source/Core/Core/PowerPC/JitArm64/Jit.cpp index 7a9eebcc1d..161caa5081 100644 --- a/Source/Core/Core/PowerPC/JitArm64/Jit.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/Jit.cpp @@ -4,8 +4,10 @@ #include "Common/Arm64Emitter.h" #include "Common/Common.h" +#include "Common/PerformanceCounter.h" #include "Core/PatchEngine.h" +#include "Core/PowerPC/Profiler.h" #include "Core/PowerPC/JitArm64/Jit.h" #include "Core/PowerPC/JitArm64/JitArm64_RegCache.h" #include "Core/PowerPC/JitArm64/JitArm64_Tables.h" @@ -106,6 +108,9 @@ void JitArm64::WriteExit(u32 destination) { DoDownCount(); + if (Profiler::g_ProfileBlocks) + EndTimeProfile(js.curBlock); + //If nobody has taken care of this yet (this can be removed when all branches are done) JitBlock *b = js.curBlock; JitBlock::LinkData linkData; @@ -140,6 +145,10 @@ void JitArm64::WriteExceptionExit(ARM64Reg dest) STR(INDEX_UNSIGNED, dest, X29, PPCSTATE_OFF(npc)); gpr.Unlock(dest); DoDownCount(); + + if (Profiler::g_ProfileBlocks) + EndTimeProfile(js.curBlock); + MOVI2R(EncodeRegTo64(dest), (u64)&PowerPC::CheckExceptions); BLR(EncodeRegTo64(dest)); LDR(INDEX_UNSIGNED, dest, X29, PPCSTATE_OFF(npc)); @@ -153,6 +162,9 @@ void JitArm64::WriteExceptionExit() { DoDownCount(); + if (Profiler::g_ProfileBlocks) + EndTimeProfile(js.curBlock); + ARM64Reg WA = gpr.GetReg(); ARM64Reg XA = EncodeRegTo64(WA); LDR(INDEX_UNSIGNED, WA, X29, PPCSTATE_OFF(pc)); @@ -173,6 +185,10 @@ void JitArm64::WriteExitDestInR(ARM64Reg Reg) STR(INDEX_UNSIGNED, Reg, X29, PPCSTATE_OFF(pc)); gpr.Unlock(Reg); DoDownCount(); + + if (Profiler::g_ProfileBlocks) + EndTimeProfile(js.curBlock); + MOVI2R(EncodeRegTo64(Reg), (u64)asm_routines.dispatcher); BR(EncodeRegTo64(Reg)); } @@ -185,6 +201,32 @@ void JitArm64::DumpCode(const u8* start, const u8* end) WARN_LOG(DYNA_REC, "Code dump from %p to %p:\n%s", start, end, output.c_str()); } +void JitArm64::BeginTimeProfile(JitBlock* b) +{ + b->ticCounter = 0; + b->ticStart = 0; + b->ticStop = 0; + + MOVI2R(X1, (u64)QueryPerformanceCounter); + MOVI2R(X0, (u64)&b->ticStart); + BLR(X1); +} + +void JitArm64::EndTimeProfile(JitBlock* b) +{ + MOVI2R(X1, (u64)QueryPerformanceCounter); + MOVI2R(X0, (u64)&b->ticStop); + BLR(X1); + + MOVI2R(X0, (u64)&b->ticStart); + LDR(INDEX_UNSIGNED, X1, X0, 0); // Start + LDR(INDEX_UNSIGNED, X2, X0, 8); // Stop + LDR(INDEX_UNSIGNED, X3, X0, 16); // Counter + SUB(X2, X2, X1); + ADD(X3, X3, X2); + STR(INDEX_UNSIGNED, X3, X0, 16); +} + void JitArm64::Run() { CompiledCode pExecAddr = (CompiledCode)asm_routines.enterCode; @@ -256,6 +298,21 @@ const u8* JitArm64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitB SetJumpTarget(bail); } + // Conditionally add profiling code. + if (Profiler::g_ProfileBlocks) + { + ARM64Reg WA = gpr.GetReg(); + ARM64Reg WB = gpr.GetReg(); + ARM64Reg XA = EncodeRegTo64(WA); + ARM64Reg XB = EncodeRegTo64(WB); + MOVI2R(XA, (u64)&b->runCount); + LDR(INDEX_UNSIGNED, XB, XA, 0); + ADD(XB, XB, 1); + STR(INDEX_UNSIGNED, XB, XA, 0); + gpr.Unlock(WA, WB); + // get start tic + BeginTimeProfile(b); + } const u8 *normalEntry = GetCodePtr(); b->normalEntry = normalEntry; diff --git a/Source/Core/Core/PowerPC/JitArm64/Jit.h b/Source/Core/Core/PowerPC/JitArm64/Jit.h index cc60865a06..e0ee7c5a83 100644 --- a/Source/Core/Core/PowerPC/JitArm64/Jit.h +++ b/Source/Core/Core/PowerPC/JitArm64/Jit.h @@ -200,6 +200,10 @@ private: void DoDownCount(); + // Profiling + void BeginTimeProfile(JitBlock* b); + void EndTimeProfile(JitBlock* b); + // Exits void WriteExit(u32 destination); void WriteExceptionExit(Arm64Gen::ARM64Reg dest);