mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-26 07:39:45 -06:00
Merge pull request #1800 from randomstuff/jit-register
Add support of more JIT-compiled code for profiling
This commit is contained in:
@ -71,19 +71,15 @@ void Shutdown()
|
|||||||
s_perf_map_file.Close();
|
s_perf_map_file.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Register(const void* base_address, u32 code_size,
|
void RegisterV(const void* base_address, u32 code_size,
|
||||||
const char* name, u32 original_address)
|
const char* format, va_list args)
|
||||||
{
|
{
|
||||||
#if !(defined USE_OPROFILE && USE_OPROFILE) && !defined(USE_VTUNE)
|
#if !(defined USE_OPROFILE && USE_OPROFILE) && !defined(USE_VTUNE)
|
||||||
if (!s_perf_map_file.IsOpen())
|
if (!s_perf_map_file.IsOpen())
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::string symbol_name;
|
std::string symbol_name = StringFromFormatV(format, args);
|
||||||
if (original_address)
|
|
||||||
symbol_name = StringFromFormat("%s_%x", name, original_address);
|
|
||||||
else
|
|
||||||
symbol_name = name;
|
|
||||||
|
|
||||||
#if defined USE_OPROFILE && USE_OPROFILE
|
#if defined USE_OPROFILE && USE_OPROFILE
|
||||||
op_write_native_code(s_agent, symbol_name.data(), (u64)base_address,
|
op_write_native_code(s_agent, symbol_name.data(), (u64)base_address,
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include <stdarg.h>
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
|
|
||||||
namespace JitRegister
|
namespace JitRegister
|
||||||
@ -10,7 +11,26 @@ namespace JitRegister
|
|||||||
|
|
||||||
void Init();
|
void Init();
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
void Register(const void* base_address, u32 code_size,
|
void RegisterV(const void* base_address, u32 code_size,
|
||||||
const char* name, u32 original_address=0);
|
const char* format, va_list args);
|
||||||
|
|
||||||
|
inline void Register(const void* base_address, u32 code_size,
|
||||||
|
const char* format, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, format);
|
||||||
|
RegisterV(base_address, code_size, format, args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Register(const void* start, const void* end,
|
||||||
|
const char* format, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, format);
|
||||||
|
u32 code_size = (u32) ((const char*) end - (const char*) start);
|
||||||
|
RegisterV(start, code_size, format, args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -95,28 +95,30 @@ bool CharArrayFromFormatV(char* out, int outsize, const char* format, va_list ar
|
|||||||
std::string StringFromFormat(const char* format, ...)
|
std::string StringFromFormat(const char* format, ...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
|
va_start(args, format);
|
||||||
|
std::string res = StringFromFormatV(format, args);
|
||||||
|
va_end(args);
|
||||||
|
return std::move(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string StringFromFormatV(const char* format, va_list args)
|
||||||
|
{
|
||||||
char *buf = nullptr;
|
char *buf = nullptr;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
int required = 0;
|
int required = _vscprintf(format, args);
|
||||||
|
|
||||||
va_start(args, format);
|
|
||||||
required = _vscprintf(format, args);
|
|
||||||
buf = new char[required + 1];
|
buf = new char[required + 1];
|
||||||
CharArrayFromFormatV(buf, required + 1, format, args);
|
CharArrayFromFormatV(buf, required + 1, format, args);
|
||||||
va_end(args);
|
|
||||||
|
|
||||||
std::string temp = buf;
|
std::string temp = buf;
|
||||||
delete[] buf;
|
delete[] buf;
|
||||||
#else
|
#else
|
||||||
va_start(args, format);
|
|
||||||
if (vasprintf(&buf, format, args) < 0)
|
if (vasprintf(&buf, format, args) < 0)
|
||||||
ERROR_LOG(COMMON, "Unable to allocate memory for string");
|
ERROR_LOG(COMMON, "Unable to allocate memory for string");
|
||||||
va_end(args);
|
|
||||||
|
|
||||||
std::string temp = buf;
|
std::string temp = buf;
|
||||||
free(buf);
|
free(buf);
|
||||||
#endif
|
#endif
|
||||||
return temp;
|
return std::move(temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
// For Debugging. Read out an u8 array.
|
// For Debugging. Read out an u8 array.
|
||||||
|
@ -13,6 +13,8 @@
|
|||||||
|
|
||||||
#include "Common/Common.h"
|
#include "Common/Common.h"
|
||||||
|
|
||||||
|
std::string StringFromFormatV(const char* format, va_list args);
|
||||||
|
|
||||||
std::string StringFromFormat(const char* format, ...)
|
std::string StringFromFormat(const char* format, ...)
|
||||||
#if !defined _WIN32
|
#if !defined _WIN32
|
||||||
// On compilers that support function attributes, this gives StringFromFormat
|
// On compilers that support function attributes, this gives StringFromFormat
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
// Licensed under GPLv2
|
// Licensed under GPLv2
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include "Common/JitRegister.h"
|
||||||
#include "Common/MemoryUtil.h"
|
#include "Common/MemoryUtil.h"
|
||||||
|
|
||||||
#include "Core/PowerPC/Jit64/Jit.h"
|
#include "Core/PowerPC/Jit64/Jit.h"
|
||||||
@ -200,6 +201,8 @@ void Jit64AsmRoutineManager::Generate()
|
|||||||
ABI_PopRegistersAndAdjustStack(ABI_ALL_CALLEE_SAVED, 8, 16);
|
ABI_PopRegistersAndAdjustStack(ABI_ALL_CALLEE_SAVED, 8, 16);
|
||||||
RET();
|
RET();
|
||||||
|
|
||||||
|
JitRegister::Register(enterCode, GetCodePtr(), "JIT_Loop");
|
||||||
|
|
||||||
GenerateCommon();
|
GenerateCommon();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
// Licensed under GPLv2
|
// Licensed under GPLv2
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include "Common/JitRegister.h"
|
||||||
#include "Common/MathUtil.h"
|
#include "Common/MathUtil.h"
|
||||||
#include "Common/x64ABI.h"
|
#include "Common/x64ABI.h"
|
||||||
#include "Common/x64Emitter.h"
|
#include "Common/x64Emitter.h"
|
||||||
@ -20,6 +21,8 @@ using namespace Gen;
|
|||||||
|
|
||||||
void CommonAsmRoutines::GenFifoWrite(int size)
|
void CommonAsmRoutines::GenFifoWrite(int size)
|
||||||
{
|
{
|
||||||
|
const void* start = GetCodePtr();
|
||||||
|
|
||||||
// Assume value in RSCRATCH
|
// Assume value in RSCRATCH
|
||||||
u32 gather_pipe = (u32)(u64)GPFifo::m_gatherPipe;
|
u32 gather_pipe = (u32)(u64)GPFifo::m_gatherPipe;
|
||||||
_assert_msg_(DYNA_REC, gather_pipe <= 0x7FFFFFFF, "Gather pipe not in low 2GB of memory!");
|
_assert_msg_(DYNA_REC, gather_pipe <= 0x7FFFFFFF, "Gather pipe not in low 2GB of memory!");
|
||||||
@ -28,10 +31,14 @@ void CommonAsmRoutines::GenFifoWrite(int size)
|
|||||||
ADD(32, R(RSCRATCH2), Imm8(size >> 3));
|
ADD(32, R(RSCRATCH2), Imm8(size >> 3));
|
||||||
MOV(32, M(&GPFifo::m_gatherPipeCount), R(RSCRATCH2));
|
MOV(32, M(&GPFifo::m_gatherPipeCount), R(RSCRATCH2));
|
||||||
RET();
|
RET();
|
||||||
|
|
||||||
|
JitRegister::Register(start, GetCodePtr(), "JIT_FifoWrite_%i", size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommonAsmRoutines::GenFrsqrte()
|
void CommonAsmRoutines::GenFrsqrte()
|
||||||
{
|
{
|
||||||
|
const void* start = GetCodePtr();
|
||||||
|
|
||||||
// Assume input in XMM0.
|
// Assume input in XMM0.
|
||||||
// This function clobbers all three RSCRATCH.
|
// This function clobbers all three RSCRATCH.
|
||||||
MOVQ_xmm(R(RSCRATCH), XMM0);
|
MOVQ_xmm(R(RSCRATCH), XMM0);
|
||||||
@ -91,10 +98,14 @@ void CommonAsmRoutines::GenFrsqrte()
|
|||||||
ABI_CallFunction((void *)&MathUtil::ApproximateReciprocalSquareRoot);
|
ABI_CallFunction((void *)&MathUtil::ApproximateReciprocalSquareRoot);
|
||||||
ABI_PopRegistersAndAdjustStack(QUANTIZED_REGS_TO_SAVE, 8);
|
ABI_PopRegistersAndAdjustStack(QUANTIZED_REGS_TO_SAVE, 8);
|
||||||
RET();
|
RET();
|
||||||
|
|
||||||
|
JitRegister::Register(start, GetCodePtr(), "JIT_Frsqrte");
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommonAsmRoutines::GenFres()
|
void CommonAsmRoutines::GenFres()
|
||||||
{
|
{
|
||||||
|
const void* start = GetCodePtr();
|
||||||
|
|
||||||
// Assume input in XMM0.
|
// Assume input in XMM0.
|
||||||
// This function clobbers all three RSCRATCH.
|
// This function clobbers all three RSCRATCH.
|
||||||
MOVQ_xmm(R(RSCRATCH), XMM0);
|
MOVQ_xmm(R(RSCRATCH), XMM0);
|
||||||
@ -149,10 +160,14 @@ void CommonAsmRoutines::GenFres()
|
|||||||
ABI_CallFunction((void *)&MathUtil::ApproximateReciprocal);
|
ABI_CallFunction((void *)&MathUtil::ApproximateReciprocal);
|
||||||
ABI_PopRegistersAndAdjustStack(QUANTIZED_REGS_TO_SAVE, 8);
|
ABI_PopRegistersAndAdjustStack(QUANTIZED_REGS_TO_SAVE, 8);
|
||||||
RET();
|
RET();
|
||||||
|
|
||||||
|
JitRegister::Register(start, GetCodePtr(), "JIT_Fres");
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommonAsmRoutines::GenMfcr()
|
void CommonAsmRoutines::GenMfcr()
|
||||||
{
|
{
|
||||||
|
const void* start = GetCodePtr();
|
||||||
|
|
||||||
// Input: none
|
// Input: none
|
||||||
// Output: RSCRATCH
|
// Output: RSCRATCH
|
||||||
// This function clobbers all three RSCRATCH.
|
// This function clobbers all three RSCRATCH.
|
||||||
@ -187,6 +202,8 @@ void CommonAsmRoutines::GenMfcr()
|
|||||||
OR(32, R(dst), MScaled(cr_val, SCALE_4, (u32)(u64)m_flagTable));
|
OR(32, R(dst), MScaled(cr_val, SCALE_4, (u32)(u64)m_flagTable));
|
||||||
}
|
}
|
||||||
RET();
|
RET();
|
||||||
|
|
||||||
|
JitRegister::Register(start, GetCodePtr(), "JIT_Mfcr");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Safe + Fast Quantizers, originally from JITIL by magumagu
|
// Safe + Fast Quantizers, originally from JITIL by magumagu
|
||||||
@ -207,6 +224,8 @@ static const float GC_ALIGNED16(m_m128) = -128.0f;
|
|||||||
// See comment in header for in/outs.
|
// See comment in header for in/outs.
|
||||||
void CommonAsmRoutines::GenQuantizedStores()
|
void CommonAsmRoutines::GenQuantizedStores()
|
||||||
{
|
{
|
||||||
|
const void* start = GetCodePtr();
|
||||||
|
|
||||||
const u8* storePairedIllegal = AlignCode4();
|
const u8* storePairedIllegal = AlignCode4();
|
||||||
UD2();
|
UD2();
|
||||||
|
|
||||||
@ -305,6 +324,8 @@ void CommonAsmRoutines::GenQuantizedStores()
|
|||||||
|
|
||||||
RET();
|
RET();
|
||||||
|
|
||||||
|
JitRegister::Register(start, GetCodePtr(), "JIT_QuantizedStore");
|
||||||
|
|
||||||
pairedStoreQuantized = reinterpret_cast<const u8**>(const_cast<u8*>(AlignCode16()));
|
pairedStoreQuantized = reinterpret_cast<const u8**>(const_cast<u8*>(AlignCode16()));
|
||||||
ReserveCodeSpace(8 * sizeof(u8*));
|
ReserveCodeSpace(8 * sizeof(u8*));
|
||||||
|
|
||||||
@ -321,6 +342,8 @@ void CommonAsmRoutines::GenQuantizedStores()
|
|||||||
// See comment in header for in/outs.
|
// See comment in header for in/outs.
|
||||||
void CommonAsmRoutines::GenQuantizedSingleStores()
|
void CommonAsmRoutines::GenQuantizedSingleStores()
|
||||||
{
|
{
|
||||||
|
const void* start = GetCodePtr();
|
||||||
|
|
||||||
const u8* storeSingleIllegal = AlignCode4();
|
const u8* storeSingleIllegal = AlignCode4();
|
||||||
UD2();
|
UD2();
|
||||||
|
|
||||||
@ -368,6 +391,8 @@ void CommonAsmRoutines::GenQuantizedSingleStores()
|
|||||||
SafeWriteRegToReg(RSCRATCH, RSCRATCH_EXTRA, 16, 0, QUANTIZED_REGS_TO_SAVE, SAFE_LOADSTORE_NO_PROLOG | SAFE_LOADSTORE_NO_FASTMEM);
|
SafeWriteRegToReg(RSCRATCH, RSCRATCH_EXTRA, 16, 0, QUANTIZED_REGS_TO_SAVE, SAFE_LOADSTORE_NO_PROLOG | SAFE_LOADSTORE_NO_FASTMEM);
|
||||||
RET();
|
RET();
|
||||||
|
|
||||||
|
JitRegister::Register(start, GetCodePtr(), "JIT_QuantizedSingleStore");
|
||||||
|
|
||||||
singleStoreQuantized = reinterpret_cast<const u8**>(const_cast<u8*>(AlignCode16()));
|
singleStoreQuantized = reinterpret_cast<const u8**>(const_cast<u8*>(AlignCode16()));
|
||||||
ReserveCodeSpace(8 * sizeof(u8*));
|
ReserveCodeSpace(8 * sizeof(u8*));
|
||||||
|
|
||||||
@ -383,6 +408,8 @@ void CommonAsmRoutines::GenQuantizedSingleStores()
|
|||||||
|
|
||||||
void CommonAsmRoutines::GenQuantizedLoads()
|
void CommonAsmRoutines::GenQuantizedLoads()
|
||||||
{
|
{
|
||||||
|
const void* start = GetCodePtr();
|
||||||
|
|
||||||
const u8* loadPairedIllegal = AlignCode4();
|
const u8* loadPairedIllegal = AlignCode4();
|
||||||
UD2();
|
UD2();
|
||||||
|
|
||||||
@ -578,6 +605,9 @@ void CommonAsmRoutines::GenQuantizedLoads()
|
|||||||
UNPCKLPS(XMM0, M(m_one));
|
UNPCKLPS(XMM0, M(m_one));
|
||||||
RET();
|
RET();
|
||||||
|
|
||||||
|
|
||||||
|
JitRegister::Register(start, GetCodePtr(), "JIT_QuantizedLoad");
|
||||||
|
|
||||||
pairedLoadQuantized = reinterpret_cast<const u8**>(const_cast<u8*>(AlignCode16()));
|
pairedLoadQuantized = reinterpret_cast<const u8**>(const_cast<u8*>(AlignCode16()));
|
||||||
ReserveCodeSpace(16 * sizeof(u8*));
|
ReserveCodeSpace(16 * sizeof(u8*));
|
||||||
|
|
||||||
|
@ -144,7 +144,7 @@ using namespace Gen;
|
|||||||
}
|
}
|
||||||
|
|
||||||
JitRegister::Register(blockCodePointers[block_num], b.codeSize,
|
JitRegister::Register(blockCodePointers[block_num], b.codeSize,
|
||||||
"JIT_PPC", b.originalAddress);
|
"JIT_PPC_%08x", b.originalAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
const u8 **JitBaseBlockCache::GetCodePointers()
|
const u8 **JitBaseBlockCache::GetCodePointers()
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
|
#include "Common/JitRegister.h"
|
||||||
#include "Common/StringUtil.h"
|
#include "Common/StringUtil.h"
|
||||||
#include "Common/x64ABI.h"
|
#include "Common/x64ABI.h"
|
||||||
#include "Core/HW/Memmap.h"
|
#include "Core/HW/Memmap.h"
|
||||||
@ -95,6 +96,8 @@ const u8* TrampolineCache::GenerateReadTrampoline(const InstructionInfo &info, B
|
|||||||
MOVZX(dataRegSize, info.operandSize * 8, dataReg, R(ABI_RETURN));
|
MOVZX(dataRegSize, info.operandSize * 8, dataReg, R(ABI_RETURN));
|
||||||
|
|
||||||
JMP(returnPtr, true);
|
JMP(returnPtr, true);
|
||||||
|
|
||||||
|
JitRegister::Register(trampoline, GetCodePtr(), "JIT_ReadTrampoline");
|
||||||
return trampoline;
|
return trampoline;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,5 +175,6 @@ const u8* TrampolineCache::GenerateWriteTrampoline(const InstructionInfo &info,
|
|||||||
}
|
}
|
||||||
JMP(returnPtr, true);
|
JMP(returnPtr, true);
|
||||||
|
|
||||||
|
JitRegister::Register(trampoline, GetCodePtr(), "JIT_WriteTrampoline_%x", pc);
|
||||||
return trampoline;
|
return trampoline;
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ VertexLoaderX64::VertexLoaderX64(const TVtxDesc& vtx_desc, const VAT& vtx_att):
|
|||||||
|
|
||||||
std::string name;
|
std::string name;
|
||||||
AppendToString(&name);
|
AppendToString(&name);
|
||||||
JitRegister::Register(region, (u32)(GetCodePtr() - region), name.c_str());
|
JitRegister::Register(region, GetCodePtr(), name.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
OpArg VertexLoaderX64::GetVertexAddr(int array, u64 attribute)
|
OpArg VertexLoaderX64::GetVertexAddr(int array, u64 attribute)
|
||||||
|
Reference in New Issue
Block a user