changeset cd9dd7f8125f in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=cd9dd7f8125f
description:
        inorder: implement trap handling

diffstat:

 src/cpu/inorder/cpu.cc                       |   23 +++-
 src/cpu/inorder/cpu.hh                       |   35 +++++--
 src/cpu/inorder/inorder_dyn_inst.cc          |   17 ++-
 src/cpu/inorder/inorder_dyn_inst.hh          |    4 +-
 src/cpu/inorder/pipeline_stage.cc            |   41 ++------
 src/cpu/inorder/pipeline_stage.hh            |   14 +--
 src/cpu/inorder/resource.cc                  |    4 +-
 src/cpu/inorder/resource.hh                  |    3 +
 src/cpu/inorder/resource_pool.9stage.cc      |    6 +-
 src/cpu/inorder/resource_pool.cc             |   20 +++-
 src/cpu/inorder/resource_pool.hh             |    3 +
 src/cpu/inorder/resources/agen_unit.cc       |    4 +-
 src/cpu/inorder/resources/cache_unit.cc      |   10 +-
 src/cpu/inorder/resources/execution_unit.cc  |    8 +-
 src/cpu/inorder/resources/fetch_seq_unit.cc  |  115 +++++++++++++++-----------
 src/cpu/inorder/resources/fetch_seq_unit.hh  |   11 +-
 src/cpu/inorder/resources/fetch_unit.cc      |    7 +
 src/cpu/inorder/resources/fetch_unit.hh      |    2 +
 src/cpu/inorder/resources/graduation_unit.cc |    9 +-
 19 files changed, 201 insertions(+), 135 deletions(-)

diffs (truncated from 732 to 300 lines):

diff -r 40d1b3f5bee6 -r cd9dd7f8125f src/cpu/inorder/cpu.cc
--- a/src/cpu/inorder/cpu.cc    Sun Jun 19 21:43:35 2011 -0400
+++ b/src/cpu/inorder/cpu.cc    Sun Jun 19 21:43:36 2011 -0400
@@ -142,7 +142,8 @@
 
       case Trap:
         DPRINTF(InOrderCPU, "Trapping CPU\n");
-        cpu->trapCPU(fault, tid, inst);
+        cpu->trap(fault, tid, inst);
+        cpu->resPool->trap(fault, tid, inst);
         break;
 
       default:
@@ -451,8 +452,8 @@
             if (inst->splitInst)
                 M.needs(DCache, CacheUnit::InitSecondSplitRead);
         } else if ( inst->isStore() ) {
-            if ( inst->numSrcRegs() >= 2 ) {
-                M.needs(RegManager, UseDefUnit::ReadSrcReg, 1);
+            for (int i = 1; i < inst->numSrcRegs(); i++ ) {
+                M.needs(RegManager, UseDefUnit::ReadSrcReg, i);
             }
             M.needs(AGEN, AGENUnit::GenerateAddr);
             M.needs(DCache, CacheUnit::InitiateWriteData);
@@ -795,14 +796,13 @@
 #endif
 
 void
-InOrderCPU::trap(Fault fault, ThreadID tid, DynInstPtr inst, int delay)
+InOrderCPU::trapContext(Fault fault, ThreadID tid, DynInstPtr inst, int delay)
 {
-    //@ Squash Pipeline during TRAP
     scheduleCpuEvent(Trap, fault, tid, inst, delay);
 }
 
 void
-InOrderCPU::trapCPU(Fault fault, ThreadID tid, DynInstPtr inst)
+InOrderCPU::trap(Fault fault, ThreadID tid, DynInstPtr inst)
 {
     fault->invoke(tcBase(tid), inst->staticInst);
 }
@@ -1302,11 +1302,18 @@
 void
 InOrderCPU::instDone(DynInstPtr inst, ThreadID tid)
 {
-    // Set the CPU's PCs - This contributes to the precise state of the CPU 
+    // Set the nextPC to be fetched if this is the last instruction
+    // committed
+    // ========
+    // This contributes to the precise state of the CPU
     // which can be used when restoring a thread to the CPU after after any
     // type of context switching activity (fork, exception, etc.)
-    pcState(inst->pcState(), tid);
+    TheISA::PCState comm_pc = inst->pcState();
+    lastCommittedPC[tid] = comm_pc;
+    TheISA::advancePC(comm_pc, inst->staticInst);
+    pcState(comm_pc, tid);
 
+    //@todo: may be unnecessary with new-ISA-specific branch handling code
     if (inst->isControl()) {
         thread[tid]->lastGradIsBranch = true;
         thread[tid]->lastBranchPC = inst->pcState();
diff -r 40d1b3f5bee6 -r cd9dd7f8125f src/cpu/inorder/cpu.hh
--- a/src/cpu/inorder/cpu.hh    Sun Jun 19 21:43:35 2011 -0400
+++ b/src/cpu/inorder/cpu.hh    Sun Jun 19 21:43:36 2011 -0400
@@ -275,6 +275,9 @@
     /** Program Counters */
     TheISA::PCState pc[ThePipeline::MaxThreads];
 
+    /** Last Committed PC */
+    TheISA::PCState lastCommittedPC[ThePipeline::MaxThreads];
+
     /** The Register File for the CPU */
     union {
         FloatReg f[ThePipeline::MaxThreads][TheISA::NumFloatRegs];
@@ -430,33 +433,45 @@
     bool validDataAddr(Addr addr) { return true; }
 #endif
 
-    /** trap() - sets up a trap event on the cpuTraps to handle given fault.
-     *  trapCPU() - Traps to handle given fault
-     */
-    void trap(Fault fault, ThreadID tid, DynInstPtr inst, int delay = 0);
-    void trapCPU(Fault fault, ThreadID tid, DynInstPtr inst);
+    /** Schedule a trap on the CPU */
+    void trapContext(Fault fault, ThreadID tid, DynInstPtr inst, int delay = 
0);
+
+    /** Perform trap to Handle Given Fault */
+    void trap(Fault fault, ThreadID tid, DynInstPtr inst);
+
+    /** Schedule thread activation on the CPU */
+    void activateContext(ThreadID tid, int delay = 0);
 
     /** Add Thread to Active Threads List. */
-    void activateContext(ThreadID tid, int delay = 0);
     void activateThread(ThreadID tid);
+
+    /** Activate Thread In Each Pipeline Stage */
     void activateThreadInPipeline(ThreadID tid);
     
-    /** Add Thread to Active Threads List. */
+    /** Schedule Thread Activation from Ready List */
     void activateNextReadyContext(int delay = 0);
+
+    /** Add Thread From Ready List to Active Threads List. */
     void activateNextReadyThread();
 
+    /** Schedule a thread deactivation on the CPU */
+    void deactivateContext(ThreadID tid, int delay = 0);
+
     /** Remove from Active Thread List */
-    void deactivateContext(ThreadID tid, int delay = 0);
     void deactivateThread(ThreadID tid);
 
+    /** Schedule a thread suspension on the CPU */
+    void suspendContext(ThreadID tid, int delay = 0);
+
     /** Suspend Thread, Remove from Active Threads List, Add to Suspend List */
-    void suspendContext(ThreadID tid, int delay = 0);
     void suspendThread(ThreadID tid);
 
+    /** Schedule a thread halt on the CPU */
+    void haltContext(ThreadID tid, int delay = 0);
+
     /** Halt Thread, Remove from Active Thread List, Place Thread on Halted 
      *  Threads List 
      */
-    void haltContext(ThreadID tid, int delay = 0);
     void haltThread(ThreadID tid);
 
     /** squashFromMemStall() - sets up a squash event
diff -r 40d1b3f5bee6 -r cd9dd7f8125f src/cpu/inorder/inorder_dyn_inst.cc
--- a/src/cpu/inorder/inorder_dyn_inst.cc       Sun Jun 19 21:43:35 2011 -0400
+++ b/src/cpu/inorder/inorder_dyn_inst.cc       Sun Jun 19 21:43:36 2011 -0400
@@ -54,7 +54,7 @@
                                InstSeqNum seq_num,
                                ThreadID tid,
                                unsigned _asid)
-  : seqNum(seq_num), bdelaySeqNum(0), threadNumber(tid), asid(_asid),
+  : seqNum(seq_num), squashSeqNum(0), threadNumber(tid), asid(_asid),
     virtProcNumber(0), staticInst(NULL), traceData(NULL), cpu(cpu),
     thread(state), fault(NoFault), memData(NULL), loadData(0),
     storeData(0), effAddr(0), physEffAddr(0), memReqFlags(0),
@@ -319,7 +319,15 @@
 InOrderDynInst::setSquashInfo(unsigned stage_num)
 {
     squashingStage = stage_num;
-    bdelaySeqNum = seqNum;
+
+    // If it's a fault, then we need to squash
+    // the faulting instruction too. Squash
+    // functions squash above a seqNum, so we
+    // decrement here for that case
+    if (fault != NoFault)
+        squashSeqNum = seqNum - 1;
+    else
+        squashSeqNum = seqNum;
 
 #if ISA_HAS_DELAY_SLOT
     if (isControl()) {
@@ -329,10 +337,9 @@
         // Check to see if we should squash after the
         // branch or after a branch delay slot.
         if (pc.nextInstAddr() == pc.instAddr() + sizeof(MachInst))
-            bdelaySeqNum = seqNum + 1;
+            squashSeqNum = seqNum + 1;
         else
-            bdelaySeqNum = seqNum;
-
+            squashSeqNum = seqNum;
     }
 #endif
 }
diff -r 40d1b3f5bee6 -r cd9dd7f8125f src/cpu/inorder/inorder_dyn_inst.hh
--- a/src/cpu/inorder/inorder_dyn_inst.hh       Sun Jun 19 21:43:35 2011 -0400
+++ b/src/cpu/inorder/inorder_dyn_inst.hh       Sun Jun 19 21:43:36 2011 -0400
@@ -122,8 +122,8 @@
     /** The sequence number of the instruction. */
     InstSeqNum seqNum;
 
-    /** The sequence number of the instruction. */
-    InstSeqNum bdelaySeqNum;
+    /** If this instruction is squashing, the number should we squash behind. 
*/
+    InstSeqNum squashSeqNum;
 
     enum Status {
         RegDepMapEntry,          /// Instruction is entered onto the RegDepMap
diff -r 40d1b3f5bee6 -r cd9dd7f8125f src/cpu/inorder/pipeline_stage.cc
--- a/src/cpu/inorder/pipeline_stage.cc Sun Jun 19 21:43:35 2011 -0400
+++ b/src/cpu/inorder/pipeline_stage.cc Sun Jun 19 21:43:36 2011 -0400
@@ -342,43 +342,27 @@
 }
 
 void
-PipelineStage::squashDueToBranch(DynInstPtr &inst, ThreadID tid)
+PipelineStage::setupSquash(DynInstPtr inst, ThreadID tid)
 {
-    if (cpu->squashSeqNum[tid] < inst->seqNum &&
-        cpu->lastSquashCycle[tid] == curTick()){
+    if (cpu->lastSquashCycle[tid] == curTick() &&
+        cpu->squashSeqNum[tid] < inst->seqNum){
         DPRINTF(Resource, "Ignoring [sn:%i] branch squash signal due to "
                 "another stage's squash signal for after [sn:%i].\n", 
                 inst->seqNum, cpu->squashSeqNum[tid]);
     } else {
-        // Send back mispredict information.
-        toPrevStages->stageInfo[stageNum][tid].branchMispredict = true;
-        toPrevStages->stageInfo[stageNum][tid].predIncorrect = true;
-        toPrevStages->stageInfo[stageNum][tid].doneSeqNum = inst->seqNum;
+        InstSeqNum squash_seq_num = inst->squashSeqNum;
+
         toPrevStages->stageInfo[stageNum][tid].squash = true;
-        toPrevStages->stageInfo[stageNum][tid].nextPC = inst->readPredTarg();
+        toPrevStages->stageInfo[stageNum][tid].doneSeqNum =
+            squash_seq_num;
 
-        toPrevStages->stageInfo[stageNum][tid].branchTaken =
-            inst->pcState().branching();
-
-#if ISA_HAS_DELAY_SLOT
-        toPrevStages->stageInfo[stageNum][tid].bdelayDoneSeqNum =
-            inst->bdelaySeqNum;
-
-        InstSeqNum squash_seq_num = inst->bdelaySeqNum;
-#else
-        toPrevStages->stageInfo[stageNum][tid].bdelayDoneSeqNum = inst->seqNum;
-        InstSeqNum squash_seq_num = inst->seqNum;
-#endif
-
-        DPRINTF(InOrderStage, "Target being re-set to %08p\n", 
-                inst->predInstAddr());
         DPRINTF(InOrderStage, "[tid:%i]: Squashing after [sn:%i], "
-                "due to [sn:%i] branch.\n", tid, squash_seq_num, 
-                inst->seqNum);
+                "due to [sn:%i] %s.\n", tid, squash_seq_num,
+                inst->seqNum, inst->instName());
 
         // Save squash num for later stage use
+        cpu->lastSquashCycle[tid] = curTick();
         cpu->squashSeqNum[tid] = squash_seq_num;
-        cpu->lastSquashCycle[tid] = curTick();
     }
 }
 
@@ -398,7 +382,6 @@
     for (int i=0; i < insts_from_prev_stage; i++) {
         if (prevStage->insts[i]->threadNumber == tid &&
             prevStage->insts[i]->seqNum > squash_seq_num) {
-            // Change Comment to Annulling previous instruction
             DPRINTF(InOrderStage, "[tid:%i]: Squashing instruction, "
                     "[sn:%i] PC %s.\n",
                     tid,
@@ -676,7 +659,7 @@
             DPRINTF(InOrderStage, "[tid:%u]: Squashing instructions due to "
                     "squash from stage %u.\n", tid, stage_idx);
             InstSeqNum squash_seq_num = fromNextStages->
-                stageInfo[stage_idx][tid].bdelayDoneSeqNum;
+                stageInfo[stage_idx][tid].doneSeqNum;
             squash(squash_seq_num, tid);
             break; //return true;
         }
@@ -989,7 +972,7 @@
                     
                     // Remove Thread From Pipeline & Resource Pool
                     inst->squashingStage = stageNum;
-                    inst->bdelaySeqNum = inst->seqNum;
+                    inst->squashSeqNum = inst->seqNum;
                     cpu->squashFromMemStall(inst, tid);  
 
                     // Switch On Cache Miss
diff -r 40d1b3f5bee6 -r cd9dd7f8125f src/cpu/inorder/pipeline_stage.hh
--- a/src/cpu/inorder/pipeline_stage.hh Sun Jun 19 21:43:35 2011 -0400
+++ b/src/cpu/inorder/pipeline_stage.hh Sun Jun 19 21:43:36 2011 -0400
@@ -227,21 +227,17 @@
   public:
     void activateThread(ThreadID tid);
     
-    /** Squashes if there is a PC-relative branch that was predicted
-     * incorrectly. Sends squash information back to fetch.
-     */
-    void squashDueToBranch(DynInstPtr &inst, ThreadID tid);
+    /** Setup Squashing Information to be passed back thru the pipeline */
+    void setupSquash(DynInstPtr inst, ThreadID tid);
 
     virtual void squashDueToMemStall(InstSeqNum seq_num, ThreadID tid);
 
+    /** Perform squash of instructions above seq_num */
+    virtual void squash(InstSeqNum squash_num, ThreadID tid);
+
     /** Squash instructions from stage buffer  */
     void squashPrevStageInsts(InstSeqNum squash_seq_num, ThreadID tid);
 
-    /** Squashes due to commit signalling a squash. Changes status to
-     *  squashing and clears block/unblock signals as needed.
-     */
-    virtual void squash(InstSeqNum squash_num, ThreadID tid);
-
     void dumpInsts();
 
   protected:
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to