| File: | /home/anal/dolphin-emu/Source/Core/DolphinWX/Src/Debugger/JitWindow.cpp |
| Location: | line 182, column 3 |
| Description: | Value stored to 'sptr' is never read |
| 1 | // Copyright 2013 Dolphin Emulator Project |
| 2 | // Licensed under GPLv2 |
| 3 | // Refer to the license.txt file included. |
| 4 | |
| 5 | #include <wx/button.h> |
| 6 | #include <wx/textctrl.h> |
| 7 | #include <wx/listctrl.h> |
| 8 | #include <wx/thread.h> |
| 9 | #include <wx/listctrl.h> |
| 10 | |
| 11 | #include "JitWindow.h" |
| 12 | #include "HW/CPU.h" |
| 13 | #include "PowerPC/PowerPC.h" |
| 14 | #include "PowerPC/JitCommon/JitBase.h" |
| 15 | #include "PowerPC/JitCommon/JitCache.h" |
| 16 | #include "PowerPC/PPCAnalyst.h" |
| 17 | #include "PowerPCDisasm.h" |
| 18 | #include "Host.h" |
| 19 | #include "disasm.h" |
| 20 | |
| 21 | #include "Debugger/PPCDebugInterface.h" |
| 22 | #include "Debugger/Debugger_SymbolMap.h" |
| 23 | |
| 24 | #include "Core.h" |
| 25 | #include "StringUtil.h" |
| 26 | #include "LogManager.h" |
| 27 | #include "../WxUtils.h" |
| 28 | |
| 29 | #include "../Globals.h" |
| 30 | |
| 31 | enum |
| 32 | { |
| 33 | IDM_REFRESH_LIST = 23350, |
| 34 | IDM_PPC_BOX, |
| 35 | IDM_X86_BOX, |
| 36 | IDM_NEXT, |
| 37 | IDM_PREV, |
| 38 | IDM_BLOCKLIST, |
| 39 | }; |
| 40 | |
| 41 | BEGIN_EVENT_TABLE(CJitWindow, wxPanel)const wxEventTable CJitWindow::sm_eventTable = { &wxPanel ::sm_eventTable, &CJitWindow::sm_eventTableEntries[0] }; const wxEventTable *CJitWindow::GetEventTable() const { return & CJitWindow::sm_eventTable; } wxEventHashTable CJitWindow::sm_eventHashTable (CJitWindow::sm_eventTable); wxEventHashTable &CJitWindow ::GetEventHashTable() const { return CJitWindow::sm_eventHashTable ; } const wxEventTableEntry CJitWindow::sm_eventTableEntries[ ] = { |
| 42 | //EVT_TEXT(IDM_ADDRBOX, CJitWindow::OnAddrBoxChange) |
| 43 | //EVT_LISTBOX(IDM_SYMBOLLIST, CJitWindow::OnSymbolListChange) |
| 44 | //EVT_HOST_COMMAND(wxID_ANY, CJitWindow::OnHostMessage) |
| 45 | EVT_BUTTON(IDM_REFRESH_LIST, CJitWindow::OnRefresh)wxEventTableEntry(wxEVT_BUTTON, IDM_REFRESH_LIST, wxID_ANY, wxNewEventTableFunctor (wxEVT_BUTTON, ( wxObjectEventFunction )( wxEventFunction )static_cast <wxCommandEventFunction>(&CJitWindow::OnRefresh)), __null ), |
| 46 | END_EVENT_TABLE()wxEventTableEntry(wxEVT_NULL, 0, 0, 0, 0) }; |
| 47 | |
| 48 | CJitWindow::CJitWindow(wxWindow* parent, wxWindowID id, const wxPoint& pos, |
| 49 | const wxSize& size, long style, const wxString& name) |
| 50 | : wxPanel(parent, id, pos, size, style, name) |
| 51 | { |
| 52 | wxBoxSizer* sizerBig = new wxBoxSizer(wxVERTICAL); |
| 53 | wxBoxSizer* sizerSplit = new wxBoxSizer(wxHORIZONTAL); |
| 54 | sizerSplit->Add(ppc_box = new wxTextCtrl(this, IDM_PPC_BOX, _T("(ppc)")L"(ppc)", |
| 55 | wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE0x0020), 1, wxEXPAND); |
| 56 | sizerSplit->Add(x86_box = new wxTextCtrl(this, IDM_X86_BOX, _T("(x86)")L"(x86)", |
| 57 | wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE0x0020), 1, wxEXPAND); |
| 58 | sizerBig->Add(block_list = new JitBlockList(this, IDM_BLOCKLIST, |
| 59 | wxDefaultPosition, wxSize(100, 140), |
| 60 | wxLC_REPORT0x0020 | wxSUNKEN_BORDERwxBORDER_SUNKEN | wxLC_ALIGN_LEFT0x0080 | wxLC_SINGLE_SEL0x2000 | wxLC_SORT_ASCENDING0x4000), |
| 61 | 0, wxEXPAND); |
| 62 | sizerBig->Add(sizerSplit, 2, wxEXPAND); |
| 63 | // sizerBig->Add(memview, 5, wxEXPAND); |
| 64 | // sizerBig->Add(sizerRight, 0, wxEXPAND | wxALL, 3); |
| 65 | sizerBig->Add(button_refresh = new wxButton(this, IDM_REFRESH_LIST, _("&Refresh")wxGetTranslation(("&Refresh")))); |
| 66 | // sizerRight->Add(addrbox = new wxTextCtrl(this, IDM_ADDRBOX, _T(""))); |
| 67 | // sizerRight->Add(new wxButton(this, IDM_SETPC, _("S&et PC"))); |
| 68 | |
| 69 | SetSizer(sizerBig); |
| 70 | |
| 71 | sizerSplit->Fit(this); |
| 72 | sizerBig->Fit(this); |
| 73 | } |
| 74 | |
| 75 | void CJitWindow::OnRefresh(wxCommandEvent& /*event*/) { |
| 76 | block_list->Update(); |
| 77 | } |
| 78 | |
| 79 | void CJitWindow::ViewAddr(u32 em_address) |
| 80 | { |
| 81 | Show(true); |
| 82 | Compare(em_address); |
| 83 | SetFocus(); |
| 84 | } |
| 85 | |
| 86 | void CJitWindow::Compare(u32 em_address) |
| 87 | { |
| 88 | u8 *xDis = new u8[1<<18]; |
| 89 | memset(xDis, 0, 1<<18); |
| 90 | |
| 91 | disassembler x64disasm; |
| 92 | x64disasm.set_syntax_intel(); |
| 93 | |
| 94 | int block_num = jit->GetBlockCache()->GetBlockNumberFromStartAddress(em_address); |
| 95 | if (block_num < 0) |
| 96 | { |
| 97 | for (int i = 0; i < 500; i++) |
| 98 | { |
| 99 | block_num = jit->GetBlockCache()->GetBlockNumberFromStartAddress(em_address - 4 * i); |
| 100 | if (block_num >= 0) |
| 101 | break; |
| 102 | } |
| 103 | |
| 104 | if (block_num >= 0) |
| 105 | { |
| 106 | JitBlock *block = jit->GetBlockCache()->GetBlock(block_num); |
| 107 | if (!(block->originalAddress <= em_address && |
| 108 | block->originalSize + block->originalAddress >= em_address)) |
| 109 | block_num = -1; |
| 110 | } |
| 111 | |
| 112 | // Do not merge this "if" with the above - block_num changes inside it. |
| 113 | if (block_num < 0) |
| 114 | { |
| 115 | ppc_box->SetValue(StrToWxStr(StringFromFormat("(non-code address: %08x)", |
| 116 | em_address))); |
| 117 | x86_box->SetValue(StrToWxStr(StringFromFormat("(no translation)"))); |
| 118 | delete[] xDis; |
| 119 | return; |
| 120 | } |
| 121 | } |
| 122 | JitBlock *block = jit->GetBlockCache()->GetBlock(block_num); |
| 123 | |
| 124 | // 800031f0 |
| 125 | // == Fill in x86 box |
| 126 | |
| 127 | const u8 *code = (const u8 *)jit->GetBlockCache()->GetCompiledCodeFromBlock(block_num); |
| 128 | u64 disasmPtr = (u64)code; |
| 129 | int size = block->codeSize; |
| 130 | const u8 *end = code + size; |
| 131 | char *sptr = (char*)xDis; |
| 132 | |
| 133 | int num_x86_instructions = 0; |
| 134 | while ((u8*)disasmPtr < end) |
| 135 | { |
| 136 | #ifdef _M_X641 |
| 137 | disasmPtr += x64disasm.disasm64(disasmPtr, disasmPtr, (u8*)disasmPtr, sptr); |
| 138 | #else |
| 139 | disasmPtr += x64disasm.disasm32(disasmPtr, disasmPtr, (u8*)disasmPtr, sptr); |
| 140 | #endif |
| 141 | sptr += strlen(sptr); |
| 142 | *sptr++ = 13; |
| 143 | *sptr++ = 10; |
| 144 | num_x86_instructions++; |
| 145 | } |
| 146 | x86_box->SetValue(StrToWxStr((char*)xDis)); |
| 147 | |
| 148 | // == Fill in ppc box |
| 149 | u32 ppc_addr = block->originalAddress; |
| 150 | PPCAnalyst::CodeBuffer code_buffer(32000); |
| 151 | PPCAnalyst::BlockStats st; |
| 152 | PPCAnalyst::BlockRegStats gpa; |
| 153 | PPCAnalyst::BlockRegStats fpa; |
| 154 | bool broken_block = false; |
| 155 | u32 merged_addresses[32]; |
| 156 | const int capacity_of_merged_addresses = sizeof(merged_addresses) / sizeof(merged_addresses[0]); |
| 157 | int size_of_merged_addresses; |
| 158 | if (PPCAnalyst::Flatten(ppc_addr, &size, &st, &gpa, &fpa, broken_block, &code_buffer, size, merged_addresses, capacity_of_merged_addresses, size_of_merged_addresses) != 0xffffffff) |
| 159 | { |
| 160 | sptr = (char*)xDis; |
| 161 | for (int i = 0; i < size; i++) |
| 162 | { |
| 163 | const PPCAnalyst::CodeOp &op = code_buffer.codebuffer[i]; |
| 164 | char temp[256]; |
| 165 | DisassembleGekko(op.inst.hex, op.address, temp, 256); |
| 166 | sptr += sprintf(sptr, "%08x %s\n", op.address, temp); |
| 167 | } |
| 168 | |
| 169 | // Add stats to the end of the ppc box since it's generally the shortest. |
| 170 | sptr += sprintf(sptr, "\n"); |
| 171 | |
| 172 | // Add some generic analysis |
| 173 | if (st.isFirstBlockOfFunction) |
| 174 | sptr += sprintf(sptr, "(first block of function)\n"); |
| 175 | if (st.isLastBlockOfFunction) |
| 176 | sptr += sprintf(sptr, "(first block of function)\n"); |
| 177 | |
| 178 | sptr += sprintf(sptr, "%i estimated cycles\n", st.numCycles); |
| 179 | |
| 180 | sptr += sprintf(sptr, "Num instr: PPC: %i x86: %i (blowup: %i%%)\n", |
| 181 | size, num_x86_instructions, 100 * (num_x86_instructions / size - 1)); |
| 182 | sptr += sprintf(sptr, "Num bytes: PPC: %i x86: %i (blowup: %i%%)\n", |
Value stored to 'sptr' is never read | |
| 183 | size * 4, block->codeSize, 100 * (block->codeSize / (4 * size) - 1)); |
| 184 | |
| 185 | ppc_box->SetValue(StrToWxStr((char*)xDis)); |
| 186 | } |
| 187 | else |
| 188 | { |
| 189 | ppc_box->SetValue(StrToWxStr(StringFromFormat( |
| 190 | "(non-code address: %08x)", em_address))); |
| 191 | x86_box->SetValue("---"); |
| 192 | } |
| 193 | |
| 194 | delete[] xDis; |
| 195 | } |
| 196 | |
| 197 | void CJitWindow::Update() |
| 198 | { |
| 199 | |
| 200 | } |
| 201 | |
| 202 | void CJitWindow::OnHostMessage(wxCommandEvent& event) |
| 203 | { |
| 204 | switch (event.GetId()) |
| 205 | { |
| 206 | case IDM_NOTIFYMAPLOADED: |
| 207 | //NotifyMapLoaded(); |
| 208 | break; |
| 209 | } |
| 210 | } |
| 211 | |
| 212 | // JitBlockList |
| 213 | //================ |
| 214 | |
| 215 | enum { |
| 216 | COLUMN_ADDRESS, |
| 217 | COLUMN_PPCSIZE, |
| 218 | COLUMN_X86SIZE, |
| 219 | COLUMN_NAME, |
| 220 | COLUMN_FLAGS, |
| 221 | COLUMN_NUMEXEC, |
| 222 | COLUMN_COST, // (estimated as x86size * numexec) |
| 223 | }; |
| 224 | |
| 225 | JitBlockList::JitBlockList(wxWindow* parent, const wxWindowID id, |
| 226 | const wxPoint& pos, const wxSize& size, long style) |
| 227 | : wxListCtrl(parent, id, pos, size, style) // | wxLC_VIRTUAL) |
| 228 | { |
| 229 | Init(); |
| 230 | } |
| 231 | |
| 232 | void JitBlockList::Init() |
| 233 | { |
| 234 | InsertColumn(COLUMN_ADDRESS, _("Address")wxGetTranslation(("Address"))); |
| 235 | InsertColumn(COLUMN_PPCSIZE, _("PPC Size")wxGetTranslation(("PPC Size"))); |
| 236 | InsertColumn(COLUMN_X86SIZE, _("x86 Size")wxGetTranslation(("x86 Size"))); |
| 237 | InsertColumn(COLUMN_NAME, _("Symbol")wxGetTranslation(("Symbol"))); |
| 238 | InsertColumn(COLUMN_FLAGS, _("Flags")wxGetTranslation(("Flags"))); |
| 239 | InsertColumn(COLUMN_NUMEXEC, _("NumExec")wxGetTranslation(("NumExec"))); |
| 240 | InsertColumn(COLUMN_COST, _("Cost")wxGetTranslation(("Cost"))); |
| 241 | } |
| 242 | |
| 243 | void JitBlockList::Update() |
| 244 | { |
| 245 | } |