aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavel Pisa <pisa@cmp.felk.cvut.cz>2019-02-03 11:52:53 +0100
committerPavel Pisa <pisa@cmp.felk.cvut.cz>2019-02-03 11:52:53 +0100
commit55e1bc746a45118e14554c957b4ee4663039d9af (patch)
treeaf416cb8dd60f47f47b6d9b943a53fe069543cdb
parent53c75d278a958e40b9c0b0ca3b04cfb11f356827 (diff)
downloadqtmips-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.cpp2
-rw-r--r--qtmips_machine/alu.cpp2
-rw-r--r--qtmips_machine/alu.h1
-rw-r--r--qtmips_machine/core.cpp5
-rw-r--r--qtmips_machine/core.h1
-rw-r--r--qtmips_machine/instruction.cpp7
-rw-r--r--qtmips_machine/instruction.h1
-rw-r--r--qtmips_machine/qtmipsmachine.cpp9
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() {