summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cpu/o3/comm.hh57
-rw-r--r--src/cpu/o3/commit.hh3
-rw-r--r--src/cpu/o3/commit_impl.hh28
-rw-r--r--src/cpu/o3/fetch_impl.hh7
-rw-r--r--src/cpu/o3/iew_impl.hh6
5 files changed, 64 insertions, 37 deletions
diff --git a/src/cpu/o3/comm.hh b/src/cpu/o3/comm.hh
index 897807fdb..840dde9ea 100644
--- a/src/cpu/o3/comm.hh
+++ b/src/cpu/o3/comm.hh
@@ -1,4 +1,16 @@
/*
+ * Copyright (c) 2011 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
* Copyright (c) 2004-2006 The Regents of The University of Michigan
* All rights reserved.
*
@@ -123,7 +135,6 @@ struct TimeBufStruct {
bool branchTaken;
Addr mispredPC;
TheISA::PCState nextPC;
-
unsigned branchCount;
};
@@ -151,29 +162,45 @@ struct TimeBufStruct {
iewComm iewInfo[Impl::MaxThreads];
struct commitComm {
- bool usedROB;
- unsigned freeROBEntries;
- bool emptyROB;
+ /////////////// For Decode, IEW, Rename, Fetch ///////////
bool squash;
bool robSquashing;
- bool branchMispredict;
- DynInstPtr mispredictInst;
- bool branchTaken;
- Addr mispredPC;
- TheISA::PCState pc;
-
+ ////////// For Fetch & IEW /////////////
// Represents the instruction that has either been retired or
// squashed. Similar to having a single bus that broadcasts the
// retired or squashed sequence number.
InstSeqNum doneSeqNum;
- //Just in case we want to do a commit/squash on a cycle
- //(necessary for multiple ROBs?)
- bool commitInsts;
- InstSeqNum squashSeqNum;
+ ////////////// For Rename /////////////////
+ // Rename should re-read number of free rob entries
+ bool usedROB;
+ // Notify Rename that the ROB is empty
+ bool emptyROB;
+ // Tell Rename how many free entries it has in the ROB
+ unsigned freeROBEntries;
+
+
+ ///////////// For Fetch //////////////////
+ // Provide fetch the instruction that mispredicted, if this
+ // pointer is not-null a misprediction occured
+ DynInstPtr mispredictInst;
+ // Was the branch taken or not
+ bool branchTaken;
+ // The pc of the next instruction to execute. This is the next
+ // instruction for a branch mispredict, but the same instruction for
+ // order violation and the like
+ TheISA::PCState pc;
+
+ // Instruction that caused the a non-mispredict squash
+ DynInstPtr squashInst;
+ // If an interrupt is pending and fetch should stall
+ bool interruptPending;
+ // If the interrupt ended up being cleared before being handled
+ bool clearInterrupt;
+ //////////// For IEW //////////////////
// Communication specifically to the IQ to tell the IQ that it can
// schedule a non-speculative instruction.
InstSeqNum nonSpecSeqNum;
@@ -182,8 +209,6 @@ struct TimeBufStruct {
bool uncached;
DynInstPtr uncachedLoad;
- bool interruptPending;
- bool clearInterrupt;
};
commitComm commitInfo[Impl::MaxThreads];
diff --git a/src/cpu/o3/commit.hh b/src/cpu/o3/commit.hh
index 047e29f5d..ff7b53440 100644
--- a/src/cpu/o3/commit.hh
+++ b/src/cpu/o3/commit.hh
@@ -262,7 +262,8 @@ class DefaultCommit
* 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);
+ void squashAfter(ThreadID tid, DynInstPtr &head_inst,
+ uint64_t squash_after_seq_num);
#if FULL_SYSTEM
/** Handles processing an interrupt. */
diff --git a/src/cpu/o3/commit_impl.hh b/src/cpu/o3/commit_impl.hh
index 104e7fb58..8c651e203 100644
--- a/src/cpu/o3/commit_impl.hh
+++ b/src/cpu/o3/commit_impl.hh
@@ -541,8 +541,8 @@ DefaultCommit<Impl>::squashAll(ThreadID tid)
// the ROB is in the process of squashing.
toIEW->commitInfo[tid].robSquashing = true;
- toIEW->commitInfo[tid].branchMispredict = false;
toIEW->commitInfo[tid].mispredictInst = NULL;
+ toIEW->commitInfo[tid].squashInst = NULL;
toIEW->commitInfo[tid].pc = pc[tid];
}
@@ -584,7 +584,8 @@ DefaultCommit<Impl>::squashFromTC(ThreadID tid)
template <class Impl>
void
-DefaultCommit<Impl>::squashAfter(ThreadID tid, uint64_t squash_after_seq_num)
+DefaultCommit<Impl>::squashAfter(ThreadID tid, DynInstPtr &head_inst,
+ uint64_t squash_after_seq_num)
{
youngestSeqNum[tid] = squash_after_seq_num;
@@ -594,6 +595,7 @@ DefaultCommit<Impl>::squashAfter(ThreadID tid, uint64_t squash_after_seq_num)
// Send back the sequence number of the squashed instruction.
toIEW->commitInfo[tid].doneSeqNum = squash_after_seq_num;
+ toIEW->commitInfo[tid].squashInst = head_inst;
// Send back the squash signal to tell stages that they should squash.
toIEW->commitInfo[tid].squash = true;
@@ -601,7 +603,7 @@ DefaultCommit<Impl>::squashAfter(ThreadID tid, uint64_t squash_after_seq_num)
// the ROB is in the process of squashing.
toIEW->commitInfo[tid].robSquashing = true;
- toIEW->commitInfo[tid].branchMispredict = false;
+ toIEW->commitInfo[tid].mispredictInst = NULL;
toIEW->commitInfo[tid].pc = pc[tid];
DPRINTF(Commit, "Executing squash after for [tid:%i] inst [sn:%lli]\n",
@@ -801,10 +803,17 @@ DefaultCommit<Impl>::commit()
commitStatus[tid] != TrapPending &&
fromIEW->squashedSeqNum[tid] <= youngestSeqNum[tid]) {
- DPRINTF(Commit, "[tid:%i]: Squashing due to PC %#x [sn:%i]\n",
+ if (fromIEW->mispredictInst[tid]) {
+ DPRINTF(Commit,
+ "[tid:%i]: Squashing due to branch mispred PC:%#x [sn:%i]\n",
tid,
- fromIEW->mispredPC[tid],
+ fromIEW->mispredictInst[tid]->instAddr(),
fromIEW->squashedSeqNum[tid]);
+ } else {
+ DPRINTF(Commit,
+ "[tid:%i]: Squashing due to order violation [sn:%i]\n",
+ tid, fromIEW->squashedSeqNum[tid]);
+ }
DPRINTF(Commit, "[tid:%i]: Redirecting to PC %#x\n",
tid,
@@ -835,18 +844,15 @@ DefaultCommit<Impl>::commit()
// the ROB is in the process of squashing.
toIEW->commitInfo[tid].robSquashing = true;
- toIEW->commitInfo[tid].branchMispredict =
- fromIEW->branchMispredict[tid];
toIEW->commitInfo[tid].mispredictInst =
fromIEW->mispredictInst[tid];
toIEW->commitInfo[tid].branchTaken =
fromIEW->branchTaken[tid];
+ toIEW->commitInfo[tid].squashInst = NULL;
toIEW->commitInfo[tid].pc = fromIEW->pc[tid];
- toIEW->commitInfo[tid].mispredPC = fromIEW->mispredPC[tid];
-
- if (toIEW->commitInfo[tid].branchMispredict) {
+ if (toIEW->commitInfo[tid].mispredictInst) {
++branchMispredicts;
}
}
@@ -988,7 +994,7 @@ DefaultCommit<Impl>::commitInsts()
// 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);
+ squashAfter(tid, head_inst, head_inst->seqNum);
int count = 0;
Addr oldpc;
diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh
index 3092bd937..5f9be039f 100644
--- a/src/cpu/o3/fetch_impl.hh
+++ b/src/cpu/o3/fetch_impl.hh
@@ -934,15 +934,12 @@ DefaultFetch<Impl>::checkSignalsAndUpdate(ThreadID tid)
// In any case, squash.
squash(fromCommit->commitInfo[tid].pc,
fromCommit->commitInfo[tid].doneSeqNum,
- tid);
+ fromCommit->commitInfo[tid].squashInst, tid);
// If it was a branch mispredict on a control instruction, update the
// branch predictor with that instruction, otherwise just kill the
// invalid state we generated in after sequence number
- assert(!fromCommit->commitInfo[tid].branchMispredict ||
- fromCommit->commitInfo[tid].mispredictInst);
-
- if (fromCommit->commitInfo[tid].branchMispredict &&
+ if (fromCommit->commitInfo[tid].mispredictInst &&
fromCommit->commitInfo[tid].mispredictInst->isControl()) {
branchPred.squash(fromCommit->commitInfo[tid].doneSeqNum,
fromCommit->commitInfo[tid].pc,
diff --git a/src/cpu/o3/iew_impl.hh b/src/cpu/o3/iew_impl.hh
index dff287ff5..8bf3c56f4 100644
--- a/src/cpu/o3/iew_impl.hh
+++ b/src/cpu/o3/iew_impl.hh
@@ -456,8 +456,6 @@ DefaultIEW<Impl>::squashDueToBranch(DynInstPtr &inst, ThreadID tid)
inst->seqNum < toCommit->squashedSeqNum[tid]) {
toCommit->squash[tid] = true;
toCommit->squashedSeqNum[tid] = inst->seqNum;
- toCommit->mispredPC[tid] = inst->instAddr();
- toCommit->branchMispredict[tid] = true;
toCommit->branchTaken[tid] = inst->pcState().branching();
TheISA::PCState pc = inst->pcState();
@@ -486,7 +484,7 @@ DefaultIEW<Impl>::squashDueToMemOrder(DynInstPtr &inst, ThreadID tid)
TheISA::PCState pc = inst->pcState();
TheISA::advancePC(pc, inst->staticInst);
toCommit->pc[tid] = pc;
- toCommit->branchMispredict[tid] = false;
+ toCommit->mispredictInst[tid] = NULL;
toCommit->includeSquashInst[tid] = false;
@@ -506,7 +504,7 @@ DefaultIEW<Impl>::squashDueToMemBlocked(DynInstPtr &inst, ThreadID tid)
toCommit->squashedSeqNum[tid] = inst->seqNum;
toCommit->pc[tid] = inst->pcState();
- toCommit->branchMispredict[tid] = false;
+ toCommit->mispredictInst[tid] = NULL;
// Must include the broadcasted SN in the squash.
toCommit->includeSquashInst[tid] = true;