aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--qtmips_machine/core.cpp56
-rw-r--r--qtmips_machine/core.h15
-rw-r--r--qtmips_machine/machinedefs.h1
-rw-r--r--qtmips_machine/qtmipsmachine.cpp16
-rw-r--r--qtmips_machine/qtmipsmachine.h3
5 files changed, 84 insertions, 7 deletions
diff --git a/qtmips_machine/core.cpp b/qtmips_machine/core.cpp
index 30d01bb..68dbe0b 100644
--- a/qtmips_machine/core.cpp
+++ b/qtmips_machine/core.cpp
@@ -40,7 +40,7 @@
using namespace machine;
Core::Core(Registers *regs, MemoryAccess *mem_program, MemoryAccess *mem_data,
- unsigned int min_cache_row_size) : ex_handlers() {
+ unsigned int min_cache_row_size) : ex_handlers(), hw_breaks() {
cycle_c = 0;
this->regs = regs;
this->mem_program = mem_program;
@@ -76,6 +76,28 @@ MemoryAccess *Core::get_mem_program() {
return mem_program;
}
+
+Core::hwBreak::hwBreak(std::uint32_t addr) {
+ this->addr = addr;
+ flags = 0;
+ count = 0;
+}
+
+void Core::inser_hwbreak(std::uint32_t address) {
+ hw_breaks.insert(address, new hwBreak(address));
+}
+
+void Core::remove_hwbreak(std::uint32_t address) {
+ hwBreak* hwbrk = hw_breaks.take(address);
+ if (hwbrk != nullptr)
+ delete hwbrk;
+}
+
+bool Core::is_hwbreak(std::uint32_t address) {
+ hwBreak* hwbrk = hw_breaks.value(address);
+ return hwbrk != nullptr;
+}
+
void Core::register_exception_handler(ExceptionCause excause, ExceptionHandler *exhandler)
{
if (excause == EXCAUSE_NONE ) {
@@ -94,6 +116,13 @@ bool Core::handle_exception(Core *core, Registers *regs, ExceptionCause excause,
std::uint32_t jump_branch_pc, bool in_delay_slot,
std::uint32_t mem_ref_addr)
{
+ if (excause == EXCAUSE_HWBREAK) {
+ if (in_delay_slot)
+ regs->pc_abs_jmp(inst_addr);
+ else
+ regs->pc_abs_jmp(jump_branch_pc);
+ }
+
ExceptionHandler *exhandler = ex_handlers.value(excause);
if (exhandler != nullptr)
return exhandler->handle_exception(core, regs, excause, inst_addr,
@@ -107,19 +136,27 @@ bool Core::handle_exception(Core *core, Registers *regs, ExceptionCause excause,
}
struct Core::dtFetch Core::fetch() {
+ enum ExceptionCause excause = EXCAUSE_NONE;
std::uint32_t inst_addr = regs->read_pc();
+ emit fetch_inst_addr_value(inst_addr);
Instruction inst(mem_program->read_word(inst_addr));
+
emit instruction_fetched(inst, inst_addr);
+ hwBreak *brk = hw_breaks.value(inst_addr);
+ if (brk != nullptr) {
+ excause = EXCAUSE_HWBREAK;
+ }
return {
.inst = inst,
.inst_addr = inst_addr,
- .excause = EXCAUSE_NONE,
+ .excause = excause,
.in_delay_slot = false,
};
}
struct Core::dtDecode Core::decode(const struct dtFetch &dt) {
uint8_t rwrite;
+ emit decode_inst_addr_value(dt.inst_addr);
emit instruction_decoded(dt.inst, dt.inst_addr);
enum InstructionFlags flags;
enum AluOp alu_op;
@@ -150,9 +187,9 @@ struct Core::dtDecode Core::decode(const struct dtFetch &dt) {
else
immediate_val = sign_extend(dt.inst.immediate());
- if ((flags & IMF_EXCEPTION) && (excause == EXCAUSE_NONE)) {
- excause = dt.inst.encoded_exception();
- }
+ if ((flags & IMF_EXCEPTION) && (excause == EXCAUSE_NONE)) {
+ excause = dt.inst.encoded_exception();
+ }
emit decode_instruction_value(dt.inst.data());
emit decode_reg1_value(val_rs);
@@ -209,6 +246,7 @@ struct Core::dtDecode Core::decode(const struct dtFetch &dt) {
}
struct Core::dtExecute Core::execute(const struct dtDecode &dt) {
+ emit execute_inst_addr_value(dt.inst_addr);
emit instruction_executed(dt.inst, dt.inst_addr);
bool discard;
@@ -275,6 +313,7 @@ struct Core::dtExecute Core::execute(const struct dtDecode &dt) {
}
struct Core::dtMemory Core::memory(const struct dtExecute &dt) {
+ emit memory_inst_addr_value(dt.inst_addr);
emit instruction_memory(dt.inst, dt.inst_addr);
std::uint32_t towrite_val = dt.alu_val;
std::uint32_t mem_addr = dt.alu_val;
@@ -319,7 +358,7 @@ struct Core::dtMemory Core::memory(const struct dtExecute &dt) {
.regwrite = regwrite,
.rwrite = dt.rwrite,
.towrite_val = towrite_val,
- .mem_addr = mem_addr,
+ .mem_addr = mem_addr,
.inst_addr = dt.inst_addr,
.excause = dt.excause,
.in_delay_slot = dt.in_delay_slot,
@@ -327,6 +366,7 @@ struct Core::dtMemory Core::memory(const struct dtExecute &dt) {
}
void Core::writeback(const struct dtMemory &dt) {
+ emit writeback_inst_addr_value(dt.inst_addr);
emit instruction_writeback(dt.inst, dt.inst_addr);
emit writeback_value(dt.towrite_val);
emit writeback_regw_value(dt.regwrite);
@@ -464,8 +504,10 @@ void CoreSingle::do_step() {
}
jump_branch_pc = jmp_delay_decode->inst_addr;
*jmp_delay_decode = d; // Copy current decode
- } else
+ } else {
handle_pc(d);
+ jump_branch_pc = d.inst_addr;
+ }
struct dtExecute e = execute(d);
struct dtMemory m = memory(e);
diff --git a/qtmips_machine/core.h b/qtmips_machine/core.h
index 3303438..88d0e9b 100644
--- a/qtmips_machine/core.h
+++ b/qtmips_machine/core.h
@@ -81,6 +81,9 @@ public:
MemoryAccess *get_mem_data();
MemoryAccess *get_mem_program();
void register_exception_handler(ExceptionCause excause, ExceptionHandler *exhandler);
+ void inser_hwbreak(std::uint32_t address);
+ void remove_hwbreak(std::uint32_t address);
+ bool is_hwbreak(std::uint32_t address);
enum ForwardFrom {
FORWARD_NONE = 0b00,
@@ -96,9 +99,11 @@ signals:
void instruction_writeback(const machine::Instruction &inst, std::uint32_t inst_addr);
void instruction_program_counter(const machine::Instruction &inst, std::uint32_t inst_addr);
+ void fetch_inst_addr_value(std::uint32_t);
void fetch_jump_reg_value(std::uint32_t);
void fetch_jump_value(std::uint32_t);
void fetch_branch_value(std::uint32_t);
+ void decode_inst_addr_value(std::uint32_t);
void decode_instruction_value(std::uint32_t);
void decode_reg1_value(std::uint32_t);
void decode_reg2_value(std::uint32_t);
@@ -115,6 +120,7 @@ signals:
void decode_regd31_value(std::uint32_t);
void forward_m_d_rs_value(std::uint32_t);
void forward_m_d_rt_value(std::uint32_t);
+ void execute_inst_addr_value(std::uint32_t);
void execute_alu_value(std::uint32_t);
void execute_reg1_value(std::uint32_t);
void execute_reg2_value(std::uint32_t);
@@ -128,6 +134,7 @@ signals:
void execute_alusrc_value(std::uint32_t);
void execute_regdest_value(std::uint32_t);
void execute_regw_num_value(std::uint32_t);
+ void memory_inst_addr_value(std::uint32_t);
void memory_alu_value(std::uint32_t);
void memory_rt_value(std::uint32_t);
void memory_mem_value(std::uint32_t);
@@ -136,6 +143,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 writeback_inst_addr_value(std::uint32_t);
void writeback_value(std::uint32_t);
void writeback_regw_value(std::uint32_t);
void writeback_regw_num_value(std::uint32_t);
@@ -231,9 +239,16 @@ protected:
void dtMemoryInit(struct dtMemory &dt);
private:
+ struct hwBreak{
+ hwBreak(std::uint32_t addr);
+ std::uint32_t addr;
+ unsigned int flags;
+ unsigned int count;
+ };
unsigned int cycle_c;
unsigned int min_cache_row_size;
std::uint32_t hwr_user_local;
+ QMap<std::uint32_t, hwBreak *> hw_breaks;
};
class CoreSingle : public Core {
diff --git a/qtmips_machine/machinedefs.h b/qtmips_machine/machinedefs.h
index 05bf103..258b76c 100644
--- a/qtmips_machine/machinedefs.h
+++ b/qtmips_machine/machinedefs.h
@@ -56,6 +56,7 @@ enum ExceptionCause {
EXCAUSE_NONE,
EXCAUSE_BREAK,
EXCAUSE_SYSCALL,
+ EXCAUSE_HWBREAK,
};
enum AluOp : std::uint8_t {
diff --git a/qtmips_machine/qtmipsmachine.cpp b/qtmips_machine/qtmipsmachine.cpp
index 2942bec..f846ed2 100644
--- a/qtmips_machine/qtmipsmachine.cpp
+++ b/qtmips_machine/qtmipsmachine.cpp
@@ -205,3 +205,19 @@ void QtMipsMachine::register_exception_handler(ExceptionCause excause,
if (cr != nullptr)
cr->register_exception_handler(excause, exhandler);
}
+
+void QtMipsMachine::inser_hwbreak(std::uint32_t address) {
+ if (cr != nullptr)
+ cr->inser_hwbreak(address);
+}
+
+void QtMipsMachine::remove_hwbreak(std::uint32_t address) {
+ if (cr != nullptr)
+ cr->remove_hwbreak(address);
+}
+
+bool QtMipsMachine::is_hwbreak(std::uint32_t address) {
+ if (cr != nullptr)
+ return cr->is_hwbreak(address);
+ return false;
+}
diff --git a/qtmips_machine/qtmipsmachine.h b/qtmips_machine/qtmipsmachine.h
index 7a128f6..82245ff 100644
--- a/qtmips_machine/qtmipsmachine.h
+++ b/qtmips_machine/qtmipsmachine.h
@@ -78,6 +78,9 @@ public:
bool exited();
void register_exception_handler(ExceptionCause excause, ExceptionHandler *exhandler);
+ void inser_hwbreak(std::uint32_t address);
+ void remove_hwbreak(std::uint32_t address);
+ bool is_hwbreak(std::uint32_t address);
public slots:
void play();