From 10f4d52221438f0d5ce7cc72c5b6c1f6720ef5c6 Mon Sep 17 00:00:00 2001 From: Pavel Pisa Date: Mon, 11 Feb 2019 17:45:47 +0100 Subject: Extend program view to support selected stage followup. Signed-off-by: Pavel Pisa --- qtmips_gui/mainwindow.cpp | 14 +++++++++ qtmips_gui/memorymodel.cpp | 1 + qtmips_gui/memorytableview.cpp | 14 ++++++++- qtmips_gui/memorytableview.h | 1 + qtmips_gui/programdock.cpp | 68 +++++++++++++++++++++++++++++++++++++++-- qtmips_gui/programdock.h | 22 ++++++++++++- qtmips_gui/programmodel.cpp | 6 ++-- qtmips_gui/programtableview.cpp | 12 ++++++++ qtmips_gui/programtableview.h | 1 + 9 files changed, 133 insertions(+), 6 deletions(-) (limited to 'qtmips_gui') diff --git a/qtmips_gui/mainwindow.cpp b/qtmips_gui/mainwindow.cpp index 90d6911..c4f57f5 100644 --- a/qtmips_gui/mainwindow.cpp +++ b/qtmips_gui/mainwindow.cpp @@ -151,12 +151,26 @@ void MainWindow::create_core(const machine::MachineConfig &config) { // Connect signal from break to machine pause connect(machine->core(), SIGNAL(stop_on_exception_reached()), machine, SLOT(pause())); + // Setup docks registers->setup(machine); program->setup(machine); memory->setup(machine); cache_program->setup(machine->cache_program()); cache_data->setup(machine->cache_data()); + + // Connect signals for instruction address followup + connect(machine->core(), SIGNAL(fetch_inst_addr_value(std::uint32_t)), + program, SLOT(fetch_inst_addr(std::uint32_t))); + connect(machine->core(), SIGNAL(decode_inst_addr_value(std::uint32_t)), + program, SLOT(decode_inst_addr(std::uint32_t))); + connect(machine->core(), SIGNAL(execute_inst_addr_value(std::uint32_t)), + program, SLOT(execute_inst_addr(std::uint32_t))); + connect(machine->core(), SIGNAL(memory_inst_addr_value(std::uint32_t)), + program, SLOT(memory_inst_addr(std::uint32_t))); + connect(machine->core(), SIGNAL(writeback_inst_addr_value(std::uint32_t)), + program, SLOT(writeback_inst_addr(std::uint32_t))); + // Set status to ready machine_status(machine::QtMipsMachine::ST_READY); } diff --git a/qtmips_gui/memorymodel.cpp b/qtmips_gui/memorymodel.cpp index 908f019..66da84c 100644 --- a/qtmips_gui/memorymodel.cpp +++ b/qtmips_gui/memorymodel.cpp @@ -101,6 +101,7 @@ QVariant MemoryModel::data(const QModelIndex &index, int role) const { case CELLSIZE_HWORD: data = machine->memory()->read_hword(address); break; + default: case CELLSIZE_WORD: data = machine->memory()->read_word(address); break; diff --git a/qtmips_gui/memorytableview.cpp b/qtmips_gui/memorytableview.cpp index 18e1bb1..e2386fa 100644 --- a/qtmips_gui/memorytableview.cpp +++ b/qtmips_gui/memorytableview.cpp @@ -167,7 +167,7 @@ void MemoryTableView::resizeEvent(QResizeEvent *event) { } } -void MemoryTableView:: go_to_address(std::uint32_t address) { +void MemoryTableView::go_to_address(std::uint32_t address) { MemoryModel *m = dynamic_cast(model()); int row; if (m == nullptr) @@ -179,3 +179,15 @@ void MemoryTableView:: go_to_address(std::uint32_t address) { addr0_save_change(address); emit m->update_all(); } + +void MemoryTableView::focus_address(std::uint32_t address) { + int row; + MemoryModel *m = dynamic_cast(model()); + if (m == nullptr) + return; + if (!m->get_row_for_address(row, address)) + go_to_address(address); + if (!m->get_row_for_address(row, address)) + return; + setCurrentIndex(m->index(row, 1)); +} diff --git a/qtmips_gui/memorytableview.h b/qtmips_gui/memorytableview.h index f5bf832..a0f2617 100644 --- a/qtmips_gui/memorytableview.h +++ b/qtmips_gui/memorytableview.h @@ -56,6 +56,7 @@ signals: public slots: void set_cell_size(int index); void go_to_address(std::uint32_t address); + void focus_address(std::uint32_t address); private slots: void adjust_scroll_pos(); private: diff --git a/qtmips_gui/programdock.cpp b/qtmips_gui/programdock.cpp index 39a3f77..a355b22 100644 --- a/qtmips_gui/programdock.cpp +++ b/qtmips_gui/programdock.cpp @@ -50,11 +50,23 @@ ProgramDock::ProgramDock(QWidget *parent, QSettings *settings) : Super(parent) { setObjectName("Program"); setWindowTitle("Program"); + this->settings = settings; + follow_source = (enum FollowSource) + settings->value("ProgramViewFollowSource", 0).toInt(); + + for (int i = 0; i < FOLLOWSRC_COUNT; i++) + follow_addr[i] = 0; + QWidget *content = new QWidget(); QComboBox *follow_inst = new QComboBox(); - follow_inst->addItem("Follow - none"); - follow_inst->addItem("Follow - fetch"); + follow_inst->addItem("Follow none"); + follow_inst->addItem("Follow fetch"); + follow_inst->addItem("Follow decode"); + follow_inst->addItem("Follow execute"); + follow_inst->addItem("Follow memory"); + follow_inst->addItem("Follow writeback"); + follow_inst->setCurrentIndex((int)follow_source); QTableView *program_content = new ProgramTableView(0, settings); // program_content->setSizePolicy(); @@ -81,8 +93,60 @@ ProgramDock::ProgramDock(QWidget *parent, QSettings *settings) : Super(parent) { go_edit, SLOT(set_value(std::uint32_t))); connect(this, SIGNAL(jump_to_pc(std::uint32_t)), program_content, SLOT(go_to_address(std::uint32_t))); + connect(follow_inst, SIGNAL(currentIndexChanged(int)), + this, SLOT(set_follow_inst(int))); + connect(this, SIGNAL(focus_addr(std::uint32_t)), + program_content, SLOT(focus_address(std::uint32_t))); } void ProgramDock::setup(machine::QtMipsMachine *machine) { + std::uint32_t pc; emit machine_setup(machine); + if (machine == nullptr) + return; + pc = machine->registers()->read_pc(); + for (int i = 0; i < FOLLOWSRC_COUNT; i++) + follow_addr[i] = pc; + update_follow_position(); +} + +void ProgramDock::set_follow_inst(int follow) { + follow_source = (enum FollowSource)follow; + settings->setValue("ProgramViewFollowSource", (int)follow_source); + update_follow_position(); +} + +void ProgramDock::fetch_inst_addr(std::uint32_t addr) { + follow_addr[FOLLOWSRC_FETCH] = addr; + if (follow_source == FOLLOWSRC_FETCH) + update_follow_position(); +} + +void ProgramDock::decode_inst_addr(std::uint32_t addr) { + follow_addr[FOLLOWSRC_DECODE] = addr; + if (follow_source == FOLLOWSRC_DECODE) + update_follow_position(); +} + +void ProgramDock::execute_inst_addr(std::uint32_t addr) { + follow_addr[FOLLOWSRC_EXECUTE] = addr; + if (follow_source == FOLLOWSRC_EXECUTE) + update_follow_position(); +} + +void ProgramDock::memory_inst_addr(std::uint32_t addr) { + follow_addr[FOLLOWSRC_MEMORY] = addr; + if (follow_source == FOLLOWSRC_MEMORY) + update_follow_position(); +} + +void ProgramDock::writeback_inst_addr(std::uint32_t addr) { + follow_addr[FOLLOWSRC_WRITEBACK] = addr; + if (follow_source == FOLLOWSRC_WRITEBACK) + update_follow_position(); +} + +void ProgramDock::update_follow_position() { + if (follow_source != FOLLOWSRC_NONE) + emit focus_addr(follow_addr[follow_source]); } diff --git a/qtmips_gui/programdock.h b/qtmips_gui/programdock.h index 10b9df1..529730a 100644 --- a/qtmips_gui/programdock.h +++ b/qtmips_gui/programdock.h @@ -54,9 +54,29 @@ public: signals: void machine_setup(machine::QtMipsMachine *machine); void jump_to_pc(std::uint32_t); - + void focus_addr(std::uint32_t); +public slots: + void set_follow_inst(int); + void fetch_inst_addr(std::uint32_t addr); + void decode_inst_addr(std::uint32_t addr); + void execute_inst_addr(std::uint32_t addr); + void memory_inst_addr(std::uint32_t addr); + void writeback_inst_addr(std::uint32_t addr); private: + enum FollowSource { + FOLLOWSRC_NONE, + FOLLOWSRC_FETCH, + FOLLOWSRC_DECODE, + FOLLOWSRC_EXECUTE, + FOLLOWSRC_MEMORY, + FOLLOWSRC_WRITEBACK, + FOLLOWSRC_COUNT, + }; + void update_follow_position(); + enum FollowSource follow_source; + std::uint32_t follow_addr[FOLLOWSRC_COUNT]; + QSettings *settings; }; #endif // PROGRAMDOCK_H diff --git a/qtmips_gui/programmodel.cpp b/qtmips_gui/programmodel.cpp index 5387058..19b0f0d 100644 --- a/qtmips_gui/programmodel.cpp +++ b/qtmips_gui/programmodel.cpp @@ -80,7 +80,6 @@ QVariant ProgramModel::data(const QModelIndex &index, int role) const { { QString s, t; std::uint32_t address; - std::uint32_t data; if (!get_row_address(address, index.row())) return QString(""); @@ -99,7 +98,10 @@ QVariant ProgramModel::data(const QModelIndex &index, int role) const { switch (index.column()) { case 0: - return QString(" "); + if (machine->is_hwbreak(address)) + return QString("B"); + else + return QString(" "); case 2: t = QString::number(inst.data(), 16); s.fill('0', 8 - t.count()); diff --git a/qtmips_gui/programtableview.cpp b/qtmips_gui/programtableview.cpp index 34a119a..005b518 100644 --- a/qtmips_gui/programtableview.cpp +++ b/qtmips_gui/programtableview.cpp @@ -153,3 +153,15 @@ void ProgramTableView:: go_to_address(std::uint32_t address) { addr0_save_change(address); emit m->update_all(); } + +void ProgramTableView::focus_address(std::uint32_t address) { + int row; + ProgramModel *m = dynamic_cast(model()); + if (m == nullptr) + return; + if (!m->get_row_for_address(row, address)) + go_to_address(address); + if (!m->get_row_for_address(row, address)) + return; + setCurrentIndex(m->index(row, 3)); +} diff --git a/qtmips_gui/programtableview.h b/qtmips_gui/programtableview.h index b24c47d..30fc5f6 100644 --- a/qtmips_gui/programtableview.h +++ b/qtmips_gui/programtableview.h @@ -55,6 +55,7 @@ signals: void address_changed(std::uint32_t address); public slots: void go_to_address(std::uint32_t address); + void focus_address(std::uint32_t address); private slots: void adjust_scroll_pos(); private: -- cgit v1.2.3