Common: Introduce the new Gekko disassembler to Common.

This moves the Gekko disassembler to Common where it should be. Having it in the Bochs disassembly Externals is incorrect.

Unlike the PowerPC disassembler prior however, this one is updated to have an API that is more fitting for C++. e.g. Not needing to specify a string buffer and size. It does all of this under the hood.

This modifies all the DebuggingInterfaces as necessary to handle this.
This commit is contained in:
Lioncash 2014-07-17 21:33:51 -04:00
parent 15920d0f10
commit 0718937237
21 changed files with 2553 additions and 2434 deletions

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
@ -48,12 +48,10 @@
<ClInclude Include="config.h" />
<ClInclude Include="disasm.h" />
<ClInclude Include="dis_tables.h" />
<ClInclude Include="PowerPCDisasm.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="dis_decode.cpp" />
<ClCompile Include="dis_groups.cpp" />
<ClCompile Include="PowerPCDisasm.cpp" />
<ClCompile Include="resolve.cpp" />
<ClCompile Include="syntax.cpp" />
</ItemGroup>

View File

@ -1,11 +1,10 @@
set(SRCS dis_decode.cpp
dis_groups.cpp
resolve.cpp
syntax.cpp
PowerPCDisasm.cpp)
set(SRCS dis_decode.cpp
dis_groups.cpp
resolve.cpp
syntax.cpp)
if(WIN32)
set(SRCS ${SRCS} stdafx.cpp)
set(SRCS ${SRCS} stdafx.cpp)
endif(WIN32)
add_library(bdisasm STATIC ${SRCS})

File diff suppressed because it is too large Load Diff

View File

@ -1,29 +0,0 @@
/* $VER: ppc_disasm V0.1 (23.05.1998)
*
* Disassembler module for the PowerPC microprocessor family
* Copyright (c) 1998-2000 Frank Wille
*
* ppc_disasm.c is freeware and may be freely redistributed as long as
* no modifications are made and nothing is charged for it.
* Non-commercial usage is allowed without any restrictions.
* EVERY PRODUCT OR PROGRAM DERIVED DIRECTLY FROM MY SOURCE MAY NOT BE
* SOLD COMMERCIALLY WITHOUT PERMISSION FROM THE AUTHOR.
*
*
* v0.1 (23.05.1998) phx
* First version, which implements all PowerPC instructions.
* v0.0 (09.05.1998) phx
* File created.
*/
// Yeah, this does not really belong in bochs_disasm, but hey, it's a disasm and it needed a common location...
#ifndef _POWERPC_DISASM
#define _POWERPC_DISASM
void DisassembleGekko(unsigned int opcode, unsigned int curInstAddr, char* dest, int max_size);
const char* GetGPRName(unsigned int index);
const char* GetFPRName(unsigned int index);
#endif

View File

@ -3,6 +3,7 @@ set(SRCS BreakPoints.cpp
ColorUtil.cpp
FileSearch.cpp
FileUtil.cpp
GekkoDisassembler.cpp
Hash.cpp
IniFile.cpp
MathUtil.cpp

View File

@ -56,6 +56,7 @@
<ClInclude Include="FileUtil.h" />
<ClInclude Include="FixedSizeQueue.h" />
<ClInclude Include="FPURoundMode.h" />
<ClInclude Include="GekkoDisassembler.h" />
<ClInclude Include="Hash.h" />
<ClInclude Include="IniFile.h" />
<ClInclude Include="LinearDiskCache.h" />
@ -94,6 +95,7 @@
<ClCompile Include="ExtendedTrace.cpp" />
<ClCompile Include="FileSearch.cpp" />
<ClCompile Include="FileUtil.cpp" />
<ClCompile Include="GekkoDisassembler.cpp" />
<ClCompile Include="Hash.cpp" />
<ClCompile Include="IniFile.cpp" />
<ClCompile Include="MathUtil.cpp" />
@ -140,4 +142,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>

View File

@ -70,6 +70,7 @@
<ClInclude Include="Crypto\bn.h">
<Filter>Crypto</Filter>
</ClInclude>
<ClInclude Include="GekkoDisassembler.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="BreakPoints.cpp" />
@ -115,6 +116,7 @@
</ClCompile>
<ClCompile Include="stdafx.cpp" />
<ClCompile Include="XSaveWorkaround.cpp" />
<ClCompile Include="GekkoDisassembler.cpp" />
</ItemGroup>
<ItemGroup>
<Text Include="CMakeLists.txt" />

View File

@ -9,7 +9,7 @@ protected:
virtual ~DebugInterface() {}
public:
virtual void Disassemble(unsigned int /*address*/, char *dest, int /*max_size*/) {strcpy(dest, "NODEBUGGER");}
virtual std::string Disassemble(unsigned int /*address*/) { return "NODEBUGGER"; }
virtual void GetRawMemoryString(int /*memory*/, unsigned int /*address*/, char *dest, int /*max_size*/) {strcpy(dest, "NODEBUGGER");}
virtual int GetInstructionSize(int /*instruction*/) {return 1;}
virtual bool IsAlive() {return true;}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,152 @@
/* $VER: ppc_disasm.h V1.6 (09.12.2011)
*
* Disassembler module for the PowerPC microprocessor family
* Copyright (c) 1998-2001,2009,2011 Frank Wille
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
// Modified for use with Dolphin
#pragma once
#include <cstdint>
#include <string>
#include "Common/CommonTypes.h"
#include "Common/StringUtil.h"
class GekkoDisassembler final
{
public:
static std::string Disassemble(u32 opcode, u32 current_instruction_address, bool big_endian = true);
static const char* GetGPRName(u32 index);
static const char* GetFPRName(u32 index);
private:
GekkoDisassembler() = delete;
static void ill(u32 in);
static std::string imm(u32 in, int uimm, int type, bool hex);
static std::string ra_rb(u32 in);
static std::string rd_ra_rb(u32 in, int mask);
static std::string fd_ra_rb(u32 in, int mask);
static void trapi(u32 in, unsigned char dmode);
static void cmpi(u32 in, int uimm);
static void addi(u32 in, const std::string& ext);
static size_t branch(u32 in, const char* bname, int aform, int bdisp);
static void bc(u32 in);
static void bli(u32 in);
static void mcrf(u32 in, char c);
static void crop(u32 in, const char* n1, const char* n2);
static void nooper(u32 in, const char* name, unsigned char dmode);
static void rlw(u32 in, const char* name, int i);
static void ori(u32 in, const char* name);
static void rld(u32 in, const char* name, int i);
static void cmp(u32 in);
static void trap(u32 in, unsigned char dmode);
static void dab(u32 in, const char* name, int mask, int smode, int chkoe, int chkrc, unsigned char dmode);
static void rrn(u32 in, const char* name, int smode, int chkoe, int chkrc, unsigned char dmode);
static void mtcr(u32 in);
static void msr(u32 in, int smode);
static void mspr(u32 in, int smode);
static void mtb(u32 in);
static void sradi(u32 in);
static void ldst(u32 in, const char* name, char reg, unsigned char dmode);
static void fdabc(u32 in, const char* name, int mask, unsigned char dmode);
static void fmr(u32 in);
static void fdab(u32 in, const char* name, int mask);
static void fcmp(u32 in, char c);
static void mtfsb(u32 in, int n);
static void ps(u32 inst);
static void ps_mem(u32 inst);
static u32* DoDisassembly(bool big_endian);
static u32 HelperRotateMask(int r, int mb, int me)
{
//first make 001111111111111 part
unsigned int begin = 0xFFFFFFFF >> mb;
//then make 000000000001111 part, which is used to flip the bits of the first one
unsigned int end = me < 31 ? (0xFFFFFFFF >> (me + 1)) : 0;
//do the bitflip
unsigned int mask = begin ^ end;
//and invert if backwards
if (me < mb)
mask = ~mask;
//rotate the mask so it can be applied to source reg
//return _rotl(mask, 32 - r);
return (mask << (32 - r)) | (mask >> r);
}
static std::string ldst_offs(u32 val)
{
if (val == 0)
{
return "0";
}
else
{
if (val & 0x8000)
{
return StringFromFormat("-0x%.4X", ((~val) & 0xffff) + 1);
}
else
{
return StringFromFormat("0x%.4X", val);
}
}
}
static int SEX12(u32 x)
{
return x & 0x800 ? (x | 0xFFFFF000) : x;
}
enum InstructionType
{
PPCINSTR_OTHER = 0, // No additional info for other instr.
PPCINSTR_BRANCH = 1, // Branch dest. = PC+displacement
PPCINSTR_LDST = 2, // Load/store instruction: displ(sreg)
PPCINSTR_IMM = 3, // 16-bit immediate val. in displacement
};
enum Flags
{
PPCF_ILLEGAL = (1 << 0), // Illegal PowerPC instruction
PPCF_UNSIGNED = (1 << 1), // Unsigned immediate instruction
PPCF_SUPER = (1 << 2), // Supervisor level instruction
PPCF_64 = (1 << 3), // 64-bit only instruction
};
static u32* m_instr; // Pointer to instruction to disassemble
static u32* m_iaddr; // Instruction.address., usually the same as instr
static std::string m_opcode; // Buffer for opcode, min. 10 chars.
static std::string m_operands; // Operand buffer, min. 24 chars.
static unsigned char m_type; // Type of instruction, see below
static unsigned char m_flags; // Additional flags
static unsigned short m_sreg; // Register in load/store instructions
static u32 m_displacement; // Branch- or load/store displacement
};

View File

@ -2,7 +2,9 @@
// Licensed under GPLv2
// Refer to the license.txt file included.
#include "PowerPCDisasm.h"
#include <string>
#include "Common/GekkoDisassembler.h"
#include "Core/Core.h"
#include "Core/Host.h"
@ -15,31 +17,37 @@
#include "Core/PowerPC/PPCSymbolDB.h"
#include "Core/PowerPC/JitCommon/JitBase.h"
void PPCDebugInterface::Disassemble(unsigned int address, char *dest, int max_size)
std::string PPCDebugInterface::Disassemble(unsigned int address)
{
// Memory::ReadUnchecked_U32 seemed to crash on shutdown
if (PowerPC::GetState() == PowerPC::CPU_POWERDOWN) return;
if (PowerPC::GetState() == PowerPC::CPU_POWERDOWN)
return "";
if (Core::GetState() != Core::CORE_UNINITIALIZED)
{
if (Memory::IsRAMAddress(address, true, true))
{
u32 op = Memory::Read_Instruction(address);
DisassembleGekko(op, address, dest, max_size);
std::string disasm = GekkoDisassembler::Disassemble(op, address);
UGeckoInstruction inst;
inst.hex = Memory::ReadUnchecked_U32(address);
if (inst.OPCD == 1) {
strcat(dest, " (hle)");
if (inst.OPCD == 1)
{
disasm += " (hle)";
}
return disasm;
}
else
{
strcpy(dest, "(No RAM here)");
return "(No RAM here)";
}
}
else
{
strcpy(dest, "<unknown>");
return "<unknown>";
}
}

View File

@ -14,7 +14,7 @@ class PPCDebugInterface final : public DebugInterface
{
public:
PPCDebugInterface(){}
virtual void Disassemble(unsigned int address, char *dest, int max_size) override;
virtual std::string Disassemble(unsigned int address) override;
virtual void GetRawMemoryString(int memory, unsigned int address, char *dest, int max_size) override;
virtual int GetInstructionSize(int /*instruction*/) override {return 4;}
virtual bool IsAlive() override;

View File

@ -2,17 +2,18 @@
// Licensed under GPLv2
// Refer to the license.txt file included.
#include <string>
#include "Core/DSP/DSPCore.h"
#include "Core/DSP/DSPDisassembler.h"
#include "Core/DSP/DSPMemoryMap.h"
#include "Core/HW/DSPLLE/DSPDebugInterface.h"
#include "Core/HW/DSPLLE/DSPSymbols.h"
void DSPDebugInterface::Disassemble(unsigned int address, char *dest, int max_size)
std::string DSPDebugInterface::Disassemble(unsigned int address)
{
// we'll treat addresses as line numbers.
strncpy(dest, DSPSymbols::GetLineText(address), max_size);
dest[max_size-1] = 0;
return DSPSymbols::GetLineText(address);
}
void DSPDebugInterface::GetRawMemoryString(int memory, unsigned int address, char *dest, int max_size)

View File

@ -5,7 +5,6 @@
#pragma once
#include <string>
#include <string.h>
#include "Common/Common.h"
#include "Common/DebugInterface.h"
@ -14,7 +13,7 @@ class DSPDebugInterface final : public DebugInterface
{
public:
DSPDebugInterface(){}
virtual void Disassemble(unsigned int address, char *dest, int max_size) override;
virtual std::string Disassemble(unsigned int address) override;
virtual void GetRawMemoryString(int memory, unsigned int address, char *dest, int max_size) override;
virtual int GetInstructionSize(int instruction) override { return 1; }
virtual bool IsAlive() override;

View File

@ -5,8 +5,7 @@
#include <cinttypes>
#include <string>
#include "PowerPCDisasm.h"
#include "Common/GekkoDisassembler.h"
#include "Common/StringUtil.h"
#include "Core/Host.h"
#include "Core/Debugger/Debugger_SymbolMap.h"
@ -82,10 +81,8 @@ static void Trace(UGeckoInstruction& instCode)
fregs += StringFromFormat("f%02d: %08" PRIx64 " %08" PRIx64 " ", i, PowerPC::ppcState.ps[i][0], PowerPC::ppcState.ps[i][1]);
}
char ppcInst[256];
DisassembleGekko(instCode.hex, PC, ppcInst, 256);
DEBUG_LOG(POWERPC, "INTER PC: %08x SRR0: %08x SRR1: %08x CRval: %016lx FPSCR: %08x MSR: %08x LR: %08x %s %08x %s", PC, SRR0, SRR1, PowerPC::ppcState.cr_val[0], PowerPC::ppcState.fpscr, PowerPC::ppcState.msr, PowerPC::ppcState.spr[8], regs.c_str(), instCode.hex, ppcInst);
std::string ppc_inst = GekkoDisassembler::Disassemble(instCode.hex, PC);
DEBUG_LOG(POWERPC, "INTER PC: %08x SRR0: %08x SRR1: %08x CRval: %016lx FPSCR: %08x MSR: %08x LR: %08x %s %08x %s", PC, SRR0, SRR1, PowerPC::ppcState.cr_val[0], PowerPC::ppcState.fpscr, PowerPC::ppcState.msr, PowerPC::ppcState.spr[8], regs.c_str(), instCode.hex, ppc_inst.c_str());
}
int Interpreter::SingleStepInner(void)
@ -312,9 +309,8 @@ void Interpreter::unknown_instruction(UGeckoInstruction _inst)
{
if (_inst.hex != 0)
{
char disasm[256];
DisassembleGekko(Memory::ReadUnchecked_U32(last_pc), last_pc, disasm, 256);
NOTICE_LOG(POWERPC, "Last PC = %08x : %s", last_pc, disasm);
std::string disasm = GekkoDisassembler::Disassemble(Memory::ReadUnchecked_U32(last_pc), last_pc);
NOTICE_LOG(POWERPC, "Last PC = %08x : %s", last_pc, disasm.c_str());
Dolphin_Debugger::PrintCallstack();
_dbg_assert_msg_(POWERPC, 0, "\nIntCPU: Unknown instruction %08x at PC = %08x last_PC = %08x LR = %08x\n", _inst.hex, PC, last_pc, LR);
}

View File

@ -21,7 +21,7 @@
#include "Core/PowerPC/Jit64/JitAsm.h"
#include "Core/PowerPC/Jit64/JitRegCache.h"
#if defined(_DEBUG) || defined(DEBUGFAST)
#include "PowerPCDisasm.h"
#include "Common/GekkoDisassembler.h"
#endif
using namespace Gen;
@ -613,9 +613,8 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
#if defined(_DEBUG) || defined(DEBUGFAST)
if (gpr.SanityCheck() || fpr.SanityCheck())
{
char ppcInst[256];
DisassembleGekko(ops[i].inst.hex, em_address, ppcInst, 256);
//NOTICE_LOG(DYNA_REC, "Unflushed register: %s", ppcInst);
std::string ppc_inst = GekkoDisassembler::Disassemble(ops[i].inst.hex, em_address);
//NOTICE_LOG(DYNA_REC, "Unflushed register: %s", ppc_inst.c_str());
}
#endif
if (js.skipnext) {

View File

@ -6,8 +6,8 @@
#include <string>
#include "disasm.h"
#include "PowerPCDisasm.h"
#include "Common/GekkoDisassembler.h"
#include "Common/StringUtil.h"
#include "Core/PowerPC/JitCommon/JitBase.h"
@ -29,15 +29,11 @@ u32 Helper_Mask(u8 mb, u8 me)
void LogGeneratedX86(int size, PPCAnalyst::CodeBuffer *code_buffer, const u8 *normalEntry, JitBlock *b)
{
std::string ppcdisasm;
for (int i = 0; i < size; i++)
{
char temp[256] = "";
const PPCAnalyst::CodeOp &op = code_buffer->codebuffer[i];
DisassembleGekko(op.inst.hex, op.address, temp, 256);
ppcdisasm += StringFromFormat("%08x %s", op.address, temp);
DEBUG_LOG(DYNA_REC, "IR_X86 PPC: %s\n", ppcdisasm.c_str());
std::string temp = StringFromFormat("%08x %s", op.address, GekkoDisassembler::Disassemble(op.inst.hex, op.address).c_str());
DEBUG_LOG(DYNA_REC, "IR_X86 PPC: %s\n", temp.c_str());
}
disassembler x64disasm;

View File

@ -334,9 +334,9 @@ bool PPCSymbolDB::SaveMap(const std::string& filename, bool WithCodes) const
for (int i = 0; i < space; i += 4)
{
int Address = LastAddress + i;
char disasm[256];
debugger->Disassemble(Address, disasm, 256);
fprintf(f.GetHandle(),"%08x %i %20s %s\n", Address, 0, TempSym.c_str(), disasm);
std::string disasm = debugger->Disassemble(Address);
fprintf(f.GetHandle(),"%08x %i %20s %s\n", Address, 0, TempSym.c_str(), disasm.c_str());
}
// Write a blank line after each block
fprintf(f.GetHandle(), "\n");

View File

@ -2,6 +2,7 @@
// Licensed under GPLv2
// Refer to the license.txt file included.
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
@ -189,15 +190,15 @@ void CCodeView::OnMouseUpL(wxMouseEvent& event)
u32 CCodeView::AddrToBranch(u32 addr)
{
char disasm[256];
m_debugger->Disassemble(addr, disasm, 256);
const char *mojs = strstr(disasm, "->0x");
if (mojs)
std::string disasm = m_debugger->Disassemble(addr);
size_t pos = disasm.find("->0x");
if (pos != std::string::npos)
{
u32 dest;
sscanf(mojs+4,"%08x", &dest);
return dest;
std::string hex = disasm.substr(pos + 2);
return std::stoul(hex, nullptr, 16);
}
return 0;
}
@ -253,16 +254,14 @@ void CCodeView::OnPopupMenu(wxCommandEvent& event)
case IDM_COPYCODE:
{
char disasm[256];
m_debugger->Disassemble(m_selection, disasm, 256);
std::string disasm = m_debugger->Disassemble(m_selection);
wxTheClipboard->SetData(new wxTextDataObject(StrToWxStr(disasm)));
}
break;
case IDM_COPYHEX:
{
char temp[24];
sprintf(temp, "%08x", m_debugger->ReadInstruction(m_selection));
std::string temp = StringFromFormat("%08x", m_debugger->ReadInstruction(m_selection));
wxTheClipboard->SetData(new wxTextDataObject(StrToWxStr(temp)));
}
break;
@ -280,9 +279,8 @@ void CCodeView::OnPopupMenu(wxCommandEvent& event)
u32 end = start + symbol->size;
for (u32 addr = start; addr != end; addr += 4)
{
char disasm[256];
m_debugger->Disassemble(addr, disasm, 256);
text = text + StringFromFormat("%08x: ", addr) + disasm + "\r\n";
std::string disasm = m_debugger->Disassemble(addr);
text += StringFromFormat("%08x: ", addr) + disasm + "\r\n";
}
wxTheClipboard->SetData(new wxTextDataObject(StrToWxStr(text)));
}
@ -478,65 +476,51 @@ void CCodeView::OnPaint(wxPaintEvent& event)
// If running
if (m_debugger->IsAlive())
{
char dis[256];
m_debugger->Disassemble(address, dis, 256);
char* dis2 = strchr(dis, '\t');
char desc[256] = "";
std::vector<std::string> dis;
SplitString(m_debugger->Disassemble(address), '\t', dis);
// If we have a code
if (dis2)
static const size_t VALID_BRANCH_LENGTH = 10;
const std::string& opcode = dis[0];
const std::string& operands = dis[1];
std::string desc;
// look for hex strings to decode branches
std::string hex_str;
size_t pos = operands.find("0x8");
if (pos != std::string::npos)
{
*dis2 = 0;
dis2++;
// look for hex strings to decode branches
const char* mojs = strstr(dis2, "0x8");
if (mojs)
{
for (int k = 0; k < 8; k++)
{
bool found = false;
for (int j = 0; j < 22; j++)
{
if (mojs[k + 2] == "0123456789ABCDEFabcdef"[j])
found = true;
}
if (!found)
{
mojs = nullptr;
break;
}
}
}
if (mojs)
{
int offs;
sscanf(mojs + 2, "%08x", &offs);
branches[numBranches].src = rowY1 + m_rowHeight / 2;
branches[numBranches].srcAddr = address / m_align;
branches[numBranches++].dst = (int)(rowY1 + ((s64)(u32)offs - (s64)(u32)address) * m_rowHeight / m_align + m_rowHeight / 2);
sprintf(desc, "-->%s", m_debugger->GetDescription(offs).c_str());
dc.SetTextForeground(wxTheColourDatabase->Find("PURPLE")); // the -> arrow illustrations are purple
}
else
{
dc.SetTextForeground(*wxBLACK);
}
dc.DrawText(StrToWxStr(dis2), 17 + 17*charWidth, rowY1);
// ------------
hex_str = operands.substr(pos);
}
if (hex_str.length() == VALID_BRANCH_LENGTH)
{
u32 offs = std::stoul(hex_str, nullptr, 16);
branches[numBranches].src = rowY1 + m_rowHeight / 2;
branches[numBranches].srcAddr = address / m_align;
branches[numBranches++].dst = (int)(rowY1 + ((s64)(u32)offs - (s64)(u32)address) * m_rowHeight / m_align + m_rowHeight / 2);
desc = StringFromFormat("-->%s", m_debugger->GetDescription(offs).c_str());
dc.SetTextForeground(wxTheColourDatabase->Find("PURPLE")); // the -> arrow illustrations are purple
}
else
{
dc.SetTextForeground(*wxBLACK);
}
dc.DrawText(StrToWxStr(operands), 17 + 17*charWidth, rowY1);
// ------------
// Show blr as its' own color
if (strcmp(dis, "blr"))
if (opcode == "blr")
dc.SetTextForeground(wxTheColourDatabase->Find("DARK GREEN"));
else
dc.SetTextForeground(wxTheColourDatabase->Find("VIOLET"));
dc.DrawText(StrToWxStr(dis), 17 + (m_plain ? 1*charWidth : 9*charWidth), rowY1);
dc.DrawText(StrToWxStr(opcode), 17 + (m_plain ? 1*charWidth : 9*charWidth), rowY1);
if (desc[0] == 0)
if (desc.empty())
{
strcpy(desc, m_debugger->GetDescription(address).c_str());
desc = m_debugger->GetDescription(address);
}
if (!m_plain)
@ -545,7 +529,7 @@ void CCodeView::OnPaint(wxPaintEvent& event)
//char temp[256];
//UnDecorateSymbolName(desc,temp,255,UNDNAME_COMPLETE);
if (strlen(desc))
if (!desc.empty())
{
dc.DrawText(StrToWxStr(desc), 17 + 35 * charWidth, rowY1);
}

View File

@ -5,7 +5,6 @@
#include <cstdio>
#include <cstring>
#include <disasm.h> // Bochs
#include <PowerPCDisasm.h> // Bochs
#include <wx/button.h>
#include <wx/chartype.h>
#include <wx/defs.h>
@ -22,6 +21,7 @@
#include <wx/windowid.h>
#include "Common/Common.h"
#include "Common/GekkoDisassembler.h"
#include "Common/StringUtil.h"
#include "Core/PowerPC/Gekko.h"
#include "Core/PowerPC/PPCAnalyst.h"
@ -161,9 +161,8 @@ void CJitWindow::Compare(u32 em_address)
for (u32 i = 0; i < code_block.m_num_instructions; i++)
{
const PPCAnalyst::CodeOp &op = code_buffer.codebuffer[i];
char temp[256];
DisassembleGekko(op.inst.hex, op.address, temp, 256);
sptr += sprintf(sptr, "%08x %s\n", op.address, temp);
std::string temp = GekkoDisassembler::Disassemble(op.inst.hex, op.address);
sptr += sprintf(sptr, "%08x %s\n", op.address, temp.c_str());
}
// Add stats to the end of the ppc box since it's generally the shortest.

View File

@ -10,6 +10,7 @@
#include <wx/windowid.h>
#include "Common/CommonTypes.h"
#include "Common/GekkoDisassembler.h"
#include "Common/StringUtil.h"
#include "Core/HW/ProcessorInterface.h"
#include "Core/PowerPC/Gekko.h"
@ -22,9 +23,6 @@ class wxWindow;
// F-zero 80005e60 wtf??
extern const char* GetGPRName(unsigned int index);
extern const char* GetFPRName(unsigned int index);
static const char *special_reg_names[] = {
"PC", "LR", "CTR", "CR", "FPSCR", "MSR", "SRR0", "SRR1", "Exceptions", "Int Mask", "Int Cause",
};
@ -54,9 +52,9 @@ wxString CRegTable::GetValue(int row, int col)
{
switch (col)
{
case 0: return StrToWxStr(GetGPRName(row));
case 0: return StrToWxStr(GekkoDisassembler::GetGPRName(row));
case 1: return wxString::Format("%08x", GPR(row));
case 2: return StrToWxStr(GetFPRName(row));
case 2: return StrToWxStr(GekkoDisassembler::GetFPRName(row));
case 3: return wxString::Format("%016llx", riPS0(row));
case 4: return wxString::Format("%016llx", riPS1(row));
default: return wxEmptyString;