diff options
author | Pavel Pisa <pisa@cmp.felk.cvut.cz> | 2019-02-03 11:52:53 +0100 |
---|---|---|
committer | Pavel Pisa <pisa@cmp.felk.cvut.cz> | 2019-02-03 11:52:53 +0100 |
commit | 55e1bc746a45118e14554c957b4ee4663039d9af (patch) | |
tree | af416cb8dd60f47f47b6d9b943a53fe069543cdb | |
parent | 53c75d278a958e40b9c0b0ca3b04cfb11f356827 (diff) | |
download | qtmips-55e1bc746a45118e14554c957b4ee4663039d9af.tar.gz qtmips-55e1bc746a45118e14554c957b4ee4663039d9af.tar.bz2 qtmips-55e1bc746a45118e14554c957b4ee4663039d9af.zip |
Implement BREAK instruction to stop continuous execution.
Signed-off-by: Pavel Pisa <pisa@cmp.felk.cvut.cz>
-rw-r--r-- | qtmips_gui/mainwindow.cpp | 2 | ||||
-rw-r--r-- | qtmips_machine/alu.cpp | 2 | ||||
-rw-r--r-- | qtmips_machine/alu.h | 1 | ||||
-rw-r--r-- | qtmips_machine/core.cpp | 5 | ||||
-rw-r--r-- | qtmips_machine/core.h | 1 | ||||
-rw-r--r-- | qtmips_machine/instruction.cpp | 7 | ||||
-rw-r--r-- | qtmips_machine/instruction.h | 1 | ||||
-rw-r--r-- | qtmips_machine/qtmipsmachine.cpp | 9 |
8 files changed, 24 insertions, 4 deletions
diff --git a/qtmips_gui/mainwindow.cpp b/qtmips_gui/mainwindow.cpp index 4fb9cbf..8c83f6b 100644 --- a/qtmips_gui/mainwindow.cpp +++ b/qtmips_gui/mainwindow.cpp @@ -113,6 +113,8 @@ void MainWindow::create_core(const machine::MachineConfig &config) { connect(corescene, SIGNAL(request_jump_to_program_counter(std::uint32_t)), program, SLOT(jump_to_pc(std::uint32_t))); connect(corescene, SIGNAL(request_cache_program()), this, SLOT(show_cache_program())); connect(corescene, SIGNAL(request_cache_data()), this, SLOT(show_cache_data())); + // Connect signal from break to machine pause + connect(machine->core(), SIGNAL(memory_break_reached()), machine, SLOT(pause())); // Setup docks registers->setup(machine); diff --git a/qtmips_machine/alu.cpp b/qtmips_machine/alu.cpp index bb3a745..49c41a3 100644 --- a/qtmips_machine/alu.cpp +++ b/qtmips_machine/alu.cpp @@ -35,6 +35,8 @@ std::uint32_t machine::alu_operate(enum AluOp operation, std::uint32_t s, std::u case ALU_OP_MOVN: // Same note as for MOVZ applies here return t != 0 ? s : 0; + case ALU_OP_BREAK: + return 0; case ALU_OP_MFHI: return regs->read_hi_lo(true); case ALU_OP_MTHI: diff --git a/qtmips_machine/alu.h b/qtmips_machine/alu.h index 7846244..351e124 100644 --- a/qtmips_machine/alu.h +++ b/qtmips_machine/alu.h @@ -19,6 +19,7 @@ enum AluOp : std::uint8_t { ALU_OP_JALR, ALU_OP_MOVZ, ALU_OP_MOVN, + ALU_OP_BREAK = 13, ALU_OP_MFHI = 16, ALU_OP_MTHI, ALU_OP_MFLO, diff --git a/qtmips_machine/core.cpp b/qtmips_machine/core.cpp index 7793305..3d5541f 100644 --- a/qtmips_machine/core.cpp +++ b/qtmips_machine/core.cpp @@ -146,6 +146,8 @@ struct Core::dtDecode Core::decode(const struct dtFetch &dt) { bool bjr_req_rs = dec.flags & DM_BJR_REQ_RS; if (dt.inst.opcode() == 0) { switch (dt.inst.funct()) { + case ALU_OP_BREAK: + FALLTROUGH case ALU_OP_MTHI: FALLTROUGH case ALU_OP_MTLO: @@ -279,6 +281,9 @@ struct Core::dtMemory Core::memory(const struct dtExecute &dt) { emit memory_memwrite_value(dt.memwrite); emit memory_regw_num_value(dt.rwrite); + if (dt.inst.is_break()) + emit memory_break_reached(); + return { .inst = dt.inst, .regwrite = dt.regwrite, diff --git a/qtmips_machine/core.h b/qtmips_machine/core.h index 00dbee6..d97f4c1 100644 --- a/qtmips_machine/core.h +++ b/qtmips_machine/core.h @@ -73,6 +73,7 @@ signals: void memory_memwrite_value(std::uint32_t); void memory_memread_value(std::uint32_t); void memory_regw_num_value(std::uint32_t); + void memory_break_reached(); void writeback_value(std::uint32_t); void writeback_regw_value(std::uint32_t); void writeback_regw_num_value(std::uint32_t); diff --git a/qtmips_machine/instruction.cpp b/qtmips_machine/instruction.cpp index 7feebd3..0ca7b24 100644 --- a/qtmips_machine/instruction.cpp +++ b/qtmips_machine/instruction.cpp @@ -1,4 +1,5 @@ #include "instruction.h" +#include "alu.h" #include "qtmipsexception.h" using namespace machine; @@ -108,7 +109,7 @@ static const struct AluInstructionMap alu_instruction_map[] = { {"MOVZ"}, {"MOVN"}, AIM_UNKNOWN, - AIM_UNKNOWN, + {"BREAK"}, AIM_UNKNOWN, AIM_UNKNOWN, {"MFHI"}, @@ -231,6 +232,10 @@ bool Instruction::is_store() const { return im.is_store; } +bool Instruction::is_break() const { + return opcode() == 0 && funct() == ALU_OP_BREAK; +} + bool Instruction::operator==(const Instruction &c) const { return (this->data() == c.data()); } diff --git a/qtmips_machine/instruction.h b/qtmips_machine/instruction.h index 1e44a1a..a93be65 100644 --- a/qtmips_machine/instruction.h +++ b/qtmips_machine/instruction.h @@ -33,6 +33,7 @@ public: std::uint32_t data() const; enum Type type() const; bool is_store() const; // Store instructions requires some additional handling so identify them + bool is_break() const; bool operator==(const Instruction &c) const; bool operator!=(const Instruction &c) const; diff --git a/qtmips_machine/qtmipsmachine.cpp b/qtmips_machine/qtmipsmachine.cpp index da4516a..75d8b8e 100644 --- a/qtmips_machine/qtmipsmachine.cpp +++ b/qtmips_machine/qtmipsmachine.cpp @@ -81,7 +81,8 @@ void QtMipsMachine::play() { } void QtMipsMachine::pause() { - CTL_GUARD; + if (stat != ST_BUSY) + CTL_GUARD; set_status(ST_READY); run_t->stop(); } @@ -103,8 +104,10 @@ void QtMipsMachine::step() { run_t->stop(); set_status(ST_EXIT); emit program_exit(); - } else - set_status(stat_prev); + } else { + if (stat == ST_BUSY) + set_status(stat_prev); + } } void QtMipsMachine::restart() { |