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:
parent
15920d0f10
commit
0718937237
|
@ -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>
|
||||
|
|
|
@ -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
|
@ -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
|
|
@ -3,6 +3,7 @@ set(SRCS BreakPoints.cpp
|
|||
ColorUtil.cpp
|
||||
FileSearch.cpp
|
||||
FileUtil.cpp
|
||||
GekkoDisassembler.cpp
|
||||
Hash.cpp
|
||||
IniFile.cpp
|
||||
MathUtil.cpp
|
||||
|
|
|
@ -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>
|
|
@ -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" />
|
||||
|
|
|
@ -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
|
@ -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
|
||||
};
|
|
@ -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>";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue