summaryrefslogtreecommitdiff
path: root/src/cpu/o3
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu/o3')
-rw-r--r--src/cpu/o3/commit.hh7
-rw-r--r--src/cpu/o3/commit_impl.hh32
2 files changed, 39 insertions, 0 deletions
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