diff options
Diffstat (limited to 'src/cpu/simple')
-rw-r--r-- | src/cpu/simple/atomic.cc | 13 | ||||
-rw-r--r-- | src/cpu/simple/base.cc | 82 | ||||
-rw-r--r-- | src/cpu/simple/base.hh | 23 | ||||
-rw-r--r-- | src/cpu/simple/timing.cc | 9 |
4 files changed, 52 insertions, 75 deletions
diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc index d97e7aeec..de26ca2f8 100644 --- a/src/cpu/simple/atomic.cc +++ b/src/cpu/simple/atomic.cc @@ -321,7 +321,7 @@ AtomicSimpleCPU::readBytes(Addr addr, uint8_t * data, dcache_latency = 0; while (1) { - req->setVirt(0, addr, size, flags, thread->readPC()); + req->setVirt(0, addr, size, flags, thread->pcState().instAddr()); // translate to physical address Fault fault = thread->dtb->translateAtomic(req, tc, BaseTLB::Read); @@ -475,7 +475,7 @@ AtomicSimpleCPU::writeBytes(uint8_t *data, unsigned size, dcache_latency = 0; while(1) { - req->setVirt(0, addr, size, flags, thread->readPC()); + req->setVirt(0, addr, size, flags, thread->pcState().instAddr()); // translate to physical address Fault fault = thread->dtb->translateAtomic(req, tc, BaseTLB::Write); @@ -643,8 +643,11 @@ AtomicSimpleCPU::tick() Fault fault = NoFault; - bool fromRom = isRomMicroPC(thread->readMicroPC()); - if (!fromRom && !curMacroStaticInst) { + TheISA::PCState pcState = thread->pcState(); + + bool needToFetch = !isRomMicroPC(pcState.microPC()) && + !curMacroStaticInst; + if (needToFetch) { setupFetchRequest(&ifetch_req); fault = thread->itb->translateAtomic(&ifetch_req, tc, BaseTLB::Execute); @@ -655,7 +658,7 @@ AtomicSimpleCPU::tick() bool icache_access = false; dcache_access = false; // assume no dcache access - if (!fromRom && !curMacroStaticInst) { + if (needToFetch) { // This is commented out because the predecoder would act like // a tiny cache otherwise. It wouldn't be flushed when needed // like the I cache. It should be flushed, and when that works diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc index 088d5ff16..196b72cc0 100644 --- a/src/cpu/simple/base.cc +++ b/src/cpu/simple/base.cc @@ -368,19 +368,13 @@ BaseSimpleCPU::checkForInterrupts() void BaseSimpleCPU::setupFetchRequest(Request *req) { - Addr threadPC = thread->readPC(); + Addr instAddr = thread->instAddr(); // set up memory request for instruction fetch -#if ISA_HAS_DELAY_SLOT - DPRINTF(Fetch,"Fetch: PC:%08p NPC:%08p NNPC:%08p\n",threadPC, - thread->readNextPC(),thread->readNextNPC()); -#else - DPRINTF(Fetch,"Fetch: PC:%08p NPC:%08p\n",threadPC, - thread->readNextPC()); -#endif + DPRINTF(Fetch, "Fetch: PC:%08p\n", instAddr); - Addr fetchPC = (threadPC & PCMask) + fetchOffset; - req->setVirt(0, fetchPC, sizeof(MachInst), Request::INST_FETCH, threadPC); + Addr fetchPC = (instAddr & PCMask) + fetchOffset; + req->setVirt(0, fetchPC, sizeof(MachInst), Request::INST_FETCH, instAddr); } @@ -399,11 +393,12 @@ BaseSimpleCPU::preExecute() // decode the instruction inst = gtoh(inst); - MicroPC upc = thread->readMicroPC(); + TheISA::PCState pcState = thread->pcState(); - if (isRomMicroPC(upc)) { + if (isRomMicroPC(pcState.microPC())) { stayAtPC = false; - curStaticInst = microcodeRom.fetchMicroop(upc, curMacroStaticInst); + curStaticInst = microcodeRom.fetchMicroop(pcState.microPC(), + curMacroStaticInst); } else if (!curMacroStaticInst) { //We're not in the middle of a macro instruction StaticInstPtr instPtr = NULL; @@ -412,21 +407,19 @@ BaseSimpleCPU::preExecute() //This should go away once the constructor can be set up properly predecoder.setTC(thread->getTC()); //If more fetch data is needed, pass it in. - Addr fetchPC = (thread->readPC() & PCMask) + fetchOffset; + Addr fetchPC = (pcState.instAddr() & PCMask) + fetchOffset; //if(predecoder.needMoreBytes()) - predecoder.moreBytes(thread->readPC(), fetchPC, inst); + predecoder.moreBytes(pcState, fetchPC, inst); //else // predecoder.process(); //If an instruction is ready, decode it. Otherwise, we'll have to //fetch beyond the MachInst at the current pc. if (predecoder.extMachInstReady()) { -#if THE_ISA == X86_ISA || THE_ISA == ARM_ISA - thread->setNextPC(thread->readPC() + predecoder.getInstSize()); -#endif // X86_ISA stayAtPC = false; - instPtr = StaticInst::decode(predecoder.getExtMachInst(), - thread->readPC()); + ExtMachInst machInst = predecoder.getExtMachInst(pcState); + thread->pcState(pcState); + instPtr = StaticInst::decode(machInst, pcState.instAddr()); } else { stayAtPC = true; fetchOffset += sizeof(MachInst); @@ -436,13 +429,13 @@ BaseSimpleCPU::preExecute() //out micro ops if (instPtr && instPtr->isMacroop()) { curMacroStaticInst = instPtr; - curStaticInst = curMacroStaticInst->fetchMicroop(upc); + curStaticInst = curMacroStaticInst->fetchMicroop(pcState.microPC()); } else { curStaticInst = instPtr; } } else { //Read the next micro op from the macro op - curStaticInst = curMacroStaticInst->fetchMicroop(upc); + curStaticInst = curMacroStaticInst->fetchMicroop(pcState.microPC()); } //If we decoded an instruction this "tick", record information about it. @@ -450,8 +443,7 @@ BaseSimpleCPU::preExecute() { #if TRACING_ON traceData = tracer->getInstRecord(curTick, tc, - curStaticInst, thread->readPC(), - curMacroStaticInst, thread->readMicroPC()); + curStaticInst, thread->pcState(), curMacroStaticInst); DPRINTF(Decode,"Decode: Decoded %s instruction: 0x%x\n", curStaticInst->getName(), curStaticInst->machInst); @@ -462,10 +454,14 @@ BaseSimpleCPU::preExecute() void BaseSimpleCPU::postExecute() { + assert(curStaticInst); + + TheISA::PCState pc = tc->pcState(); + Addr instAddr = pc.instAddr(); #if FULL_SYSTEM - if (thread->profile && curStaticInst) { + if (thread->profile) { bool usermode = TheISA::inUserMode(tc); - thread->profilePC = usermode ? 1 : thread->readPC(); + thread->profilePC = usermode ? 1 : instAddr; ProfileNode *node = thread->profile->consume(tc, curStaticInst); if (node) thread->profileNode = node; @@ -482,10 +478,10 @@ BaseSimpleCPU::postExecute() } if (CPA::available()) { - CPA::cpa()->swAutoBegin(tc, thread->readNextPC()); + CPA::cpa()->swAutoBegin(tc, pc.nextInstAddr()); } - traceFunctions(thread->readPC()); + traceFunctions(instAddr); if (traceData) { traceData->dump(); @@ -505,30 +501,12 @@ BaseSimpleCPU::advancePC(Fault fault) fault->invoke(tc, curStaticInst); predecoder.reset(); } else { - //If we're at the last micro op for this instruction - if (curStaticInst && curStaticInst->isLastMicroop()) { - //We should be working with a macro op or be in the ROM - assert(curMacroStaticInst || - isRomMicroPC(thread->readMicroPC())); - //Close out this macro op, and clean up the - //microcode state - curMacroStaticInst = StaticInst::nullStaticInstPtr; - thread->setMicroPC(normalMicroPC(0)); - thread->setNextMicroPC(normalMicroPC(1)); - } - //If we're still in a macro op - if (curMacroStaticInst || isRomMicroPC(thread->readMicroPC())) { - //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()); - thread->setNextPC(thread->readNextNPC()); - thread->setNextNPC(thread->readNextNPC() + sizeof(MachInst)); - assert(thread->readNextPC() != thread->readNextNPC()); + if (curStaticInst) { + if (curStaticInst->isLastMicroop()) + curMacroStaticInst = StaticInst::nullStaticInstPtr; + TheISA::PCState pcState = thread->pcState(); + TheISA::advancePC(pcState, curStaticInst); + thread->pcState(pcState); } } } diff --git a/src/cpu/simple/base.hh b/src/cpu/simple/base.hh index 0aa0a295c..a713533fc 100644 --- a/src/cpu/simple/base.hh +++ b/src/cpu/simple/base.hh @@ -88,11 +88,12 @@ class BaseSimpleCPU : public BaseCPU Trace::InstRecord *traceData; inline void checkPcEventQueue() { - Addr oldpc; + Addr oldpc, pc = thread->instAddr(); do { - oldpc = thread->readPC(); + oldpc = pc; system->pcEventQueue.service(tc); - } while (oldpc != thread->readPC()); + pc = thread->instAddr(); + } while (oldpc != pc); } public: @@ -282,18 +283,7 @@ class BaseSimpleCPU : public BaseCPU thread->setFloatRegBits(reg_idx, val); } - uint64_t readPC() { return thread->readPC(); } - uint64_t readMicroPC() { return thread->readMicroPC(); } - uint64_t readNextPC() { return thread->readNextPC(); } - uint64_t readNextMicroPC() { return thread->readNextMicroPC(); } - uint64_t readNextNPC() { return thread->readNextNPC(); } bool readPredicate() { return thread->readPredicate(); } - - void setPC(uint64_t val) { thread->setPC(val); } - void setMicroPC(uint64_t val) { thread->setMicroPC(val); } - void setNextPC(uint64_t val) { thread->setNextPC(val); } - void setNextMicroPC(uint64_t val) { thread->setNextMicroPC(val); } - void setNextNPC(uint64_t val) { thread->setNextNPC(val); } void setPredicate(bool val) { thread->setPredicate(val); @@ -301,6 +291,11 @@ class BaseSimpleCPU : public BaseCPU traceData->setPredicate(val); } } + TheISA::PCState pcState() { return thread->pcState(); } + void pcState(const TheISA::PCState &val) { thread->pcState(val); } + Addr instAddr() { return thread->instAddr(); } + Addr nextInstAddr() { return thread->nextInstAddr(); } + MicroPC microPC() { return thread->microPC(); } MiscReg readMiscRegNoEffect(int misc_reg) { diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc index 2eb5b432b..863c28be2 100644 --- a/src/cpu/simple/timing.cc +++ b/src/cpu/simple/timing.cc @@ -422,7 +422,7 @@ TimingSimpleCPU::readBytes(Addr addr, uint8_t *data, Fault fault; const int asid = 0; const ThreadID tid = 0; - const Addr pc = thread->readPC(); + const Addr pc = thread->instAddr(); unsigned block_size = dcachePort.peerBlockSize(); BaseTLB::Mode mode = BaseTLB::Read; @@ -545,7 +545,7 @@ TimingSimpleCPU::writeTheseBytes(uint8_t *data, unsigned size, { const int asid = 0; const ThreadID tid = 0; - const Addr pc = thread->readPC(); + const Addr pc = thread->instAddr(); unsigned block_size = dcachePort.peerBlockSize(); BaseTLB::Mode mode = BaseTLB::Write; @@ -701,9 +701,10 @@ TimingSimpleCPU::fetch() checkPcEventQueue(); - bool fromRom = isRomMicroPC(thread->readMicroPC()); + TheISA::PCState pcState = thread->pcState(); + bool needToFetch = !isRomMicroPC(pcState.microPC()) && !curMacroStaticInst; - if (!fromRom && !curMacroStaticInst) { + if (needToFetch) { Request *ifetch_req = new Request(); ifetch_req->setThreadContext(_cpuId, /* thread ID */ 0); setupFetchRequest(ifetch_req); |