aboutsummaryrefslogtreecommitdiff
path: root/qtmips_machine/core.cpp
diff options
context:
space:
mode:
authorKarel Kočí <cynerd@email.cz>2018-02-16 16:24:35 +0100
committerKarel Kočí <cynerd@email.cz>2018-03-06 21:58:49 +0100
commit1a20d908b6eefe32807f906b7294c562256a7518 (patch)
tree38cd063d902767d637b65426eecff538c9233672 /qtmips_machine/core.cpp
parenta56b25212865c57251719a1d4a5d9d6a79b339c5 (diff)
downloadqtmips-1a20d908b6eefe32807f906b7294c562256a7518.tar.gz
qtmips-1a20d908b6eefe32807f906b7294c562256a7518.tar.bz2
qtmips-1a20d908b6eefe32807f906b7294c562256a7518.zip
Fix forwarding checker for I and J and S* instructions
THere are exceptions when we care about forwarding and when we don't.
Diffstat (limited to 'qtmips_machine/core.cpp')
-rw-r--r--qtmips_machine/core.cpp30
1 files changed, 18 insertions, 12 deletions
diff --git a/qtmips_machine/core.cpp b/qtmips_machine/core.cpp
index 75f7173..273842d 100644
--- a/qtmips_machine/core.cpp
+++ b/qtmips_machine/core.cpp
@@ -305,20 +305,26 @@ void CorePipelined::step() {
bool stall = false;
if (hazard_unit != MachineConfig::HU_NONE) {
// Note: We make exception with $0 as that has no effect when written and is used in nop instruction
-// TODO rt should be compared onlu if instruction is R or it's S*
-#define HAZARD(STAGE) ((STAGE).regwrite && (STAGE).rwrite != 0 && ((STAGE).rwrite == dt_d.inst.rs() || (STAGE).rwrite == dt_d.inst.rt())) // Note: We make exception with $0 as that has no effect and is used in nop instruction
+
+#define HAZARD(STAGE) ( \
+ (STAGE).regwrite && (STAGE).rwrite != 0 && \
+ ((STAGE).rwrite == dt_d.inst.rs() || ( \
+ ((STAGE).inst.type() == Instruction::T_R || (STAGE).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
+
if (HAZARD(dt_e)) {
// Hazard with instruction in execute stage
if (hazard_unit == MachineConfig::HU_STALL_FORWARD) {
- if (dt_e.memread)
- stall = true;
- else {
- // Forward result value
- if (dt_e.rwrite == dt_d.inst.rs())
- dt_d.val_rs = dt_e.alu_val;
- if (dt_e.rwrite == dt_d.inst.rt())
- dt_d.val_rt = dt_e.alu_val;
- }
+ if (dt_e.memread) // TODO extend by branch instructions
+ stall = true;
+ else {
+ // Forward result value
+ if (dt_e.rwrite == dt_d.inst.rs())
+ dt_d.val_rs = dt_e.alu_val;
+ if (dt_e.rwrite == dt_d.inst.rt())
+ dt_d.val_rt = dt_e.alu_val;
+ }
} else
stall = true;
}
@@ -346,7 +352,7 @@ void CorePipelined::step() {
fetch();
// clear decode latch (insert nope to execute stage)
dtDecodeInit(dt_d);
- }
+ }
}
void CorePipelined::reset() {