summaryrefslogtreecommitdiff
path: root/src/cpu/inorder
diff options
context:
space:
mode:
authorKorey Sewell <ksewell@umich.edu>2011-06-19 21:43:34 -0400
committerKorey Sewell <ksewell@umich.edu>2011-06-19 21:43:34 -0400
commit2a59fcfbe9f4d68bfe3dcb263acf68b998e0705c (patch)
treefa977d636015d5b588be07ad818bd50fb3aa2b55 /src/cpu/inorder
parentd4b4ef13249f78714f5507ea6353d64b44ff8b25 (diff)
downloadgem5-2a59fcfbe9f4d68bfe3dcb263acf68b998e0705c.tar.xz
inorder: update support for branch delay slots
Diffstat (limited to 'src/cpu/inorder')
-rw-r--r--src/cpu/inorder/cpu.cc6
-rw-r--r--src/cpu/inorder/inorder_dyn_inst.cc2
-rw-r--r--src/cpu/inorder/inorder_dyn_inst.hh4
-rw-r--r--src/cpu/inorder/resources/branch_predictor.cc2
-rw-r--r--src/cpu/inorder/resources/execution_unit.cc9
-rw-r--r--src/cpu/inorder/resources/fetch_seq_unit.cc72
-rw-r--r--src/cpu/inorder/resources/fetch_seq_unit.hh1
7 files changed, 33 insertions, 63 deletions
diff --git a/src/cpu/inorder/cpu.cc b/src/cpu/inorder/cpu.cc
index ef6d5fb20..01eab9af7 100644
--- a/src/cpu/inorder/cpu.cc
+++ b/src/cpu/inorder/cpu.cc
@@ -1433,9 +1433,7 @@ InOrderCPU::cleanUpRemovedInsts()
ThreadID tid = inst->threadNumber;
// Remove From Register Dependency Map, If Necessary
- archRegDepMap[(*removeList.front())->threadNumber].
- remove((*removeList.front()));
-
+ archRegDepMap[tid].remove(inst);
// Clear if Non-Speculative
if (inst->staticInst &&
@@ -1444,6 +1442,8 @@ InOrderCPU::cleanUpRemovedInsts()
nonSpecInstActive[tid] = false;
}
+ inst->onInstList = false;
+
instList[tid].erase(removeList.front());
removeList.pop();
diff --git a/src/cpu/inorder/inorder_dyn_inst.cc b/src/cpu/inorder/inorder_dyn_inst.cc
index 25f458379..dea1a7dfe 100644
--- a/src/cpu/inorder/inorder_dyn_inst.cc
+++ b/src/cpu/inorder/inorder_dyn_inst.cc
@@ -66,7 +66,7 @@ InOrderDynInst::InOrderDynInst(InOrderCPU *cpu,
inFrontEnd(true), frontSked(NULL), backSked(NULL),
squashingStage(0), predictTaken(false), procDelaySlotOnMispred(false),
fetchMemReq(NULL), dataMemReq(NULL), instEffAddr(0), eaCalcDone(false),
- lqIdx(0), sqIdx(0), instListIt(NULL)
+ lqIdx(0), sqIdx(0), instListIt(NULL), onInstList(false)
{
for(int i = 0; i < MaxInstSrcRegs; i++) {
instSrc[i].integer = 0;
diff --git a/src/cpu/inorder/inorder_dyn_inst.hh b/src/cpu/inorder/inorder_dyn_inst.hh
index 1ef2b2af4..ff60120a3 100644
--- a/src/cpu/inorder/inorder_dyn_inst.hh
+++ b/src/cpu/inorder/inorder_dyn_inst.hh
@@ -988,11 +988,13 @@ class InOrderDynInst : public FastAlloc, public RefCounted
/** Iterator pointing to this BaseDynInst in the list of all insts. */
ListIt instListIt;
+ bool onInstList;
+
/** Returns iterator to this instruction in the list of all insts. */
ListIt getInstListIt() { return instListIt; }
/** Sets iterator for this instruction in the list of all insts. */
- void setInstListIt(ListIt _instListIt) { instListIt = _instListIt; }
+ void setInstListIt(ListIt _instListIt) { onInstList = true; instListIt = _instListIt; }
/** Count of total number of dynamic instructions. */
static int instcount;
diff --git a/src/cpu/inorder/resources/branch_predictor.cc b/src/cpu/inorder/resources/branch_predictor.cc
index 0507bc356..a34991854 100644
--- a/src/cpu/inorder/resources/branch_predictor.cc
+++ b/src/cpu/inorder/resources/branch_predictor.cc
@@ -153,7 +153,7 @@ BranchPredictor::squash(DynInstPtr inst, int squash_stage,
#if ISA_HAS_DELAY_SLOT
// We need to squash the actual branch , NOT the delay slot
// in the branch predictor
- squash_seq_num = squash_seq_num - 1;
+ //squash_seq_num = squash_seq_num - 1;
#endif
if (squash_stage >= ThePipeline::BackEndStartStage) {
diff --git a/src/cpu/inorder/resources/execution_unit.cc b/src/cpu/inorder/resources/execution_unit.cc
index 4fca9e5e1..6c9b6322f 100644
--- a/src/cpu/inorder/resources/execution_unit.cc
+++ b/src/cpu/inorder/resources/execution_unit.cc
@@ -177,11 +177,8 @@ ExecutionUnit::execute(int slot_num)
"predicted as not taken.\n", tid,
seq_num, inst->pcState());
} else {
-#if ISA_HAS_DELAY_SLOT
- inst->bdelaySeqNum = seq_num + 1;
-#else
inst->bdelaySeqNum = seq_num;
-#endif
+
DPRINTF(InOrderExecute, "[tid:%i]: "
"Misprediction detected at "
"[sn:%i] PC %s,\n\t squashing after "
@@ -203,11 +200,7 @@ ExecutionUnit::execute(int slot_num)
inst->seqNum = seq_num;
inst->setPredTarg(pc);
-#if ISA_HAS_DELAY_SLOT
- inst->bdelaySeqNum = seq_num + 1;
-#else
inst->bdelaySeqNum = seq_num;
-#endif
DPRINTF(InOrderExecute, "[tid:%i] Redirecting"
" fetch to %s.\n", tid,
diff --git a/src/cpu/inorder/resources/fetch_seq_unit.cc b/src/cpu/inorder/resources/fetch_seq_unit.cc
index 67f6c5102..579f9d45b 100644
--- a/src/cpu/inorder/resources/fetch_seq_unit.cc
+++ b/src/cpu/inorder/resources/fetch_seq_unit.cc
@@ -143,15 +143,7 @@ FetchSeqUnit::execute(int slot_num)
inst->readPredTarg());
} else if (inst->predTaken()) {
// Taken Control
-#if ISA_HAS_DELAY_SLOT
- DPRINTF(InOrderFetchSeq, "[tid:%i]: [sn:%i] Updating delay"
- " slot target to PC %s\n", tid, inst->seqNum,
- inst->readPredTarg());
- inst->bdelaySeqNum = seq_num + 1;
-#else
inst->bdelaySeqNum = seq_num;
-#endif
-
inst->squashingStage = stage_num;
DPRINTF(InOrderFetchSeq, "[tid:%i] Setting up squash to "
"start from stage %i, after [sn:%i].\n",
@@ -190,59 +182,41 @@ void
FetchSeqUnit::squash(DynInstPtr inst, int squash_stage,
InstSeqNum squash_seq_num, ThreadID tid)
{
- DPRINTF(InOrderFetchSeq, "[tid:%i]: Updating due to squash from stage %i."
- "\n", tid, squash_stage);
+ DPRINTF(InOrderFetchSeq, "[tid:%i]: Updating due to squash from %s (%s) "
+ "stage %i.\n", tid, inst->instName(), inst->pcState(),
+ squash_stage);
+ assert(squash_seq_num == inst->seqNum);
- InstSeqNum done_seq_num = inst->bdelaySeqNum;
+ TheISA::PCState nextPC = inst->pcState();
+ assert(inst->staticInst);
+ advancePC(nextPC, inst->staticInst);
- // Handles the case where we are squashing because of something that is
- // not a branch...like a memory stall
- TheISA::PCState newPC;
+#if ISA_HAS_DELAY_SLOT
if (inst->isControl()) {
- newPC = inst->readPredTarg();
- } else {
- TheISA::PCState thisPC = inst->pcState();
- assert(inst->staticInst);
- advancePC(thisPC, inst->staticInst);
- newPC = thisPC;
+ if (inst->onInstList) {
+ ListIt inst_it = inst->getInstListIt();
+ inst_it++;
+ if (inst_it != cpu->instList[tid].end()) {
+ DynInstPtr delaySlotInst = (*inst_it);
+ if (delaySlotInst->pcState() != nextPC)
+ squash_seq_num = delaySlotInst->seqNum;
+ }
+ }
}
+#endif
- if (squashSeqNum[tid] <= done_seq_num &&
+ if (squashSeqNum[tid] <= squash_seq_num &&
lastSquashCycle[tid] == curTick()) {
DPRINTF(InOrderFetchSeq, "[tid:%i]: Ignoring squash from stage %i, "
"since there is an outstanding squash that is older.\n",
tid, squash_stage);
} else {
- squashSeqNum[tid] = done_seq_num;
+ squashSeqNum[tid] = squash_seq_num;
lastSquashCycle[tid] = curTick();
- if (inst->isControl()) {
- // If the next inst. num is greater than done seq num,
- // then that means we have seen the delay slot
- assert(cpu->nextInstSeqNum(tid) >= done_seq_num);
- if (cpu->nextInstSeqNum(tid) > done_seq_num) {
- // Reset PC
- pc[tid] = newPC;
-
-#if ISA_HAS_DELAY_SLOT
- // The Pred. Target will be (NPC, NNPC, NNPC+4)
- // so since we already saw the NPC (i.e. delay slot)
- // advance one more to get (NNPC, NNPC+4, NNPC+8)
- TheISA::advancePC(pc[tid], inst->staticInst);
-#endif
-
- DPRINTF(InOrderFetchSeq, "[tid:%i]: Setting PC to %s.\n",
- tid, newPC);
- } else {
- // If The very next instruction number that needs to be given
- // out by the CPU is the done seq. num, then we haven't seen
- // the delay slot instruction yet.
- assert(ISA_HAS_DELAY_SLOT);
- pc[tid] = newPC;
- }
- } else {
- pc[tid] = newPC;
- }
+ DPRINTF(InOrderFetchSeq, "[tid:%i]: Setting PC to %s.\n",
+ tid, nextPC);
+ pc[tid] = nextPC;
// Unblock Any Stages Waiting for this information to be updated ...
if (!pcValid[tid]) {
diff --git a/src/cpu/inorder/resources/fetch_seq_unit.hh b/src/cpu/inorder/resources/fetch_seq_unit.hh
index be3c59a13..7c57fa17b 100644
--- a/src/cpu/inorder/resources/fetch_seq_unit.hh
+++ b/src/cpu/inorder/resources/fetch_seq_unit.hh
@@ -45,6 +45,7 @@
class FetchSeqUnit : public Resource {
public:
typedef ThePipeline::DynInstPtr DynInstPtr;
+ typedef std::list<DynInstPtr>::iterator ListIt;
enum Command {
AssignNextPC,