summaryrefslogtreecommitdiff
path: root/src/cpu/simple
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu/simple')
-rw-r--r--src/cpu/simple/atomic.cc13
-rw-r--r--src/cpu/simple/base.cc82
-rw-r--r--src/cpu/simple/base.hh23
-rw-r--r--src/cpu/simple/timing.cc9
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);