mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-05 06:21:26 +12:00
SPU Debugger: Improve registers panel
This commit is contained in:
parent
a83df01bfd
commit
52fa69d93d
5 changed files with 106 additions and 13 deletions
|
@ -7,7 +7,7 @@ enum CPUDisAsmMode
|
||||||
{
|
{
|
||||||
CPUDisAsm_DumpMode,
|
CPUDisAsm_DumpMode,
|
||||||
CPUDisAsm_InterpreterMode,
|
CPUDisAsm_InterpreterMode,
|
||||||
//CPUDisAsm_NormalMode,
|
CPUDisAsm_NormalMode,
|
||||||
CPUDisAsm_CompilerElfMode,
|
CPUDisAsm_CompilerElfMode,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -21,24 +21,36 @@ protected:
|
||||||
switch(m_mode)
|
switch(m_mode)
|
||||||
{
|
{
|
||||||
case CPUDisAsm_DumpMode:
|
case CPUDisAsm_DumpMode:
|
||||||
|
{
|
||||||
last_opcode = fmt::format("\t%08x:\t%02x %02x %02x %02x\t%s\n", dump_pc,
|
last_opcode = fmt::format("\t%08x:\t%02x %02x %02x %02x\t%s\n", dump_pc,
|
||||||
offset[dump_pc],
|
offset[dump_pc],
|
||||||
offset[dump_pc + 1],
|
offset[dump_pc + 1],
|
||||||
offset[dump_pc + 2],
|
offset[dump_pc + 2],
|
||||||
offset[dump_pc + 3], value);
|
offset[dump_pc + 3], value);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case CPUDisAsm_InterpreterMode:
|
case CPUDisAsm_InterpreterMode:
|
||||||
|
{
|
||||||
last_opcode = fmt::format("[%08x] %02x %02x %02x %02x: %s", dump_pc,
|
last_opcode = fmt::format("[%08x] %02x %02x %02x %02x: %s", dump_pc,
|
||||||
offset[dump_pc],
|
offset[dump_pc],
|
||||||
offset[dump_pc + 1],
|
offset[dump_pc + 1],
|
||||||
offset[dump_pc + 2],
|
offset[dump_pc + 2],
|
||||||
offset[dump_pc + 3], value);
|
offset[dump_pc + 3], value);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case CPUDisAsm_CompilerElfMode:
|
case CPUDisAsm_CompilerElfMode:
|
||||||
last_opcode = value + "\n";
|
{
|
||||||
break;
|
last_opcode = value + '\n';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CPUDisAsm_NormalMode:
|
||||||
|
{
|
||||||
|
last_opcode = value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: ASSUME(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,9 +91,13 @@ protected:
|
||||||
return fmt::format("%s%s", v < 0 ? "-" : "", av);
|
return fmt::format("%s%s", v < 0 ? "-" : "", av);
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string FixOp(std::string op)
|
std::string FixOp(std::string op) const
|
||||||
{
|
{
|
||||||
op.resize(std::max<std::size_t>(op.length(), 10), ' ');
|
if (m_mode != CPUDisAsm_NormalMode)
|
||||||
|
{
|
||||||
|
op.resize(std::max<std::size_t>(op.length(), 10), ' ');
|
||||||
|
}
|
||||||
|
|
||||||
return op;
|
return op;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "PPUInterpreter.h"
|
#include "PPUInterpreter.h"
|
||||||
#include "PPUAnalyser.h"
|
#include "PPUAnalyser.h"
|
||||||
#include "PPUModule.h"
|
#include "PPUModule.h"
|
||||||
|
#include "PPUDisAsm.h"
|
||||||
#include "SPURecompiler.h"
|
#include "SPURecompiler.h"
|
||||||
#include "lv2/sys_sync.h"
|
#include "lv2/sys_sync.h"
|
||||||
#include "lv2/sys_prx.h"
|
#include "lv2/sys_prx.h"
|
||||||
|
@ -482,7 +483,11 @@ std::string ppu_thread::dump_regs() const
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fmt::append(ret, " -> function-code");
|
PPUDisAsm dis_asm(CPUDisAsm_NormalMode);
|
||||||
|
dis_asm.offset = vm::g_sudo_addr;
|
||||||
|
dis_asm.dump_pc = reg;
|
||||||
|
dis_asm.disasm(reg);
|
||||||
|
fmt::append(ret, " -> %s", dis_asm.last_opcode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (std::isprint(static_cast<u8>(buf_tmp[0])) && std::isprint(static_cast<u8>(buf_tmp[1])) && std::isprint(static_cast<u8>(buf_tmp[2])))
|
else if (std::isprint(static_cast<u8>(buf_tmp[0])) && std::isprint(static_cast<u8>(buf_tmp[1])) && std::isprint(static_cast<u8>(buf_tmp[2])))
|
||||||
|
|
|
@ -97,7 +97,11 @@ private:
|
||||||
private:
|
private:
|
||||||
std::string& FixOp(std::string& op)
|
std::string& FixOp(std::string& op)
|
||||||
{
|
{
|
||||||
op.append(std::max<int>(10 - ::narrow<int>(op.size()), 0),' ');
|
if (m_mode != CPUDisAsm_NormalMode)
|
||||||
|
{
|
||||||
|
op.append(std::max<int>(10 - ::narrow<int>(op.size()), 0), ' ');
|
||||||
|
}
|
||||||
|
|
||||||
return op;
|
return op;
|
||||||
}
|
}
|
||||||
void DisAsm(const char* op)
|
void DisAsm(const char* op)
|
||||||
|
|
|
@ -1194,9 +1194,49 @@ std::string spu_thread::dump_regs() const
|
||||||
{
|
{
|
||||||
std::string ret;
|
std::string ret;
|
||||||
|
|
||||||
for (u32 i = 0; i < 128; i++)
|
for (u32 i = 0; i < 128; i++, ret += '\n')
|
||||||
{
|
{
|
||||||
fmt::append(ret, "r%d: %s\n", i, gpr[i]);
|
fmt::append(ret, "r%d: ", i);
|
||||||
|
|
||||||
|
const auto r = gpr[i];
|
||||||
|
|
||||||
|
if (auto [size, dst, src] = SPUDisAsm::try_get_insert_mask_info(r); size)
|
||||||
|
{
|
||||||
|
// Special: insertation masks
|
||||||
|
|
||||||
|
const std::string_view type =
|
||||||
|
size == 1 ? "byte" :
|
||||||
|
size == 2 ? "half" :
|
||||||
|
size == 4 ? "word" :
|
||||||
|
size == 8 ? "dword" : "error";
|
||||||
|
|
||||||
|
if ((size >= 4u && !src) || (size == 2u && src == 1u) || (size == 1u && src == 3u))
|
||||||
|
{
|
||||||
|
fmt::append(ret, "insert -> %s[%u]", type, dst);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const u32 i3 = r._u32[3];
|
||||||
|
|
||||||
|
if (v128::from32p(i3) == r)
|
||||||
|
{
|
||||||
|
// Shortand formatting
|
||||||
|
fmt::append(ret, "0x%08x$", i3);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fmt::append(ret, "%s", r);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i3 >= 0x80 && is_exec_code(i3))
|
||||||
|
{
|
||||||
|
SPUDisAsm dis_asm(CPUDisAsm_NormalMode);
|
||||||
|
dis_asm.offset = ls;
|
||||||
|
dis_asm.dump_pc = i3;
|
||||||
|
dis_asm.disasm(i3);
|
||||||
|
fmt::append(ret, " -> %s", dis_asm.last_opcode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto events = ch_events.load();
|
const auto events = ch_events.load();
|
||||||
|
@ -1264,8 +1304,7 @@ std::vector<std::pair<u32, u32>> spu_thread::dump_callstack_list() const
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const u32 op = _ref<u32>(addr);
|
return !addr || !is_exec_code(addr);
|
||||||
return s_spu_itype.decode(op) == spu_itype::UNK || !op || !addr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (is_invalid(lr))
|
if (is_invalid(lr))
|
||||||
|
@ -2863,6 +2902,34 @@ bool spu_thread::check_mfc_interrupts(u32 next_pc)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool spu_thread::is_exec_code(u32 addr) const
|
||||||
|
{
|
||||||
|
if (addr & ~0x3FFFC)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (u32 i = 0; i < 30; i++)
|
||||||
|
{
|
||||||
|
const u32 addr0 = addr + (i * 4);
|
||||||
|
const u32 op = _ref<u32>(addr0);
|
||||||
|
const auto type = s_spu_itype.decode(op);
|
||||||
|
|
||||||
|
if (type == spu_itype::UNK || !op)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type & spu_itype::branch)
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
u32 spu_thread::get_mfc_completed()
|
u32 spu_thread::get_mfc_completed()
|
||||||
{
|
{
|
||||||
return ch_tag_mask & ~mfc_fence;
|
return ch_tag_mask & ~mfc_fence;
|
||||||
|
|
|
@ -778,6 +778,7 @@ public:
|
||||||
void set_events(u32 bits);
|
void set_events(u32 bits);
|
||||||
void set_interrupt_status(bool enable);
|
void set_interrupt_status(bool enable);
|
||||||
bool check_mfc_interrupts(u32 nex_pc);
|
bool check_mfc_interrupts(u32 nex_pc);
|
||||||
|
bool is_exec_code(u32 addr) const; // Only a hint, do not rely on it other than debugging purposes
|
||||||
u32 get_ch_count(u32 ch);
|
u32 get_ch_count(u32 ch);
|
||||||
s64 get_ch_value(u32 ch);
|
s64 get_ch_value(u32 ch);
|
||||||
bool set_ch_value(u32 ch, u32 value);
|
bool set_ch_value(u32 ch, u32 value);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue