mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-09 23:59:27 +01:00
Clean up DisassembleBlock and JitInterface::GetHostCode
This commit is contained in:
parent
5842b90bee
commit
6a6d24550e
@ -146,43 +146,42 @@ void GetProfileResults(Profiler::ProfileStats* prof_stats)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetHostCode(u32* address, const u8** code, u32* code_size)
|
std::variant<GetHostCodeError, GetHostCodeResult> GetHostCode(u32 address)
|
||||||
{
|
{
|
||||||
if (!g_jit)
|
if (!g_jit)
|
||||||
{
|
{
|
||||||
*code_size = 0;
|
return GetHostCodeError::NoJitActive;
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JitBlock* block = g_jit->GetBlockCache()->GetBlockFromStartAddress(*address, MSR.Hex);
|
JitBlock* block = g_jit->GetBlockCache()->GetBlockFromStartAddress(address, MSR.Hex);
|
||||||
if (!block)
|
if (!block)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 500; i++)
|
for (int i = 0; i < 500; i++)
|
||||||
{
|
{
|
||||||
block = g_jit->GetBlockCache()->GetBlockFromStartAddress(*address - 4 * i, MSR.Hex);
|
block = g_jit->GetBlockCache()->GetBlockFromStartAddress(address - 4 * i, MSR.Hex);
|
||||||
if (block)
|
if (block)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (block)
|
if (block)
|
||||||
{
|
{
|
||||||
if (!(block->effectiveAddress <= *address &&
|
if (!(block->effectiveAddress <= address &&
|
||||||
block->originalSize + block->effectiveAddress >= *address))
|
block->originalSize + block->effectiveAddress >= address))
|
||||||
block = nullptr;
|
block = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do not merge this "if" with the above - block_num changes inside it.
|
// Do not merge this "if" with the above - block changes inside it.
|
||||||
if (!block)
|
if (!block)
|
||||||
{
|
{
|
||||||
*code_size = 0;
|
return GetHostCodeError::NoTranslation;
|
||||||
return 2;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*code = block->checkedEntry;
|
GetHostCodeResult result;
|
||||||
*code_size = block->codeSize;
|
result.code = block->checkedEntry;
|
||||||
*address = block->effectiveAddress;
|
result.code_size = block->codeSize;
|
||||||
return 0;
|
result.entry_address = block->effectiveAddress;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HandleFault(uintptr_t access_address, SContext* ctx)
|
bool HandleFault(uintptr_t access_address, SContext* ctx)
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <variant>
|
||||||
|
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
#include "Core/MachineContext.h"
|
#include "Core/MachineContext.h"
|
||||||
@ -43,10 +44,22 @@ enum class ProfilingState
|
|||||||
Disabled
|
Disabled
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class GetHostCodeError
|
||||||
|
{
|
||||||
|
NoJitActive,
|
||||||
|
NoTranslation,
|
||||||
|
};
|
||||||
|
struct GetHostCodeResult
|
||||||
|
{
|
||||||
|
const u8* code;
|
||||||
|
u32 code_size;
|
||||||
|
u32 entry_address;
|
||||||
|
};
|
||||||
|
|
||||||
void SetProfilingState(ProfilingState state);
|
void SetProfilingState(ProfilingState state);
|
||||||
void WriteProfileResults(const std::string& filename);
|
void WriteProfileResults(const std::string& filename);
|
||||||
void GetProfileResults(Profiler::ProfileStats* prof_stats);
|
void GetProfileResults(Profiler::ProfileStats* prof_stats);
|
||||||
int GetHostCode(u32* address, const u8** code, u32* code_size);
|
std::variant<GetHostCodeError, GetHostCodeResult> GetHostCode(u32 address);
|
||||||
|
|
||||||
// Memory Utilities
|
// Memory Utilities
|
||||||
bool HandleFault(uintptr_t access_address, SContext* ctx);
|
bool HandleFault(uintptr_t access_address, SContext* ctx);
|
||||||
|
@ -146,14 +146,11 @@ void JITWidget::Update()
|
|||||||
// TODO: Actually do something with the table (Wx doesn't)
|
// TODO: Actually do something with the table (Wx doesn't)
|
||||||
|
|
||||||
// Get host side code disassembly
|
// Get host side code disassembly
|
||||||
u32 host_instructions_count = 0;
|
auto host_instructions_disasm = DisassembleBlock(m_disassembler.get(), m_address);
|
||||||
u32 host_code_size = 0;
|
m_address = host_instructions_disasm.entry_address;
|
||||||
std::string host_instructions_disasm;
|
|
||||||
host_instructions_disasm =
|
|
||||||
DisassembleBlock(m_disassembler.get(), &m_address, &host_instructions_count, &host_code_size);
|
|
||||||
|
|
||||||
m_host_asm_widget->setHtml(
|
m_host_asm_widget->setHtml(
|
||||||
QStringLiteral("<pre>%1</pre>").arg(QString::fromStdString(host_instructions_disasm)));
|
QStringLiteral("<pre>%1</pre>").arg(QString::fromStdString(host_instructions_disasm.text)));
|
||||||
|
|
||||||
// == Fill in ppc box
|
// == Fill in ppc box
|
||||||
u32 ppc_addr = m_address;
|
u32 ppc_addr = m_address;
|
||||||
@ -191,19 +188,24 @@ void JITWidget::Update()
|
|||||||
ppc_disasm << st.numCycles << " estimated cycles" << std::endl;
|
ppc_disasm << st.numCycles << " estimated cycles" << std::endl;
|
||||||
|
|
||||||
ppc_disasm << "Num instr: PPC: " << code_block.m_num_instructions
|
ppc_disasm << "Num instr: PPC: " << code_block.m_num_instructions
|
||||||
<< " Host: " << host_instructions_count;
|
<< " Host: " << host_instructions_disasm.instruction_count;
|
||||||
if (code_block.m_num_instructions != 0)
|
if (code_block.m_num_instructions != 0)
|
||||||
{
|
{
|
||||||
ppc_disasm << " (blowup: "
|
ppc_disasm << " (blowup: "
|
||||||
<< 100 * host_instructions_count / code_block.m_num_instructions - 100 << "%)";
|
<< 100 * host_instructions_disasm.instruction_count /
|
||||||
|
code_block.m_num_instructions -
|
||||||
|
100
|
||||||
|
<< "%)";
|
||||||
}
|
}
|
||||||
ppc_disasm << std::endl;
|
ppc_disasm << std::endl;
|
||||||
|
|
||||||
ppc_disasm << "Num bytes: PPC: " << code_block.m_num_instructions * 4
|
ppc_disasm << "Num bytes: PPC: " << code_block.m_num_instructions * 4
|
||||||
<< " Host: " << host_code_size;
|
<< " Host: " << host_instructions_disasm.code_size;
|
||||||
if (code_block.m_num_instructions != 0)
|
if (code_block.m_num_instructions != 0)
|
||||||
{
|
{
|
||||||
ppc_disasm << " (blowup: " << 100 * host_code_size / (4 * code_block.m_num_instructions) - 100
|
ppc_disasm << " (blowup: "
|
||||||
|
<< 100 * host_instructions_disasm.code_size / (4 * code_block.m_num_instructions) -
|
||||||
|
100
|
||||||
<< "%)";
|
<< "%)";
|
||||||
}
|
}
|
||||||
ppc_disasm << std::endl;
|
ppc_disasm << std::endl;
|
||||||
|
@ -16,6 +16,8 @@
|
|||||||
#include <disasm.h> // Bochs
|
#include <disasm.h> // Bochs
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "Common/Assert.h"
|
||||||
|
#include "Common/VariantUtil.h"
|
||||||
#include "Core/PowerPC/JitInterface.h"
|
#include "Core/PowerPC/JitInterface.h"
|
||||||
|
|
||||||
#if defined(HAVE_LLVM)
|
#if defined(HAVE_LLVM)
|
||||||
@ -169,21 +171,39 @@ std::unique_ptr<HostDisassembler> GetNewDisassembler(const std::string& arch)
|
|||||||
return std::make_unique<HostDisassembler>();
|
return std::make_unique<HostDisassembler>();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string DisassembleBlock(HostDisassembler* disasm, u32* address, u32* host_instructions_count,
|
DisassembleResult DisassembleBlock(HostDisassembler* disasm, u32 address)
|
||||||
u32* code_size)
|
|
||||||
{
|
{
|
||||||
const u8* code;
|
auto res = JitInterface::GetHostCode(address);
|
||||||
int res = JitInterface::GetHostCode(address, &code, code_size);
|
|
||||||
|
|
||||||
if (res == 1)
|
return std::visit(overloaded{[&](JitInterface::GetHostCodeError error) {
|
||||||
{
|
DisassembleResult result;
|
||||||
*host_instructions_count = 0;
|
switch (error)
|
||||||
return "(No JIT active)";
|
{
|
||||||
}
|
case JitInterface::GetHostCodeError::NoJitActive:
|
||||||
else if (res == 2)
|
result.text = "(No JIT active)";
|
||||||
{
|
break;
|
||||||
*host_instructions_count = 0;
|
case JitInterface::GetHostCodeError::NoTranslation:
|
||||||
return "(No translation)";
|
result.text = "(No translation)";
|
||||||
}
|
break;
|
||||||
return disasm->DisassembleHostBlock(code, *code_size, host_instructions_count, (u64)code);
|
default:
|
||||||
|
ASSERT(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
result.entry_address = address;
|
||||||
|
result.instruction_count = 0;
|
||||||
|
result.code_size = 0;
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
[&](JitInterface::GetHostCodeResult host_result) {
|
||||||
|
DisassembleResult new_result;
|
||||||
|
u32 instruction_count = 0;
|
||||||
|
new_result.text = disasm->DisassembleHostBlock(
|
||||||
|
host_result.code, host_result.code_size, &instruction_count,
|
||||||
|
(u64)host_result.code);
|
||||||
|
new_result.entry_address = host_result.entry_address;
|
||||||
|
new_result.code_size = host_result.code_size;
|
||||||
|
new_result.instruction_count = instruction_count;
|
||||||
|
return new_result;
|
||||||
|
}},
|
||||||
|
res);
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,13 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct DisassembleResult
|
||||||
|
{
|
||||||
|
std::string text;
|
||||||
|
u32 entry_address;
|
||||||
|
u32 instruction_count;
|
||||||
|
u32 code_size;
|
||||||
|
};
|
||||||
|
|
||||||
std::unique_ptr<HostDisassembler> GetNewDisassembler(const std::string& arch);
|
std::unique_ptr<HostDisassembler> GetNewDisassembler(const std::string& arch);
|
||||||
std::string DisassembleBlock(HostDisassembler* disasm, u32* address, u32* host_instructions_count,
|
DisassembleResult DisassembleBlock(HostDisassembler* disasm, u32 address);
|
||||||
u32* code_size);
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user