diff options
author | Karel Kočí <cynerd@email.cz> | 2018-02-16 16:24:35 +0100 |
---|---|---|
committer | Karel Kočí <cynerd@email.cz> | 2018-03-06 21:58:49 +0100 |
commit | 1a20d908b6eefe32807f906b7294c562256a7518 (patch) | |
tree | 38cd063d902767d637b65426eecff538c9233672 /qtmips_machine/core.cpp | |
parent | a56b25212865c57251719a1d4a5d9d6a79b339c5 (diff) | |
download | qtmips-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.cpp | 30 |
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() { |