diff options
Diffstat (limited to 'src/cpu')
-rw-r--r-- | src/cpu/base_dyn_inst.hh | 1 | ||||
-rw-r--r-- | src/cpu/o3/commit.hh | 7 | ||||
-rw-r--r-- | src/cpu/o3/commit_impl.hh | 32 | ||||
-rw-r--r-- | src/cpu/static_inst.hh | 3 |
4 files changed, 42 insertions, 1 deletions
diff --git a/src/cpu/base_dyn_inst.hh b/src/cpu/base_dyn_inst.hh index bd2d9fa95..0c566ec65 100644 --- a/src/cpu/base_dyn_inst.hh +++ b/src/cpu/base_dyn_inst.hh @@ -478,6 +478,7 @@ class BaseDynInst : public FastAlloc, public RefCounted { return staticInst->isSerializeBefore() || status[SerializeBefore]; } bool isSerializeAfter() const { return staticInst->isSerializeAfter() || status[SerializeAfter]; } + bool isSquashAfter() const { return staticInst->isSquashAfter(); } bool isMemBarrier() const { return staticInst->isMemBarrier(); } bool isWriteBarrier() const { return staticInst->isWriteBarrier(); } bool isNonSpeculative() const { return staticInst->isNonSpeculative(); } diff --git a/src/cpu/o3/commit.hh b/src/cpu/o3/commit.hh index 326f3a1d3..468153dc7 100644 --- a/src/cpu/o3/commit.hh +++ b/src/cpu/o3/commit.hh @@ -245,6 +245,13 @@ class DefaultCommit /** Handles squashing due to an TC write. */ void squashFromTC(ThreadID tid); + /** Handles squashing from instruction with SquashAfter set. + * This differs from the other squashes as it squashes following + * instructions instead of the current instruction and doesn't + * clean up various status bits about traps/tc writes pending. + */ + void squashAfter(ThreadID tid, uint64_t squash_after_seq_num); + #if FULL_SYSTEM /** Handles processing an interrupt. */ void handleInterrupt(); diff --git a/src/cpu/o3/commit_impl.hh b/src/cpu/o3/commit_impl.hh index 1a44c64ee..2895de293 100644 --- a/src/cpu/o3/commit_impl.hh +++ b/src/cpu/o3/commit_impl.hh @@ -561,6 +561,33 @@ DefaultCommit<Impl>::squashFromTC(ThreadID tid) template <class Impl> void +DefaultCommit<Impl>::squashAfter(ThreadID tid, uint64_t squash_after_seq_num) +{ + youngestSeqNum[tid] = squash_after_seq_num; + + rob->squash(squash_after_seq_num, tid); + changedROBNumEntries[tid] = true; + + // Send back the sequence number of the squashed instruction. + toIEW->commitInfo[tid].doneSeqNum = squash_after_seq_num; + + // Send back the squash signal to tell stages that they should squash. + toIEW->commitInfo[tid].squash = true; + + // Send back the rob squashing signal so other stages know that + // the ROB is in the process of squashing. + toIEW->commitInfo[tid].robSquashing = true; + + toIEW->commitInfo[tid].branchMispredict = false; + + toIEW->commitInfo[tid].pc = pc[tid]; + DPRINTF(Commit, "Executing squash after for [tid:%i] inst [sn:%lli]\n", + tid, squash_after_seq_num); + commitStatus[tid] = ROBSquashing; +} + +template <class Impl> +void DefaultCommit<Impl>::tick() { wroteToTimeBuffer = false; @@ -917,6 +944,11 @@ DefaultCommit<Impl>::commitInsts() TheISA::advancePC(pc[tid], head_inst->staticInst); + // If this is an instruction that doesn't play nicely with + // others squash everything and restart fetch + if (head_inst->isSquashAfter()) + squashAfter(tid, head_inst->seqNum); + int count = 0; Addr oldpc; // Debug statement. Checks to make sure we're not diff --git a/src/cpu/static_inst.hh b/src/cpu/static_inst.hh index e08cbcdb6..15ac444ae 100644 --- a/src/cpu/static_inst.hh +++ b/src/cpu/static_inst.hh @@ -158,7 +158,7 @@ class StaticInstBase : public RefCounted //This flag doesn't do anything yet IsMicroBranch, ///< This microop branches within the microcode for a macroop IsDspOp, - + IsSquashAfter, ///< Squash all uncommitted state after executed NumFlags }; @@ -248,6 +248,7 @@ class StaticInstBase : public RefCounted flags[IsSerializeAfter]; } bool isSerializeBefore() const { return flags[IsSerializeBefore]; } bool isSerializeAfter() const { return flags[IsSerializeAfter]; } + bool isSquashAfter() const { return flags[IsSquashAfter]; } bool isMemBarrier() const { return flags[IsMemBarrier]; } bool isWriteBarrier() const { return flags[IsWriteBarrier]; } bool isNonSpeculative() const { return flags[IsNonSpeculative]; } |