mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-02-13 03:40:49 +00:00
SPU Debugger: Implement float registers view + General debugger fixes (#9265)
* SPU Debugger: Fix try_get_insert_mask_info * Debugger: Always update thread state on context's data change No longer needing to press on thread's instructions for actions to work!
This commit is contained in:
parent
dfae7bd073
commit
b1710bb712
@ -218,6 +218,12 @@ typename SPUDisAsm::insert_mask_info SPUDisAsm::try_get_insert_mask_info(v128 ma
|
||||
return {};
|
||||
}
|
||||
|
||||
if (size == 16)
|
||||
{
|
||||
// 0x0, 0x1, 0x2, .. 0xE, 0xF is not allowed
|
||||
return {};
|
||||
}
|
||||
|
||||
// [type size, dst index, src index]
|
||||
return {size, first / size, src_first / size};
|
||||
}
|
||||
|
@ -1194,9 +1194,11 @@ std::string spu_thread::dump_regs() const
|
||||
{
|
||||
std::string ret;
|
||||
|
||||
const bool floats_only = debugger_float_mode.load();
|
||||
|
||||
for (u32 i = 0; i < 128; i++, ret += '\n')
|
||||
{
|
||||
fmt::append(ret, "r%d: ", i);
|
||||
fmt::append(ret, "%s: ", spu_reg_name[i]);
|
||||
|
||||
const auto r = gpr[i];
|
||||
|
||||
@ -1217,9 +1219,25 @@ std::string spu_thread::dump_regs() const
|
||||
}
|
||||
}
|
||||
|
||||
const u32 i3 = r._u32[3];
|
||||
auto to_f64 = [](u32 bits)
|
||||
{
|
||||
const u32 abs = bits & 0x7fff'ffff;
|
||||
constexpr u32 scale = (1 << 23);
|
||||
return std::copysign(abs < scale ? 0 : std::ldexp((scale + (abs % scale)) / f64{scale}, static_cast<int>(abs >> 23) - 127), bits >> 31 ? -1 : 1);
|
||||
};
|
||||
|
||||
if (v128::from32p(i3) == r)
|
||||
const double array[]{to_f64(r.u32r[0]), to_f64(r.u32r[1]), to_f64(r.u32r[2]), to_f64(r.u32r[3])};
|
||||
|
||||
const u32 i3 = r._u32[3];
|
||||
const bool is_packed = v128::from32p(i3) == r;
|
||||
|
||||
if (floats_only)
|
||||
{
|
||||
fmt::append(ret, "%g, %g, %g, %g", array[0], array[1], array[2], array[3]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_packed)
|
||||
{
|
||||
// Shortand formatting
|
||||
fmt::append(ret, "%08x", i3);
|
||||
@ -1229,8 +1247,6 @@ std::string spu_thread::dump_regs() const
|
||||
fmt::append(ret, "%08x %08x %08x %08x", r.u32r[0], r.u32r[1], r.u32r[2], r.u32r[3]);
|
||||
}
|
||||
|
||||
// TODO: SPU floats fomatting
|
||||
|
||||
if (i3 >= 0x80 && is_exec_code(i3))
|
||||
{
|
||||
SPUDisAsm dis_asm(CPUDisAsm_NormalMode);
|
||||
@ -1239,6 +1255,18 @@ std::string spu_thread::dump_regs() const
|
||||
dis_asm.disasm(i3);
|
||||
fmt::append(ret, " -> %s", dis_asm.last_opcode);
|
||||
}
|
||||
|
||||
if (std::any_of(std::begin(array), std::end(array), [](f64 v){ return v != 0; }))
|
||||
{
|
||||
if (is_packed)
|
||||
{
|
||||
fmt::append(ret, " (%g)", array[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
fmt::append(ret, " (%g, %g, %g, %g)", array[0], array[1], array[2], array[3]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const auto events = ch_events.load();
|
||||
|
@ -764,6 +764,8 @@ public:
|
||||
const char* current_func{}; // Current STOP or RDCH blocking function
|
||||
u64 start_time{}; // Starting time of STOP or RDCH bloking function
|
||||
|
||||
atomic_t<u8> debugger_float_mode = 0;
|
||||
|
||||
void push_snr(u32 number, u32 value);
|
||||
static void do_dma_transfer(spu_thread* _this, const spu_mfc_cmd& args, u8* ls);
|
||||
bool do_dma_check(const spu_mfc_cmd& args);
|
||||
|
@ -224,12 +224,12 @@ void debugger_frame::keyPressEvent(QKeyEvent* event)
|
||||
const auto cpu = this->cpu.lock();
|
||||
int i = m_debugger_list->currentRow();
|
||||
|
||||
if (!isActiveWindow() || i < 0 || !cpu || m_no_thread_selected)
|
||||
if (!isActiveWindow() || !cpu || m_no_thread_selected)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const u32 pc = m_debugger_list->m_pc + i * 4;
|
||||
const u32 pc = i >= 0 ? m_debugger_list->m_pc + i * 4 : GetPc();
|
||||
|
||||
const auto modifiers = QApplication::keyboardModifiers();
|
||||
|
||||
@ -254,9 +254,19 @@ void debugger_frame::keyPressEvent(QKeyEvent* event)
|
||||
dlg->show();
|
||||
return;
|
||||
}
|
||||
case Qt::Key_F:
|
||||
{
|
||||
if (cpu->id_type() != 2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static_cast<spu_thread*>(cpu.get())->debugger_float_mode ^= 1; // Switch mode
|
||||
return;
|
||||
}
|
||||
case Qt::Key_R:
|
||||
{
|
||||
register_editor_dialog* dlg = new register_editor_dialog(this, pc, cpu, m_disasm.get());
|
||||
register_editor_dialog* dlg = new register_editor_dialog(this, cpu, m_disasm.get());
|
||||
dlg->show();
|
||||
return;
|
||||
}
|
||||
@ -264,9 +274,7 @@ void debugger_frame::keyPressEvent(QKeyEvent* event)
|
||||
{
|
||||
if (modifiers & Qt::AltModifier)
|
||||
{
|
||||
const auto cpu = this->cpu.lock();
|
||||
|
||||
if (!cpu || cpu->id_type() != 2)
|
||||
if (cpu->id_type() != 2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -321,10 +329,10 @@ void debugger_frame::UpdateUI()
|
||||
|
||||
if (!cpu)
|
||||
{
|
||||
if (m_last_pc != umax || m_last_stat)
|
||||
if (m_last_pc != umax || !m_last_query_state.empty())
|
||||
{
|
||||
m_last_query_state.clear();
|
||||
m_last_pc = -1;
|
||||
m_last_stat = 0;
|
||||
DoUpdate();
|
||||
}
|
||||
|
||||
@ -335,15 +343,18 @@ void debugger_frame::UpdateUI()
|
||||
else
|
||||
{
|
||||
const auto cia = GetPc();
|
||||
const auto state = cpu->state.load();
|
||||
const auto size_context = cpu->id_type() == 1 ? sizeof(ppu_thread) : sizeof(spu_thread);
|
||||
|
||||
if (m_last_pc != cia || m_last_stat != static_cast<u32>(state))
|
||||
if (m_last_pc != cia || m_last_query_state.size() != size_context || std::memcmp(m_last_query_state.data(), cpu.get(), size_context))
|
||||
{
|
||||
// Copy thread data
|
||||
m_last_query_state.resize(size_context);
|
||||
std::memcpy(m_last_query_state.data(), cpu.get(), size_context);
|
||||
|
||||
m_last_pc = cia;
|
||||
m_last_stat = static_cast<u32>(state);
|
||||
DoUpdate();
|
||||
|
||||
if (state & cpu_flag::dbg_pause)
|
||||
if (cpu->state & cpu_flag::dbg_pause)
|
||||
{
|
||||
m_btn_run->setText(RunString);
|
||||
m_btn_step->setEnabled(true);
|
||||
|
@ -43,7 +43,7 @@ class debugger_frame : public custom_dock_widget
|
||||
u64 m_threads_created = 0;
|
||||
u64 m_threads_deleted = 0;
|
||||
u32 m_last_pc = -1;
|
||||
u32 m_last_stat = 0;
|
||||
std::vector<char> m_last_query_state;
|
||||
u32 m_last_step_over_breakpoint = -1;
|
||||
bool m_no_thread_selected = true;
|
||||
|
||||
|
@ -55,9 +55,8 @@ enum registers : int
|
||||
PC,
|
||||
};
|
||||
|
||||
register_editor_dialog::register_editor_dialog(QWidget *parent, u32 _pc, const std::shared_ptr<cpu_thread>& _cpu, CPUDisAsm* _disasm)
|
||||
register_editor_dialog::register_editor_dialog(QWidget *parent, const std::shared_ptr<cpu_thread>& _cpu, CPUDisAsm* _disasm)
|
||||
: QDialog(parent)
|
||||
, m_pc(_pc)
|
||||
, m_disasm(_disasm)
|
||||
, cpu(_cpu)
|
||||
{
|
||||
|
@ -13,7 +13,6 @@ class register_editor_dialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
u32 m_pc;
|
||||
CPUDisAsm* m_disasm;
|
||||
QComboBox* m_register_combo;
|
||||
QLineEdit* m_value_line;
|
||||
@ -22,7 +21,7 @@ public:
|
||||
std::weak_ptr<cpu_thread> cpu;
|
||||
|
||||
public:
|
||||
register_editor_dialog(QWidget *parent, u32 _pc, const std::shared_ptr<cpu_thread>& _cpu, CPUDisAsm* _disasm);
|
||||
register_editor_dialog(QWidget *parent, const std::shared_ptr<cpu_thread>& _cpu, CPUDisAsm* _disasm);
|
||||
|
||||
private:
|
||||
void OnOkay(const std::shared_ptr<cpu_thread>& _cpu);
|
||||
|
Loading…
x
Reference in New Issue
Block a user