mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-10 16:19:28 +01:00
Merge pull request #647 from lioncash/disasm
Common: Introduce the new Gekko disassembler to Common.
This commit is contained in:
commit
6befa34b60
4
Externals/Bochs_disasm/Bochs_disasm.vcxproj
vendored
4
Externals/Bochs_disasm/Bochs_disasm.vcxproj
vendored
@ -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>
|
||||
|
3
Externals/Bochs_disasm/CMakeLists.txt
vendored
3
Externals/Bochs_disasm/CMakeLists.txt
vendored
@ -1,8 +1,7 @@
|
||||
set(SRCS dis_decode.cpp
|
||||
dis_groups.cpp
|
||||
resolve.cpp
|
||||
syntax.cpp
|
||||
PowerPCDisasm.cpp)
|
||||
syntax.cpp)
|
||||
|
||||
if(WIN32)
|
||||
set(SRCS ${SRCS} stdafx.cpp)
|
||||
|
2285
Externals/Bochs_disasm/PowerPCDisasm.cpp
vendored
2285
Externals/Bochs_disasm/PowerPCDisasm.cpp
vendored
File diff suppressed because it is too large
Load Diff
29
Externals/Bochs_disasm/PowerPCDisasm.h
vendored
29
Externals/Bochs_disasm/PowerPCDisasm.h
vendored
@ -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" />
|
||||
|
@ -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;}
|
||||
|
2299
Source/Core/Common/GekkoDisassembler.cpp
Normal file
2299
Source/Core/Common/GekkoDisassembler.cpp
Normal file
File diff suppressed because it is too large
Load Diff
152
Source/Core/Common/GekkoDisassembler.h
Normal file
152
Source/Core/Common/GekkoDisassembler.h
Normal 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
|
||||
};
|
@ -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
|
||||
{
|
||||
return "(No RAM here)";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(dest, "(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,43 +476,30 @@ 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);
|
||||
|
||||
static const size_t VALID_BRANCH_LENGTH = 10;
|
||||
const std::string& opcode = dis[0];
|
||||
const std::string& operands = dis[1];
|
||||
std::string desc;
|
||||
|
||||
// If we have a code
|
||||
if (dis2)
|
||||
{
|
||||
*dis2 = 0;
|
||||
dis2++;
|
||||
// look for hex strings to decode branches
|
||||
const char* mojs = strstr(dis2, "0x8");
|
||||
if (mojs)
|
||||
std::string hex_str;
|
||||
size_t pos = operands.find("0x8");
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
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;
|
||||
hex_str = operands.substr(pos);
|
||||
}
|
||||
if (!found)
|
||||
|
||||
if (hex_str.length() == VALID_BRANCH_LENGTH)
|
||||
{
|
||||
mojs = nullptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mojs)
|
||||
{
|
||||
int offs;
|
||||
sscanf(mojs + 2, "%08x", &offs);
|
||||
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);
|
||||
sprintf(desc, "-->%s", m_debugger->GetDescription(offs).c_str());
|
||||
desc = StringFromFormat("-->%s", m_debugger->GetDescription(offs).c_str());
|
||||
dc.SetTextForeground(wxTheColourDatabase->Find("PURPLE")); // the -> arrow illustrations are purple
|
||||
}
|
||||
else
|
||||
@ -522,21 +507,20 @@ void CCodeView::OnPaint(wxPaintEvent& event)
|
||||
dc.SetTextForeground(*wxBLACK);
|
||||
}
|
||||
|
||||
dc.DrawText(StrToWxStr(dis2), 17 + 17*charWidth, rowY1);
|
||||
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…
x
Reference in New Issue
Block a user