Skip to content

Commit

Permalink
PPU/Debugger: View the currently used CR field content in register panel
Browse files Browse the repository at this point in the history
  • Loading branch information
elad335 committed Jul 12, 2023
1 parent d153e97 commit 38810e7
Show file tree
Hide file tree
Showing 10 changed files with 84 additions and 12 deletions.
6 changes: 4 additions & 2 deletions rpcs3/Emu/CPU/CPUThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1093,9 +1093,11 @@ std::shared_ptr<CPUDisAsm> make_disasm(const cpu_thread* cpu);

void cpu_thread::dump_all(std::string& ret) const
{
std::any func_data;

ret += dump_misc();
ret += '\n';
dump_regs(ret);
dump_regs(ret, func_data);
ret += '\n';
ret += dump_callstack();
ret += '\n';
Expand All @@ -1118,7 +1120,7 @@ void cpu_thread::dump_all(std::string& ret) const
}
}

void cpu_thread::dump_regs(std::string&) const
void cpu_thread::dump_regs(std::string&, std::any&) const
{
}

Expand Down
3 changes: 2 additions & 1 deletion rpcs3/Emu/CPU/CPUThread.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "../Utilities/bit_set.h"

#include <vector>
#include <any>

template <typename Derived, typename Base>
concept DerivedFrom = std::is_base_of_v<Base, Derived> &&
Expand Down Expand Up @@ -159,7 +160,7 @@ class cpu_thread
virtual void dump_all(std::string&) const;

// Get CPU register dump
virtual void dump_regs(std::string&) const;
virtual void dump_regs(std::string& ret, std::any& custom_data) const;

// Get CPU call stack dump
virtual std::string dump_callstack() const;
Expand Down
73 changes: 70 additions & 3 deletions rpcs3/Emu/Cell/PPUThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1235,14 +1235,30 @@ std::array<u32, 2> op_branch_targets(u32 pc, ppu_opcode_t op)
return res;
}

void ppu_thread::dump_regs(std::string& ret) const
void ppu_thread::dump_regs(std::string& ret, std::any& custom_data) const
{
const system_state emu_state = Emu.GetStatus(false);
const bool is_stopped_or_frozen = state & cpu_flag::exit || emu_state == system_state::frozen || emu_state <= system_state::stopping;
const ppu_debugger_mode mode = debugger_mode.load();

const bool is_decimal = !is_stopped_or_frozen && mode == ppu_debugger_mode::is_decimal;

struct dump_registers_data_t
{
u32 preferred_cr_field_index = 7;
};

dump_registers_data_t* func_data = nullptr;

func_data = std::any_cast<dump_registers_data_t>(&custom_data);

if (!func_data)
{
custom_data.reset();
custom_data = std::make_any<dump_registers_data_t>();
func_data = ensure(std::any_cast<dump_registers_data_t>(&custom_data));
}

PPUDisAsm dis_asm(cpu_disasm_mode::normal, vm::g_sudo_addr);

for (uint i = 0; i < 32; ++i)
Expand Down Expand Up @@ -1367,6 +1383,58 @@ void ppu_thread::dump_regs(std::string& ret) const
ret += '\n';
}

const u32 current_cia = cia;
const u32 cr_packed = cr.pack();

for (u32 addr :
{
current_cia,
current_cia + 4,
current_cia + 8,
current_cia - 4,
current_cia + 12,
})
{
dis_asm.disasm(addr);

if (dis_asm.last_opcode.size() <= 4)
{
continue;
}

if (usz index = dis_asm.last_opcode.rfind(",cr"); index < dis_asm.last_opcode.size() - 4)
{
const char result = dis_asm.last_opcode[index + 3];

if (result >= '0' && result <= '7')
{
func_data->preferred_cr_field_index = result - '0';
break;
}
}

if (usz index = dis_asm.last_opcode.rfind(" cr"); index < dis_asm.last_opcode.size() - 4)
{
const char result = dis_asm.last_opcode[index + 3];

if (result >= '0' && result <= '7')
{
func_data->preferred_cr_field_index = result - '0';
break;
}
}

if (dis_asm.last_opcode.find("stdcx.") != umax || dis_asm.last_opcode.find("stwcx.") != umax)
{
// Modifying CR0
func_data->preferred_cr_field_index = 0;
}
}

const u32 displayed_cr_field = (cr_packed >> ((7 - func_data->preferred_cr_field_index) * 4)) & 0xf;

fmt::append(ret, "CR: 0x%08x, CR%d: [LT=%u GT=%u EQ=%u SO=%u]\n", cr_packed, func_data->preferred_cr_field_index, displayed_cr_field >> 3, (displayed_cr_field >> 2) & 1, (displayed_cr_field >> 1) & 1, displayed_cr_field & 1);

for (uint i = 0; i < 32; ++i)
{
const f64 r = fpr[i];
Expand Down Expand Up @@ -1400,8 +1468,7 @@ void ppu_thread::dump_regs(std::string& ret) const
}
}

fmt::append(ret, "CIA: 0x%x\n", cia);
fmt::append(ret, "CR: 0x%08x\n", cr.pack());
fmt::append(ret, "CIA: 0x%x\n", current_cia);
fmt::append(ret, "LR: 0x%llx\n", lr);
fmt::append(ret, "CTR: 0x%llx\n", ctr);
fmt::append(ret, "VRSAVE: 0x%08x\n", vrsave);
Expand Down
2 changes: 1 addition & 1 deletion rpcs3/Emu/Cell/PPUThread.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ class ppu_thread : public cpu_thread
static const u32 id_count = 100;
static constexpr std::pair<u32, u32> id_invl_range = {12, 12};

virtual void dump_regs(std::string&) const override;
virtual void dump_regs(std::string&, std::any& custom_data) const override;
virtual std::string dump_callstack() const override;
virtual std::vector<std::pair<u32, u32>> dump_callstack_list() const override;
virtual std::string dump_misc() const override;
Expand Down
2 changes: 1 addition & 1 deletion rpcs3/Emu/Cell/SPUThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1017,7 +1017,7 @@ spu_imm_table_t::spu_imm_table_t()
}
}

void spu_thread::dump_regs(std::string& ret) const
void spu_thread::dump_regs(std::string& ret, std::any& /*custom_data*/) const
{
const system_state emu_state = Emu.GetStatus(false);
const bool is_stopped_or_frozen = state & cpu_flag::exit || emu_state == system_state::frozen || emu_state <= system_state::stopping;
Expand Down
2 changes: 1 addition & 1 deletion rpcs3/Emu/Cell/SPUThread.h
Original file line number Diff line number Diff line change
Expand Up @@ -620,7 +620,7 @@ enum class spu_debugger_mode : u32
class spu_thread : public cpu_thread
{
public:
virtual void dump_regs(std::string&) const override;
virtual void dump_regs(std::string&, std::any& custom_data) const override;
virtual std::string dump_callstack() const override;
virtual std::vector<std::pair<u32, u32>> dump_callstack_list() const override;
virtual std::string dump_misc() const override;
Expand Down
2 changes: 1 addition & 1 deletion rpcs3/Emu/RSX/RSXThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3164,7 +3164,7 @@ namespace rsx

void invalid_method(thread*, u32, u32);

void thread::dump_regs(std::string& result) const
void thread::dump_regs(std::string& result, std::any& /*custom_data*/) const
{
if (ctrl)
{
Expand Down
2 changes: 1 addition & 1 deletion rpcs3/Emu/RSX/RSXThread.h
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ namespace rsx
static void fifo_wake_delay(u64 div = 1);
u32 get_fifo_cmd() const;

void dump_regs(std::string&) const override;
void dump_regs(std::string&, std::any& custom_data) const override;
void cpu_wait(bs_t<cpu_flag> old) override;

static constexpr u32 id_base = 0x5555'5555; // See get_current_cpu_thread()
Expand Down
2 changes: 1 addition & 1 deletion rpcs3/rpcs3qt/debugger_frame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1155,7 +1155,7 @@ void debugger_frame::WritePanels()
hloc = m_regs->horizontalScrollBar()->value();
m_regs->clear();
m_last_reg_state.clear();
cpu->dump_regs(m_last_reg_state);
cpu->dump_regs(m_last_reg_state, m_dump_reg_func_data);
m_regs->setText(qstr(m_last_reg_state));
m_regs->verticalScrollBar()->setValue(loc);
m_regs->horizontalScrollBar()->setValue(hloc);
Expand Down
2 changes: 2 additions & 0 deletions rpcs3/rpcs3qt/debugger_frame.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#include <memory>
#include <vector>
#include <any>

class CPUDisAsm;
class cpu_thread;
Expand Down Expand Up @@ -58,6 +59,7 @@ class debugger_frame : public custom_dock_widget
u32 m_last_pc = -1;
std::vector<char> m_last_query_state;
std::string m_last_reg_state;
std::any m_dump_reg_func_data;
u32 m_last_step_over_breakpoint = -1;
u64 m_ui_update_ctr = 0;
u64 m_ui_fast_update_permission_deadline = 0;
Expand Down

0 comments on commit 38810e7

Please sign in to comment.