inorder: handle serializing instructions
authorKorey Sewell <ksewell@umich.edu>
Mon, 20 Jun 2011 01:43:41 +0000 (21:43 -0400)
committerKorey Sewell <ksewell@umich.edu>
Mon, 20 Jun 2011 01:43:41 +0000 (21:43 -0400)
including IPR accesses and store-conditionals. These class of instructions will not
execute correctly in a superscalar machine

src/cpu/inorder/pipeline_stage.cc
src/cpu/inorder/resource.cc
src/cpu/inorder/resources/cache_unit.cc
src/cpu/inorder/resources/execution_unit.cc
src/cpu/inorder/resources/execution_unit.hh
src/cpu/inorder/resources/use_def.cc
src/cpu/inorder/resources/use_def.hh

index ac180d3c0b4f02b09b98a58211408d7dc3d24b87..4dec386298f4cc95037de2434a9ee7fdb2ea09db 100644 (file)
@@ -1093,6 +1093,7 @@ PipelineStage::sendInstToNextStage(DynInstPtr inst)
 
             // Take note of trace data for this inst & stage
             if (inst->traceData) {
+                //@todo: exec traces are broke. fix them
                 inst->traceData->setStageCycle(stageNum, curTick());
             }
 
index b7f6a8db66e307579c9ca34d19d92cba85123dc7..9eec63062275d9ea87d9f12c933242dba4be912e 100644 (file)
@@ -272,6 +272,7 @@ Resource::rejectRequest(DynInstPtr inst)
 void
 Resource::execute(int slot_idx)
 {
+    //@todo: have each resource print out command their executing
     DPRINTF(Resource, "[tid:%i]: Executing %s resource.\n",
             reqs[slot_idx]->getTid(), name());
     reqs[slot_idx]->setCompleted(true);
index 7c8ad6905164e46aa9450534b31bb25c574e4b1d..7a24348fcb94dcc4ad4837c31868061b1676424c 100644 (file)
@@ -105,8 +105,10 @@ CacheUnit::CachePort::recvTiming(Packet *pkt)
                 pkt->getAddr());
     else if (pkt->isResponse())
         cachePortUnit->processCacheCompletion(pkt);
-    else
-        DPRINTF(Cache, "Received snoop pkt %x,Ignoring\n", pkt->getAddr());
+    else {
+        //@note: depending on consistency model, update here
+        DPRINTF(InOrderCachePort, "Received snoop pkt %x,Ignoring\n", pkt->getAddr());
+    }
 
     return true;
 }
index c1945488c623df428742ae3d507e9eae2358da9a..25575695639fb4a90f6a1f39b35ae3ecf1483864 100644 (file)
@@ -45,7 +45,7 @@ ExecutionUnit::ExecutionUnit(string res_name, int res_id, int res_width,
                              int res_latency, InOrderCPU *_cpu,
                              ThePipeline::Params *params)
     : Resource(res_name, res_id, res_width, res_latency, _cpu),
-      lastExecuteTick(0), lastControlTick(0), serializeTick(0)
+      lastExecuteTick(0), lastControlTick(0)
 { }
 
 void
@@ -103,13 +103,6 @@ ExecutionUnit::execute(int slot_num)
 #if TRACING_ON
     InstSeqNum seq_num = inst->seqNum;
 #endif
-    if (cur_tick == serializeTick) {
-        DPRINTF(InOrderExecute, "Can not execute [tid:%i][sn:%i][PC:%s] %s. "
-                "All instructions are being serialized this cycle\n",
-                inst->readTid(), seq_num, inst->pcState(), inst->instName());
-        exec_req->done(false);
-        return;
-    }
 
     switch (exec_req->cmd)
     {
@@ -131,15 +124,9 @@ ExecutionUnit::execute(int slot_num)
                 lastExecuteTick = cur_tick;
             }
 
+            //@todo: handle address generation here
             assert(!inst->isMemRef());
 
-            if (inst->isSerializeAfter()) {
-                serializeTick = cur_tick;
-                DPRINTF(InOrderExecute, "Serializing execution after [tid:%i] "
-                        "[sn:%i] [PC:%s] %s.\n", inst->readTid(), seq_num,
-                        inst->pcState(), inst->instName());
-            }
-
             if (inst->isControl()) {
                 if (lastControlTick == cur_tick) {
                     DPRINTF(InOrderExecute, "Can not Execute More than One Control "
@@ -219,11 +206,12 @@ ExecutionUnit::execute(int slot_num)
 #if TRACING_ON
                     for (int didx = 0; didx < inst->numDestRegs(); didx++)
                         if (inst->resultType(didx) == InOrderDynInst::Float ||
+                            inst->resultType(didx) == InOrderDynInst::FloatBits ||
                             inst->resultType(didx) == InOrderDynInst::Double)
                             DPRINTF(InOrderExecute, "[tid:%i]: [sn:%i]: Dest result %i "
                                     "of FP execution is %08f (%x).\n", inst->readTid(),
                                     seq_num, didx, inst->readFloatResult(didx),
-                                    inst->readIntResult(didx));
+                                    inst->readFloatBitsResult(didx));
                         else
                             DPRINTF(InOrderExecute, "[tid:%i]: [sn:%i]: Dest result %i "
                                     "of Int execution is 0x%x.\n", inst->readTid(),
index ed645ec3bf75090b8416b49cf3c3b2f474b7b536..bebb69ca34824ed69e86c8668e8dbe18f6dea94b 100644 (file)
@@ -76,7 +76,6 @@ class ExecutionUnit : public Resource {
     Stats::Scalar executions;
     Tick lastExecuteTick;
     Tick lastControlTick;
-    Tick serializeTick;
 };
 
 
index 06591121e8ee1c956006c008a1f60c18aa19b05b..f7376c83c9aaeadbc82412fc31f8ffdc932d4220 100644 (file)
@@ -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 "
index 7e2a7746996ce9c1e335609a344aa3c933607aab..9581bc5f58604fd74c6087d0d96d86f6c2060dd2 100644 (file)
@@ -76,9 +76,11 @@ class UseDefUnit : public Resource {
     RegDepMap *regDepMap[ThePipeline::MaxThreads];
 
     bool *nonSpecInstActive[ThePipeline::MaxThreads];
-
     InstSeqNum *nonSpecSeqNum[ThePipeline::MaxThreads];
 
+    bool serializeOnNextInst[ThePipeline::MaxThreads];
+    InstSeqNum serializeAfterSeqNum[ThePipeline::MaxThreads];
+
     Stats::Average uniqueRegsPerSwitch;
     std::map<RegIndex, bool> uniqueIntRegMap;
     std::map<RegIndex, bool> uniqueFloatRegMap;