summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/arch/sparc/isa/decoder.isa3
-rw-r--r--src/cpu/base_dyn_inst.hh1
-rw-r--r--src/cpu/o3/commit.hh7
-rw-r--r--src/cpu/o3/commit_impl.hh32
-rw-r--r--src/cpu/static_inst.hh3
5 files changed, 44 insertions, 2 deletions
diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa
index e0a34a1b1..b62b8400d 100644
--- a/src/arch/sparc/isa/decoder.isa
+++ b/src/arch/sparc/isa/decoder.isa
@@ -490,7 +490,8 @@ decode OP default Unknown::unknown()
0x00: NoPriv::wry({{Y = (Rs1 ^ Rs2_or_imm13)<31:0>;}});
// 0x01 should cause an illegal instruction exception
0x02: NoPriv::wrccr({{Ccr = Rs1 ^ Rs2_or_imm13;}});
- 0x03: NoPriv::wrasi({{Asi = Rs1 ^ Rs2_or_imm13;}});
+ 0x03: NoPriv::wrasi({{Asi = Rs1 ^ Rs2_or_imm13;}}, false,
+ IsSquashAfter);
// 0x04-0x05 should cause an illegal instruction exception
0x06: NoPriv::wrfprs({{Fprs = Rs1 ^ Rs2_or_imm13;}});
// 0x07-0x0E should cause an illegal instruction exception
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]; }