diff options
Diffstat (limited to 'qtmips_machine')
-rw-r--r-- | qtmips_machine/core.cpp | 20 | ||||
-rw-r--r-- | qtmips_machine/core.h | 4 | ||||
-rw-r--r-- | qtmips_machine/machinedefs.h | 2 |
3 files changed, 22 insertions, 4 deletions
diff --git a/qtmips_machine/core.cpp b/qtmips_machine/core.cpp index 45b08ec..64c309b 100644 --- a/qtmips_machine/core.cpp +++ b/qtmips_machine/core.cpp @@ -275,6 +275,7 @@ struct Core::dtFetch Core::fetch(bool skip_break) { .inst_addr = inst_addr, .excause = excause, .in_delay_slot = false, + .is_valid = true, }; } @@ -316,7 +317,7 @@ struct Core::dtDecode Core::decode(const struct dtFetch &dt) { excause = dt.inst.encoded_exception(); } - emit decode_inst_addr_value(dt.inst_addr); + emit decode_inst_addr_value(dt.is_valid? dt.inst_addr: STAGEADDR_NONE); emit instruction_decoded(dt.inst, dt.inst_addr, excause); emit decode_instruction_value(dt.inst.data()); emit decode_reg1_value(val_rs); @@ -374,6 +375,7 @@ struct Core::dtDecode Core::decode(const struct dtFetch &dt) { .in_delay_slot = dt.in_delay_slot, .stall = false, .stop_if = !!(flags & IMF_STOP_IF), + .is_valid = dt.is_valid, }; } @@ -447,7 +449,7 @@ struct Core::dtExecute Core::execute(const struct dtDecode &dt) { } } - emit execute_inst_addr_value(dt.inst_addr); + emit execute_inst_addr_value(dt.is_valid? dt.inst_addr: STAGEADDR_NONE); emit instruction_executed(dt.inst, dt.inst_addr, excause); emit execute_alu_value(alu_val); emit execute_reg1_value(dt.val_rs); @@ -485,6 +487,7 @@ struct Core::dtExecute Core::execute(const struct dtDecode &dt) { .excause = excause, .in_delay_slot = dt.in_delay_slot, .stop_if = dt.stop_if, + .is_valid = dt.is_valid, }; } @@ -514,7 +517,7 @@ struct Core::dtMemory Core::memory(const struct dtExecute &dt) { regwrite = false; } - emit memory_inst_addr_value(dt.inst_addr); + emit memory_inst_addr_value(dt.is_valid? dt.inst_addr: STAGEADDR_NONE); emit instruction_memory(dt.inst, dt.inst_addr, dt.excause); emit memory_alu_value(dt.alu_val); emit memory_rt_value(dt.val_rt); @@ -537,11 +540,12 @@ struct Core::dtMemory Core::memory(const struct dtExecute &dt) { .excause = dt.excause, .in_delay_slot = dt.in_delay_slot, .stop_if = dt.stop_if, + .is_valid = dt.is_valid, }; } void Core::writeback(const struct dtMemory &dt) { - emit writeback_inst_addr_value(dt.inst_addr); + emit writeback_inst_addr_value(dt.is_valid? dt.inst_addr: STAGEADDR_NONE); emit instruction_writeback(dt.inst, dt.inst_addr, dt.excause); emit writeback_value(dt.towrite_val); emit writeback_regw_value(dt.regwrite); @@ -600,6 +604,7 @@ void Core::dtFetchInit(struct dtFetch &dt) { dt.inst = Instruction(0x00); dt.excause = EXCAUSE_NONE; dt.in_delay_slot = false; + dt.is_valid = false; } void Core::dtDecodeInit(struct dtDecode &dt) { @@ -632,6 +637,7 @@ void Core::dtDecodeInit(struct dtDecode &dt) { dt.in_delay_slot = false; dt.stall = false; dt.stop_if = false; + dt.is_valid = false; } void Core::dtExecuteInit(struct dtExecute &dt) { @@ -646,6 +652,7 @@ void Core::dtExecuteInit(struct dtExecute &dt) { dt.excause = EXCAUSE_NONE; dt.in_delay_slot = false; dt.stop_if = false; + dt.is_valid = false; } void Core::dtMemoryInit(struct dtMemory &dt) { @@ -658,6 +665,7 @@ void Core::dtMemoryInit(struct dtMemory &dt) { dt.excause = EXCAUSE_NONE; dt.in_delay_slot = false; dt.stop_if = false; + dt.is_valid = false; } CoreSingle::CoreSingle(Registers *regs, MemoryAccess *mem_program, MemoryAccess *mem_data, @@ -742,16 +750,19 @@ void CorePipelined::do_step(bool skip_break) { if (excpt_in_progress) { dtExecuteInit(dt_e); emit instruction_executed(dt_e.inst, dt_e.inst_addr, dt_e.excause); + emit execute_inst_addr_value(STAGEADDR_NONE); } excpt_in_progress = excpt_in_progress || dt_e.excause != EXCAUSE_NONE; if (excpt_in_progress) { dtDecodeInit(dt_d); emit instruction_decoded(dt_d.inst, dt_d.inst_addr, dt_d.excause); + emit decode_inst_addr_value(STAGEADDR_NONE); } excpt_in_progress = excpt_in_progress || dt_e.excause != EXCAUSE_NONE; if (excpt_in_progress) { dtFetchInit(dt_f); emit instruction_fetched(dt_f.inst, dt_f.inst_addr, dt_f.excause); + emit fetch_inst_addr_value(STAGEADDR_NONE); if (dt_m.excause != EXCAUSE_NONE) { regs->pc_abs_jmp(dt_e.inst_addr); handle_exception(this, regs, dt_m.excause, dt_m.inst_addr, @@ -867,6 +878,7 @@ void CorePipelined::do_step(bool skip_break) { if (dt_d.nb_skip_ds) { dtFetchInit(dt_f); emit instruction_fetched(dt_f.inst, dt_f.inst_addr, dt_f.excause); + emit fetch_inst_addr_value(STAGEADDR_NONE); } } } else { diff --git a/qtmips_machine/core.h b/qtmips_machine/core.h index 52cadb4..5658726 100644 --- a/qtmips_machine/core.h +++ b/qtmips_machine/core.h @@ -186,6 +186,7 @@ protected: uint32_t inst_addr; // Address of instruction enum ExceptionCause excause; bool in_delay_slot; + bool is_valid; }; struct dtDecode { Instruction inst; @@ -222,6 +223,7 @@ protected: bool in_delay_slot; bool stall; bool stop_if; + bool is_valid; }; struct dtExecute { Instruction inst; @@ -236,6 +238,7 @@ protected: enum ExceptionCause excause; bool in_delay_slot; bool stop_if; + bool is_valid; }; struct dtMemory { Instruction inst; @@ -248,6 +251,7 @@ protected: enum ExceptionCause excause; bool in_delay_slot; bool stop_if; + bool is_valid; }; struct dtFetch fetch(bool skip_break = false); diff --git a/qtmips_machine/machinedefs.h b/qtmips_machine/machinedefs.h index d8219b6..9f85240 100644 --- a/qtmips_machine/machinedefs.h +++ b/qtmips_machine/machinedefs.h @@ -141,6 +141,8 @@ enum LocationStatus { LOCSTAT_ILLEGAL = 1 << 3, }; +const std::uint32_t STAGEADDR_NONE = 0xffffffff; + } #endif // MACHINEDEFS_H |