/*
+ * 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.
*
bool branchTaken;
Addr mispredPC;
TheISA::PCState nextPC;
-
unsigned branchCount;
};
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;
bool uncached;
DynInstPtr uncachedLoad;
- bool interruptPending;
- bool clearInterrupt;
};
commitComm commitInfo[Impl::MaxThreads];
* 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. */
// 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];
}
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;
// 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;
// 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",
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,
// 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;
}
}
// 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;
// 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,
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();
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;
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;