diff options
Diffstat (limited to 'src/cpu/simple')
-rw-r--r-- | src/cpu/simple/atomic.cc | 14 | ||||
-rw-r--r-- | src/cpu/simple/base.cc | 50 | ||||
-rw-r--r-- | src/cpu/simple/base.hh | 1 | ||||
-rw-r--r-- | src/cpu/simple/timing.cc | 3 |
4 files changed, 52 insertions, 16 deletions
diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc index 38a8ba097..edba55b0d 100644 --- a/src/cpu/simple/atomic.cc +++ b/src/cpu/simple/atomic.cc @@ -183,11 +183,14 @@ AtomicSimpleCPU::unserialize(Checkpoint *cp, const string §ion) void AtomicSimpleCPU::resume() { - changeState(SimObject::Running); - if (thread->status() == ThreadContext::Active) { + if (_status != SwitchedOut && _status != Idle) { assert(system->getMemoryMode() == System::Atomic); - if (!tickEvent.scheduled()) - tickEvent.schedule(curTick); + + changeState(SimObject::Running); + if (thread->status() == ThreadContext::Active) { + if (!tickEvent.scheduled()) + tickEvent.schedule(curTick); + } } } @@ -448,7 +451,8 @@ AtomicSimpleCPU::tick() for (int i = 0; i < width; ++i) { numCycles++; - checkForInterrupts(); + if (!curStaticInst || !curStaticInst->isDelayedCommit()) + checkForInterrupts(); Fault fault = setupFetchRequest(ifetch_req); diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc index a79d3c542..cbb3980cb 100644 --- a/src/cpu/simple/base.cc +++ b/src/cpu/simple/base.cc @@ -396,7 +396,20 @@ 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) { + StaticInstPtr instPtr = StaticInst::decode(makeExtMI(inst, thread->getTC())); + if (instPtr->isMacroOp()) { + curMacroStaticInst = instPtr; + curStaticInst = curMacroStaticInst->fetchMicroOp(0); + } else { + curStaticInst = instPtr; + } + } else { + //Read the next micro op from the macro op + curStaticInst = curMacroStaticInst->fetchMicroOp(thread->readMicroPC()); + } + traceData = Trace::getInstRecord(curTick, tc, curStaticInst, thread->readPC()); @@ -446,18 +459,35 @@ BaseSimpleCPU::advancePC(Fault fault) { if (fault != NoFault) { 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 diff --git a/src/cpu/simple/base.hh b/src/cpu/simple/base.hh index 57cfa3c2c..af6b6f835 100644 --- a/src/cpu/simple/base.hh +++ b/src/cpu/simple/base.hh @@ -128,6 +128,7 @@ class BaseSimpleCPU : public BaseCPU TheISA::IntReg dataReg; StaticInstPtr curStaticInst; + StaticInstPtr curMacroStaticInst; void checkForInterrupts(); Fault setupFetchRequest(Request *req); diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc index 97df0e5d5..fe6775ea4 100644 --- a/src/cpu/simple/timing.cc +++ b/src/cpu/simple/timing.cc @@ -427,7 +427,8 @@ TimingSimpleCPU::write(int32_t data, Addr addr, unsigned flags, uint64_t *res) void TimingSimpleCPU::fetch() { - checkForInterrupts(); + if (!curStaticInst || !curStaticInst->isDelayedCommit()) + checkForInterrupts(); Request *ifetch_req = new Request(); ifetch_req->setThreadContext(cpu_id, /* thread ID */ 0); |