From 55e1bc746a45118e14554c957b4ee4663039d9af Mon Sep 17 00:00:00 2001 From: Pavel Pisa Date: Sun, 3 Feb 2019 11:52:53 +0100 Subject: Implement BREAK instruction to stop continuous execution. Signed-off-by: Pavel Pisa --- qtmips_machine/alu.cpp | 2 ++ qtmips_machine/alu.h | 1 + qtmips_machine/core.cpp | 5 +++++ qtmips_machine/core.h | 1 + qtmips_machine/instruction.cpp | 7 ++++++- qtmips_machine/instruction.h | 1 + qtmips_machine/qtmipsmachine.cpp | 9 ++++++--- 7 files changed, 22 insertions(+), 4 deletions(-) (limited to 'qtmips_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() { -- cgit v1.2.3