O3PCU: Split loads and stores that cross cache line boundaries.
[gem5.git] / src / cpu / base_dyn_inst_impl.hh
index a344990b4d18eb4e3d24bdcd635607bd12863803..70c91cedaa1e0b6f18a98b5e883752c48ec342db 100644 (file)
 
 #include "base/cprintf.hh"
 #include "base/trace.hh"
-
-#include "arch/faults.hh"
+#include "config/the_isa.hh"
+#include "cpu/base_dyn_inst.hh"
 #include "cpu/exetrace.hh"
 #include "mem/request.hh"
-
-#include "cpu/base_dyn_inst.hh"
-
-using namespace std;
-using namespace TheISA;
+#include "sim/faults.hh"
 
 #define NOHASH
 #ifndef NOHASH
@@ -65,17 +61,67 @@ my_hash_t thishash;
 #endif
 
 template <class Impl>
-BaseDynInst<Impl>::BaseDynInst(ExtMachInst machInst, Addr inst_PC,
-                               Addr pred_PC, InstSeqNum seq_num,
-                               ImplCPU *cpu)
-  : staticInst(machInst), traceData(NULL), cpu(cpu)
+BaseDynInst<Impl>::BaseDynInst(StaticInstPtr _staticInst,
+                               Addr inst_PC, Addr inst_NPC,
+                               Addr inst_MicroPC,
+                               Addr pred_PC, Addr pred_NPC,
+                               Addr pred_MicroPC,
+                               InstSeqNum seq_num, ImplCPU *cpu)
+  : staticInst(_staticInst), traceData(NULL), cpu(cpu)
 {
     seqNum = seq_num;
 
+    bool nextIsMicro =
+        staticInst->isMicroop() && !staticInst->isLastMicroop();
+
     PC = inst_PC;
-    nextPC = PC + sizeof(MachInst);
-    nextNPC = nextPC + sizeof(MachInst);
+    microPC = inst_MicroPC;
+    if (nextIsMicro) {
+        nextPC = inst_PC;
+        nextNPC = inst_NPC;
+        nextMicroPC = microPC + 1;
+    } else {
+        nextPC = inst_NPC;
+        nextNPC = nextPC + sizeof(TheISA::MachInst);
+        nextMicroPC = 0;
+    }
     predPC = pred_PC;
+    predNPC = pred_NPC;
+    predMicroPC = pred_MicroPC;
+    predTaken = false;
+
+    initVars();
+}
+
+template <class Impl>
+BaseDynInst<Impl>::BaseDynInst(TheISA::ExtMachInst inst,
+                               Addr inst_PC, Addr inst_NPC,
+                               Addr inst_MicroPC,
+                               Addr pred_PC, Addr pred_NPC,
+                               Addr pred_MicroPC,
+                               InstSeqNum seq_num, ImplCPU *cpu)
+  : staticInst(inst, inst_PC), traceData(NULL), cpu(cpu)
+{
+    seqNum = seq_num;
+
+    bool nextIsMicro =
+        staticInst->isMicroop() && !staticInst->isLastMicroop();
+
+    PC = inst_PC;
+    microPC = inst_MicroPC;
+    if (nextIsMicro) {
+        nextPC = inst_PC;
+        nextNPC = inst_NPC;
+        nextMicroPC = microPC + 1;
+    } else {
+        nextPC = inst_NPC;
+        nextNPC = nextPC + sizeof(TheISA::MachInst);
+        nextMicroPC = 0;
+    }
+    predPC = pred_PC;
+    predNPC = pred_NPC;
+    predMicroPC = pred_MicroPC;
+    predTaken = false;
 
     initVars();
 }
@@ -92,14 +138,17 @@ template <class Impl>
 void
 BaseDynInst<Impl>::initVars()
 {
-    req = NULL;
     memData = NULL;
     effAddr = 0;
+    effAddrValid = false;
     physEffAddr = 0;
 
+    isUncacheable = false;
+    reqMade = false;
     readyRegs = 0;
 
     instResult.integer = 0;
+    recordResult = true;
 
     status.reset();
 
@@ -118,18 +167,21 @@ BaseDynInst<Impl>::initVars()
     // Initialize the fault to be NoFault.
     fault = NoFault;
 
-    ++instcount;
+#ifndef NDEBUG
+    ++cpu->instcount;
 
-    if (instcount > 1500) {
-        cpu->dumpInsts();
+    if (cpu->instcount > 1500) {
 #ifdef DEBUG
+        cpu->dumpInsts();
         dumpSNList();
 #endif
-        assert(instcount <= 1500);
+        assert(cpu->instcount <= 1500);
     }
 
-    DPRINTF(DynInst, "DynInst: [sn:%lli] Instruction created. Instcount=%i\n",
-            seqNum, instcount);
+    DPRINTF(DynInst,
+        "DynInst: [sn:%lli] Instruction created. Instcount for %s = %i\n",
+        seqNum, cpu->name(), cpu->instcount);
+#endif
 
 #ifdef DEBUG
     cpu->snList.insert(seqNum);
@@ -139,10 +191,6 @@ BaseDynInst<Impl>::initVars()
 template <class Impl>
 BaseDynInst<Impl>::~BaseDynInst()
 {
-    if (req) {
-        delete req;
-    }
-
     if (memData) {
         delete [] memData;
     }
@@ -153,10 +201,13 @@ BaseDynInst<Impl>::~BaseDynInst()
 
     fault = NoFault;
 
-    --instcount;
+#ifndef NDEBUG
+    --cpu->instcount;
 
-    DPRINTF(DynInst, "DynInst: [sn:%lli] Instruction destroyed. Instcount=%i\n",
-            seqNum, instcount);
+    DPRINTF(DynInst,
+        "DynInst: [sn:%lli] Instruction destroyed. Instcount for %s = %i\n",
+        seqNum, cpu->name(), cpu->instcount);
+#endif
 #ifdef DEBUG
     cpu->snList.erase(seqNum);
 #endif
@@ -196,7 +247,7 @@ BaseDynInst<Impl>::prefetch(Addr addr, unsigned flags)
     // note this is a local, not BaseDynInst::fault
     Fault trans_fault = cpu->translateDataReadReq(req);
 
-    if (trans_fault == NoFault && !(req->flags & UNCACHEABLE)) {
+    if (trans_fault == NoFault && !(req->isUncacheable())) {
         // It's a valid address to cacheable space.  Record key MemReq
         // parameters so we can generate another one just like it for
         // the timing access without calling translate() again (which
@@ -250,7 +301,7 @@ void
 BaseDynInst<Impl>::dump()
 {
     cprintf("T%d : %#08d `", threadNumber, PC);
-    cout << staticInst->disassemble(PC);
+    std::cout << staticInst->disassemble(PC);
     cprintf("'\n");
 }
 
@@ -270,7 +321,7 @@ void
 BaseDynInst<Impl>::markSrcRegReady()
 {
     if (++readyRegs == numSrcRegs()) {
-        status.set(CanIssue);
+        setCanIssue();
     }
 }