mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-09-04 08:35:55 +00:00
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
21 changed files with 2553 additions and 2434 deletions
|
@ -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");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue