summaryrefslogtreecommitdiff
path: root/Source/Core/DolphinWX/Debugger/JitWindow.cpp
diff options
context:
space:
mode:
authorskidau <skidau@gmail.com>2014-10-24 13:01:53 +1100
committerskidau <skidau@gmail.com>2014-10-24 13:01:53 +1100
commitace57fb51524f47752da12b1f3476b6c5cc89ec5 (patch)
treed33fd609153b4ce6497233205dc116ff12189de4 /Source/Core/DolphinWX/Debugger/JitWindow.cpp
parent1f5b1001ce507024143498b887401163af67654d (diff)
parentecf65d6f1fc5f20f5a8f1ba6eecab54f7913c2a7 (diff)
Merge pull request #1348 from Sonicadvance1/JitBlockView-cleanup
Cleans up the JIT block viewer in the WX UI.
Diffstat (limited to 'Source/Core/DolphinWX/Debugger/JitWindow.cpp')
-rw-r--r--Source/Core/DolphinWX/Debugger/JitWindow.cpp172
1 files changed, 102 insertions, 70 deletions
diff --git a/Source/Core/DolphinWX/Debugger/JitWindow.cpp b/Source/Core/DolphinWX/Debugger/JitWindow.cpp
index e9cd5cd409..e17546181d 100644
--- a/Source/Core/DolphinWX/Debugger/JitWindow.cpp
+++ b/Source/Core/DolphinWX/Debugger/JitWindow.cpp
@@ -5,6 +5,8 @@
#include <cstdio>
#include <cstring>
#include <disasm.h> // Bochs
+#include <sstream>
+
#include <wx/button.h>
#include <wx/chartype.h>
#include <wx/defs.h>
@@ -31,6 +33,73 @@
#include "DolphinWX/WxUtils.h"
#include "DolphinWX/Debugger/JitWindow.h"
+std::string HostDisassembler::DisassembleBlock(u32* address, u32* host_instructions_count, u32* code_size)
+{
+ if (!jit)
+ {
+ *host_instructions_count = 0;
+ *code_size = 0;
+ return "(No JIT active)";
+ }
+
+ int block_num = jit->GetBlockCache()->GetBlockNumberFromStartAddress(*address);
+ if (block_num < 0)
+ {
+ for (int i = 0; i < 500; i++)
+ {
+ block_num = jit->GetBlockCache()->GetBlockNumberFromStartAddress(*address - 4 * i);
+ if (block_num >= 0)
+ break;
+ }
+
+ if (block_num >= 0)
+ {
+ JitBlock* block = jit->GetBlockCache()->GetBlock(block_num);
+ if (!(block->originalAddress <= *address &&
+ block->originalSize + block->originalAddress >= *address))
+ block_num = -1;
+ }
+
+ // Do not merge this "if" with the above - block_num changes inside it.
+ if (block_num < 0)
+ {
+ host_instructions_count = 0;
+ code_size = 0;
+ return "(No translation)";
+ }
+ }
+
+ JitBlock* block = jit->GetBlockCache()->GetBlock(block_num);
+
+ const u8* code = (const u8*)jit->GetBlockCache()->GetCompiledCodeFromBlock(block_num);
+
+ *code_size = block->codeSize;
+ *address = block->originalAddress;
+ return DisassembleHostBlock(code, block->codeSize, host_instructions_count);
+}
+
+HostDisassemblerX86::HostDisassemblerX86()
+{
+ m_disasm.set_syntax_intel();
+}
+
+std::string HostDisassemblerX86::DisassembleHostBlock(const u8* code_start, const u32 code_size, u32* host_instructions_count)
+{
+ u64 disasmPtr = (u64)code_start;
+ const u8* end = code_start + code_size;
+
+ std::ostringstream x86_disasm;
+ while ((u8*)disasmPtr < end)
+ {
+ char inst_disasm[256];
+ disasmPtr += m_disasm.disasm64(disasmPtr, disasmPtr, (u8*)disasmPtr, inst_disasm);
+ x86_disasm << inst_disasm << std::endl;
+ (*host_instructions_count)++;
+ }
+
+ return x86_disasm.str();
+}
+
enum
{
IDM_REFRESH_LIST = 23350,
@@ -73,6 +142,12 @@ CJitWindow::CJitWindow(wxWindow* parent, wxWindowID id, const wxPoint& pos,
sizerSplit->Fit(this);
sizerBig->Fit(this);
+
+#ifdef _M_X86
+ m_disassembler.reset(new HostDisassemblerX86());
+#else
+ m_disassembler.reset(new HostDisassembler());
+#endif
}
void CJitWindow::OnRefresh(wxCommandEvent& /*event*/)
@@ -89,62 +164,16 @@ void CJitWindow::ViewAddr(u32 em_address)
void CJitWindow::Compare(u32 em_address)
{
- u8 *xDis = new u8[1<<18];
- memset(xDis, 0, 1<<18);
+ // Get host side code disassembly
+ u32 host_instructions_count = 0;
+ u32 host_code_size = 0;
+ std::string host_instructions_disasm;
+ host_instructions_disasm = m_disassembler->DisassembleBlock(&em_address, &host_instructions_count, &host_code_size);
- disassembler x64disasm;
- x64disasm.set_syntax_intel();
-
- int block_num = jit->GetBlockCache()->GetBlockNumberFromStartAddress(em_address);
- if (block_num < 0)
- {
- for (int i = 0; i < 500; i++)
- {
- block_num = jit->GetBlockCache()->GetBlockNumberFromStartAddress(em_address - 4 * i);
- if (block_num >= 0)
- break;
- }
-
- if (block_num >= 0)
- {
- JitBlock *block = jit->GetBlockCache()->GetBlock(block_num);
- if (!(block->originalAddress <= em_address &&
- block->originalSize + block->originalAddress >= em_address))
- block_num = -1;
- }
-
- // Do not merge this "if" with the above - block_num changes inside it.
- if (block_num < 0)
- {
- ppc_box->SetValue(_(StringFromFormat("(non-code address: %08x)", em_address)));
- x86_box->SetValue(_("(no translation)"));
- delete[] xDis;
- return;
- }
- }
- JitBlock *block = jit->GetBlockCache()->GetBlock(block_num);
-
- // 800031f0
- // == Fill in x86 box
-
- const u8 *code = (const u8 *)jit->GetBlockCache()->GetCompiledCodeFromBlock(block_num);
- u64 disasmPtr = (u64)code;
- const u8 *end = code + block->codeSize;
- char *sptr = (char*)xDis;
-
- int num_x86_instructions = 0;
- while ((u8*)disasmPtr < end)
- {
- disasmPtr += x64disasm.disasm64(disasmPtr, disasmPtr, (u8*)disasmPtr, sptr);
- sptr += strlen(sptr);
- *sptr++ = 13;
- *sptr++ = 10;
- num_x86_instructions++;
- }
- x86_box->SetValue(StrToWxStr((char*)xDis));
+ x86_box->SetValue(host_instructions_disasm);
// == Fill in ppc box
- u32 ppc_addr = block->originalAddress;
+ u32 ppc_addr = em_address;
PPCAnalyst::CodeBuffer code_buffer(32000);
PPCAnalyst::BlockStats st;
PPCAnalyst::BlockRegStats gpa;
@@ -157,42 +186,45 @@ void CJitWindow::Compare(u32 em_address)
code_block.m_gpa = &gpa;
code_block.m_fpa = &fpa;
- if (analyzer.Analyze(ppc_addr, &code_block, &code_buffer, block->codeSize) != 0xFFFFFFFF)
+ if (analyzer.Analyze(ppc_addr, &code_block, &code_buffer, 32000) != 0xFFFFFFFF)
{
- sptr = (char*)xDis;
+ std::ostringstream ppc_disasm;
for (u32 i = 0; i < code_block.m_num_instructions; i++)
{
const PPCAnalyst::CodeOp &op = code_buffer.codebuffer[i];
- std::string temp = GekkoDisassembler::Disassemble(op.inst.hex, op.address);
- sptr += sprintf(sptr, "%08x %s\n", op.address, temp.c_str());
+ std::string opcode = GekkoDisassembler::Disassemble(op.inst.hex, op.address);
+ ppc_disasm << std::setfill('0') << std::setw(8) << std::hex << op.address;
+ ppc_disasm << " " << opcode << std::endl;
}
// Add stats to the end of the ppc box since it's generally the shortest.
- sptr += sprintf(sptr, "\n");
+ ppc_disasm << std::dec << std::endl;
// Add some generic analysis
if (st.isFirstBlockOfFunction)
- sptr += sprintf(sptr, "(first block of function)\n");
+ ppc_disasm << "(first block of function)" << std::endl;
if (st.isLastBlockOfFunction)
- sptr += sprintf(sptr, "(last block of function)\n");
+ ppc_disasm << "(last block of function)" << std::endl;
- sptr += sprintf(sptr, "%i estimated cycles\n", st.numCycles);
+ ppc_disasm << st.numCycles << " estimated cycles" << std::endl;
- sptr += sprintf(sptr, "Num instr: PPC: %i x86: %i (blowup: %i%%)\n",
- code_block.m_num_instructions, num_x86_instructions, 100 * num_x86_instructions / code_block.m_num_instructions - 100);
- sptr += sprintf(sptr, "Num bytes: PPC: %i x86: %i (blowup: %i%%)\n",
- code_block.m_num_instructions * 4, block->codeSize, 100 * block->codeSize / (4 * code_block.m_num_instructions) - 100);
+ ppc_disasm << "Num instr: PPC: " << code_block.m_num_instructions
+ << " x86: " << host_instructions_count
+ << " (blowup: " << 100 * host_instructions_count / code_block.m_num_instructions - 100
+ << "%)" << std::endl;
- ppc_box->SetValue(StrToWxStr((char*)xDis));
+ ppc_disasm << "Num bytes: PPC: " << code_block.m_num_instructions * 4
+ << " x86: " << host_code_size
+ << " (blowup: " << 100 * host_code_size / (4 * code_block.m_num_instructions) - 100
+ << "%)" << std::endl;
+
+ ppc_box->SetValue(ppc_disasm.str());
}
else
{
- ppc_box->SetValue(StrToWxStr(StringFromFormat(
- "(non-code address: %08x)", em_address)));
+ ppc_box->SetValue(StringFromFormat("(non-code address: %08x)", em_address));
x86_box->SetValue("---");
}
-
- delete[] xDis;
}
void CJitWindow::Update()