summaryrefslogtreecommitdiff
path: root/src/cpu/inorder/resources/use_def.cc
diff options
context:
space:
mode:
authorKorey Sewell <ksewell@umich.edu>2011-06-19 21:43:41 -0400
committerKorey Sewell <ksewell@umich.edu>2011-06-19 21:43:41 -0400
commit716e447da8424386f2c3448c17891927aeb49f67 (patch)
tree7cd5ba23161faa0a5337b5a7add3f75569bbfd76 /src/cpu/inorder/resources/use_def.cc
parent83a0fd24f72ed46e71c015c23b723c04d39ca93c (diff)
downloadgem5-716e447da8424386f2c3448c17891927aeb49f67.tar.xz
inorder: handle serializing instructions
including IPR accesses and store-conditionals. These class of instructions will not execute correctly in a superscalar machine
Diffstat (limited to 'src/cpu/inorder/resources/use_def.cc')
-rw-r--r--src/cpu/inorder/resources/use_def.cc33
1 files changed, 26 insertions, 7 deletions
diff --git a/src/cpu/inorder/resources/use_def.cc b/src/cpu/inorder/resources/use_def.cc
index 06591121e..f7376c83c 100644
--- a/src/cpu/inorder/resources/use_def.cc
+++ b/src/cpu/inorder/resources/use_def.cc
@@ -52,7 +52,8 @@ UseDefUnit::UseDefUnit(string res_name, int res_id, int res_width,
for (ThreadID tid = 0; tid < ThePipeline::MaxThreads; tid++) {
nonSpecInstActive[tid] = &cpu->nonSpecInstActive[tid];
nonSpecSeqNum[tid] = &cpu->nonSpecSeqNum[tid];
-
+ serializeOnNextInst[tid] = false;
+ serializeAfterSeqNum[tid] = 0;
regDepMap[tid] = &cpu->archRegDepMap[tid];
}
@@ -152,11 +153,12 @@ UseDefUnit::findRequest(DynInstPtr inst)
void
UseDefUnit::execute(int slot_idx)
{
- // After this is working, change this to a reinterpret cast
- // for performance considerations
UseDefRequest* ud_req = dynamic_cast<UseDefRequest*>(reqs[slot_idx]);
- assert(ud_req);
DynInstPtr inst = ud_req->inst;
+ ThreadID tid = inst->readTid();
+ InstSeqNum seq_num = inst->seqNum;
+ int ud_idx = ud_req->useDefIdx;
+
if (inst->fault != NoFault) {
DPRINTF(InOrderUseDef,
"[tid:%i]: [sn:%i]: Detected %s fault @ %x. Forwarding to "
@@ -166,11 +168,28 @@ UseDefUnit::execute(int slot_idx)
return;
}
- ThreadID tid = inst->readTid();
- InstSeqNum seq_num = inst->seqNum;
- int ud_idx = ud_req->useDefIdx;
+ if (serializeOnNextInst[tid] &&
+ seq_num > serializeAfterSeqNum[tid]) {
+ inst->setSerializeBefore();
+ serializeOnNextInst[tid] = false;
+ }
+
+ if ((inst->isIprAccess() || inst->isSerializeBefore()) &&
+ cpu->instList[tid].front() != inst) {
+ DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i] Serialize before instruction encountered."
+ " Blocking until pipeline is clear.\n", tid, seq_num);
+ ud_req->done(false);
+ return;
+ } else if (inst->isStoreConditional() || inst->isSerializeAfter()) {
+ DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i] Serialize after instruction encountered."
+ " Blocking until pipeline is clear.\n", tid, seq_num);
+ serializeOnNextInst[tid] = true;
+ serializeAfterSeqNum[tid] = seq_num;
+ }
+
// If there is a non-speculative instruction
// in the pipeline then stall instructions here
+ // ---
if (*nonSpecInstActive[tid] == true && seq_num > *nonSpecSeqNum[tid]) {
DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i] cannot execute because"
"there is non-speculative instruction [sn:%i] has not "