mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-17 08:11:51 +00:00
SPU Debugger: Improve registers panel
This commit is contained in:
parent
a83df01bfd
commit
52fa69d93d
@ -7,7 +7,7 @@ enum CPUDisAsmMode
|
||||
{
|
||||
CPUDisAsm_DumpMode,
|
||||
CPUDisAsm_InterpreterMode,
|
||||
//CPUDisAsm_NormalMode,
|
||||
CPUDisAsm_NormalMode,
|
||||
CPUDisAsm_CompilerElfMode,
|
||||
};
|
||||
|
||||
@ -21,25 +21,37 @@ protected:
|
||||
switch(m_mode)
|
||||
{
|
||||
case CPUDisAsm_DumpMode:
|
||||
{
|
||||
last_opcode = fmt::format("\t%08x:\t%02x %02x %02x %02x\t%s\n", dump_pc,
|
||||
offset[dump_pc],
|
||||
offset[dump_pc + 1],
|
||||
offset[dump_pc + 2],
|
||||
offset[dump_pc + 3], value);
|
||||
break;
|
||||
}
|
||||
|
||||
case CPUDisAsm_InterpreterMode:
|
||||
{
|
||||
last_opcode = fmt::format("[%08x] %02x %02x %02x %02x: %s", dump_pc,
|
||||
offset[dump_pc],
|
||||
offset[dump_pc + 1],
|
||||
offset[dump_pc + 2],
|
||||
offset[dump_pc + 3], value);
|
||||
break;
|
||||
}
|
||||
|
||||
case CPUDisAsm_CompilerElfMode:
|
||||
last_opcode = value + "\n";
|
||||
{
|
||||
last_opcode = value + '\n';
|
||||
break;
|
||||
}
|
||||
case CPUDisAsm_NormalMode:
|
||||
{
|
||||
last_opcode = value;
|
||||
break;
|
||||
}
|
||||
default: ASSUME(0);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
@ -79,9 +91,13 @@ protected:
|
||||
return fmt::format("%s%s", v < 0 ? "-" : "", av);
|
||||
}
|
||||
|
||||
static std::string FixOp(std::string op)
|
||||
std::string FixOp(std::string op) const
|
||||
{
|
||||
if (m_mode != CPUDisAsm_NormalMode)
|
||||
{
|
||||
op.resize(std::max<std::size_t>(op.length(), 10), ' ');
|
||||
}
|
||||
|
||||
return op;
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "PPUInterpreter.h"
|
||||
#include "PPUAnalyser.h"
|
||||
#include "PPUModule.h"
|
||||
#include "PPUDisAsm.h"
|
||||
#include "SPURecompiler.h"
|
||||
#include "lv2/sys_sync.h"
|
||||
#include "lv2/sys_prx.h"
|
||||
@ -482,7 +483,11 @@ std::string ppu_thread::dump_regs() const
|
||||
}
|
||||
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])))
|
||||
|
@ -97,7 +97,11 @@ private:
|
||||
private:
|
||||
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;
|
||||
}
|
||||
void DisAsm(const char* op)
|
||||
|
@ -1194,9 +1194,49 @@ std::string spu_thread::dump_regs() const
|
||||
{
|
||||
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();
|
||||
@ -1264,8 +1304,7 @@ std::vector<std::pair<u32, u32>> spu_thread::dump_callstack_list() const
|
||||
return true;
|
||||
}
|
||||
|
||||
const u32 op = _ref<u32>(addr);
|
||||
return s_spu_itype.decode(op) == spu_itype::UNK || !op || !addr;
|
||||
return !addr || !is_exec_code(addr);
|
||||
};
|
||||
|
||||
if (is_invalid(lr))
|
||||
@ -2863,6 +2902,34 @@ bool spu_thread::check_mfc_interrupts(u32 next_pc)
|
||||
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()
|
||||
{
|
||||
return ch_tag_mask & ~mfc_fence;
|
||||
|
@ -778,6 +778,7 @@ public:
|
||||
void set_events(u32 bits);
|
||||
void set_interrupt_status(bool enable);
|
||||
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);
|
||||
s64 get_ch_value(u32 ch);
|
||||
bool set_ch_value(u32 ch, u32 value);
|
||||
|
Loading…
Reference in New Issue
Block a user