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
{ 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(); }
/** 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();
tcSquash[tid] = false;
}
+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()
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
//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
};
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]; }