Merge zed.eecs.umich.edu:/.automount/zeep/z/saidi/work/m5.newmem
[gem5.git] / src / cpu / simple / base.cc
index 22a210115a2243351dfa4e2b1a7a445d0961483f..ddccc5a9b8670e506a778f98656866231a20f1d5 100644 (file)
@@ -46,8 +46,7 @@
 #include "cpu/smt.hh"
 #include "cpu/static_inst.hh"
 #include "cpu/thread_context.hh"
-#include "kern/kernel_stats.hh"
-#include "mem/packet_impl.hh"
+#include "mem/packet.hh"
 #include "sim/builder.hh"
 #include "sim/byteswap.hh"
 #include "sim/debug.hh"
 #include "sim/system.hh"
 
 #if FULL_SYSTEM
-#include "base/remote_gdb.hh"
-#include "arch/tlb.hh"
+#include "arch/kernel_stats.hh"
 #include "arch/stacktrace.hh"
+#include "arch/tlb.hh"
 #include "arch/vtophys.hh"
+#include "base/remote_gdb.hh"
 #else // !FULL_SYSTEM
 #include "mem/mem_object.hh"
 #endif // FULL_SYSTEM
@@ -70,13 +70,13 @@ using namespace std;
 using namespace TheISA;
 
 BaseSimpleCPU::BaseSimpleCPU(Params *p)
-    : BaseCPU(p), mem(p->mem), thread(NULL)
+    : BaseCPU(p), thread(NULL)
 {
 #if FULL_SYSTEM
     thread = new SimpleThread(this, 0, p->system, p->itb, p->dtb);
 #else
     thread = new SimpleThread(this, /* thread_num */ 0, p->process,
-            /* asid */ 0, mem);
+            /* asid */ 0);
 #endif // !FULL_SYSTEM
 
     thread->setStatus(ThreadContext::Suspended);
@@ -170,7 +170,7 @@ BaseSimpleCPU::regStats()
 void
 BaseSimpleCPU::resetStats()
 {
-    startNumInst = numInst;
+//    startNumInst = numInst;
     // notIdleFraction = (_status != Idle);
 }
 
@@ -311,43 +311,13 @@ void
 BaseSimpleCPU::checkForInterrupts()
 {
 #if FULL_SYSTEM
-    if (checkInterrupts && check_interrupts() && !thread->inPalMode()) {
-        int ipl = 0;
-        int summary = 0;
-        checkInterrupts = false;
-
-        if (thread->readMiscReg(IPR_SIRR)) {
-            for (int i = INTLEVEL_SOFTWARE_MIN;
-                 i < INTLEVEL_SOFTWARE_MAX; i++) {
-                if (thread->readMiscReg(IPR_SIRR) & (ULL(1) << i)) {
-                    // See table 4-19 of 21164 hardware reference
-                    ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1;
-                    summary |= (ULL(1) << i);
-                }
-            }
-        }
+    if (checkInterrupts && check_interrupts(tc)) {
+        Fault interrupt = interrupts.getInterrupt(tc);
 
-        uint64_t interrupts = thread->cpu->intr_status();
-        for (int i = INTLEVEL_EXTERNAL_MIN;
-            i < INTLEVEL_EXTERNAL_MAX; i++) {
-            if (interrupts & (ULL(1) << i)) {
-                // See table 4-19 of 21164 hardware reference
-                ipl = i;
-                summary |= (ULL(1) << i);
-            }
-        }
-
-        if (thread->readMiscReg(IPR_ASTRR))
-            panic("asynchronous traps not implemented\n");
-
-        if (ipl && ipl > thread->readMiscReg(IPR_IPLR)) {
-            thread->setMiscReg(IPR_ISR, summary);
-            thread->setMiscReg(IPR_INTID, ipl);
-
-            Fault(new InterruptFault)->invoke(tc);
-
-            DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n",
-                    thread->readMiscReg(IPR_IPLR), ipl, summary);
+        if (interrupt != NoFault) {
+            interrupts.updateIntrInfo(tc);
+            checkInterrupts = false;
+            interrupt->invoke(tc);
         }
     }
 #endif
@@ -396,9 +366,32 @@ BaseSimpleCPU::preExecute()
 
     // decode the instruction
     inst = gtoh(inst);
-    curStaticInst = StaticInst::decode(makeExtMI(inst, thread->readPC()));
+    //If we're not in the middle of a macro instruction
+    if (!curMacroStaticInst) {
+#if THE_ISA == ALPHA_ISA
+        StaticInstPtr instPtr = StaticInst::decode(makeExtMI(inst, thread->readPC()));
+#elif THE_ISA == SPARC_ISA
+        StaticInstPtr instPtr = StaticInst::decode(makeExtMI(inst, thread->getTC()));
+#elif THE_ISA == MIPS_ISA
+        //Mips doesn't do anything in it's MakeExtMI function right now,
+        //so it won't be called.
+        StaticInstPtr instPtr = StaticInst::decode(inst);
+#endif
+        if (instPtr->isMacroOp()) {
+            curMacroStaticInst = instPtr;
+            curStaticInst = curMacroStaticInst->
+                fetchMicroOp(thread->readMicroPC());
+        } else {
+            curStaticInst = instPtr;
+        }
+    } else {
+        //Read the next micro op from the macro op
+        curStaticInst = curMacroStaticInst->
+            fetchMicroOp(thread->readMicroPC());
+    }
+
 
-    traceData = Trace::getInstRecord(curTick, tc, this, curStaticInst,
+    traceData = Trace::getInstRecord(curTick, tc, curStaticInst,
                                      thread->readPC());
 
     DPRINTF(Decode,"Decode: Decoded %s instruction (opcode: 0x%x): 0x%x\n",
@@ -415,8 +408,7 @@ BaseSimpleCPU::postExecute()
 {
 #if FULL_SYSTEM
     if (thread->profile) {
-        bool usermode =
-            (thread->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0;
+        bool usermode = TheISA::inUserMode(tc);
         thread->profilePC = usermode ? 1 : thread->readPC();
         ProfileNode *node = thread->profile->consume(tc, inst);
         if (node)
@@ -445,19 +437,37 @@ void
 BaseSimpleCPU::advancePC(Fault fault)
 {
     if (fault != NoFault) {
+        curMacroStaticInst = StaticInst::nullStaticInstPtr;
         fault->invoke(tc);
-    }
-    else {
-        // go to the next instruction
-        thread->setPC(thread->readNextPC());
+    } else {
+        //If we're at the last micro op for this instruction
+        if (curStaticInst->isLastMicroOp()) {
+            //We should be working with a macro op
+            assert(curMacroStaticInst);
+            //Close out this macro op, and clean up the
+            //microcode state
+            curMacroStaticInst = StaticInst::nullStaticInstPtr;
+            thread->setMicroPC(0);
+            thread->setNextMicroPC(1);
+        }
+        //If we're still in a macro op
+        if (curMacroStaticInst) {
+            //Advance the micro pc
+            thread->setMicroPC(thread->readNextMicroPC());
+            //Advance the "next" micro pc. Note that there are no delay
+            //slots, and micro ops are "word" addressed.
+            thread->setNextMicroPC(thread->readNextMicroPC() + 1);
+        } else {
+            // go to the next instruction
+            thread->setPC(thread->readNextPC());
 #if ISA_HAS_DELAY_SLOT
-        thread->setNextPC(thread->readNextNPC());
-        thread->setNextNPC(thread->readNextNPC() + sizeof(MachInst));
-        assert(thread->readNextPC() != thread->readNextNPC());
+            thread->setNextPC(thread->readNextNPC());
+            thread->setNextNPC(thread->readNextNPC() + sizeof(MachInst));
+            assert(thread->readNextPC() != thread->readNextNPC());
 #else
-        thread->setNextPC(thread->readNextPC() + sizeof(MachInst));
+            thread->setNextPC(thread->readNextPC() + sizeof(MachInst));
 #endif
-
+        }
     }
 
 #if FULL_SYSTEM