aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--qtmips_machine/core.cpp21
-rw-r--r--qtmips_machine/core.h2
-rw-r--r--qtmips_machine/instruction.cpp25
3 files changed, 27 insertions, 21 deletions
diff --git a/qtmips_machine/core.cpp b/qtmips_machine/core.cpp
index fd37d6b..d91a36e 100644
--- a/qtmips_machine/core.cpp
+++ b/qtmips_machine/core.cpp
@@ -153,6 +153,8 @@ struct Core::dtDecode Core::decode(const struct dtFetch &dt) {
.regd = regd,
.regd31 = regd31,
.regwrite = regwrite,
+ .alu_req_rs = flags & IMF_ALU_REQ_RS,
+ .alu_req_rt = flags & IMF_ALU_REQ_RT,
.bjr_req_rs = bjr_req_rs,
.bjr_req_rt = bjr_req_rt,
.forward_m_d_rs = false,
@@ -401,23 +403,21 @@ void CorePipelined::do_step() {
// Note: We make exception with $0 as that has no effect when written and is used in nop instruction
#define HAZARD(STAGE) ( \
- (STAGE).regwrite && (STAGE).rwrite != 0 && \
- ((STAGE).rwrite == dt_d.inst.rs() || ( \
- (dt_d.inst.type() == Instruction::T_R || dt_d.inst.is_store()) && \
- (STAGE).rwrite == dt_d.inst.rt()) \
- )) // Note: We make exception with $0 as that has no effect and is used in nop instruction
+ (STAGE).regwrite && (STAGE).rwrite != 0 && \
+ ((dt_d.alu_req_rs && (STAGE).rwrite == dt_d.inst.rs()) || \
+ (dt_d.alu_req_rt && (STAGE).rwrite == dt_d.inst.rt())) \
+ ) // Note: We make exception with $0 as that has no effect and is used in nop instruction
// Write back stage combinatoricly propagates written instruction to decode stage so nothing has to be done for that stage
if (HAZARD(dt_m)) {
// Hazard with instruction in memory stage
if (hazard_unit == MachineConfig::HU_STALL_FORWARD) {
// Forward result value
- if (dt_m.rwrite == dt_d.inst.rs()) {
+ if (dt_d.alu_req_rs && dt_m.rwrite == dt_d.inst.rs()) {
dt_d.val_rs = dt_m.towrite_val;
dt_d.ff_rs = FORWARD_FROM_M;
}
- if ((dt_d.inst.type() == Instruction::T_R || dt_d.inst.is_store()) &&
- (dt_m.rwrite == dt_d.inst.rt())) {
+ if (dt_d.alu_req_rt && dt_m.rwrite == dt_d.inst.rt()) {
dt_d.val_rt = dt_m.towrite_val;
dt_d.ff_rt = FORWARD_FROM_M;
}
@@ -431,12 +431,11 @@ void CorePipelined::do_step() {
stall = true;
else {
// Forward result value
- if (dt_e.rwrite == dt_d.inst.rs()) {
+ if (dt_d.alu_req_rs && dt_e.rwrite == dt_d.inst.rs()) {
dt_d.val_rs = dt_e.alu_val;
dt_d.ff_rs = FORWARD_FROM_W;
}
- if ((dt_d.inst.type() == Instruction::T_R || dt_d.inst.is_store()) &&
- (dt_e.rwrite == dt_d.inst.rt())) {
+ if (dt_d.alu_req_rt && dt_e.rwrite == dt_d.inst.rt()) {
dt_d.val_rt = dt_e.alu_val;
dt_d.ff_rt = FORWARD_FROM_W;
}
diff --git a/qtmips_machine/core.h b/qtmips_machine/core.h
index 3a27f55..6f9509f 100644
--- a/qtmips_machine/core.h
+++ b/qtmips_machine/core.h
@@ -132,6 +132,8 @@ protected:
bool regd; // If rd is used (otherwise rt is used for write target)
bool regd31; // Use R31 as destionation for JAL
bool regwrite; // If output should be written back to register (which one depends on regd)
+ bool alu_req_rs; // requires rs value for ALU
+ bool alu_req_rt; // requires rt value for ALU or SW
bool bjr_req_rs; // requires rs for beq, bne, blez, bgtz, jr nad jalr
bool bjr_req_rt; // requires rt for beq, bne
bool forward_m_d_rs; // forwarding required for beq, bne, blez, bgtz, jr nad jalr
diff --git a/qtmips_machine/instruction.cpp b/qtmips_machine/instruction.cpp
index 9a7b9c9..4c91d6f 100644
--- a/qtmips_machine/instruction.cpp
+++ b/qtmips_machine/instruction.cpp
@@ -40,8 +40,13 @@
using namespace machine;
-#define FLAGS_ALU_I (IMF_SUPPORTED | IMF_ALUSRC | IMF_REGWRITE)
-#define FLAGS_ALU_I_ZE (IMF_SUPPORTED | IMF_ALUSRC | IMF_REGWRITE | IMF_ZERO_EXTEND)
+#define FLAGS_ALU_I (IMF_SUPPORTED | IMF_ALUSRC | IMF_REGWRITE | IMF_ALU_REQ_RS)
+#define FLAGS_ALU_I_ZE (FLAGS_ALU_I | IMF_ZERO_EXTEND)
+
+#define FLAGS_ALU_I_LOAD (IMF_SUPPORTED | IMF_ALUSRC | IMF_REGWRITE | \
+ IMF_MEMREAD | IMF_MEM | IMF_ALU_REQ_RS)
+#define FLAGS_ALU_I_STORE (IMF_SUPPORTED | IMF_ALUSRC | IMF_MEMWRITE | \
+ IMF_MEM | IMF_MEM_STORE | IMF_ALU_REQ_RS | IMF_ALU_REQ_RT)
#define FLAGS_ALU_T_R (IMF_SUPPORTED | IMF_REGD | IMF_REGWRITE)
#define FLAGS_ALU_T_R_STD (IMF_SUPPORTED | IMF_REGD | IMF_REGWRITE \
@@ -119,28 +124,28 @@ static const struct InstructionMap instruction_map[] = {
IM_UNKNOWN, // 30
IM_UNKNOWN, // 31
{"LB", IT_I, ALU_OP_ADDU, AC_BYTE, // LB
- .flags = IMF_SUPPORTED | IMF_ALUSRC | IMF_REGWRITE | IMF_MEMREAD | IMF_MEM},
+ .flags = FLAGS_ALU_I_LOAD},
{"LH", IT_I, ALU_OP_ADDU, AC_HALFWORD, // LH
- .flags = IMF_SUPPORTED | IMF_ALUSRC | IMF_REGWRITE | IMF_MEMREAD | IMF_MEM},
+ .flags = FLAGS_ALU_I_LOAD},
{"LWL", IT_I, ALU_OP_ADDU, NOMEM, // LWL - unsupported
.flags = IMF_MEM},
{"LW", IT_I, ALU_OP_ADDU, AC_WORD, // LW
- .flags = IMF_SUPPORTED | IMF_ALUSRC | IMF_REGWRITE | IMF_MEMREAD | IMF_MEM},
+ .flags = FLAGS_ALU_I_LOAD},
{"LBU", IT_I, ALU_OP_ADDU, AC_BYTE_UNSIGNED, // LBU
- .flags = IMF_SUPPORTED | IMF_ALUSRC | IMF_REGWRITE | IMF_MEMREAD | IMF_MEM },
+ .flags = FLAGS_ALU_I_LOAD},
{"LHU", IT_I, ALU_OP_ADDU, AC_HALFWORD_UNSIGNED, // LHU
- .flags = IMF_SUPPORTED | IMF_ALUSRC | IMF_REGWRITE | IMF_MEMREAD | IMF_MEM,},
+ .flags = FLAGS_ALU_I_LOAD},
{"LWR", IT_I, ALU_OP_ADDU, NOMEM, // LWR - unsupported
.flags = IMF_MEM},
IM_UNKNOWN, // 39
{"SB", IT_I, ALU_OP_ADDU, AC_BYTE, // SB
- .flags = IMF_SUPPORTED | IMF_ALUSRC | IMF_MEMWRITE | IMF_MEM | IMF_MEM_STORE},
+ .flags = FLAGS_ALU_I_STORE},
{"SH", IT_I, ALU_OP_ADDU, AC_HALFWORD, // SH
- .flags = IMF_SUPPORTED | IMF_ALUSRC | IMF_MEMWRITE | IMF_MEM | IMF_MEM_STORE},
+ .flags = FLAGS_ALU_I_STORE},
{"SWL", IT_I, ALU_OP_ADDU, NOMEM, // SWL
.flags = IMF_MEM | IMF_MEM_STORE},
{"SW", IT_I, ALU_OP_ADDU, AC_WORD, // SW
- .flags = IMF_SUPPORTED | IMF_ALUSRC | IMF_MEMWRITE | IMF_MEM | IMF_MEM_STORE},
+ .flags = FLAGS_ALU_I_STORE},
IM_UNKNOWN, // 44,NOPE, // 44
IM_UNKNOWN, // 45,NOPE, // 45
{"SWR", IT_I, ALU_OP_ADDU, NOMEM, // SWR