diff options
Diffstat (limited to 'src/cpu/inorder')
-rw-r--r-- | src/cpu/inorder/comm.hh | 4 | ||||
-rw-r--r-- | src/cpu/inorder/cpu.cc | 91 | ||||
-rw-r--r-- | src/cpu/inorder/cpu.hh | 30 | ||||
-rw-r--r-- | src/cpu/inorder/first_stage.cc | 4 | ||||
-rw-r--r-- | src/cpu/inorder/inorder_dyn_inst.cc | 25 | ||||
-rw-r--r-- | src/cpu/inorder/inorder_dyn_inst.hh | 87 | ||||
-rw-r--r-- | src/cpu/inorder/inorder_trace.cc | 8 | ||||
-rw-r--r-- | src/cpu/inorder/inorder_trace.hh | 13 | ||||
-rw-r--r-- | src/cpu/inorder/pipeline_stage.cc | 49 | ||||
-rw-r--r-- | src/cpu/inorder/pipeline_stage.hh | 6 | ||||
-rw-r--r-- | src/cpu/inorder/resources/bpred_unit.cc | 94 | ||||
-rw-r--r-- | src/cpu/inorder/resources/bpred_unit.hh | 44 | ||||
-rw-r--r-- | src/cpu/inorder/resources/branch_predictor.cc | 28 | ||||
-rw-r--r-- | src/cpu/inorder/resources/cache_unit.cc | 33 | ||||
-rw-r--r-- | src/cpu/inorder/resources/execution_unit.cc | 59 | ||||
-rw-r--r-- | src/cpu/inorder/resources/fetch_seq_unit.cc | 171 | ||||
-rw-r--r-- | src/cpu/inorder/resources/fetch_seq_unit.hh | 17 | ||||
-rw-r--r-- | src/cpu/inorder/resources/tlb_unit.hh | 12 | ||||
-rw-r--r-- | src/cpu/inorder/thread_context.cc | 24 | ||||
-rw-r--r-- | src/cpu/inorder/thread_context.hh | 22 | ||||
-rw-r--r-- | src/cpu/inorder/thread_state.hh | 4 |
21 files changed, 320 insertions, 505 deletions
diff --git a/src/cpu/inorder/comm.hh b/src/cpu/inorder/comm.hh index f1b3cacac..386046d1c 100644 --- a/src/cpu/inorder/comm.hh +++ b/src/cpu/inorder/comm.hh @@ -75,8 +75,8 @@ struct TimeStruct { // struct as it is used pretty frequently. bool branchMispredict; bool branchTaken; - uint64_t mispredPC; - uint64_t nextPC; + Addr mispredPC; + TheISA::PCState nextPC; unsigned branchCount; diff --git a/src/cpu/inorder/cpu.cc b/src/cpu/inorder/cpu.cc index 5d42ba559..6cd938dc6 100644 --- a/src/cpu/inorder/cpu.cc +++ b/src/cpu/inorder/cpu.cc @@ -988,47 +988,6 @@ InOrderCPU::getPipeStage(int stage_num) } uint64_t -InOrderCPU::readPC(ThreadID tid) -{ - return PC[tid]; -} - - -void -InOrderCPU::setPC(Addr new_PC, ThreadID tid) -{ - PC[tid] = new_PC; -} - - -uint64_t -InOrderCPU::readNextPC(ThreadID tid) -{ - return nextPC[tid]; -} - - -void -InOrderCPU::setNextPC(uint64_t new_NPC, ThreadID tid) -{ - nextPC[tid] = new_NPC; -} - - -uint64_t -InOrderCPU::readNextNPC(ThreadID tid) -{ - return nextNPC[tid]; -} - - -void -InOrderCPU::setNextNPC(uint64_t new_NNPC, ThreadID tid) -{ - nextNPC[tid] = new_NNPC; -} - -uint64_t InOrderCPU::readIntReg(int reg_idx, ThreadID tid) { return intRegs[tid][reg_idx]; @@ -1156,15 +1115,12 @@ InOrderCPU::instDone(DynInstPtr inst, ThreadID tid) // Set the CPU's PCs - This contributes to the precise state of the CPU // which can be used when restoring a thread to the CPU after after any // type of context switching activity (fork, exception, etc.) - setPC(inst->readPC(), tid); - setNextPC(inst->readNextPC(), tid); - setNextNPC(inst->readNextNPC(), tid); + pcState(inst->pcState(), tid); if (inst->isControl()) { thread[tid]->lastGradIsBranch = true; - thread[tid]->lastBranchPC = inst->readPC(); - thread[tid]->lastBranchNextPC = inst->readNextPC(); - thread[tid]->lastBranchNextNPC = inst->readNextNPC(); + thread[tid]->lastBranchPC = inst->pcState(); + TheISA::advancePC(thread[tid]->lastBranchPC, inst->staticInst); } else { thread[tid]->lastGradIsBranch = false; } @@ -1236,15 +1192,15 @@ InOrderCPU::addToRemoveList(DynInstPtr &inst) { removeInstsThisCycle = true; if (!inst->isRemoveList()) { - DPRINTF(InOrderCPU, "Pushing instruction [tid:%i] PC %#x " + DPRINTF(InOrderCPU, "Pushing instruction [tid:%i] PC %s " "[sn:%lli] to remove list\n", - inst->threadNumber, inst->readPC(), inst->seqNum); + inst->threadNumber, inst->pcState(), inst->seqNum); inst->setRemoveList(); removeList.push(inst->getInstListIt()); } else { - DPRINTF(InOrderCPU, "Ignoring instruction removal for [tid:%i] PC %#x " + DPRINTF(InOrderCPU, "Ignoring instruction removal for [tid:%i] PC %s " "[sn:%lli], already remove list\n", - inst->threadNumber, inst->readPC(), inst->seqNum); + inst->threadNumber, inst->pcState(), inst->seqNum); } } @@ -1252,23 +1208,23 @@ InOrderCPU::addToRemoveList(DynInstPtr &inst) void InOrderCPU::removeInst(DynInstPtr &inst) { - DPRINTF(InOrderCPU, "Removing graduated instruction [tid:%i] PC %#x " + DPRINTF(InOrderCPU, "Removing graduated instruction [tid:%i] PC %s " "[sn:%lli]\n", - inst->threadNumber, inst->readPC(), inst->seqNum); + inst->threadNumber, inst->pcState(), inst->seqNum); removeInstsThisCycle = true; // Remove the instruction. if (!inst->isRemoveList()) { - DPRINTF(InOrderCPU, "Pushing instruction [tid:%i] PC %#x " + DPRINTF(InOrderCPU, "Pushing instruction [tid:%i] PC %s " "[sn:%lli] to remove list\n", - inst->threadNumber, inst->readPC(), inst->seqNum); + inst->threadNumber, inst->pcState(), inst->seqNum); inst->setRemoveList(); removeList.push(inst->getInstListIt()); } else { - DPRINTF(InOrderCPU, "Ignoring instruction removal for [tid:%i] PC %#x " + DPRINTF(InOrderCPU, "Ignoring instruction removal for [tid:%i] PC %s " "[sn:%lli], already on remove list\n", - inst->threadNumber, inst->readPC(), inst->seqNum); + inst->threadNumber, inst->pcState(), inst->seqNum); } } @@ -1307,24 +1263,24 @@ InOrderCPU::squashInstIt(const ListIt &instIt, ThreadID tid) { if ((*instIt)->threadNumber == tid) { DPRINTF(InOrderCPU, "Squashing instruction, " - "[tid:%i] [sn:%lli] PC %#x\n", + "[tid:%i] [sn:%lli] PC %s\n", (*instIt)->threadNumber, (*instIt)->seqNum, - (*instIt)->readPC()); + (*instIt)->pcState()); (*instIt)->setSquashed(); if (!(*instIt)->isRemoveList()) { - DPRINTF(InOrderCPU, "Pushing instruction [tid:%i] PC %#x " + DPRINTF(InOrderCPU, "Pushing instruction [tid:%i] PC %s " "[sn:%lli] to remove list\n", - (*instIt)->threadNumber, (*instIt)->readPC(), + (*instIt)->threadNumber, (*instIt)->pcState(), (*instIt)->seqNum); (*instIt)->setRemoveList(); removeList.push(instIt); } else { DPRINTF(InOrderCPU, "Ignoring instruction removal for [tid:%i]" - " PC %#x [sn:%lli], already on remove list\n", - (*instIt)->threadNumber, (*instIt)->readPC(), + " PC %s [sn:%lli], already on remove list\n", + (*instIt)->threadNumber, (*instIt)->pcState(), (*instIt)->seqNum); } @@ -1338,10 +1294,10 @@ InOrderCPU::cleanUpRemovedInsts() { while (!removeList.empty()) { DPRINTF(InOrderCPU, "Removing instruction, " - "[tid:%i] [sn:%lli] PC %#x\n", + "[tid:%i] [sn:%lli] PC %s\n", (*removeList.front())->threadNumber, (*removeList.front())->seqNum, - (*removeList.front())->readPC()); + (*removeList.front())->pcState()); DynInstPtr inst = *removeList.front(); ThreadID tid = inst->threadNumber; @@ -1417,9 +1373,10 @@ InOrderCPU::dumpInsts() cprintf("Dumping Instruction List\n"); while (inst_list_it != instList[0].end()) { - cprintf("Instruction:%i\nPC:%#x\n[tid:%i]\n[sn:%lli]\nIssued:%i\n" + cprintf("Instruction:%i\nPC:%s\n[tid:%i]\n[sn:%lli]\nIssued:%i\n" "Squashed:%i\n\n", - num, (*inst_list_it)->readPC(), (*inst_list_it)->threadNumber, + num, (*inst_list_it)->pcState(), + (*inst_list_it)->threadNumber, (*inst_list_it)->seqNum, (*inst_list_it)->isIssued(), (*inst_list_it)->isSquashed()); inst_list_it++; diff --git a/src/cpu/inorder/cpu.hh b/src/cpu/inorder/cpu.hh index abe24d6ed..df6617d56 100644 --- a/src/cpu/inorder/cpu.hh +++ b/src/cpu/inorder/cpu.hh @@ -273,9 +273,7 @@ class InOrderCPU : public BaseCPU PipelineStage *pipelineStage[ThePipeline::NumStages]; /** Program Counters */ - TheISA::IntReg PC[ThePipeline::MaxThreads]; - TheISA::IntReg nextPC[ThePipeline::MaxThreads]; - TheISA::IntReg nextNPC[ThePipeline::MaxThreads]; + TheISA::PCState pc[ThePipeline::MaxThreads]; /** The Register File for the CPU */ union { @@ -471,22 +469,22 @@ class InOrderCPU : public BaseCPU ThreadID tid); /** Reads the commit PC of a specific thread. */ - uint64_t readPC(ThreadID tid); + TheISA::PCState + pcState(ThreadID tid) + { + return pc[tid]; + } /** Sets the commit PC of a specific thread. */ - void setPC(Addr new_PC, ThreadID tid); - - /** Reads the next PC of a specific thread. */ - uint64_t readNextPC(ThreadID tid); - - /** Sets the next PC of a specific thread. */ - void setNextPC(uint64_t val, ThreadID tid); - - /** Reads the next NPC of a specific thread. */ - uint64_t readNextNPC(ThreadID tid); + void + pcState(const TheISA::PCState &newPC, ThreadID tid) + { + pc[tid] = newPC; + } - /** Sets the next NPC of a specific thread. */ - void setNextNPC(uint64_t val, ThreadID tid); + Addr instAddr(ThreadID tid) { return pc[tid].instAddr(); } + Addr nextInstAddr(ThreadID tid) { return pc[tid].nextInstAddr(); } + MicroPC microPC(ThreadID tid) { return pc[tid].microPC(); } /** Function to add instruction onto the head of the list of the * instructions. Used when new instructions are fetched. diff --git a/src/cpu/inorder/first_stage.cc b/src/cpu/inorder/first_stage.cc index 658ce37d3..ae458c604 100644 --- a/src/cpu/inorder/first_stage.cc +++ b/src/cpu/inorder/first_stage.cc @@ -84,8 +84,8 @@ FirstStage::squash(InstSeqNum squash_seq_num, ThreadID tid) break; } DPRINTF(InOrderStage, "[tid:%i]: Removing instruction, [sn:%i] " - "PC %08p.\n", tid, insts[tid].front()->seqNum, - insts[tid].front()->PC); + "PC %s.\n", tid, insts[tid].front()->seqNum, + insts[tid].front()->pc); insts[tid].pop(); } diff --git a/src/cpu/inorder/inorder_dyn_inst.cc b/src/cpu/inorder/inorder_dyn_inst.cc index 2465744e5..f672082f3 100644 --- a/src/cpu/inorder/inorder_dyn_inst.cc +++ b/src/cpu/inorder/inorder_dyn_inst.cc @@ -47,17 +47,16 @@ using namespace std; using namespace TheISA; using namespace ThePipeline; -InOrderDynInst::InOrderDynInst(TheISA::ExtMachInst machInst, Addr inst_PC, - Addr pred_PC, InstSeqNum seq_num, - InOrderCPU *cpu) - : staticInst(machInst, inst_PC), traceData(NULL), cpu(cpu) +InOrderDynInst::InOrderDynInst(TheISA::ExtMachInst machInst, + const TheISA::PCState &instPC, + const TheISA::PCState &_predPC, + InstSeqNum seq_num, InOrderCPU *cpu) + : staticInst(machInst, instPC.instAddr()), traceData(NULL), cpu(cpu) { seqNum = seq_num; - PC = inst_PC; - nextPC = PC + sizeof(MachInst); - nextNPC = nextPC + sizeof(MachInst); - predPC = pred_PC; + pc = instPC; + predPC = _predPC; initVars(); } @@ -94,7 +93,7 @@ int InOrderDynInst::instcount = 0; void InOrderDynInst::setMachInst(ExtMachInst machInst) { - staticInst = StaticInst::decode(machInst, PC); + staticInst = StaticInst::decode(machInst, pc.instAddr()); for (int i = 0; i < this->staticInst->numDestRegs(); i++) { _destRegIdx[i] = this->staticInst->destRegIdx(i); @@ -747,8 +746,8 @@ InOrderDynInst::write(int32_t data, Addr addr, unsigned flags, uint64_t *res) void InOrderDynInst::dump() { - cprintf("T%d : %#08d `", threadNumber, PC); - cout << staticInst->disassemble(PC); + cprintf("T%d : %#08d `", threadNumber, pc.instAddr()); + cout << staticInst->disassemble(pc.instAddr()); cprintf("'\n"); } @@ -756,8 +755,8 @@ void InOrderDynInst::dump(std::string &outstring) { std::ostringstream s; - s << "T" << threadNumber << " : 0x" << PC << " " - << staticInst->disassemble(PC); + s << "T" << threadNumber << " : " << pc << " " + << staticInst->disassemble(pc.instAddr()); outstring = s.str(); } diff --git a/src/cpu/inorder/inorder_dyn_inst.hh b/src/cpu/inorder/inorder_dyn_inst.hh index 0d42f4696..105e37657 100644 --- a/src/cpu/inorder/inorder_dyn_inst.hh +++ b/src/cpu/inorder/inorder_dyn_inst.hh @@ -41,6 +41,7 @@ #include "arch/isa_traits.hh" #include "arch/mt.hh" #include "arch/types.hh" +#include "arch/utility.hh" #include "base/fast_alloc.hh" #include "base/trace.hh" #include "base/types.hh" @@ -108,12 +109,13 @@ class InOrderDynInst : public FastAlloc, public RefCounted /** BaseDynInst constructor given a binary instruction. * @param inst The binary instruction. * @param PC The PC of the instruction. - * @param pred_PC The predicted next PC. + * @param predPC The predicted next PC. * @param seq_num The sequence number of the instruction. * @param cpu Pointer to the instruction's CPU. */ - InOrderDynInst(ExtMachInst inst, Addr PC, Addr pred_PC, InstSeqNum seq_num, - InOrderCPU *cpu); + InOrderDynInst(ExtMachInst inst, const TheISA::PCState &PC, + const TheISA::PCState &predPC, InstSeqNum seq_num, + InOrderCPU *cpu); /** BaseDynInst constructor given a binary instruction. * @param seq_num The sequence number of the instruction. @@ -269,28 +271,10 @@ class InOrderDynInst : public FastAlloc, public RefCounted InstResult instResult[MaxInstDestRegs]; /** PC of this instruction. */ - Addr PC; - - /** Next non-speculative PC. It is not filled in at fetch, but rather - * once the target of the branch is truly known (either decode or - * execute). - */ - Addr nextPC; - - /** Next next non-speculative PC. It is not filled in at fetch, but rather - * once the target of the branch is truly known (either decode or - * execute). - */ - Addr nextNPC; + TheISA::PCState pc; /** Predicted next PC. */ - Addr predPC; - - /** Predicted next NPC. */ - Addr predNPC; - - /** Predicted next microPC */ - Addr predMicroPC; + TheISA::PCState predPC; /** Address to fetch from */ Addr fetchAddr; @@ -540,33 +524,14 @@ class InOrderDynInst : public FastAlloc, public RefCounted // //////////////////////////////////////////////////////////// /** Read the PC of this instruction. */ - const Addr readPC() const { return PC; } + const TheISA::PCState &pcState() const { return pc; } /** Sets the PC of this instruction. */ - void setPC(Addr pc) { PC = pc; } - - /** Returns the next PC. This could be the speculative next PC if it is - * called prior to the actual branch target being calculated. - */ - Addr readNextPC() { return nextPC; } + void pcState(const TheISA::PCState &_pc) { pc = _pc; } - /** Set the next PC of this instruction (its actual target). */ - void setNextPC(uint64_t val) { nextPC = val; } - - /** Returns the next NPC. This could be the speculative next NPC if it is - * called prior to the actual branch target being calculated. - */ - Addr readNextNPC() - { -#if ISA_HAS_DELAY_SLOT - return nextNPC; -#else - return nextPC + sizeof(TheISA::MachInst); -#endif - } - - /** Set the next PC of this instruction (its actual target). */ - void setNextNPC(uint64_t val) { nextNPC = val; } + const Addr instAddr() { return pc.instAddr(); } + const Addr nextInstAddr() { return pc.nextInstAddr(); } + const MicroPC microPC() { return pc.microPC(); } //////////////////////////////////////////////////////////// // @@ -574,38 +539,36 @@ class InOrderDynInst : public FastAlloc, public RefCounted // //////////////////////////////////////////////////////////// /** Set the predicted target of this current instruction. */ - void setPredTarg(Addr predicted_PC) { predPC = predicted_PC; } + void setPredTarg(const TheISA::PCState &predictedPC) + { predPC = predictedPC; } /** Returns the predicted target of the branch. */ - Addr readPredTarg() { return predPC; } + TheISA::PCState readPredTarg() { return predPC; } /** Returns the predicted PC immediately after the branch. */ - Addr readPredPC() { return predPC; } + Addr predInstAddr() { return predPC.instAddr(); } /** Returns the predicted PC two instructions after the branch */ - Addr readPredNPC() { return predNPC; } + Addr predNextInstAddr() { return predPC.nextInstAddr(); } /** Returns the predicted micro PC after the branch */ - Addr readPredMicroPC() { return predMicroPC; } + Addr readPredMicroPC() { return predPC.microPC(); } /** Returns whether the instruction was predicted taken or not. */ bool predTaken() { return predictTaken; } /** Returns whether the instruction mispredicted. */ - bool mispredicted() + bool + mispredicted() { -#if ISA_HAS_DELAY_SLOT - return predPC != nextNPC; -#else - return predPC != nextPC; -#endif + TheISA::PCState nextPC = pc; + TheISA::advancePC(nextPC, staticInst); + return !(nextPC == predPC); } - /** Returns whether the instruction mispredicted. */ - bool mistargeted() { return predPC != nextNPC; } - /** Returns the branch target address. */ - Addr branchTarget() const { return staticInst->branchTarget(PC); } + TheISA::PCState branchTarget() const + { return staticInst->branchTarget(pc); } /** Checks whether or not this instruction has had its branch target * calculated yet. For now it is not utilized and is hacked to be diff --git a/src/cpu/inorder/inorder_trace.cc b/src/cpu/inorder/inorder_trace.cc index 90c94a4f5..70a947671 100644 --- a/src/cpu/inorder/inorder_trace.cc +++ b/src/cpu/inorder/inorder_trace.cc @@ -70,15 +70,15 @@ InOrderTrace::getInstRecord(unsigned num_stages, bool stage_tracing, if (!Trace::enabled) return NULL; - return new InOrderTraceRecord(num_stages, stage_tracing, tc); + return new InOrderTraceRecord(num_stages, stage_tracing, tc, 0); } InOrderTraceRecord * InOrderTrace::getInstRecord(Tick when, ThreadContext *tc, - const StaticInstPtr staticInst, Addr pc, - const StaticInstPtr macroStaticInst, MicroPC upc) + const StaticInstPtr staticInst, TheISA::PCState _pc, + const StaticInstPtr macroStaticInst) { - return new InOrderTraceRecord(ThePipeline::NumStages, true, tc); + return new InOrderTraceRecord(ThePipeline::NumStages, true, tc, _pc); } /* namespace Trace */ } diff --git a/src/cpu/inorder/inorder_trace.hh b/src/cpu/inorder/inorder_trace.hh index ccc868f15..fd1427500 100644 --- a/src/cpu/inorder/inorder_trace.hh +++ b/src/cpu/inorder/inorder_trace.hh @@ -47,8 +47,8 @@ class InOrderTraceRecord : public ExeTracerRecord { public: InOrderTraceRecord(unsigned num_stages, bool _stage_tracing, - ThreadContext *_thread, bool spec = false) - : ExeTracerRecord(0, _thread, NULL, 0, spec) + ThreadContext *_thread, TheISA::PCState _pc, bool spec = false) + : ExeTracerRecord(0, _thread, NULL, _pc, spec) { stageTrace = _stage_tracing; stageCycle.resize(num_stages); @@ -75,7 +75,8 @@ class InOrderTraceRecord : public ExeTracerRecord { staticInst = _staticInst; } - void setPC(Addr _pc) { PC = _pc; } + + void setPC(TheISA::PCState _pc) { pc = _pc; } }; class InOrderTrace : public InstTracer @@ -87,9 +88,9 @@ class InOrderTrace : public InstTracer InOrderTraceRecord * getInstRecord(unsigned num_stages, bool stage_tracing, ThreadContext *tc); - virtual InOrderTraceRecord *getInstRecord(Tick when, ThreadContext *tc, - const StaticInstPtr staticInst, Addr pc, - const StaticInstPtr macroStaticInst = NULL, MicroPC upc = 0); + InOrderTraceRecord *getInstRecord(Tick when, ThreadContext *tc, + const StaticInstPtr staticInst, TheISA::PCState pc, + const StaticInstPtr macroStaticInst = NULL); }; /* namespace Trace */ } diff --git a/src/cpu/inorder/pipeline_stage.cc b/src/cpu/inorder/pipeline_stage.cc index f0b48d6f6..dc36965b0 100644 --- a/src/cpu/inorder/pipeline_stage.cc +++ b/src/cpu/inorder/pipeline_stage.cc @@ -350,27 +350,21 @@ PipelineStage::squashDueToBranch(DynInstPtr &inst, ThreadID tid) toPrevStages->stageInfo[stageNum][tid].squash = true; toPrevStages->stageInfo[stageNum][tid].nextPC = inst->readPredTarg(); + toPrevStages->stageInfo[stageNum][tid].branchTaken = + inst->pcState().branching(); #if ISA_HAS_DELAY_SLOT - toPrevStages->stageInfo[stageNum][tid].branchTaken = - inst->readNextNPC() != - (inst->readNextPC() + sizeof(TheISA::MachInst)); - - toPrevStages->stageInfo[stageNum][tid].bdelayDoneSeqNum = + toPrevStages->stageInfo[stageNum][tid].bdelayDoneSeqNum = inst->bdelaySeqNum; InstSeqNum squash_seq_num = inst->bdelaySeqNum; #else - toPrevStages->stageInfo[stageNum][tid].branchTaken = - inst->readNextPC() != - (inst->readPC() + sizeof(TheISA::MachInst)); - toPrevStages->stageInfo[stageNum][tid].bdelayDoneSeqNum = inst->seqNum; InstSeqNum squash_seq_num = inst->seqNum; #endif DPRINTF(InOrderStage, "Target being re-set to %08p\n", - inst->readPredTarg()); + inst->predInstAddr()); DPRINTF(InOrderStage, "[tid:%i]: Squashing after [sn:%i], " "due to [sn:%i] branch.\n", tid, squash_seq_num, inst->seqNum); @@ -398,10 +392,10 @@ PipelineStage::squashPrevStageInsts(InstSeqNum squash_seq_num, ThreadID tid) prevStage->insts[i]->seqNum > squash_seq_num) { // Change Comment to Annulling previous instruction DPRINTF(InOrderStage, "[tid:%i]: Squashing instruction, " - "[sn:%i] PC %08p.\n", + "[sn:%i] PC %s.\n", tid, prevStage->insts[i]->seqNum, - prevStage->insts[i]->readPC()); + prevStage->insts[i]->pcState()); prevStage->insts[i]->setSquashed(); prevStage->insts[i] = cpu->dummyBufferInst; @@ -429,8 +423,8 @@ PipelineStage::squash(InstSeqNum squash_seq_num, ThreadID tid) break; } DPRINTF(InOrderStage, "[tid:%i]: Removing instruction, [sn:%i] " - " PC %08p.\n", tid, skidBuffer[tid].front()->seqNum, - skidBuffer[tid].front()->PC); + " PC %s.\n", tid, skidBuffer[tid].front()->seqNum, + skidBuffer[tid].front()->pc); skidBuffer[tid].pop(); } @@ -488,8 +482,8 @@ PipelineStage::skidInsert(ThreadID tid) assert(tid == inst->threadNumber); - DPRINTF(InOrderStage,"[tid:%i]: Inserting [sn:%lli] PC:%#x into stage " - "skidBuffer %i\n", tid, inst->seqNum, inst->readPC(), + DPRINTF(InOrderStage,"[tid:%i]: Inserting [sn:%lli] PC:%s into stage " + "skidBuffer %i\n", tid, inst->seqNum, inst->pcState(), inst->threadNumber); skidBuffer[tid].push(inst); @@ -571,9 +565,9 @@ PipelineStage::activateThread(ThreadID tid) } else { DynInstPtr inst = switchedOutBuffer[tid]; - DPRINTF(InOrderStage,"[tid:%i]: Re-Inserting [sn:%lli] PC:%#x into" + DPRINTF(InOrderStage,"[tid:%i]: Re-Inserting [sn:%lli] PC:%s into" " stage skidBuffer %i\n", tid, inst->seqNum, - inst->readPC(), inst->threadNumber); + inst->pcState(), inst->threadNumber); // Make instruction available for pipeline processing skidBuffer[tid].push(inst); @@ -895,13 +889,12 @@ PipelineStage::processInsts(ThreadID tid) inst = insts_to_stage.front(); DPRINTF(InOrderStage, "[tid:%u]: Processing instruction [sn:%lli] " - "with PC %#x\n", - tid, inst->seqNum, inst->readPC()); + "with PC %s\n", tid, inst->seqNum, inst->pcState()); if (inst->isSquashed()) { - DPRINTF(InOrderStage, "[tid:%u]: Instruction %i with PC %#x is " + DPRINTF(InOrderStage, "[tid:%u]: Instruction %i with PC %s is " "squashed, skipping.\n", - tid, inst->seqNum, inst->readPC()); + tid, inst->seqNum, inst->pcState()); insts_to_stage.pop(); @@ -1001,8 +994,8 @@ PipelineStage::processInstSchedule(DynInstPtr inst,int &reqs_processed) switchedOutValid[tid] = true; // Remove Thread From Pipeline & Resource Pool - inst->squashingStage = stageNum; - inst->bdelaySeqNum = inst->seqNum; + inst->squashingStage = stageNum; + inst->bdelaySeqNum = inst->seqNum; cpu->squashFromMemStall(inst, tid); // Switch On Cache Miss @@ -1038,9 +1031,9 @@ PipelineStage::processInstSchedule(DynInstPtr inst,int &reqs_processed) res_stage_num = inst->nextResStage(); } } else { - DPRINTF(InOrderStage, "[tid:%u]: Instruction [sn:%i] with PC %#x " + DPRINTF(InOrderStage, "[tid:%u]: Instruction [sn:%i] with PC %s " " needed no resources in stage %i.\n", - tid, inst->seqNum, inst->readPC(), stageNum); + tid, inst->seqNum, inst->pcState(), stageNum); } return last_req_completed; @@ -1134,8 +1127,8 @@ PipelineStage::dumpInsts() while (!copy_buff.empty()) { DynInstPtr inst = copy_buff.front(); - cprintf("Inst. PC:%#x\n[tid:%i]\n[sn:%i]\n\n", - inst->readPC(), inst->threadNumber, inst->seqNum); + cprintf("Inst. PC:%s\n[tid:%i]\n[sn:%i]\n\n", + inst->pcState(), inst->threadNumber, inst->seqNum); copy_buff.pop(); } diff --git a/src/cpu/inorder/pipeline_stage.hh b/src/cpu/inorder/pipeline_stage.hh index c971e400e..6df104e6c 100644 --- a/src/cpu/inorder/pipeline_stage.hh +++ b/src/cpu/inorder/pipeline_stage.hh @@ -293,15 +293,15 @@ class PipelineStage /** SeqNum of Squashing Branch Delay Instruction (used for MIPS) */ Addr bdelayDoneSeqNum[ThePipeline::MaxThreads]; - /** Instruction used for squashing branch (used for MIPS) */ - DynInstPtr squashInst[ThePipeline::MaxThreads]; - /** Tells when their is a pending delay slot inst. to send * to rename. If there is, then wait squash after the next * instruction (used for MIPS). */ bool squashAfterDelaySlot[ThePipeline::MaxThreads]; + /** Instruction used for squashing branch (used for MIPS) */ + DynInstPtr squashInst[ThePipeline::MaxThreads]; + /** Maximum size of the inter-stage buffer connecting the previous stage to * this stage (which we call a skid buffer) */ unsigned stageBufferMax; diff --git a/src/cpu/inorder/resources/bpred_unit.cc b/src/cpu/inorder/resources/bpred_unit.cc index b08a393f7..310053409 100644 --- a/src/cpu/inorder/resources/bpred_unit.cc +++ b/src/cpu/inorder/resources/bpred_unit.cc @@ -31,6 +31,7 @@ #include <list> #include <vector> +#include "arch/utility.hh" #include "base/trace.hh" #include "base/traceflags.hh" #include "config/the_isa.hh" @@ -149,7 +150,7 @@ BPredUnit::takeOverFrom() bool -BPredUnit::predict(DynInstPtr &inst, Addr &pred_PC, ThreadID tid) +BPredUnit::predict(DynInstPtr &inst, TheISA::PCState &predPC, ThreadID tid) { // See if branch predictor predicts taken. // If so, get its target addr either from the BTB or the RAS. @@ -160,12 +161,13 @@ BPredUnit::predict(DynInstPtr &inst, Addr &pred_PC, ThreadID tid) int asid = inst->asid; bool pred_taken = false; - Addr target; + TheISA::PCState target; ++lookups; - DPRINTF(InOrderBPred, "[tid:%i] [sn:%i] %s ... PC%#x doing branch " + DPRINTF(InOrderBPred, "[tid:%i] [sn:%i] %s ... PC %s doing branch " "prediction\n", tid, inst->seqNum, - inst->staticInst->disassemble(inst->PC), inst->readPC()); + inst->staticInst->disassemble(inst->instAddr()), + inst->pcState()); void *bp_history = NULL; @@ -185,14 +187,14 @@ BPredUnit::predict(DynInstPtr &inst, Addr &pred_PC, ThreadID tid) } else { ++condPredicted; - pred_taken = BPLookup(pred_PC, bp_history); + pred_taken = BPLookup(predPC.instAddr(), bp_history); DPRINTF(InOrderBPred, "[tid:%i]: Branch predictor predicted %i " - "for PC %#x\n", - tid, pred_taken, inst->readPC()); + "for PC %s\n", + tid, pred_taken, inst->pcState()); } - PredictorHistory predict_record(inst->seqNum, pred_PC, pred_taken, + PredictorHistory predict_record(inst->seqNum, predPC, pred_taken, bp_history, tid); // Now lookup in the BTB or RAS. @@ -202,40 +204,37 @@ BPredUnit::predict(DynInstPtr &inst, Addr &pred_PC, ThreadID tid) // If it's a function return call, then look up the address // in the RAS. - target = RAS[tid].top(); + TheISA::PCState rasTop = RAS[tid].top(); + target = TheISA::buildRetPC(inst->pcState(), rasTop); // Record the top entry of the RAS, and its index. predict_record.usedRAS = true; predict_record.RASIndex = RAS[tid].topIdx(); - predict_record.RASTarget = target; + predict_record.rasTarget = rasTop; assert(predict_record.RASIndex < 16); RAS[tid].pop(); - DPRINTF(InOrderBPred, "[tid:%i]: Instruction %#x is a return, " - "RAS predicted target: %#x, RAS index: %i.\n", - tid, inst->readPC(), target, predict_record.RASIndex); + DPRINTF(InOrderBPred, "[tid:%i]: Instruction %s is a return, " + "RAS predicted target: %s, RAS index: %i.\n", + tid, inst->pcState(), target, + predict_record.RASIndex); } else { ++BTBLookups; if (inst->isCall()) { -#if ISA_HAS_DELAY_SLOT - Addr ras_pc = pred_PC + instSize; // Next Next PC -#else - Addr ras_pc = pred_PC; // Next PC -#endif - - RAS[tid].push(ras_pc); + RAS[tid].push(inst->pcState()); // Record that it was a call so that the top RAS entry can // be popped off if the speculation is incorrect. predict_record.wasCall = true; - DPRINTF(InOrderBPred, "[tid:%i]: Instruction %#x was a call" - ", adding %#x to the RAS index: %i.\n", - tid, inst->readPC(), ras_pc, RAS[tid].topIdx()); + DPRINTF(InOrderBPred, "[tid:%i]: Instruction %s was a call" + ", adding %s to the RAS index: %i.\n", + tid, inst->pcState(), predPC, + RAS[tid].topIdx()); } if (inst->isCall() && @@ -243,18 +242,18 @@ BPredUnit::predict(DynInstPtr &inst, Addr &pred_PC, ThreadID tid) inst->isDirectCtrl()) { target = inst->branchTarget(); - DPRINTF(InOrderBPred, "[tid:%i]: Setting %#x predicted" - " target to %#x.\n", - tid, inst->readPC(), target); - } else if (BTB.valid(pred_PC, asid)) { + DPRINTF(InOrderBPred, "[tid:%i]: Setting %s predicted" + " target to %s.\n", + tid, inst->pcState(), target); + } else if (BTB.valid(predPC.instAddr(), asid)) { ++BTBHits; // If it's not a return, use the BTB to get the target addr. - target = BTB.lookup(pred_PC, asid); + target = BTB.lookup(predPC.instAddr(), asid); - DPRINTF(InOrderBPred, "[tid:%i]: [asid:%i] Instruction %#x " - "predicted target is %#x.\n", - tid, asid, inst->readPC(), target); + DPRINTF(InOrderBPred, "[tid:%i]: [asid:%i] Instruction %s " + "predicted target is %s.\n", + tid, asid, inst->pcState(), target); } else { DPRINTF(InOrderBPred, "[tid:%i]: BTB doesn't have a " "valid entry.\n",tid); @@ -265,14 +264,7 @@ BPredUnit::predict(DynInstPtr &inst, Addr &pred_PC, ThreadID tid) if (pred_taken) { // Set the PC and the instruction's predicted target. - pred_PC = target; - } else { -#if ISA_HAS_DELAY_SLOT - // This value will be inst->PC + 4 (nextPC) - // Delay Slot archs need this to be inst->PC + 8 (nextNPC) - // so we increment one more time here. - pred_PC = pred_PC + instSize; -#endif + predPC = target; } predHist[tid].push_front(predict_record); @@ -296,7 +288,7 @@ BPredUnit::update(const InstSeqNum &done_sn, ThreadID tid) while (!predHist[tid].empty() && predHist[tid].back().seqNum <= done_sn) { // Update the branch predictor with the correct results. - BPUpdate(predHist[tid].back().PC, + BPUpdate(predHist[tid].back().pc.instAddr(), predHist[tid].back().predTaken, predHist[tid].back().bpHistory); @@ -314,13 +306,13 @@ BPredUnit::squash(const InstSeqNum &squashed_sn, ThreadID tid, ThreadID asid) pred_hist.front().seqNum > squashed_sn) { if (pred_hist.front().usedRAS) { DPRINTF(InOrderBPred, "BranchPred: [tid:%i]: Restoring top of RAS " - "to: %i, target: %#x.\n", + "to: %i, target: %s.\n", tid, pred_hist.front().RASIndex, - pred_hist.front().RASTarget); + pred_hist.front().rasTarget); RAS[tid].restore(pred_hist.front().RASIndex, - pred_hist.front().RASTarget); + pred_hist.front().rasTarget); } else if (pred_hist.front().wasCall) { DPRINTF(InOrderBPred, "BranchPred: [tid:%i]: Removing speculative " @@ -340,7 +332,7 @@ BPredUnit::squash(const InstSeqNum &squashed_sn, ThreadID tid, ThreadID asid) void BPredUnit::squash(const InstSeqNum &squashed_sn, - const Addr &corr_target, + const TheISA::PCState &corrTarget, bool actually_taken, ThreadID tid, ThreadID asid) @@ -354,8 +346,8 @@ BPredUnit::squash(const InstSeqNum &squashed_sn, ++condIncorrect; DPRINTF(InOrderBPred, "[tid:%i]: Squashing from sequence number %i, " - "setting target to %#x.\n", - tid, squashed_sn, corr_target); + "setting target to %s.\n", + tid, squashed_sn, corrTarget); squash(squashed_sn, tid); @@ -380,13 +372,13 @@ BPredUnit::squash(const InstSeqNum &squashed_sn, ++RASIncorrect; } - BPUpdate((*hist_it).PC, actually_taken, + BPUpdate((*hist_it).pc.instAddr(), actually_taken, pred_hist.front().bpHistory); - BTB.update((*hist_it).PC, corr_target, asid); + BTB.update((*hist_it).pc.instAddr(), corrTarget, asid); DPRINTF(InOrderBPred, "[tid:%i]: Removing history for [sn:%i] " - "PC %#x.\n", tid, (*hist_it).seqNum, (*hist_it).PC); + "PC %s.\n", tid, (*hist_it).seqNum, (*hist_it).pc); pred_hist.erase(hist_it); @@ -424,7 +416,7 @@ BPredUnit::BPSquash(void *bp_history) bool -BPredUnit::BPLookup(Addr &inst_PC, void * &bp_history) +BPredUnit::BPLookup(Addr inst_PC, void * &bp_history) { if (predictor == Local) { return localBP->lookup(inst_PC, bp_history); @@ -437,7 +429,7 @@ BPredUnit::BPLookup(Addr &inst_PC, void * &bp_history) void -BPredUnit::BPUpdate(Addr &inst_PC, bool taken, void *bp_history) +BPredUnit::BPUpdate(Addr inst_PC, bool taken, void *bp_history) { if (predictor == Local) { localBP->update(inst_PC, taken, bp_history); diff --git a/src/cpu/inorder/resources/bpred_unit.hh b/src/cpu/inorder/resources/bpred_unit.hh index 881bfcc95..3b1c0f4ef 100644 --- a/src/cpu/inorder/resources/bpred_unit.hh +++ b/src/cpu/inorder/resources/bpred_unit.hh @@ -83,11 +83,12 @@ class BPredUnit * Predicts whether or not the instruction is a taken branch, and the * target of the branch if it is taken. * @param inst The branch instruction. - * @param pred_PC The predicted PC is passed back through this parameter. + * @param predPC The predicted PC is passed back through this parameter. * @param tid The thread id. * @return Returns if the branch is taken or not. */ - bool predict(ThePipeline::DynInstPtr &inst, Addr &pred_PC, ThreadID tid); + bool predict(ThePipeline::DynInstPtr &inst, + TheISA::PCState &predPC, ThreadID tid); // @todo: Rename this function. void BPUncond(void * &bp_history); @@ -114,12 +115,13 @@ class BPredUnit * corrects that sn's update with the proper address and taken/not taken. * @param squashed_sn The sequence number to squash any younger updates up * until. - * @param corr_target The correct branch target. + * @param corrTarget The correct branch target. * @param actually_taken The correct branch direction. * @param tid The thread id. */ - void squash(const InstSeqNum &squashed_sn, const Addr &corr_target, - bool actually_taken, ThreadID tid, ThreadID asid = 0); + void squash(const InstSeqNum &squashed_sn, + const TheISA::PCState &corrTarget, bool actually_taken, + ThreadID tid, ThreadID asid = 0); /** * @param bp_history Pointer to the history object. The predictor @@ -134,7 +136,7 @@ class BPredUnit * has the branch predictor state associated with the lookup. * @return Whether the branch is taken or not taken. */ - bool BPLookup(Addr &inst_PC, void * &bp_history); + bool BPLookup(Addr instPC, void * &bp_history); /** * Looks up a given PC in the BTB to see if a matching entry exists. @@ -149,26 +151,26 @@ class BPredUnit * @param inst_PC The PC to look up. * @return The address of the target of the branch. */ - Addr BTBLookup(Addr &inst_PC) - { return BTB.lookup(inst_PC, 0); } + TheISA::PCState BTBLookup(Addr instPC) + { return BTB.lookup(instPC, 0); } /** * Updates the BP with taken/not taken information. - * @param inst_PC The branch's PC that will be updated. + * @param instPC The branch's PC that will be updated. * @param taken Whether the branch was taken or not taken. * @param bp_history Pointer to the branch predictor state that is * associated with the branch lookup that is being updated. * @todo Make this update flexible enough to handle a global predictor. */ - void BPUpdate(Addr &inst_PC, bool taken, void *bp_history); + void BPUpdate(Addr instPC, bool taken, void *bp_history); /** * Updates the BTB with the target of a branch. * @param inst_PC The branch's PC that will be updated. * @param target_PC The branch's target that will be added to the BTB. */ - void BTBUpdate(Addr &inst_PC, Addr &target_PC) - { BTB.update(inst_PC, target_PC,0); } + void BTBUpdate(Addr instPC, const TheISA::PCState &targetPC) + { BTB.update(instPC, targetPC, 0); } void dump(); @@ -181,22 +183,22 @@ class BPredUnit * Makes a predictor history struct that contains any * information needed to update the predictor, BTB, and RAS. */ - PredictorHistory(const InstSeqNum &seq_num, const Addr &inst_PC, - bool pred_taken, void *bp_history, - ThreadID _tid) - : seqNum(seq_num), PC(inst_PC), RASTarget(0), - RASIndex(0), tid(_tid), predTaken(pred_taken), usedRAS(0), - wasCall(0), bpHistory(bp_history) - { } + PredictorHistory(const InstSeqNum &seq_num, + const TheISA::PCState &instPC, bool pred_taken, + void *bp_history, ThreadID _tid) + : seqNum(seq_num), pc(instPC), rasTarget(0), RASIndex(0), + tid(_tid), predTaken(pred_taken), usedRAS(0), wasCall(0), + bpHistory(bp_history) + {} /** The sequence number for the predictor history entry. */ InstSeqNum seqNum; /** The PC associated with the sequence number. */ - Addr PC; + TheISA::PCState pc; /** The RAS target (only valid if a return). */ - Addr RASTarget; + TheISA::PCState rasTarget; /** The RAS index of the instruction (only valid if a call). */ unsigned RASIndex; diff --git a/src/cpu/inorder/resources/branch_predictor.cc b/src/cpu/inorder/resources/branch_predictor.cc index b971d959a..33b67ce4a 100644 --- a/src/cpu/inorder/resources/branch_predictor.cc +++ b/src/cpu/inorder/resources/branch_predictor.cc @@ -84,41 +84,34 @@ BranchPredictor::execute(int slot_num) DPRINTF(InOrderStage, "[tid:%u]: [sn:%i]: squashed, " "skipping prediction \n", tid, inst->seqNum); } else { - Addr pred_PC = inst->readNextPC(); + TheISA::PCState predPC = inst->pcState(); + TheISA::advancePC(predPC, inst->staticInst); if (inst->isControl()) { // If not, the pred_PC be updated to pc+8 // If predicted, the pred_PC will be updated to new target // value - bool predict_taken = branchPred.predict(inst, pred_PC, tid); + bool predict_taken = branchPred.predict(inst, predPC, tid); if (predict_taken) { DPRINTF(InOrderBPred, "[tid:%i]: [sn:%i]: Branch " "predicted true.\n", tid, seq_num); - - inst->setPredTarg(pred_PC); - predictedTaken++; } else { DPRINTF(InOrderBPred, "[tid:%i]: [sn:%i]: Branch " "predicted false.\n", tid, seq_num); - - if (inst->isCondDelaySlot()) - { - inst->setPredTarg(inst->readPC() + (2 * instSize)); - } else { - inst->setPredTarg(pred_PC); - } - predictedNotTaken++; } + inst->setPredTarg(predPC); + inst->setBranchPred(predict_taken); DPRINTF(InOrderBPred, "[tid:%i]: [sn:%i]: Predicted PC is " - "%08p.\n", tid, seq_num, pred_PC); + "%s.\n", tid, seq_num, predPC); } else { + inst->setPredTarg(predPC); //DPRINTF(InOrderBPred, "[tid:%i]: Ignoring [sn:%i] " // "because this isn't " // "a control instruction.\n", tid, seq_num); @@ -166,10 +159,9 @@ BranchPredictor::squash(DynInstPtr inst, int squash_stage, squash_seq_num = squash_seq_num - 1; #endif - if(squash_stage>=ThePipeline::BackEndStartStage) { - Addr corr_targ=inst->readPredPC(); - bool taken=inst->predTaken(); - branchPred.squash(squash_seq_num,corr_targ,taken,tid); + if (squash_stage >= ThePipeline::BackEndStartStage) { + bool taken = inst->predTaken(); + branchPred.squash(squash_seq_num, inst->readPredTarg(), taken, tid); } else { branchPred.squash(squash_seq_num, tid); } diff --git a/src/cpu/inorder/resources/cache_unit.cc b/src/cpu/inorder/resources/cache_unit.cc index 73deacb12..e7f689ffa 100644 --- a/src/cpu/inorder/resources/cache_unit.cc +++ b/src/cpu/inorder/resources/cache_unit.cc @@ -392,15 +392,16 @@ CacheUnit::doTLBAccess(DynInstPtr inst, CacheReqPtr cache_req, int acc_size, unsigned slot_idx = cache_req->getSlot(); if (tlb_mode == TheISA::TLB::Execute) { - inst->fetchMemReq = new Request(inst->readTid(), aligned_addr, - acc_size, flags, inst->readPC(), - cpu->readCpuId(), inst->readTid()); - cache_req->memReq = inst->fetchMemReq; + inst->fetchMemReq = + new Request(inst->readTid(), aligned_addr, acc_size, flags, + inst->instAddr(), cpu->readCpuId(), inst->readTid()); + cache_req->memReq = inst->fetchMemReq; } else { if (!cache_req->is2ndSplit()) { - inst->dataMemReq = new Request(cpu->asid[tid], aligned_addr, - acc_size, flags, inst->readPC(), - cpu->readCpuId(), inst->readTid()); + inst->dataMemReq = + new Request(cpu->asid[tid], aligned_addr, acc_size, flags, + inst->instAddr(), cpu->readCpuId(), + inst->readTid()); cache_req->memReq = inst->dataMemReq; } else { assert(inst->splitInst); @@ -409,7 +410,7 @@ CacheUnit::doTLBAccess(DynInstPtr inst, CacheReqPtr cache_req, int acc_size, inst->split2ndAddr, acc_size, flags, - inst->readPC(), + inst->instAddr(), cpu->readCpuId(), tid); cache_req->memReq = inst->splitMemReq; @@ -754,7 +755,8 @@ CacheUnit::execute(int slot_num) DPRINTF(InOrderCachePort, "[tid:%i]: Instruction [sn:%i] is: %s\n", - tid, seq_num, inst->staticInst->disassemble(inst->PC)); + tid, seq_num, + inst->staticInst->disassemble(inst->instAddr())); removeAddrDependency(inst); @@ -771,7 +773,7 @@ CacheUnit::execute(int slot_num) tid, inst->seqNum); DPRINTF(InOrderStall, "STALL: [tid:%i]: Fetch miss from %08p\n", - tid, cache_req->inst->readPC()); + tid, cache_req->inst->instAddr()); cache_req->setCompleted(false); //cache_req->setMemStall(true); } @@ -1046,21 +1048,22 @@ CacheUnit::processCacheCompletion(PacketPtr pkt) // @todo: update thsi ExtMachInst ext_inst; StaticInstPtr staticInst = NULL; - Addr inst_pc = inst->readPC(); + TheISA::PCState instPC = inst->pcState(); MachInst mach_inst = TheISA::gtoh(*reinterpret_cast<TheISA::MachInst *> (cache_pkt->getPtr<uint8_t>())); predecoder.setTC(cpu->thread[tid]->getTC()); - predecoder.moreBytes(inst_pc, inst_pc, mach_inst); - ext_inst = predecoder.getExtMachInst(); + predecoder.moreBytes(instPC, inst->instAddr(), mach_inst); + ext_inst = predecoder.getExtMachInst(instPC); + inst->pcState(instPC); inst->setMachInst(ext_inst); // Set Up More TraceData info if (inst->traceData) { inst->traceData->setStaticInst(inst->staticInst); - inst->traceData->setPC(inst->readPC()); + inst->traceData->setPC(instPC); } } else if (inst->staticInst && inst->isMemRef()) { @@ -1149,7 +1152,7 @@ CacheUnit::processCacheCompletion(PacketPtr pkt) } else { DPRINTF(InOrderCachePort, "[tid:%u] Miss on block @ %08p completed, but squashed\n", - tid, cache_req->inst->readPC()); + tid, cache_req->inst->instAddr()); cache_req->setMemAccCompleted(); } } diff --git a/src/cpu/inorder/resources/execution_unit.cc b/src/cpu/inorder/resources/execution_unit.cc index 91e788fbc..4342042e9 100644 --- a/src/cpu/inorder/resources/execution_unit.cc +++ b/src/cpu/inorder/resources/execution_unit.cc @@ -91,8 +91,8 @@ ExecutionUnit::execute(int slot_num) exec_req->fault = NoFault; - DPRINTF(InOrderExecute, "[tid:%i] Executing [sn:%i] [PC:%#x] %s.\n", - tid, seq_num, inst->readPC(), inst->instName()); + DPRINTF(InOrderExecute, "[tid:%i] Executing [sn:%i] [PC:%s] %s.\n", + tid, seq_num, inst->pcState(), inst->instName()); switch (exec_req->cmd) { @@ -124,58 +124,61 @@ ExecutionUnit::execute(int slot_num) if (inst->isDirectCtrl()) { assert(!inst->isIndirectCtrl()); + TheISA::PCState pc = inst->pcState(); + TheISA::advancePC(pc, inst->staticInst); + inst->setPredTarg(pc); + if (inst->predTaken() && inst->isCondDelaySlot()) { inst->bdelaySeqNum = seq_num; - inst->setPredTarg(inst->nextPC); DPRINTF(InOrderExecute, "[tid:%i]: Conditional" - " branch inst [sn:%i] PC %#x mis" + " branch inst [sn:%i] PC %s mis" "predicted as taken.\n", tid, - seq_num, inst->PC); + seq_num, inst->pcState()); } else if (!inst->predTaken() && inst->isCondDelaySlot()) { inst->bdelaySeqNum = seq_num; - inst->setPredTarg(inst->nextPC); inst->procDelaySlotOnMispred = true; DPRINTF(InOrderExecute, "[tid:%i]: Conditional" - " branch inst [sn:%i] PC %#x mis" + " branch inst [sn:%i] PC %s mis" "predicted as not taken.\n", tid, - seq_num, inst->PC); + seq_num, inst->pcState()); } else { #if ISA_HAS_DELAY_SLOT inst->bdelaySeqNum = seq_num + 1; - inst->setPredTarg(inst->nextNPC); #else inst->bdelaySeqNum = seq_num; - inst->setPredTarg(inst->nextPC); #endif DPRINTF(InOrderExecute, "[tid:%i]: " "Misprediction detected at " - "[sn:%i] PC %#x,\n\t squashing after " + "[sn:%i] PC %s,\n\t squashing after " "delay slot instruction [sn:%i].\n", - tid, seq_num, inst->PC, + tid, seq_num, inst->pcState(), inst->bdelaySeqNum); DPRINTF(InOrderStall, "STALL: [tid:%i]: Branch" - " misprediction at %#x\n", - tid, inst->PC); + " misprediction at %s\n", + tid, inst->pcState()); } DPRINTF(InOrderExecute, "[tid:%i] Redirecting " - "fetch to %#x.\n", tid, + "fetch to %s.\n", tid, inst->readPredTarg()); - } else if(inst->isIndirectCtrl()){ + } else if (inst->isIndirectCtrl()){ + TheISA::PCState pc = inst->pcState(); + TheISA::advancePC(pc, inst->staticInst); + inst->seqNum = seq_num; + inst->setPredTarg(pc); + #if ISA_HAS_DELAY_SLOT - inst->setPredTarg(inst->nextNPC); inst->bdelaySeqNum = seq_num + 1; #else - inst->setPredTarg(inst->nextPC); inst->bdelaySeqNum = seq_num; #endif DPRINTF(InOrderExecute, "[tid:%i] Redirecting" - " fetch to %#x.\n", tid, + " fetch to %s.\n", tid, inst->readPredTarg()); } else { panic("Non-control instruction (%s) mispredict" @@ -197,14 +200,20 @@ ExecutionUnit::execute(int slot_num) if (inst->predTaken()) { predictedTakenIncorrect++; - DPRINTF(InOrderExecute, "[tid:%i] [sn:%i] %s ... PC%#x ... Mispredicts! (Taken)\n", - tid, inst->seqNum, inst->staticInst->disassemble(inst->PC), - inst->readPC()); + DPRINTF(InOrderExecute, "[tid:%i] [sn:%i] %s ..." + "PC %s ... Mispredicts! (Taken)\n", + tid, inst->seqNum, + inst->staticInst->disassemble( + inst->instAddr()), + inst->pcState()); } else { predictedNotTakenIncorrect++; - DPRINTF(InOrderExecute, "[tid:%i] [sn:%i] %s ... PC%#x ... Mispredicts! (Not Taken)\n", - tid, inst->seqNum, inst->staticInst->disassemble(inst->PC), - inst->readPC()); + DPRINTF(InOrderExecute, "[tid:%i] [sn:%i] %s ..." + "PC %s ... Mispredicts! (Not Taken)\n", + tid, inst->seqNum, + inst->staticInst->disassemble( + inst->instAddr()), + inst->pcState()); } predictedIncorrect++; } else { diff --git a/src/cpu/inorder/resources/fetch_seq_unit.cc b/src/cpu/inorder/resources/fetch_seq_unit.cc index 8a1ec3ce5..3bfe912e7 100644 --- a/src/cpu/inorder/resources/fetch_seq_unit.cc +++ b/src/cpu/inorder/resources/fetch_seq_unit.cc @@ -44,9 +44,6 @@ FetchSeqUnit::FetchSeqUnit(std::string res_name, int res_id, int res_width, instSize(sizeof(MachInst)) { for (ThreadID tid = 0; tid < ThePipeline::MaxThreads; tid++) { - delaySlotInfo[tid].numInsts = 0; - delaySlotInfo[tid].targetReady = false; - pcValid[tid] = false; pcBlockStage[tid] = 0; @@ -86,53 +83,17 @@ FetchSeqUnit::execute(int slot_num) case AssignNextPC: { if (pcValid[tid]) { + inst->pcState(pc[tid]); + inst->setMemAddr(pc[tid].instAddr()); - if (delaySlotInfo[tid].targetReady && - delaySlotInfo[tid].numInsts == 0) { - // Set PC to target - PC[tid] = delaySlotInfo[tid].targetAddr; //next_PC - nextPC[tid] = PC[tid] + instSize; //next_NPC - nextNPC[tid] = PC[tid] + (2 * instSize); - - delaySlotInfo[tid].targetReady = false; - - DPRINTF(InOrderFetchSeq, "[tid:%i]: Setting PC to delay " - "slot target\n",tid); - } + pc[tid].advance(); //XXX HACK! + inst->setPredTarg(pc[tid]); - inst->setPC(PC[tid]); - inst->setNextPC(PC[tid] + instSize); - inst->setNextNPC(PC[tid] + (instSize * 2)); - -#if ISA_HAS_DELAY_SLOT - inst->setPredTarg(inst->readNextNPC()); -#else - inst->setPredTarg(inst->readNextPC()); -#endif - inst->setMemAddr(PC[tid]); inst->setSeqNum(cpu->getAndIncrementInstSeq(tid)); DPRINTF(InOrderFetchSeq, "[tid:%i]: Assigning [sn:%i] to " - "PC %08p, NPC %08p, NNPC %08p\n", tid, - inst->seqNum, inst->readPC(), inst->readNextPC(), - inst->readNextNPC()); - - if (delaySlotInfo[tid].numInsts > 0) { - --delaySlotInfo[tid].numInsts; - - // It's OK to set PC to target of branch - if (delaySlotInfo[tid].numInsts == 0) { - delaySlotInfo[tid].targetReady = true; - } - - DPRINTF(InOrderFetchSeq, "[tid:%i]: %i delay slot inst(s) " - "left to process.\n", tid, - delaySlotInfo[tid].numInsts); - } - - PC[tid] = nextPC[tid]; - nextPC[tid] = nextNPC[tid]; - nextNPC[tid] += instSize; + "PC %s\n", tid, inst->seqNum, + inst->pcState()); fs_req->done(); } else { @@ -147,18 +108,21 @@ FetchSeqUnit::execute(int slot_num) if (inst->isControl()) { // If it's a return, then we must wait for resolved address. if (inst->isReturn() && !inst->predTaken()) { - cpu->pipelineStage[stage_num]->toPrevStages->stageBlock[stage_num][tid] = true; + cpu->pipelineStage[stage_num]-> + toPrevStages->stageBlock[stage_num][tid] = true; pcValid[tid] = false; pcBlockStage[tid] = stage_num; } else if (inst->isCondDelaySlot() && !inst->predTaken()) { // Not-Taken AND Conditional Control - DPRINTF(InOrderFetchSeq, "[tid:%i]: [sn:%i]: [PC:%08p] " - "Predicted Not-Taken Cond. " - "Delay inst. Skipping delay slot and Updating PC to %08p\n", - tid, inst->seqNum, inst->readPC(), inst->readPredTarg()); + DPRINTF(InOrderFetchSeq, "[tid:%i]: [sn:%i]: [PC:%s] " + "Predicted Not-Taken Cond. Delay inst. Skipping " + "delay slot and Updating PC to %s\n", + tid, inst->seqNum, inst->pcState(), + inst->readPredTarg()); - DPRINTF(InOrderFetchSeq, "[tid:%i] Setting up squash to start from stage %i, after [sn:%i].\n", - tid, stage_num, seq_num); + DPRINTF(InOrderFetchSeq, "[tid:%i] Setting up squash to " + "start from stage %i, after [sn:%i].\n", tid, + stage_num, seq_num); inst->bdelaySeqNum = seq_num; inst->squashingStage = stage_num; @@ -168,33 +132,26 @@ FetchSeqUnit::execute(int slot_num) // Not-Taken Control DPRINTF(InOrderFetchSeq, "[tid:%i]: [sn:%i]: Predicted " "Not-Taken Control " - "inst. updating PC to %08p\n", tid, inst->seqNum, - inst->readNextPC()); + "inst. updating PC to %s\n", tid, inst->seqNum, + inst->readPredTarg()); #if ISA_HAS_DELAY_SLOT - ++delaySlotInfo[tid].numInsts; - delaySlotInfo[tid].targetReady = false; - delaySlotInfo[tid].targetAddr = inst->readNextNPC(); -#else - assert(delaySlotInfo[tid].numInsts == 0); + pc[tid] = inst->pcState(); + advancePC(pc[tid], inst->staticInst); #endif } else if (inst->predTaken()) { // Taken Control #if ISA_HAS_DELAY_SLOT - ++delaySlotInfo[tid].numInsts; - delaySlotInfo[tid].targetReady = false; - delaySlotInfo[tid].targetAddr = inst->readPredTarg(); + pc[tid] = inst->readPredTarg(); DPRINTF(InOrderFetchSeq, "[tid:%i]: [sn:%i] Updating delay" - " slot target to PC %08p\n", tid, inst->seqNum, + " slot target to PC %s\n", tid, inst->seqNum, inst->readPredTarg()); inst->bdelaySeqNum = seq_num + 1; #else inst->bdelaySeqNum = seq_num; - assert(delaySlotInfo[tid].numInsts == 0); #endif inst->squashingStage = stage_num; - DPRINTF(InOrderFetchSeq, "[tid:%i] Setting up squash to " "start from stage %i, after [sn:%i].\n", tid, stage_num, inst->bdelaySeqNum); @@ -225,11 +182,12 @@ FetchSeqUnit::squashAfterInst(DynInstPtr inst, int stage_num, ThreadID tid) // Squash inside current resource, so if there needs to be fetching on // same cycle the fetch information will be correct. - // squash(inst, stage_num, inst->bdelaySeqNum, tid); // Schedule Squash Through-out Resource Pool - cpu->resPool->scheduleEvent((InOrderCPU::CPUEventType)ResourcePool::SquashAll, inst, 0); + cpu->resPool->scheduleEvent( + (InOrderCPU::CPUEventType)ResourcePool::SquashAll, inst, 0); } + void FetchSeqUnit::squash(DynInstPtr inst, int squash_stage, InstSeqNum squash_seq_num, ThreadID tid) @@ -241,8 +199,15 @@ FetchSeqUnit::squash(DynInstPtr inst, int squash_stage, // Handles the case where we are squashing because of something that is // not a branch...like a memory stall - Addr new_PC = (inst->isControl()) ? - inst->readPredTarg() : inst->readPC() + instSize; + TheISA::PCState newPC; + if (inst->isControl()) { + newPC = inst->readPredTarg(); + } else { + TheISA::PCState thisPC = inst->pcState(); + assert(inst->staticInst); + advancePC(thisPC, inst->staticInst); + newPC = thisPC; + } if (squashSeqNum[tid] <= done_seq_num && lastSquashCycle[tid] == curTick) { @@ -258,31 +223,25 @@ FetchSeqUnit::squash(DynInstPtr inst, int squash_stage, // the last done_seq_num then this is the delay slot inst. if (cpu->nextInstSeqNum(tid) != done_seq_num && !inst->procDelaySlotOnMispred) { - delaySlotInfo[tid].numInsts = 0; - delaySlotInfo[tid].targetReady = false; // Reset PC - PC[tid] = new_PC; - nextPC[tid] = new_PC + instSize; - nextNPC[tid] = new_PC + (2 * instSize); + pc[tid] = newPC; +#if ISA_HAS_DELAY_SLOT + TheISA::advancePC(pc[tid], inst->staticInst); +#endif - DPRINTF(InOrderFetchSeq, "[tid:%i]: Setting PC to %08p.\n", - tid, PC[tid]); + DPRINTF(InOrderFetchSeq, "[tid:%i]: Setting PC to %s.\n", + tid, newPC); } else { -#if !ISA_HAS_DELAY_SLOT - assert(0); -#endif + assert(ISA_HAS_DELAY_SLOT); - delaySlotInfo[tid].numInsts = 1; - delaySlotInfo[tid].targetReady = false; - delaySlotInfo[tid].targetAddr = (inst->procDelaySlotOnMispred) ? - inst->branchTarget() : new_PC; + pc[tid] = (inst->procDelaySlotOnMispred) ? + inst->branchTarget() : newPC; // Reset PC to Delay Slot Instruction if (inst->procDelaySlotOnMispred) { - PC[tid] = new_PC; - nextPC[tid] = new_PC + instSize; - nextNPC[tid] = new_PC + (2 * instSize); + // Reset PC + pc[tid] = newPC; } } @@ -309,18 +268,13 @@ FetchSeqUnit::FetchSeqEvent::process() FetchSeqUnit* fs_res = dynamic_cast<FetchSeqUnit*>(resource); assert(fs_res); - for (int i=0; i < MaxThreads; i++) { - fs_res->PC[i] = fs_res->cpu->readPC(i); - fs_res->nextPC[i] = fs_res->cpu->readNextPC(i); - fs_res->nextNPC[i] = fs_res->cpu->readNextNPC(i); - DPRINTF(InOrderFetchSeq, "[tid:%i]: Setting PC:%08p NPC:%08p " - "NNPC:%08p.\n", fs_res->PC[i], fs_res->nextPC[i], - fs_res->nextNPC[i]); + for (int i = 0; i < MaxThreads; i++) { + fs_res->pc[i] = fs_res->cpu->pcState(i); + DPRINTF(InOrderFetchSeq, "[tid:%i]: Setting PC: %s.\n", + fs_res->pc[i]); fs_res->pcValid[i] = true; } - - //cpu->fetchPriorityList.push_back(tid); } @@ -329,22 +283,17 @@ FetchSeqUnit::activateThread(ThreadID tid) { pcValid[tid] = true; - PC[tid] = cpu->readPC(tid); - nextPC[tid] = cpu->readNextPC(tid); - nextNPC[tid] = cpu->readNextNPC(tid); + pc[tid] = cpu->pcState(tid); cpu->fetchPriorityList.push_back(tid); - DPRINTF(InOrderFetchSeq, "[tid:%i]: Reading PC:%08p NPC:%08p " - "NNPC:%08p.\n", tid, PC[tid], nextPC[tid], nextNPC[tid]); + DPRINTF(InOrderFetchSeq, "[tid:%i]: Reading PC: %s.\n", + tid, pc[tid]); } void FetchSeqUnit::deactivateThread(ThreadID tid) { - delaySlotInfo[tid].numInsts = 0; - delaySlotInfo[tid].targetReady = false; - pcValid[tid] = false; pcBlockStage[tid] = 0; @@ -375,18 +324,14 @@ FetchSeqUnit::updateAfterContextSwitch(DynInstPtr inst, ThreadID tid) * switch was right after the branch. Thus, if it's not, then * we are updating incorrectly here */ - assert(cpu->thread[tid]->lastBranchNextPC == inst->readPC()); - - PC[tid] = cpu->thread[tid]->lastBranchNextNPC; - nextPC[tid] = PC[tid] + instSize; - nextNPC[tid] = nextPC[tid] + instSize; + assert(cpu->nextInstAddr(tid) == inst->instAddr()); + pc[tid] = cpu->thread[tid]->lastBranchPC; } else { - PC[tid] = inst->readNextPC(); - nextPC[tid] = inst->readNextNPC(); - nextNPC[tid] = inst->readNextNPC() + instSize; + pc[tid] = inst->pcState(); } + assert(inst->staticInst); + advancePC(pc[tid], inst->staticInst); DPRINTF(InOrderFetchSeq, "[tid:%i]: Updating PCs due to Context Switch." - "Assigning PC:%08p NPC:%08p NNPC:%08p.\n", tid, PC[tid], - nextPC[tid], nextNPC[tid]); + "Assigning PC: %s.\n", tid, pc[tid]); } diff --git a/src/cpu/inorder/resources/fetch_seq_unit.hh b/src/cpu/inorder/resources/fetch_seq_unit.hh index aab462224..a258dc0e5 100644 --- a/src/cpu/inorder/resources/fetch_seq_unit.hh +++ b/src/cpu/inorder/resources/fetch_seq_unit.hh @@ -80,22 +80,7 @@ class FetchSeqUnit : public Resource { bool pcValid[ThePipeline::MaxThreads]; int pcBlockStage[ThePipeline::MaxThreads]; - TheISA::IntReg PC[ThePipeline::MaxThreads]; - TheISA::IntReg nextPC[ThePipeline::MaxThreads]; - TheISA::IntReg nextNPC[ThePipeline::MaxThreads]; - - /** Tracks delay slot information for threads in ISAs which use - * delay slots; - */ - struct DelaySlotInfo { - InstSeqNum delaySlotSeqNum; - InstSeqNum branchSeqNum; - int numInsts; - Addr targetAddr; - bool targetReady; - }; - - DelaySlotInfo delaySlotInfo[ThePipeline::MaxThreads]; + TheISA::PCState pc[ThePipeline::MaxThreads]; /** Squash Seq. Nums*/ InstSeqNum squashSeqNum[ThePipeline::MaxThreads]; diff --git a/src/cpu/inorder/resources/tlb_unit.hh b/src/cpu/inorder/resources/tlb_unit.hh index 5c62c7751..eb1bf55f0 100644 --- a/src/cpu/inorder/resources/tlb_unit.hh +++ b/src/cpu/inorder/resources/tlb_unit.hh @@ -111,8 +111,10 @@ class TLBUnitRequest : public ResourceRequest { aligned_addr = inst->getMemAddr(); req_size = sizeof(TheISA::MachInst); flags = 0; - inst->fetchMemReq = new Request(inst->readTid(), aligned_addr, req_size, - flags, inst->readPC(), res->cpu->readCpuId(), inst->readTid()); + inst->fetchMemReq = new Request(inst->readTid(), aligned_addr, + req_size, flags, inst->instAddr(), + res->cpu->readCpuId(), + inst->readTid()); memReq = inst->fetchMemReq; } else { aligned_addr = inst->getMemAddr();; @@ -123,8 +125,10 @@ class TLBUnitRequest : public ResourceRequest { req_size = 8; } - inst->dataMemReq = new Request(inst->readTid(), aligned_addr, req_size, - flags, inst->readPC(), res->cpu->readCpuId(), inst->readTid()); + inst->dataMemReq = new Request(inst->readTid(), aligned_addr, + req_size, flags, inst->instAddr(), + res->cpu->readCpuId(), + inst->readTid()); memReq = inst->dataMemReq; } } diff --git a/src/cpu/inorder/thread_context.cc b/src/cpu/inorder/thread_context.cc index e6d0af2cc..bbccf626a 100644 --- a/src/cpu/inorder/thread_context.cc +++ b/src/cpu/inorder/thread_context.cc @@ -234,30 +234,6 @@ InOrderThreadContext::setRegOtherThread(int misc_reg, const MiscReg &val, } void -InOrderThreadContext::setPC(uint64_t val) -{ - DPRINTF(InOrderCPU, "[tid:%i] Setting PC to %08p\n", - thread->readTid(), val); - cpu->setPC(val, thread->readTid()); -} - -void -InOrderThreadContext::setNextPC(uint64_t val) -{ - DPRINTF(InOrderCPU, "[tid:%i] Setting NPC to %08p\n", - thread->readTid(), val); - cpu->setNextPC(val, thread->readTid()); -} - -void -InOrderThreadContext::setNextNPC(uint64_t val) -{ - DPRINTF(InOrderCPU, "[tid:%i] Setting NNPC to %08p\n", - thread->readTid(), val); - cpu->setNextNPC(val, thread->readTid()); -} - -void InOrderThreadContext::setMiscRegNoEffect(int misc_reg, const MiscReg &val) { cpu->setMiscRegNoEffect(misc_reg, val, thread->readTid()); diff --git a/src/cpu/inorder/thread_context.hh b/src/cpu/inorder/thread_context.hh index 0c0f563c0..21f1e5835 100644 --- a/src/cpu/inorder/thread_context.hh +++ b/src/cpu/inorder/thread_context.hh @@ -204,23 +204,21 @@ class InOrderThreadContext : public ThreadContext ThreadID tid); /** Reads this thread's PC. */ - uint64_t readPC() - { return cpu->readPC(thread->readTid()); } + TheISA::PCState pcState() + { return cpu->pcState(thread->readTid()); } /** Sets this thread's PC. */ - void setPC(uint64_t val); + void pcState(const TheISA::PCState &val) + { cpu->pcState(val, thread->readTid()); } - /** Reads this thread's next PC. */ - uint64_t readNextPC() - { return cpu->readNextPC(thread->readTid()); } + Addr instAddr() + { return cpu->instAddr(thread->readTid()); } - /** Sets this thread's next PC. */ - void setNextPC(uint64_t val); + Addr nextInstAddr() + { return cpu->nextInstAddr(thread->readTid()); } - uint64_t readNextNPC() - { return cpu->readNextNPC(thread->readTid()); } - - void setNextNPC(uint64_t val); + MicroPC microPC() + { return cpu->microPC(thread->readTid()); } /** Reads a miscellaneous register. */ MiscReg readMiscRegNoEffect(int misc_reg) diff --git a/src/cpu/inorder/thread_state.hh b/src/cpu/inorder/thread_state.hh index 0a171a99f..20ace6659 100644 --- a/src/cpu/inorder/thread_state.hh +++ b/src/cpu/inorder/thread_state.hh @@ -111,9 +111,7 @@ class InOrderThreadState : public ThreadState { /** Is last instruction graduated a branch? */ bool lastGradIsBranch; - Addr lastBranchPC; - Addr lastBranchNextPC; - Addr lastBranchNextNPC; + TheISA::PCState lastBranchPC; }; #endif // __CPU_INORDER_THREAD_STATE_HH__ |