summaryrefslogtreecommitdiff
path: root/src/cpu
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu')
-rw-r--r--src/cpu/base_dyn_inst.hh130
-rw-r--r--src/cpu/base_dyn_inst_impl.hh58
-rw-r--r--src/cpu/checker/cpu.hh8
-rw-r--r--src/cpu/exetrace.cc10
-rw-r--r--src/cpu/exetrace.hh12
-rw-r--r--src/cpu/inorder/comm.hh4
-rw-r--r--src/cpu/inorder/cpu.cc91
-rw-r--r--src/cpu/inorder/cpu.hh30
-rw-r--r--src/cpu/inorder/first_stage.cc4
-rw-r--r--src/cpu/inorder/inorder_dyn_inst.cc25
-rw-r--r--src/cpu/inorder/inorder_dyn_inst.hh87
-rw-r--r--src/cpu/inorder/inorder_trace.cc8
-rw-r--r--src/cpu/inorder/inorder_trace.hh13
-rw-r--r--src/cpu/inorder/pipeline_stage.cc49
-rw-r--r--src/cpu/inorder/pipeline_stage.hh6
-rw-r--r--src/cpu/inorder/resources/bpred_unit.cc94
-rw-r--r--src/cpu/inorder/resources/bpred_unit.hh44
-rw-r--r--src/cpu/inorder/resources/branch_predictor.cc28
-rw-r--r--src/cpu/inorder/resources/cache_unit.cc33
-rw-r--r--src/cpu/inorder/resources/execution_unit.cc59
-rw-r--r--src/cpu/inorder/resources/fetch_seq_unit.cc171
-rw-r--r--src/cpu/inorder/resources/fetch_seq_unit.hh17
-rw-r--r--src/cpu/inorder/resources/tlb_unit.hh12
-rw-r--r--src/cpu/inorder/thread_context.cc24
-rw-r--r--src/cpu/inorder/thread_context.hh22
-rw-r--r--src/cpu/inorder/thread_state.hh4
-rw-r--r--src/cpu/inteltrace.cc2
-rw-r--r--src/cpu/inteltrace.hh12
-rw-r--r--src/cpu/legiontrace.cc9
-rw-r--r--src/cpu/legiontrace.hh12
-rw-r--r--src/cpu/nativetrace.hh12
-rw-r--r--src/cpu/o3/bpred_unit.hh33
-rw-r--r--src/cpu/o3/bpred_unit_impl.hh103
-rw-r--r--src/cpu/o3/comm.hh13
-rw-r--r--src/cpu/o3/commit.hh55
-rw-r--r--src/cpu/o3/commit_impl.hh86
-rw-r--r--src/cpu/o3/cpu.cc83
-rw-r--r--src/cpu/o3/cpu.hh33
-rw-r--r--src/cpu/o3/decode_impl.hh51
-rw-r--r--src/cpu/o3/dep_graph.hh8
-rw-r--r--src/cpu/o3/dyn_inst.hh12
-rw-r--r--src/cpu/o3/dyn_inst_impl.hh32
-rw-r--r--src/cpu/o3/fetch.hh20
-rw-r--r--src/cpu/o3/fetch_impl.hh178
-rw-r--r--src/cpu/o3/iew_impl.hh94
-rw-r--r--src/cpu/o3/inst_queue_impl.hh49
-rw-r--r--src/cpu/o3/lsq_unit.hh8
-rw-r--r--src/cpu/o3/lsq_unit_impl.hh44
-rw-r--r--src/cpu/o3/mem_dep_unit_impl.hh52
-rw-r--r--src/cpu/o3/rename_impl.hh23
-rw-r--r--src/cpu/o3/rob_impl.hh8
-rwxr-xr-xsrc/cpu/o3/thread_context.hh42
-rwxr-xr-xsrc/cpu/o3/thread_context_impl.hh46
-rw-r--r--src/cpu/pc_event.cc4
-rw-r--r--src/cpu/pred/btb.cc28
-rw-r--r--src/cpu/pred/btb.hh17
-rw-r--r--src/cpu/pred/ras.cc15
-rw-r--r--src/cpu/pred/ras.hh12
-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
-rw-r--r--src/cpu/simple_thread.cc12
-rw-r--r--src/cpu/simple_thread.hh82
-rw-r--r--src/cpu/static_inst.cc11
-rw-r--r--src/cpu/static_inst.hh34
-rw-r--r--src/cpu/thread_context.cc12
-rw-r--r--src/cpu/thread_context.hh42
68 files changed, 937 insertions, 1622 deletions
diff --git a/src/cpu/base_dyn_inst.hh b/src/cpu/base_dyn_inst.hh
index e9b7daa4a..bc6f59407 100644
--- a/src/cpu/base_dyn_inst.hh
+++ b/src/cpu/base_dyn_inst.hh
@@ -38,6 +38,7 @@
#include <string>
#include "arch/faults.hh"
+#include "arch/utility.hh"
#include "base/fast_alloc.hh"
#include "base/trace.hh"
#include "config/full_system.hh"
@@ -241,36 +242,15 @@ class BaseDynInst : public FastAlloc, public RefCounted
/** Records changes to result? */
bool recordResult;
- /** PC of this instruction. */
- Addr PC;
-
- /** Micro PC of this instruction. */
- Addr microPC;
-
/** Did this instruction execute, or is it predicated false */
bool predicate;
protected:
- /** 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 non-speculative NPC. Target PC for Mips or Sparc. */
- Addr nextNPC;
+ /** PC state for this instruction. */
+ TheISA::PCState pc;
- /** Next non-speculative micro PC. */
- Addr nextMicroPC;
-
- /** Predicted next PC. */
- Addr predPC;
-
- /** Predicted next NPC. */
- Addr predNPC;
-
- /** Predicted next microPC */
- Addr predMicroPC;
+ /** Predicted PC state after this instruction. */
+ TheISA::PCState predPC;
/** If this is a branch that was predicted taken */
bool predTaken;
@@ -386,27 +366,23 @@ class BaseDynInst : public FastAlloc, public RefCounted
}
/** BaseDynInst constructor given a binary instruction.
* @param staticInst A StaticInstPtr to the underlying instruction.
- * @param PC The PC of the instruction.
- * @param pred_PC The predicted next PC.
- * @param pred_NPC The predicted next NPC.
+ * @param pc The PC state for the instruction.
+ * @param predPC The predicted next PC state for the instruction.
* @param seq_num The sequence number of the instruction.
* @param cpu Pointer to the instruction's CPU.
*/
- BaseDynInst(StaticInstPtr staticInst, Addr PC, Addr NPC, Addr microPC,
- Addr pred_PC, Addr pred_NPC, Addr pred_MicroPC,
- InstSeqNum seq_num, ImplCPU *cpu);
+ BaseDynInst(StaticInstPtr staticInst, TheISA::PCState pc,
+ TheISA::PCState predPC, InstSeqNum seq_num, ImplCPU *cpu);
/** 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 pred_NPC The predicted next NPC.
+ * @param _pc The PC state for the instruction.
+ * @param _predPC The predicted next PC state for the instruction.
* @param seq_num The sequence number of the instruction.
* @param cpu Pointer to the instruction's CPU.
*/
- BaseDynInst(TheISA::ExtMachInst inst, Addr PC, Addr NPC, Addr microPC,
- Addr pred_PC, Addr pred_NPC, Addr pred_MicroPC,
- InstSeqNum seq_num, ImplCPU *cpu);
+ BaseDynInst(TheISA::ExtMachInst inst, TheISA::PCState pc,
+ TheISA::PCState predPC, InstSeqNum seq_num, ImplCPU *cpu);
/** BaseDynInst constructor given a StaticInst pointer.
* @param _staticInst The StaticInst for this BaseDynInst.
@@ -443,45 +419,22 @@ class BaseDynInst : public FastAlloc, public RefCounted
*/
bool doneTargCalc() { return false; }
- /** 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; }
-
- /** 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
- }
-
- Addr readNextMicroPC()
- {
- return nextMicroPC;
- }
-
/** Set the predicted target of this current instruction. */
- void setPredTarg(Addr predicted_PC, Addr predicted_NPC,
- Addr predicted_MicroPC)
+ void setPredTarg(const TheISA::PCState &_predPC)
{
- predPC = predicted_PC;
- predNPC = predicted_NPC;
- predMicroPC = predicted_MicroPC;
+ predPC = _predPC;
}
+ const 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 predMicroPC() { return predPC.microPC(); }
/** Returns whether the instruction was predicted taken or not. */
bool readPredTaken()
@@ -497,9 +450,9 @@ class BaseDynInst : public FastAlloc, public RefCounted
/** Returns whether the instruction mispredicted. */
bool mispredicted()
{
- return readPredPC() != readNextPC() ||
- readPredNPC() != readNextNPC() ||
- readPredMicroPC() != readNextMicroPC();
+ TheISA::PCState tempPC = pc;
+ TheISA::advancePC(tempPC, staticInst);
+ return !(tempPC == predPC);
}
//
@@ -576,7 +529,8 @@ class BaseDynInst : public FastAlloc, public RefCounted
OpClass opClass() const { return staticInst->opClass(); }
/** Returns the branch target address. */
- Addr branchTarget() const { return staticInst->branchTarget(PC); }
+ TheISA::PCState branchTarget() const
+ { return staticInst->branchTarget(pc); }
/** Returns the number of source registers. */
int8_t numSrcRegs() const { return staticInst->numSrcRegs(); }
@@ -773,30 +727,20 @@ class BaseDynInst : public FastAlloc, public RefCounted
/** Returns whether or not this instruction is squashed in the ROB. */
bool isSquashedInROB() const { return status[SquashedInROB]; }
- /** Read the PC of this instruction. */
- const Addr readPC() const { return PC; }
+ /** Read the PC state of this instruction. */
+ const TheISA::PCState pcState() const { return pc; }
- /**Read the micro PC of this instruction. */
- const Addr readMicroPC() const { return microPC; }
+ /** Set the PC state of this instruction. */
+ const void pcState(const TheISA::PCState &val) { pc = val; }
- /** Set the next PC of this instruction (its actual target). */
- void setNextPC(Addr val)
- {
- nextPC = val;
- }
+ /** Read the PC of this instruction. */
+ const Addr instAddr() const { return pc.instAddr(); }
- /** Set the next NPC of this instruction (the target in Mips or Sparc).*/
- void setNextNPC(Addr val)
- {
-#if ISA_HAS_DELAY_SLOT
- nextNPC = val;
-#endif
- }
+ /** Read the PC of the next instruction. */
+ const Addr nextInstAddr() const { return pc.nextInstAddr(); }
- void setNextMicroPC(Addr val)
- {
- nextMicroPC = val;
- }
+ /**Read the micro PC of this instruction. */
+ const Addr microPC() const { return pc.microPC(); }
bool readPredicate()
{
@@ -895,7 +839,7 @@ BaseDynInst<Impl>::readBytes(Addr addr, uint8_t *data,
unsigned size, unsigned flags)
{
reqMade = true;
- Request *req = new Request(asid, addr, size, flags, this->PC,
+ Request *req = new Request(asid, addr, size, flags, this->pc.instAddr(),
thread->contextId(), threadNumber);
Request *sreqLow = NULL;
@@ -956,7 +900,7 @@ BaseDynInst<Impl>::writeBytes(uint8_t *data, unsigned size,
}
reqMade = true;
- Request *req = new Request(asid, addr, size, flags, this->PC,
+ Request *req = new Request(asid, addr, size, flags, this->pc.instAddr(),
thread->contextId(), threadNumber);
Request *sreqLow = NULL;
diff --git a/src/cpu/base_dyn_inst_impl.hh b/src/cpu/base_dyn_inst_impl.hh
index 4fb8490c1..923b204ce 100644
--- a/src/cpu/base_dyn_inst_impl.hh
+++ b/src/cpu/base_dyn_inst_impl.hh
@@ -62,32 +62,14 @@ my_hash_t thishash;
template <class Impl>
BaseDynInst<Impl>::BaseDynInst(StaticInstPtr _staticInst,
- Addr inst_PC, Addr inst_NPC,
- Addr inst_MicroPC,
- Addr pred_PC, Addr pred_NPC,
- Addr pred_MicroPC,
+ TheISA::PCState _pc, TheISA::PCState _predPC,
InstSeqNum seq_num, ImplCPU *cpu)
: staticInst(_staticInst), traceData(NULL), cpu(cpu)
{
seqNum = seq_num;
- bool nextIsMicro =
- staticInst->isMicroop() && !staticInst->isLastMicroop();
-
- PC = inst_PC;
- microPC = inst_MicroPC;
- if (nextIsMicro) {
- nextPC = inst_PC;
- nextNPC = inst_NPC;
- nextMicroPC = microPC + 1;
- } else {
- nextPC = inst_NPC;
- nextNPC = nextPC + sizeof(TheISA::MachInst);
- nextMicroPC = 0;
- }
- predPC = pred_PC;
- predNPC = pred_NPC;
- predMicroPC = pred_MicroPC;
+ pc = _pc;
+ predPC = _predPC;
predTaken = false;
initVars();
@@ -95,32 +77,14 @@ BaseDynInst<Impl>::BaseDynInst(StaticInstPtr _staticInst,
template <class Impl>
BaseDynInst<Impl>::BaseDynInst(TheISA::ExtMachInst inst,
- Addr inst_PC, Addr inst_NPC,
- Addr inst_MicroPC,
- Addr pred_PC, Addr pred_NPC,
- Addr pred_MicroPC,
+ TheISA::PCState _pc, TheISA::PCState _predPC,
InstSeqNum seq_num, ImplCPU *cpu)
- : staticInst(inst, inst_PC), traceData(NULL), cpu(cpu)
+ : staticInst(inst, _pc.instAddr()), traceData(NULL), cpu(cpu)
{
seqNum = seq_num;
- bool nextIsMicro =
- staticInst->isMicroop() && !staticInst->isLastMicroop();
-
- PC = inst_PC;
- microPC = inst_MicroPC;
- if (nextIsMicro) {
- nextPC = inst_PC;
- nextNPC = inst_NPC;
- nextMicroPC = microPC + 1;
- } else {
- nextPC = inst_NPC;
- nextNPC = nextPC + sizeof(TheISA::MachInst);
- nextMicroPC = 0;
- }
- predPC = pred_PC;
- predNPC = pred_NPC;
- predMicroPC = pred_MicroPC;
+ pc = _pc;
+ predPC = _predPC;
predTaken = false;
initVars();
@@ -301,8 +265,8 @@ template <class Impl>
void
BaseDynInst<Impl>::dump()
{
- cprintf("T%d : %#08d `", threadNumber, PC);
- std::cout << staticInst->disassemble(PC);
+ cprintf("T%d : %#08d `", threadNumber, pc.instAddr());
+ std::cout << staticInst->disassemble(pc.instAddr());
cprintf("'\n");
}
@@ -311,8 +275,8 @@ void
BaseDynInst<Impl>::dump(std::string &outstring)
{
std::ostringstream s;
- s << "T" << threadNumber << " : 0x" << PC << " "
- << staticInst->disassemble(PC);
+ s << "T" << threadNumber << " : 0x" << pc.instAddr() << " "
+ << staticInst->disassemble(pc.instAddr());
outstring = s.str();
}
diff --git a/src/cpu/checker/cpu.hh b/src/cpu/checker/cpu.hh
index a2f44106d..df5d8209b 100644
--- a/src/cpu/checker/cpu.hh
+++ b/src/cpu/checker/cpu.hh
@@ -241,13 +241,9 @@ class CheckerCPU : public BaseCPU
result.integer = val;
}
- uint64_t readPC() { return thread->readPC(); }
+ uint64_t instAddr() { return thread->instAddr(); }
- uint64_t readNextPC() { return thread->readNextPC(); }
-
- void setNextPC(uint64_t val) {
- thread->setNextPC(val);
- }
+ uint64_t nextInstAddr() { return thread->nextInstAddr(); }
MiscReg readMiscRegNoEffect(int misc_reg)
{
diff --git a/src/cpu/exetrace.cc b/src/cpu/exetrace.cc
index 4bab778ba..f8b25ef73 100644
--- a/src/cpu/exetrace.cc
+++ b/src/cpu/exetrace.cc
@@ -72,10 +72,7 @@ Trace::ExeTracerRecord::traceInst(StaticInstPtr inst, bool ran)
std::string sym_str;
Addr sym_addr;
- Addr cur_pc = PC;
-#if THE_ISA == ARM_ISA
- cur_pc &= ~PcModeMask;
-#endif
+ Addr cur_pc = pc.instAddr();
if (debugSymbolTable
&& IsOn(ExecSymbol)
#if FULL_SYSTEM
@@ -85,13 +82,12 @@ Trace::ExeTracerRecord::traceInst(StaticInstPtr inst, bool ran)
if (cur_pc != sym_addr)
sym_str += csprintf("+%d",cur_pc - sym_addr);
outs << "@" << sym_str;
- }
- else {
+ } else {
outs << "0x" << hex << cur_pc;
}
if (inst->isMicroop()) {
- outs << "." << setw(2) << dec << upc;
+ outs << "." << setw(2) << dec << pc.microPC();
} else {
outs << " ";
}
diff --git a/src/cpu/exetrace.hh b/src/cpu/exetrace.hh
index 1982595eb..65950728b 100644
--- a/src/cpu/exetrace.hh
+++ b/src/cpu/exetrace.hh
@@ -47,10 +47,10 @@ class ExeTracerRecord : public InstRecord
{
public:
ExeTracerRecord(Tick _when, ThreadContext *_thread,
- const StaticInstPtr _staticInst, Addr _pc, bool spec,
- const StaticInstPtr _macroStaticInst = NULL, MicroPC _upc = 0)
+ const StaticInstPtr _staticInst, TheISA::PCState _pc,
+ bool spec, const StaticInstPtr _macroStaticInst = NULL)
: InstRecord(_when, _thread, _staticInst, _pc, spec,
- _macroStaticInst, _upc)
+ _macroStaticInst)
{
}
@@ -69,8 +69,8 @@ class ExeTracer : public InstTracer
InstRecord *
getInstRecord(Tick when, ThreadContext *tc,
- const StaticInstPtr staticInst, Addr pc,
- const StaticInstPtr macroStaticInst = NULL, MicroPC upc = 0)
+ const StaticInstPtr staticInst, TheISA::PCState pc,
+ const StaticInstPtr macroStaticInst = NULL)
{
if (!IsOn(ExecEnable))
return NULL;
@@ -82,7 +82,7 @@ class ExeTracer : public InstTracer
return NULL;
return new ExeTracerRecord(when, tc,
- staticInst, pc, tc->misspeculating(), macroStaticInst, upc);
+ staticInst, pc, tc->misspeculating(), macroStaticInst);
}
};
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__
diff --git a/src/cpu/inteltrace.cc b/src/cpu/inteltrace.cc
index ec51b80e7..ee148c50f 100644
--- a/src/cpu/inteltrace.cc
+++ b/src/cpu/inteltrace.cc
@@ -48,7 +48,7 @@ Trace::IntelTraceRecord::dump()
{
ostream &outs = Trace::output();
ccprintf(outs, "%7d ) ", when);
- outs << "0x" << hex << PC << ":\t";
+ outs << "0x" << hex << pc.instAddr() << ":\t";
if (staticInst->isLoad()) {
ccprintf(outs, "<RD %#x>", addr);
} else if (staticInst->isStore()) {
diff --git a/src/cpu/inteltrace.hh b/src/cpu/inteltrace.hh
index c4ace4f4b..234b173e9 100644
--- a/src/cpu/inteltrace.hh
+++ b/src/cpu/inteltrace.hh
@@ -46,10 +46,10 @@ class IntelTraceRecord : public InstRecord
{
public:
IntelTraceRecord(Tick _when, ThreadContext *_thread,
- const StaticInstPtr _staticInst, Addr _pc, bool spec,
- const StaticInstPtr _macroStaticInst = NULL, MicroPC _upc = 0)
+ const StaticInstPtr _staticInst, TheISA::PCState _pc,
+ bool spec, const StaticInstPtr _macroStaticInst = NULL)
: InstRecord(_when, _thread, _staticInst, _pc, spec,
- _macroStaticInst, _upc)
+ _macroStaticInst)
{
}
@@ -65,8 +65,8 @@ class IntelTrace : public InstTracer
IntelTraceRecord *
getInstRecord(Tick when, ThreadContext *tc,
- const StaticInstPtr staticInst, Addr pc,
- const StaticInstPtr macroStaticInst = NULL, MicroPC upc = 0)
+ const StaticInstPtr staticInst, TheISA::PCState pc,
+ const StaticInstPtr macroStaticInst = NULL)
{
if (!IsOn(ExecEnable))
return NULL;
@@ -78,7 +78,7 @@ class IntelTrace : public InstTracer
return NULL;
return new IntelTraceRecord(when, tc,
- staticInst, pc, tc->misspeculating(), macroStaticInst, upc);
+ staticInst, pc, tc->misspeculating(), macroStaticInst);
}
};
diff --git a/src/cpu/legiontrace.cc b/src/cpu/legiontrace.cc
index 1390d0807..8750e56e5 100644
--- a/src/cpu/legiontrace.cc
+++ b/src/cpu/legiontrace.cc
@@ -211,7 +211,7 @@ Trace::LegionTraceRecord::dump()
if(!staticInst->isMicroop() || staticInst->isLastMicroop()) {
while (!compared) {
if (shared_data->flags == OWN_M5) {
- m5Pc = PC & SparcISA::PAddrImplMask;
+ m5Pc = pc.instAddr() & SparcISA::PAddrImplMask;
if (bits(shared_data->pstate,3,3)) {
m5Pc &= mask(32);
}
@@ -432,13 +432,14 @@ Trace::LegionTraceRecord::dump()
<< endl;
predecoder.setTC(thread);
- predecoder.moreBytes(m5Pc, m5Pc,
- shared_data->instruction);
+ predecoder.moreBytes(m5Pc, m5Pc, shared_data->instruction);
assert(predecoder.extMachInstReady());
+ PCState tempPC = pc;
StaticInstPtr legionInst =
- StaticInst::decode(predecoder.getExtMachInst(), lgnPc);
+ StaticInst::decode(predecoder.getExtMachInst(tempPC),
+ lgnPc);
outs << setfill(' ') << setw(15)
<< " Legion Inst: "
<< "0x" << setw(8) << setfill('0') << hex
diff --git a/src/cpu/legiontrace.hh b/src/cpu/legiontrace.hh
index 829941d4b..a60b9ad10 100644
--- a/src/cpu/legiontrace.hh
+++ b/src/cpu/legiontrace.hh
@@ -46,10 +46,10 @@ class LegionTraceRecord : public InstRecord
{
public:
LegionTraceRecord(Tick _when, ThreadContext *_thread,
- const StaticInstPtr _staticInst, Addr _pc, bool spec,
- const StaticInstPtr _macroStaticInst = NULL, MicroPC _upc = 0)
+ const StaticInstPtr _staticInst, TheISA::PCState _pc,
+ bool spec, const StaticInstPtr _macroStaticInst = NULL)
: InstRecord(_when, _thread, _staticInst, _pc, spec,
- _macroStaticInst, _upc)
+ _macroStaticInst)
{
}
@@ -65,14 +65,14 @@ class LegionTrace : public InstTracer
LegionTraceRecord *
getInstRecord(Tick when, ThreadContext *tc,
- const StaticInstPtr staticInst, Addr pc,
- const StaticInstPtr macroStaticInst = NULL, MicroPC upc = 0)
+ const StaticInstPtr staticInst, TheISA::PCState pc,
+ const StaticInstPtr macroStaticInst = NULL)
{
if (tc->misspeculating())
return NULL;
return new LegionTraceRecord(when, tc,
- staticInst, pc, tc->misspeculating(), macroStaticInst, upc);
+ staticInst, pc, tc->misspeculating(), macroStaticInst);
}
};
diff --git a/src/cpu/nativetrace.hh b/src/cpu/nativetrace.hh
index 6ad6b0242..5c5b9a66d 100644
--- a/src/cpu/nativetrace.hh
+++ b/src/cpu/nativetrace.hh
@@ -54,10 +54,10 @@ class NativeTraceRecord : public ExeTracerRecord
public:
NativeTraceRecord(NativeTrace * _parent,
Tick _when, ThreadContext *_thread,
- const StaticInstPtr _staticInst, Addr _pc, bool spec,
- const StaticInstPtr _macroStaticInst = NULL, MicroPC _upc = 0)
+ const StaticInstPtr _staticInst, TheISA::PCState _pc,
+ bool spec, const StaticInstPtr _macroStaticInst = NULL)
: ExeTracerRecord(_when, _thread, _staticInst, _pc, spec,
- _macroStaticInst, _upc),
+ _macroStaticInst),
parent(_parent)
{
}
@@ -79,14 +79,14 @@ class NativeTrace : public ExeTracer
NativeTraceRecord *
getInstRecord(Tick when, ThreadContext *tc,
- const StaticInstPtr staticInst, Addr pc,
- const StaticInstPtr macroStaticInst = NULL, MicroPC upc = 0)
+ const StaticInstPtr staticInst, TheISA::PCState pc,
+ const StaticInstPtr macroStaticInst = NULL)
{
if (tc->misspeculating())
return NULL;
return new NativeTraceRecord(this, when, tc,
- staticInst, pc, tc->misspeculating(), macroStaticInst, upc);
+ staticInst, pc, tc->misspeculating(), macroStaticInst);
}
template<class T>
diff --git a/src/cpu/o3/bpred_unit.hh b/src/cpu/o3/bpred_unit.hh
index f199bdd75..58b1147c9 100644
--- a/src/cpu/o3/bpred_unit.hh
+++ b/src/cpu/o3/bpred_unit.hh
@@ -88,7 +88,7 @@ class BPredUnit
* @param tid The thread id.
* @return Returns if the branch is taken or not.
*/
- bool predict(DynInstPtr &inst, Addr &PC, ThreadID tid);
+ bool predict(DynInstPtr &inst, TheISA::PCState &pc, ThreadID tid);
// @todo: Rename this function.
void BPUncond(void * &bp_history);
@@ -118,7 +118,8 @@ class BPredUnit
* @param actually_taken The correct branch direction.
* @param tid The thread id.
*/
- void squash(const InstSeqNum &squashed_sn, const Addr &corr_target,
+ void squash(const InstSeqNum &squashed_sn,
+ const TheISA::PCState &corr_target,
bool actually_taken, ThreadID tid);
/**
@@ -134,23 +135,23 @@ 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.
* @param inst_PC The PC to look up.
* @return Whether the BTB contains the given PC.
*/
- bool BTBValid(Addr &inst_PC)
- { return BTB.valid(inst_PC, 0); }
+ bool BTBValid(Addr instPC)
+ { return BTB.valid(instPC, 0); }
/**
* Looks up a given PC in the BTB to get the predicted target.
* @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.
@@ -160,15 +161,15 @@ class BPredUnit
* 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 &target)
+ { BTB.update(instPC, target, 0); }
void dump();
@@ -178,13 +179,13 @@ 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,
+ PredictorHistory(const InstSeqNum &seq_num, Addr instPC,
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),
+ : seqNum(seq_num), pc(instPC), RASTarget(0), RASIndex(0),
+ tid(_tid), predTaken(pred_taken), usedRAS(0),
wasCall(0), bpHistory(bp_history)
- { }
+ {}
bool operator==(const PredictorHistory &entry) const {
return this->seqNum == entry.seqNum;
@@ -194,10 +195,10 @@ class BPredUnit
InstSeqNum seqNum;
/** The PC associated with the sequence number. */
- Addr PC;
+ Addr 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/o3/bpred_unit_impl.hh b/src/cpu/o3/bpred_unit_impl.hh
index ed3471761..14d47df9f 100644
--- a/src/cpu/o3/bpred_unit_impl.hh
+++ b/src/cpu/o3/bpred_unit_impl.hh
@@ -31,6 +31,7 @@
#include <algorithm>
#include "arch/types.hh"
+#include "arch/utility.hh"
#include "arch/isa_traits.hh"
#include "base/trace.hh"
#include "base/traceflags.hh"
@@ -144,17 +145,15 @@ BPredUnit<Impl>::takeOverFrom()
template <class Impl>
bool
-BPredUnit<Impl>::predict(DynInstPtr &inst, Addr &PC, ThreadID tid)
+BPredUnit<Impl>::predict(DynInstPtr &inst, TheISA::PCState &pc, ThreadID tid)
{
// See if branch predictor predicts taken.
// If so, get its target addr either from the BTB or the RAS.
// Save off record of branch stuff so the RAS can be fixed
// up once it's done.
- using TheISA::MachInst;
-
bool pred_taken = false;
- Addr target = PC;
+ TheISA::PCState target = pc;
++lookups;
@@ -168,19 +167,19 @@ BPredUnit<Impl>::predict(DynInstPtr &inst, Addr &PC, ThreadID tid)
} else {
++condPredicted;
- pred_taken = BPLookup(PC, bp_history);
+ pred_taken = BPLookup(pc.instAddr(), bp_history);
DPRINTF(Fetch, "BranchPred: [tid:%i]: Branch predictor predicted %i "
- "for PC %#x\n",
- tid, pred_taken, inst->readPC());
+ "for PC %s\n",
+ tid, pred_taken, inst->pcState());
}
DPRINTF(Fetch, "BranchPred: [tid:%i]: [sn:%i] Creating prediction history "
- "for PC %#x\n",
- tid, inst->seqNum, inst->readPC());
+ "for PC %s\n",
+ tid, inst->seqNum, inst->pcState());
- PredictorHistory predict_record(inst->seqNum, PC, pred_taken,
- bp_history, tid);
+ PredictorHistory predict_record(inst->seqNum, pc.instAddr(),
+ pred_taken, bp_history, tid);
// Now lookup in the BTB or RAS.
if (pred_taken) {
@@ -189,60 +188,58 @@ BPredUnit<Impl>::predict(DynInstPtr &inst, Addr &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(pc, 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(Fetch, "BranchPred: [tid:%i]: Instruction %#x is a return, "
- "RAS predicted target: %#x, RAS index: %i.\n",
- tid, inst->readPC(), target, predict_record.RASIndex);
+ DPRINTF(Fetch, "BranchPred: [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 = PC + (2 * sizeof(MachInst)); // Next Next PC
-#else
- Addr ras_pc = PC + sizeof(MachInst); // Next PC
-#endif
- RAS[tid].push(ras_pc);
+ RAS[tid].push(pc);
// 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(Fetch, "BranchPred: [tid:%i]: Instruction %#x was a call"
- ", adding %#x to the RAS index: %i.\n",
- tid, inst->readPC(), ras_pc, RAS[tid].topIdx());
+ DPRINTF(Fetch, "BranchPred: [tid:%i]: Instruction %s was a "
+ "call, adding %s to the RAS index: %i.\n",
+ tid, inst->pcState(), pc, RAS[tid].topIdx());
}
- if (BTB.valid(PC, tid)) {
+ if (BTB.valid(pc.instAddr(), tid)) {
++BTBHits;
// If it's not a return, use the BTB to get the target addr.
- target = BTB.lookup(PC, tid);
+ target = BTB.lookup(pc.instAddr(), tid);
- DPRINTF(Fetch, "BranchPred: [tid:%i]: Instruction %#x predicted"
- " target is %#x.\n",
- tid, inst->readPC(), target);
+ DPRINTF(Fetch, "BranchPred: [tid:%i]: Instruction %s predicted"
+ " target is %s.\n", tid, inst->pcState(), target);
} else {
DPRINTF(Fetch, "BranchPred: [tid:%i]: BTB doesn't have a "
"valid entry.\n",tid);
pred_taken = false;
+ TheISA::advancePC(target, inst->staticInst);
}
}
+ } else {
+ TheISA::advancePC(target, inst->staticInst);
}
- PC = target;
+ pc = target;
predHist[tid].push_front(predict_record);
@@ -262,7 +259,7 @@ BPredUnit<Impl>::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,
predHist[tid].back().predTaken,
predHist[tid].back().bpHistory);
@@ -280,10 +277,8 @@ BPredUnit<Impl>::squash(const InstSeqNum &squashed_sn, ThreadID tid)
pred_hist.front().seqNum > squashed_sn) {
if (pred_hist.front().usedRAS) {
DPRINTF(Fetch, "BranchPred: [tid:%i]: Restoring top of RAS to: %i,"
- " target: %#x.\n",
- tid,
- pred_hist.front().RASIndex,
- pred_hist.front().RASTarget);
+ " target: %s.\n", tid,
+ pred_hist.front().RASIndex, pred_hist.front().RASTarget);
RAS[tid].restore(pred_hist.front().RASIndex,
pred_hist.front().RASTarget);
@@ -298,11 +293,13 @@ BPredUnit<Impl>::squash(const InstSeqNum &squashed_sn, ThreadID tid)
BPSquash(pred_hist.front().bpHistory);
DPRINTF(Fetch, "BranchPred: [tid:%i]: Removing history for [sn:%i] "
- "PC %#x.\n", tid, pred_hist.front().seqNum, pred_hist.front().PC);
+ "PC %s.\n", tid, pred_hist.front().seqNum,
+ pred_hist.front().pc);
pred_hist.pop_front();
- DPRINTF(Fetch, "[tid:%i]: predHist.size(): %i\n", tid, predHist[tid].size());
+ DPRINTF(Fetch, "[tid:%i]: predHist.size(): %i\n",
+ tid, predHist[tid].size());
}
}
@@ -310,7 +307,7 @@ BPredUnit<Impl>::squash(const InstSeqNum &squashed_sn, ThreadID tid)
template <class Impl>
void
BPredUnit<Impl>::squash(const InstSeqNum &squashed_sn,
- const Addr &corr_target,
+ const TheISA::PCState &corrTarget,
bool actually_taken,
ThreadID tid)
{
@@ -330,8 +327,8 @@ BPredUnit<Impl>::squash(const InstSeqNum &squashed_sn,
++condIncorrect;
DPRINTF(Fetch, "BranchPred: [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 All Branches AFTER this mispredicted branch
squash(squashed_sn, tid);
@@ -358,13 +355,13 @@ BPredUnit<Impl>::squash(const InstSeqNum &squashed_sn,
++RASIncorrect;
}
- BPUpdate((*hist_it).PC, actually_taken,
+ BPUpdate((*hist_it).pc, actually_taken,
pred_hist.front().bpHistory);
- BTB.update((*hist_it).PC, corr_target, tid);
+ BTB.update((*hist_it).pc, corrTarget, tid);
DPRINTF(Fetch, "BranchPred: [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);
@@ -397,12 +394,12 @@ BPredUnit<Impl>::BPSquash(void *bp_history)
template <class Impl>
bool
-BPredUnit<Impl>::BPLookup(Addr &inst_PC, void * &bp_history)
+BPredUnit<Impl>::BPLookup(Addr instPC, void * &bp_history)
{
if (predictor == Local) {
- return localBP->lookup(inst_PC, bp_history);
+ return localBP->lookup(instPC, bp_history);
} else if (predictor == Tournament) {
- return tournamentBP->lookup(inst_PC, bp_history);
+ return tournamentBP->lookup(instPC, bp_history);
} else {
panic("Predictor type is unexpected value!");
}
@@ -410,12 +407,12 @@ BPredUnit<Impl>::BPLookup(Addr &inst_PC, void * &bp_history)
template <class Impl>
void
-BPredUnit<Impl>::BPUpdate(Addr &inst_PC, bool taken, void *bp_history)
+BPredUnit<Impl>::BPUpdate(Addr instPC, bool taken, void *bp_history)
{
if (predictor == Local) {
- localBP->update(inst_PC, taken, bp_history);
+ localBP->update(instPC, taken, bp_history);
} else if (predictor == Tournament) {
- tournamentBP->update(inst_PC, taken, bp_history);
+ tournamentBP->update(instPC, taken, bp_history);
} else {
panic("Predictor type is unexpected value!");
}
@@ -436,9 +433,9 @@ BPredUnit<Impl>::dump()
while (pred_hist_it != predHist[i].end()) {
cprintf("[sn:%lli], PC:%#x, tid:%i, predTaken:%i, "
"bpHistory:%#x\n",
- (*pred_hist_it).seqNum, (*pred_hist_it).PC,
- (*pred_hist_it).tid, (*pred_hist_it).predTaken,
- (*pred_hist_it).bpHistory);
+ pred_hist_it->seqNum, pred_hist_it->pc,
+ pred_hist_it->tid, pred_hist_it->predTaken,
+ pred_hist_it->bpHistory);
pred_hist_it++;
}
diff --git a/src/cpu/o3/comm.hh b/src/cpu/o3/comm.hh
index 23b836f73..c9fb3319b 100644
--- a/src/cpu/o3/comm.hh
+++ b/src/cpu/o3/comm.hh
@@ -33,6 +33,7 @@
#include <vector>
+#include "arch/types.hh"
#include "base/types.hh"
#include "cpu/inst_seq.hh"
#include "sim/faults.hh"
@@ -88,9 +89,7 @@ struct DefaultIEWDefaultCommit {
bool branchMispredict[Impl::MaxThreads];
bool branchTaken[Impl::MaxThreads];
Addr mispredPC[Impl::MaxThreads];
- Addr nextPC[Impl::MaxThreads];
- Addr nextNPC[Impl::MaxThreads];
- Addr nextMicroPC[Impl::MaxThreads];
+ TheISA::PCState pc[Impl::MaxThreads];
InstSeqNum squashedSeqNum[Impl::MaxThreads];
bool includeSquashInst[Impl::MaxThreads];
@@ -120,9 +119,7 @@ struct TimeBufStruct {
bool branchMispredict;
bool branchTaken;
Addr mispredPC;
- Addr nextPC;
- Addr nextNPC;
- Addr nextMicroPC;
+ TheISA::PCState nextPC;
unsigned branchCount;
};
@@ -161,9 +158,7 @@ struct TimeBufStruct {
bool branchMispredict;
bool branchTaken;
Addr mispredPC;
- Addr nextPC;
- Addr nextNPC;
- Addr nextMicroPC;
+ TheISA::PCState pc;
// Represents the instruction that has either been retired or
// squashed. Similar to having a single bus that broadcasts the
diff --git a/src/cpu/o3/commit.hh b/src/cpu/o3/commit.hh
index d93b85984..326f3a1d3 100644
--- a/src/cpu/o3/commit.hh
+++ b/src/cpu/o3/commit.hh
@@ -277,40 +277,21 @@ class DefaultCommit
ThreadID oldestReady();
public:
- /** Returns the PC of the head instruction of the ROB.
- * @todo: Probably remove this function as it returns only thread 0.
- */
- Addr readPC() { return PC[0]; }
-
- /** Returns the PC of a specific thread. */
- Addr readPC(ThreadID tid) { return PC[tid]; }
+ /** Reads the PC of a specific thread. */
+ TheISA::PCState pcState(ThreadID tid) { return pc[tid]; }
/** Sets the PC of a specific thread. */
- void setPC(Addr val, ThreadID tid) { PC[tid] = val; }
-
- /** Reads the micro PC of a specific thread. */
- Addr readMicroPC(ThreadID tid) { return microPC[tid]; }
-
- /** Sets the micro PC of a specific thread */
- void setMicroPC(Addr val, ThreadID tid) { microPC[tid] = val; }
-
- /** Reads the next PC of a specific thread. */
- Addr readNextPC(ThreadID tid) { return nextPC[tid]; }
-
- /** Sets the next PC of a specific thread. */
- void setNextPC(Addr val, ThreadID tid) { nextPC[tid] = val; }
+ void pcState(const TheISA::PCState &val, ThreadID tid)
+ { pc[tid] = val; }
- /** Reads the next NPC of a specific thread. */
- Addr readNextNPC(ThreadID tid) { return nextNPC[tid]; }
+ /** Returns the PC of a specific thread. */
+ Addr instAddr(ThreadID tid) { return pc[tid].instAddr(); }
- /** Sets the next NPC of a specific thread. */
- void setNextNPC(Addr val, ThreadID tid) { nextNPC[tid] = val; }
+ /** Returns the next PC of a specific thread. */
+ Addr nextInstAddr(ThreadID tid) { return pc[tid].nextInstAddr(); }
/** Reads the micro PC of a specific thread. */
- Addr readNextMicroPC(ThreadID tid) { return nextMicroPC[tid]; }
-
- /** Sets the micro PC of a specific thread */
- void setNextMicroPC(Addr val, ThreadID tid) { nextMicroPC[tid] = val; }
+ Addr microPC(ThreadID tid) { return pc[tid].microPC(); }
private:
/** Time buffer interface. */
@@ -410,24 +391,10 @@ class DefaultCommit
/** The interrupt fault. */
Fault interrupt;
- /** The commit PC of each thread. Refers to the instruction that
- * is currently being processed/committed.
- */
- Addr PC[Impl::MaxThreads];
-
- /** The commit micro PC of each thread. Refers to the instruction that
+ /** The commit PC state of each thread. Refers to the instruction that
* is currently being processed/committed.
*/
- Addr microPC[Impl::MaxThreads];
-
- /** The next PC of each thread. */
- Addr nextPC[Impl::MaxThreads];
-
- /** The next NPC of each thread. */
- Addr nextNPC[Impl::MaxThreads];
-
- /** The next micro PC of each thread. */
- Addr nextMicroPC[Impl::MaxThreads];
+ TheISA::PCState pc[Impl::MaxThreads];
/** The sequence number of the youngest valid instruction in the ROB. */
InstSeqNum youngestSeqNum[Impl::MaxThreads];
diff --git a/src/cpu/o3/commit_impl.hh b/src/cpu/o3/commit_impl.hh
index 98c7b49c8..8d3edfb19 100644
--- a/src/cpu/o3/commit_impl.hh
+++ b/src/cpu/o3/commit_impl.hh
@@ -128,11 +128,7 @@ DefaultCommit<Impl>::DefaultCommit(O3CPU *_cpu, DerivO3CPUParams *params)
committedStores[tid] = false;
trapSquash[tid] = false;
tcSquash[tid] = false;
- microPC[tid] = 0;
- nextMicroPC[tid] = 0;
- PC[tid] = 0;
- nextPC[tid] = 0;
- nextNPC[tid] = 0;
+ pc[tid].set(0);
}
#if FULL_SYSTEM
interrupt = NoFault;
@@ -513,9 +509,7 @@ DefaultCommit<Impl>::squashAll(ThreadID tid)
toIEW->commitInfo[tid].branchMispredict = false;
- toIEW->commitInfo[tid].nextPC = PC[tid];
- toIEW->commitInfo[tid].nextNPC = nextPC[tid];
- toIEW->commitInfo[tid].nextMicroPC = nextMicroPC[tid];
+ toIEW->commitInfo[tid].pc = pc[tid];
}
template <class Impl>
@@ -524,7 +518,7 @@ DefaultCommit<Impl>::squashFromTrap(ThreadID tid)
{
squashAll(tid);
- DPRINTF(Commit, "Squashing from trap, restarting at PC %#x\n", PC[tid]);
+ DPRINTF(Commit, "Squashing from trap, restarting at PC %s\n", pc[tid]);
thread[tid]->trapPending = false;
thread[tid]->inSyscall = false;
@@ -542,7 +536,7 @@ DefaultCommit<Impl>::squashFromTC(ThreadID tid)
{
squashAll(tid);
- DPRINTF(Commit, "Squashing from TC, restarting at PC %#x\n", PC[tid]);
+ DPRINTF(Commit, "Squashing from TC, restarting at PC %s\n", pc[tid]);
thread[tid]->inSyscall = false;
assert(!thread[tid]->trapPending);
@@ -611,16 +605,16 @@ DefaultCommit<Impl>::tick()
DynInstPtr inst = rob->readHeadInst(tid);
- DPRINTF(Commit,"[tid:%i]: Instruction [sn:%lli] PC %#x is head of"
+ DPRINTF(Commit,"[tid:%i]: Instruction [sn:%lli] PC %s is head of"
" ROB and ready to commit\n",
- tid, inst->seqNum, inst->readPC());
+ tid, inst->seqNum, inst->pcState());
} else if (!rob->isEmpty(tid)) {
DynInstPtr inst = rob->readHeadInst(tid);
DPRINTF(Commit,"[tid:%i]: Can't commit, Instruction [sn:%lli] PC "
- "%#x is head of ROB and not ready\n",
- tid, inst->seqNum, inst->readPC());
+ "%s is head of ROB and not ready\n",
+ tid, inst->seqNum, inst->pcState());
}
DPRINTF(Commit, "[tid:%i]: ROB has %d insts & %d free entries.\n",
@@ -738,7 +732,7 @@ DefaultCommit<Impl>::commit()
DPRINTF(Commit, "[tid:%i]: Redirecting to PC %#x\n",
tid,
- fromIEW->nextPC[tid]);
+ fromIEW->pc[tid].nextInstAddr());
commitStatus[tid] = ROBSquashing;
@@ -771,9 +765,7 @@ DefaultCommit<Impl>::commit()
toIEW->commitInfo[tid].branchTaken =
fromIEW->branchTaken[tid];
- toIEW->commitInfo[tid].nextPC = fromIEW->nextPC[tid];
- toIEW->commitInfo[tid].nextNPC = fromIEW->nextNPC[tid];
- toIEW->commitInfo[tid].nextMicroPC = fromIEW->nextMicroPC[tid];
+ toIEW->commitInfo[tid].pc = fromIEW->pc[tid];
toIEW->commitInfo[tid].mispredPC = fromIEW->mispredPC[tid];
@@ -880,10 +872,7 @@ DefaultCommit<Impl>::commitInsts()
// Record that the number of ROB entries has changed.
changedROBNumEntries[tid] = true;
} else {
- PC[tid] = head_inst->readPC();
- nextPC[tid] = head_inst->readNextPC();
- nextNPC[tid] = head_inst->readNextNPC();
- nextMicroPC[tid] = head_inst->readNextMicroPC();
+ pc[tid] = head_inst->pcState();
// Increment the total number of non-speculative instructions
// executed.
@@ -911,11 +900,7 @@ DefaultCommit<Impl>::commitInsts()
cpu->instDone(tid);
}
- PC[tid] = nextPC[tid];
- nextPC[tid] = nextNPC[tid];
- nextNPC[tid] = nextNPC[tid] + sizeof(TheISA::MachInst);
- microPC[tid] = nextMicroPC[tid];
- nextMicroPC[tid] = microPC[tid] + 1;
+ TheISA::advancePC(pc[tid], head_inst->staticInst);
int count = 0;
Addr oldpc;
@@ -923,19 +908,19 @@ DefaultCommit<Impl>::commitInsts()
// currently updating state while handling PC events.
assert(!thread[tid]->inSyscall && !thread[tid]->trapPending);
do {
- oldpc = PC[tid];
+ oldpc = pc[tid].instAddr();
cpu->system->pcEventQueue.service(thread[tid]->getTC());
count++;
- } while (oldpc != PC[tid]);
+ } while (oldpc != pc[tid].instAddr());
if (count > 1) {
DPRINTF(Commit,
"PC skip function event, stopping commit\n");
break;
}
} else {
- DPRINTF(Commit, "Unable to commit head instruction PC:%#x "
+ DPRINTF(Commit, "Unable to commit head instruction PC:%s "
"[tid:%i] [sn:%i].\n",
- head_inst->readPC(), tid ,head_inst->seqNum);
+ head_inst->pcState(), tid ,head_inst->seqNum);
break;
}
}
@@ -970,8 +955,8 @@ DefaultCommit<Impl>::commitHead(DynInstPtr &head_inst, unsigned inst_num)
head_inst->isWriteBarrier()) {
DPRINTF(Commit, "Encountered a barrier or non-speculative "
- "instruction [sn:%lli] at the head of the ROB, PC %#x.\n",
- head_inst->seqNum, head_inst->readPC());
+ "instruction [sn:%lli] at the head of the ROB, PC %s.\n",
+ head_inst->seqNum, head_inst->pcState());
if (inst_num > 0 || iewStage->hasStoresToWB(tid)) {
DPRINTF(Commit, "Waiting for all stores to writeback.\n");
@@ -994,8 +979,8 @@ DefaultCommit<Impl>::commitHead(DynInstPtr &head_inst, unsigned inst_num)
}
assert(head_inst->uncacheable());
- DPRINTF(Commit, "[sn:%lli]: Uncached load, PC %#x.\n",
- head_inst->seqNum, head_inst->readPC());
+ DPRINTF(Commit, "[sn:%lli]: Uncached load, PC %s.\n",
+ head_inst->seqNum, head_inst->pcState());
// Send back the non-speculative instruction's sequence
// number. Tell the lsq to re-execute the load.
@@ -1034,8 +1019,8 @@ DefaultCommit<Impl>::commitHead(DynInstPtr &head_inst, unsigned inst_num)
#endif
if (inst_fault != NoFault) {
- DPRINTF(Commit, "Inst [sn:%lli] PC %#x has a fault\n",
- head_inst->seqNum, head_inst->readPC());
+ DPRINTF(Commit, "Inst [sn:%lli] PC %s has a fault\n",
+ head_inst->seqNum, head_inst->pcState());
if (iewStage->hasStoresToWB(tid) || inst_num > 0) {
DPRINTF(Commit, "Stores outstanding, fault must wait.\n");
@@ -1081,7 +1066,6 @@ DefaultCommit<Impl>::commitHead(DynInstPtr &head_inst, unsigned inst_num)
// Generate trap squash event.
generateTrapEvent(tid);
-// warn("%lli fault (%d) handled @ PC %08p", curTick, inst_fault->name(), head_inst->readPC());
return false;
}
@@ -1089,9 +1073,7 @@ DefaultCommit<Impl>::commitHead(DynInstPtr &head_inst, unsigned inst_num)
#if FULL_SYSTEM
if (thread[tid]->profile) {
-// bool usermode = TheISA::inUserMode(thread[tid]->getTC());
-// thread[tid]->profilePC = usermode ? 1 : head_inst->readPC();
- thread[tid]->profilePC = head_inst->readPC();
+ thread[tid]->profilePC = head_inst->instAddr();
ProfileNode *node = thread[tid]->profile->consume(thread[tid]->getTC(),
head_inst->staticInst);
@@ -1101,7 +1083,7 @@ DefaultCommit<Impl>::commitHead(DynInstPtr &head_inst, unsigned inst_num)
if (CPA::available()) {
if (head_inst->isControl()) {
ThreadContext *tc = thread[tid]->getTC();
- CPA::cpa()->swAutoBegin(tc, head_inst->readNextPC());
+ CPA::cpa()->swAutoBegin(tc, head_inst->nextInstAddr());
}
}
#endif
@@ -1154,8 +1136,8 @@ DefaultCommit<Impl>::getInsts()
commitStatus[tid] != TrapPending) {
changedROBNumEntries[tid] = true;
- DPRINTF(Commit, "Inserting PC %#x [sn:%i] [tid:%i] into ROB.\n",
- inst->readPC(), inst->seqNum, tid);
+ DPRINTF(Commit, "Inserting PC %s [sn:%i] [tid:%i] into ROB.\n",
+ inst->pcState(), inst->seqNum, tid);
rob->insertInst(inst);
@@ -1163,9 +1145,9 @@ DefaultCommit<Impl>::getInsts()
youngestSeqNum[tid] = inst->seqNum;
} else {
- DPRINTF(Commit, "Instruction PC %#x [sn:%i] [tid:%i] was "
+ DPRINTF(Commit, "Instruction PC %s [sn:%i] [tid:%i] was "
"squashed, skipping.\n",
- inst->readPC(), inst->seqNum, tid);
+ inst->pcState(), inst->seqNum, tid);
}
}
}
@@ -1181,14 +1163,14 @@ DefaultCommit<Impl>::skidInsert()
DynInstPtr inst = fromRename->insts[inst_num];
if (!inst->isSquashed()) {
- DPRINTF(Commit, "Inserting PC %#x [sn:%i] [tid:%i] into ",
- "skidBuffer.\n", inst->readPC(), inst->seqNum,
+ DPRINTF(Commit, "Inserting PC %s [sn:%i] [tid:%i] into ",
+ "skidBuffer.\n", inst->pcState(), inst->seqNum,
inst->threadNumber);
skidBuffer.push(inst);
} else {
- DPRINTF(Commit, "Instruction PC %#x [sn:%i] [tid:%i] was "
+ DPRINTF(Commit, "Instruction PC %s [sn:%i] [tid:%i] was "
"squashed, skipping.\n",
- inst->readPC(), inst->seqNum, inst->threadNumber);
+ inst->pcState(), inst->seqNum, inst->threadNumber);
}
}
}
@@ -1204,10 +1186,10 @@ DefaultCommit<Impl>::markCompletedInsts()
++inst_num)
{
if (!fromIEW->insts[inst_num]->isSquashed()) {
- DPRINTF(Commit, "[tid:%i]: Marking PC %#x, [sn:%lli] ready "
+ DPRINTF(Commit, "[tid:%i]: Marking PC %s, [sn:%lli] ready "
"within ROB.\n",
fromIEW->insts[inst_num]->threadNumber,
- fromIEW->insts[inst_num]->readPC(),
+ fromIEW->insts[inst_num]->pcState(),
fromIEW->insts[inst_num]->seqNum);
// Mark the instruction as ready to commit.
diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc
index 8e9f3ef5d..21c5cc706 100644
--- a/src/cpu/o3/cpu.cc
+++ b/src/cpu/o3/cpu.cc
@@ -732,9 +732,7 @@ FullO3CPU<Impl>::insertThread(ThreadID tid)
//this->copyFromTC(tid);
//Set PC/NPC/NNPC
- setPC(src_tc->readPC(), tid);
- setNextPC(src_tc->readNextPC(), tid);
- setNextNPC(src_tc->readNextNPC(), tid);
+ pcState(src_tc->pcState(), tid);
src_tc->setStatus(ThreadContext::Active);
@@ -778,7 +776,7 @@ FullO3CPU<Impl>::removeThread(ThreadID tid)
// Squash Throughout Pipeline
InstSeqNum squash_seq_num = commit.rob->readHeadInst(tid)->seqNum;
- fetch.squash(0, sizeof(TheISA::MachInst), 0, squash_seq_num, tid);
+ fetch.squash(0, squash_seq_num, tid);
decode.squash(tid);
rename.squash(squash_seq_num, tid);
iew.squash(tid);
@@ -1306,73 +1304,38 @@ FullO3CPU<Impl>::setArchFloatRegInt(int reg_idx, uint64_t val, ThreadID tid)
}
template <class Impl>
-uint64_t
-FullO3CPU<Impl>::readPC(ThreadID tid)
+TheISA::PCState
+FullO3CPU<Impl>::pcState(ThreadID tid)
{
- return commit.readPC(tid);
+ return commit.pcState(tid);
}
template <class Impl>
void
-FullO3CPU<Impl>::setPC(Addr new_PC, ThreadID tid)
-{
- commit.setPC(new_PC, tid);
-}
-
-template <class Impl>
-uint64_t
-FullO3CPU<Impl>::readMicroPC(ThreadID tid)
+FullO3CPU<Impl>::pcState(const TheISA::PCState &val, ThreadID tid)
{
- return commit.readMicroPC(tid);
+ commit.pcState(val, tid);
}
template <class Impl>
-void
-FullO3CPU<Impl>::setMicroPC(Addr new_PC, ThreadID tid)
+Addr
+FullO3CPU<Impl>::instAddr(ThreadID tid)
{
- commit.setMicroPC(new_PC, tid);
+ return commit.instAddr(tid);
}
template <class Impl>
-uint64_t
-FullO3CPU<Impl>::readNextPC(ThreadID tid)
+Addr
+FullO3CPU<Impl>::nextInstAddr(ThreadID tid)
{
- return commit.readNextPC(tid);
+ return commit.nextInstAddr(tid);
}
template <class Impl>
-void
-FullO3CPU<Impl>::setNextPC(uint64_t val, ThreadID tid)
-{
- commit.setNextPC(val, tid);
-}
-
-template <class Impl>
-uint64_t
-FullO3CPU<Impl>::readNextNPC(ThreadID tid)
-{
- return commit.readNextNPC(tid);
-}
-
-template <class Impl>
-void
-FullO3CPU<Impl>::setNextNPC(uint64_t val, ThreadID tid)
-{
- commit.setNextNPC(val, tid);
-}
-
-template <class Impl>
-uint64_t
-FullO3CPU<Impl>::readNextMicroPC(ThreadID tid)
-{
- return commit.readNextMicroPC(tid);
-}
-
-template <class Impl>
-void
-FullO3CPU<Impl>::setNextMicroPC(Addr new_PC, ThreadID tid)
+MicroPC
+FullO3CPU<Impl>::microPC(ThreadID tid)
{
- commit.setNextMicroPC(new_PC, tid);
+ return commit.microPC(tid);
}
template <class Impl>
@@ -1419,9 +1382,9 @@ template <class Impl>
void
FullO3CPU<Impl>::removeFrontInst(DynInstPtr &inst)
{
- DPRINTF(O3CPU, "Removing committed instruction [tid:%i] PC %#x "
+ DPRINTF(O3CPU, "Removing committed instruction [tid:%i] PC %s "
"[sn:%lli]\n",
- inst->threadNumber, inst->readPC(), inst->seqNum);
+ inst->threadNumber, inst->pcState(), inst->seqNum);
removeInstsThisCycle = true;
@@ -1509,10 +1472,10 @@ FullO3CPU<Impl>::squashInstIt(const ListIt &instIt, ThreadID tid)
{
if ((*instIt)->threadNumber == tid) {
DPRINTF(O3CPU, "Squashing instruction, "
- "[tid:%i] [sn:%lli] PC %#x\n",
+ "[tid:%i] [sn:%lli] PC %s\n",
(*instIt)->threadNumber,
(*instIt)->seqNum,
- (*instIt)->readPC());
+ (*instIt)->pcState());
// Mark it as squashed.
(*instIt)->setSquashed();
@@ -1530,10 +1493,10 @@ FullO3CPU<Impl>::cleanUpRemovedInsts()
{
while (!removeList.empty()) {
DPRINTF(O3CPU, "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());
instList.erase(removeList.front());
@@ -1563,7 +1526,7 @@ FullO3CPU<Impl>::dumpInsts()
while (inst_list_it != instList.end()) {
cprintf("Instruction:%i\nPC:%#x\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)->instAddr(), (*inst_list_it)->threadNumber,
(*inst_list_it)->seqNum, (*inst_list_it)->isIssued(),
(*inst_list_it)->isSquashed());
inst_list_it++;
diff --git a/src/cpu/o3/cpu.hh b/src/cpu/o3/cpu.hh
index 57c07a9ec..2669016ff 100644
--- a/src/cpu/o3/cpu.hh
+++ b/src/cpu/o3/cpu.hh
@@ -444,35 +444,20 @@ class FullO3CPU : public BaseO3CPU
void setArchFloatRegInt(int reg_idx, uint64_t val, ThreadID tid);
- /** Reads the commit PC of a specific thread. */
- Addr readPC(ThreadID tid);
+ /** Sets the commit PC state of a specific thread. */
+ void pcState(const TheISA::PCState &newPCState, ThreadID tid);
- /** Sets the commit PC of a specific thread. */
- void setPC(Addr new_PC, ThreadID tid);
+ /** Reads the commit PC state of a specific thread. */
+ TheISA::PCState pcState(ThreadID tid);
- /** Reads the commit micro PC of a specific thread. */
- Addr readMicroPC(ThreadID tid);
+ /** Reads the commit PC of a specific thread. */
+ Addr instAddr(ThreadID tid);
- /** Sets the commmit micro PC of a specific thread. */
- void setMicroPC(Addr new_microPC, ThreadID tid);
+ /** Reads the commit micro PC of a specific thread. */
+ MicroPC microPC(ThreadID tid);
/** Reads the next PC of a specific thread. */
- Addr readNextPC(ThreadID tid);
-
- /** Sets the next PC of a specific thread. */
- void setNextPC(Addr val, ThreadID tid);
-
- /** Reads the next NPC of a specific thread. */
- Addr readNextNPC(ThreadID tid);
-
- /** Sets the next NPC of a specific thread. */
- void setNextNPC(Addr val, ThreadID tid);
-
- /** Reads the commit next micro PC of a specific thread. */
- Addr readNextMicroPC(ThreadID tid);
-
- /** Sets the commit next micro PC of a specific thread. */
- void setNextMicroPC(Addr val, ThreadID tid);
+ Addr nextInstAddr(ThreadID tid);
/** Initiates a squash of all in-flight instructions for a given
* thread. The source of the squash is an external update of
diff --git a/src/cpu/o3/decode_impl.hh b/src/cpu/o3/decode_impl.hh
index 1b76de132..5063e0f07 100644
--- a/src/cpu/o3/decode_impl.hh
+++ b/src/cpu/o3/decode_impl.hh
@@ -264,29 +264,16 @@ template<class Impl>
void
DefaultDecode<Impl>::squash(DynInstPtr &inst, ThreadID tid)
{
- DPRINTF(Decode, "[tid:%i]: [sn:%i] Squashing due to incorrect branch prediction "
- "detected at decode.\n", tid, inst->seqNum);
+ DPRINTF(Decode, "[tid:%i]: [sn:%i] Squashing due to incorrect branch "
+ "prediction detected at decode.\n", tid, inst->seqNum);
// Send back mispredict information.
toFetch->decodeInfo[tid].branchMispredict = true;
toFetch->decodeInfo[tid].predIncorrect = true;
toFetch->decodeInfo[tid].squash = true;
toFetch->decodeInfo[tid].doneSeqNum = inst->seqNum;
- toFetch->decodeInfo[tid].nextMicroPC = inst->readMicroPC();
-
-#if ISA_HAS_DELAY_SLOT
- toFetch->decodeInfo[tid].nextPC = inst->readPC() + sizeof(TheISA::MachInst);
- toFetch->decodeInfo[tid].nextNPC = inst->branchTarget();
- toFetch->decodeInfo[tid].branchTaken = inst->readNextNPC() !=
- (inst->readNextPC() + sizeof(TheISA::MachInst));
-#else
toFetch->decodeInfo[tid].nextPC = inst->branchTarget();
- toFetch->decodeInfo[tid].nextNPC =
- inst->branchTarget() + sizeof(TheISA::MachInst);
- toFetch->decodeInfo[tid].branchTaken =
- inst->readNextPC() != (inst->readPC() + sizeof(TheISA::MachInst));
-#endif
-
+ toFetch->decodeInfo[tid].branchTaken = inst->pcState().branching();
InstSeqNum squash_seq_num = inst->seqNum;
@@ -382,8 +369,8 @@ DefaultDecode<Impl>::skidInsert(ThreadID tid)
assert(tid == inst->threadNumber);
- DPRINTF(Decode,"Inserting [sn:%lli] PC:%#x into decode skidBuffer %i\n",
- inst->seqNum, inst->readPC(), inst->threadNumber);
+ DPRINTF(Decode,"Inserting [sn:%lli] PC: %s into decode skidBuffer %i\n",
+ inst->seqNum, inst->pcState(), inst->threadNumber);
skidBuffer[tid].push(inst);
}
@@ -681,13 +668,12 @@ DefaultDecode<Impl>::decodeInsts(ThreadID tid)
insts_to_decode.pop();
DPRINTF(Decode, "[tid:%u]: Processing instruction [sn:%lli] with "
- "PC %#x\n",
- tid, inst->seqNum, inst->readPC());
+ "PC %s\n", tid, inst->seqNum, inst->pcState());
if (inst->isSquashed()) {
- DPRINTF(Decode, "[tid:%u]: Instruction %i with PC %#x is "
+ DPRINTF(Decode, "[tid:%u]: Instruction %i with PC %s is "
"squashed, skipping.\n",
- tid, inst->seqNum, inst->readPC());
+ tid, inst->seqNum, inst->pcState());
++decodeSquashedInsts;
@@ -717,9 +703,6 @@ DefaultDecode<Impl>::decodeInsts(ThreadID tid)
// Ensure that if it was predicted as a branch, it really is a
// branch.
if (inst->readPredTaken() && !inst->isControl()) {
- DPRINTF(Decode, "PredPC : %#x != NextPC: %#x\n",
- inst->readPredPC(), inst->readNextPC() + 4);
-
panic("Instruction predicted as a branch!");
++decodeControlMispred;
@@ -735,26 +718,18 @@ DefaultDecode<Impl>::decodeInsts(ThreadID tid)
if (inst->isDirectCtrl() && inst->isUncondCtrl()) {
++decodeBranchResolved;
- if (inst->branchTarget() != inst->readPredPC()) {
+ if (!(inst->branchTarget() == inst->readPredTarg())) {
++decodeBranchMispred;
// Might want to set some sort of boolean and just do
// a check at the end
squash(inst, inst->threadNumber);
- Addr target = inst->branchTarget();
+ TheISA::PCState target = inst->branchTarget();
-#if ISA_HAS_DELAY_SLOT
- DPRINTF(Decode, "[sn:%i]: Updating predictions: PredPC: %#x PredNextPC: %#x\n",
- inst->seqNum, inst->readPC() + sizeof(TheISA::MachInst), target);
-
- //The micro pc after an instruction level branch should be 0
- inst->setPredTarg(inst->readPC() + sizeof(TheISA::MachInst), target, 0);
-#else
- DPRINTF(Decode, "[sn:%i]: Updating predictions: PredPC: %#x PredNextPC: %#x\n",
- inst->seqNum, target, target + sizeof(TheISA::MachInst));
+ DPRINTF(Decode, "[sn:%i]: Updating predictions: PredPC: %s\n",
+ inst->seqNum, target);
//The micro pc after an instruction level branch should be 0
- inst->setPredTarg(target, target + sizeof(TheISA::MachInst), 0);
-#endif
+ inst->setPredTarg(target);
break;
}
}
diff --git a/src/cpu/o3/dep_graph.hh b/src/cpu/o3/dep_graph.hh
index c19fd0abf..804b3f9cd 100644
--- a/src/cpu/o3/dep_graph.hh
+++ b/src/cpu/o3/dep_graph.hh
@@ -251,8 +251,8 @@ DependencyGraph<DynInstPtr>::dump()
curr = &dependGraph[i];
if (curr->inst) {
- cprintf("dependGraph[%i]: producer: %#x [sn:%lli] consumer: ",
- i, curr->inst->readPC(), curr->inst->seqNum);
+ cprintf("dependGraph[%i]: producer: %s [sn:%lli] consumer: ",
+ i, curr->inst->pcState(), curr->inst->seqNum);
} else {
cprintf("dependGraph[%i]: No producer. consumer: ", i);
}
@@ -260,8 +260,8 @@ DependencyGraph<DynInstPtr>::dump()
while (curr->next != NULL) {
curr = curr->next;
- cprintf("%#x [sn:%lli] ",
- curr->inst->readPC(), curr->inst->seqNum);
+ cprintf("%s [sn:%lli] ",
+ curr->inst->pcState(), curr->inst->seqNum);
}
cprintf("\n");
diff --git a/src/cpu/o3/dyn_inst.hh b/src/cpu/o3/dyn_inst.hh
index e1279f82b..6bd1f9fad 100644
--- a/src/cpu/o3/dyn_inst.hh
+++ b/src/cpu/o3/dyn_inst.hh
@@ -74,14 +74,14 @@ class BaseO3DynInst : public BaseDynInst<Impl>
public:
/** BaseDynInst constructor given a binary instruction. */
- BaseO3DynInst(StaticInstPtr staticInst, Addr PC, Addr NPC, Addr microPC,
- Addr Pred_PC, Addr Pred_NPC, Addr Pred_MicroPC,
- InstSeqNum seq_num, O3CPU *cpu);
+ BaseO3DynInst(StaticInstPtr staticInst,
+ TheISA::PCState pc, TheISA::PCState predPC,
+ InstSeqNum seq_num, O3CPU *cpu);
/** BaseDynInst constructor given a binary instruction. */
- BaseO3DynInst(ExtMachInst inst, Addr PC, Addr NPC, Addr microPC,
- Addr Pred_PC, Addr Pred_NPC, Addr Pred_MicroPC,
- InstSeqNum seq_num, O3CPU *cpu);
+ BaseO3DynInst(ExtMachInst inst,
+ TheISA::PCState pc, TheISA::PCState predPC,
+ InstSeqNum seq_num, O3CPU *cpu);
/** BaseDynInst constructor given a static inst pointer. */
BaseO3DynInst(StaticInstPtr &_staticInst);
diff --git a/src/cpu/o3/dyn_inst_impl.hh b/src/cpu/o3/dyn_inst_impl.hh
index 3e015d962..6f7c23b2f 100644
--- a/src/cpu/o3/dyn_inst_impl.hh
+++ b/src/cpu/o3/dyn_inst_impl.hh
@@ -33,24 +33,18 @@
template <class Impl>
BaseO3DynInst<Impl>::BaseO3DynInst(StaticInstPtr staticInst,
- Addr PC, Addr NPC, Addr microPC,
- Addr Pred_PC, Addr Pred_NPC,
- Addr Pred_MicroPC,
+ TheISA::PCState pc, TheISA::PCState predPC,
InstSeqNum seq_num, O3CPU *cpu)
- : BaseDynInst<Impl>(staticInst, PC, NPC, microPC,
- Pred_PC, Pred_NPC, Pred_MicroPC, seq_num, cpu)
+ : BaseDynInst<Impl>(staticInst, pc, predPC, seq_num, cpu)
{
initVars();
}
template <class Impl>
BaseO3DynInst<Impl>::BaseO3DynInst(ExtMachInst inst,
- Addr PC, Addr NPC, Addr microPC,
- Addr Pred_PC, Addr Pred_NPC,
- Addr Pred_MicroPC,
+ TheISA::PCState pc, TheISA::PCState predPC,
InstSeqNum seq_num, O3CPU *cpu)
- : BaseDynInst<Impl>(inst, PC, NPC, microPC,
- Pred_PC, Pred_NPC, Pred_MicroPC, seq_num, cpu)
+ : BaseDynInst<Impl>(inst, pc, predPC, seq_num, cpu)
{
initVars();
}
@@ -131,15 +125,17 @@ BaseO3DynInst<Impl>::hwrei()
{
#if THE_ISA == ALPHA_ISA
// Can only do a hwrei when in pal mode.
- if (!(this->readPC() & 0x3))
+ if (!(this->instAddr() & 0x3))
return new AlphaISA::UnimplementedOpcodeFault;
// Set the next PC based on the value of the EXC_ADDR IPR.
- this->setNextPC(this->cpu->readMiscRegNoEffect(AlphaISA::IPR_EXC_ADDR,
- this->threadNumber));
+ AlphaISA::PCState pc = this->pcState();
+ pc.npc(this->cpu->readMiscRegNoEffect(AlphaISA::IPR_EXC_ADDR,
+ this->threadNumber));
+ this->pcState(pc);
if (CPA::available()) {
ThreadContext *tc = this->cpu->tcBase(this->threadNumber);
- CPA::cpa()->swAutoBegin(tc, this->readNextPC());
+ CPA::cpa()->swAutoBegin(tc, this->nextInstAddr());
}
// Tell CPU to clear any state it needs to if a hwrei is taken.
@@ -175,11 +171,11 @@ BaseO3DynInst<Impl>::syscall(int64_t callnum)
// HACK: check CPU's nextPC before and after syscall. If it
// changes, update this instruction's nextPC because the syscall
// must have changed the nextPC.
- Addr cpu_next_pc = this->cpu->readNextPC(this->threadNumber);
+ TheISA::PCState curPC = this->cpu->pcState(this->threadNumber);
this->cpu->syscall(callnum, this->threadNumber);
- Addr new_next_pc = this->cpu->readNextPC(this->threadNumber);
- if (cpu_next_pc != new_next_pc) {
- this->setNextPC(new_next_pc);
+ TheISA::PCState newPC = this->cpu->pcState(this->threadNumber);
+ if (!(curPC == newPC)) {
+ this->pcState(newPC);
}
}
#endif
diff --git a/src/cpu/o3/fetch.hh b/src/cpu/o3/fetch.hh
index d881c291f..22e9e51b4 100644
--- a/src/cpu/o3/fetch.hh
+++ b/src/cpu/o3/fetch.hh
@@ -229,7 +229,7 @@ class DefaultFetch
* @param next_NPC Used for ISAs which use delay slots.
* @return Whether or not a branch was predicted as taken.
*/
- bool lookupAndUpdateNextPC(DynInstPtr &inst, Addr &next_PC, Addr &next_NPC, Addr &next_MicroPC);
+ bool lookupAndUpdateNextPC(DynInstPtr &inst, TheISA::PCState &pc);
/**
* Fetches the cache line that contains fetch_PC. Returns any
@@ -244,14 +244,12 @@ class DefaultFetch
bool fetchCacheLine(Addr fetch_PC, Fault &ret_fault, ThreadID tid);
/** Squashes a specific thread and resets the PC. */
- inline void doSquash(const Addr &new_PC, const Addr &new_NPC,
- const Addr &new_MicroPC, ThreadID tid);
+ inline void doSquash(const TheISA::PCState &newPC, ThreadID tid);
/** Squashes a specific thread and resets the PC. Also tells the CPU to
* remove any instructions between fetch and decode that should be sqaushed.
*/
- void squashFromDecode(const Addr &new_PC, const Addr &new_NPC,
- const Addr &new_MicroPC,
+ void squashFromDecode(const TheISA::PCState &newPC,
const InstSeqNum &seq_num, ThreadID tid);
/** Checks if a thread is stalled. */
@@ -266,8 +264,7 @@ class DefaultFetch
* remove any instructions that are not in the ROB. The source of this
* squash should be the commit stage.
*/
- void squash(const Addr &new_PC, const Addr &new_NPC,
- const Addr &new_MicroPC,
+ void squash(const TheISA::PCState &newPC,
const InstSeqNum &seq_num, ThreadID tid);
/** Ticks the fetch stage, processing all inputs signals and fetching
@@ -348,14 +345,7 @@ class DefaultFetch
/** Predecoder. */
TheISA::Predecoder predecoder;
- /** Per-thread fetch PC. */
- Addr PC[Impl::MaxThreads];
-
- /** Per-thread fetch micro PC. */
- Addr microPC[Impl::MaxThreads];
-
- /** Per-thread next PC. */
- Addr nextPC[Impl::MaxThreads];
+ TheISA::PCState pc[Impl::MaxThreads];
/** Memory request used to access cache. */
RequestPtr memReq[Impl::MaxThreads];
diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh
index 3f8f84cab..bbd9ce4a2 100644
--- a/src/cpu/o3/fetch_impl.hh
+++ b/src/cpu/o3/fetch_impl.hh
@@ -316,9 +316,7 @@ DefaultFetch<Impl>::initStage()
{
// Setup PC and nextPC with initial state.
for (ThreadID tid = 0; tid < numThreads; tid++) {
- PC[tid] = cpu->readPC(tid);
- nextPC[tid] = cpu->readNextPC(tid);
- microPC[tid] = cpu->readMicroPC(tid);
+ pc[tid] = cpu->pcState(tid);
}
for (ThreadID tid = 0; tid < numThreads; tid++) {
@@ -445,9 +443,7 @@ DefaultFetch<Impl>::takeOverFrom()
stalls[i].rename = 0;
stalls[i].iew = 0;
stalls[i].commit = 0;
- PC[i] = cpu->readPC(i);
- nextPC[i] = cpu->readNextPC(i);
- microPC[i] = cpu->readMicroPC(i);
+ pc[i] = cpu->pcState(i);
fetchStatus[i] = Running;
}
numInst = 0;
@@ -496,8 +492,8 @@ DefaultFetch<Impl>::switchToInactive()
template <class Impl>
bool
-DefaultFetch<Impl>::lookupAndUpdateNextPC(DynInstPtr &inst, Addr &next_PC,
- Addr &next_NPC, Addr &next_MicroPC)
+DefaultFetch<Impl>::lookupAndUpdateNextPC(
+ DynInstPtr &inst, TheISA::PCState &nextPC)
{
// Do branch prediction check here.
// A bit of a misnomer...next_PC is actually the current PC until
@@ -505,51 +501,26 @@ DefaultFetch<Impl>::lookupAndUpdateNextPC(DynInstPtr &inst, Addr &next_PC,
bool predict_taken;
if (!inst->isControl()) {
- if (inst->isMicroop() && !inst->isLastMicroop()) {
- next_MicroPC++;
- } else {
- next_PC = next_NPC;
- next_NPC = next_NPC + instSize;
- next_MicroPC = 0;
- }
- inst->setPredTarg(next_PC, next_NPC, next_MicroPC);
+ TheISA::advancePC(nextPC, inst->staticInst);
+ inst->setPredTarg(nextPC);
inst->setPredTaken(false);
return false;
}
- //Assume for now that all control flow is to a different macroop which
- //would reset the micro pc to 0.
- next_MicroPC = 0;
-
ThreadID tid = inst->threadNumber;
- Addr pred_PC = next_PC;
- predict_taken = branchPred.predict(inst, pred_PC, tid);
+ predict_taken = branchPred.predict(inst, nextPC, tid);
if (predict_taken) {
- DPRINTF(Fetch, "[tid:%i]: [sn:%i]: Branch predicted to be taken to %#x.\n",
- tid, inst->seqNum, pred_PC);
+ DPRINTF(Fetch, "[tid:%i]: [sn:%i]: Branch predicted to be taken to %s.\n",
+ tid, inst->seqNum, nextPC);
} else {
DPRINTF(Fetch, "[tid:%i]: [sn:%i]:Branch predicted to be not taken.\n",
tid, inst->seqNum);
}
-#if ISA_HAS_DELAY_SLOT
- next_PC = next_NPC;
- if (predict_taken)
- next_NPC = pred_PC;
- else
- next_NPC += instSize;
-#else
- if (predict_taken)
- next_PC = pred_PC;
- else
- next_PC += instSize;
- next_NPC = next_PC + instSize;
-#endif
-
- DPRINTF(Fetch, "[tid:%i]: [sn:%i] Branch predicted to go to %#x and then %#x.\n",
- tid, inst->seqNum, next_PC, next_NPC);
- inst->setPredTarg(next_PC, next_NPC, next_MicroPC);
+ DPRINTF(Fetch, "[tid:%i]: [sn:%i] Branch predicted to go to %s.\n",
+ tid, inst->seqNum, nextPC);
+ inst->setPredTarg(nextPC);
inst->setPredTaken(predict_taken);
++fetchedBranches;
@@ -668,15 +639,12 @@ DefaultFetch<Impl>::fetchCacheLine(Addr fetch_PC, Fault &ret_fault, ThreadID tid
template <class Impl>
inline void
-DefaultFetch<Impl>::doSquash(const Addr &new_PC,
- const Addr &new_NPC, const Addr &new_microPC, ThreadID tid)
+DefaultFetch<Impl>::doSquash(const TheISA::PCState &newPC, ThreadID tid)
{
- DPRINTF(Fetch, "[tid:%i]: Squashing, setting PC to: %#x, NPC to: %#x.\n",
- tid, new_PC, new_NPC);
+ DPRINTF(Fetch, "[tid:%i]: Squashing, setting PC to: %s.\n",
+ tid, newPC);
- PC[tid] = new_PC;
- nextPC[tid] = new_NPC;
- microPC[tid] = new_microPC;
+ pc[tid] = newPC;
// Clear the icache miss if it's outstanding.
if (fetchStatus[tid] == IcacheWaitResponse) {
@@ -703,13 +671,12 @@ DefaultFetch<Impl>::doSquash(const Addr &new_PC,
template<class Impl>
void
-DefaultFetch<Impl>::squashFromDecode(const Addr &new_PC, const Addr &new_NPC,
- const Addr &new_MicroPC,
+DefaultFetch<Impl>::squashFromDecode(const TheISA::PCState &newPC,
const InstSeqNum &seq_num, ThreadID tid)
{
- DPRINTF(Fetch, "[tid:%i]: Squashing from decode.\n",tid);
+ DPRINTF(Fetch, "[tid:%i]: Squashing from decode.\n", tid);
- doSquash(new_PC, new_NPC, new_MicroPC, tid);
+ doSquash(newPC, tid);
// Tell the CPU to remove any instructions that are in flight between
// fetch and decode.
@@ -784,13 +751,12 @@ DefaultFetch<Impl>::updateFetchStatus()
template <class Impl>
void
-DefaultFetch<Impl>::squash(const Addr &new_PC, const Addr &new_NPC,
- const Addr &new_MicroPC,
+DefaultFetch<Impl>::squash(const TheISA::PCState &newPC,
const InstSeqNum &seq_num, ThreadID tid)
{
- DPRINTF(Fetch, "[tid:%u]: Squash from commit.\n",tid);
+ DPRINTF(Fetch, "[tid:%u]: Squash from commit.\n", tid);
- doSquash(new_PC, new_NPC, new_MicroPC, tid);
+ doSquash(newPC, tid);
// Tell the CPU to remove any instructions that are not in the ROB.
cpu->removeInstsNotInROB(tid);
@@ -903,16 +869,14 @@ DefaultFetch<Impl>::checkSignalsAndUpdate(ThreadID tid)
DPRINTF(Fetch, "[tid:%u]: Squashing instructions due to squash "
"from commit.\n",tid);
// In any case, squash.
- squash(fromCommit->commitInfo[tid].nextPC,
- fromCommit->commitInfo[tid].nextNPC,
- fromCommit->commitInfo[tid].nextMicroPC,
+ squash(fromCommit->commitInfo[tid].pc,
fromCommit->commitInfo[tid].doneSeqNum,
tid);
// Also check if there's a mispredict that happened.
if (fromCommit->commitInfo[tid].branchMispredict) {
branchPred.squash(fromCommit->commitInfo[tid].doneSeqNum,
- fromCommit->commitInfo[tid].nextPC,
+ fromCommit->commitInfo[tid].pc,
fromCommit->commitInfo[tid].branchTaken,
tid);
} else {
@@ -955,13 +919,10 @@ DefaultFetch<Impl>::checkSignalsAndUpdate(ThreadID tid)
if (fetchStatus[tid] != Squashing) {
- DPRINTF(Fetch, "Squashing from decode with PC = %#x, NPC = %#x\n",
- fromDecode->decodeInfo[tid].nextPC,
- fromDecode->decodeInfo[tid].nextNPC);
+ TheISA::PCState nextPC = fromDecode->decodeInfo[tid].nextPC;
+ DPRINTF(Fetch, "Squashing from decode with PC = %s\n", nextPC);
// Squash unless we're already squashing
squashFromDecode(fromDecode->decodeInfo[tid].nextPC,
- fromDecode->decodeInfo[tid].nextNPC,
- fromDecode->decodeInfo[tid].nextMicroPC,
fromDecode->decodeInfo[tid].doneSeqNum,
tid);
@@ -1016,9 +977,7 @@ DefaultFetch<Impl>::fetch(bool &status_change)
DPRINTF(Fetch, "Attempting to fetch from [tid:%i]\n", tid);
// The current PC.
- Addr fetch_PC = PC[tid];
- Addr fetch_NPC = nextPC[tid];
- Addr fetch_MicroPC = microPC[tid];
+ TheISA::PCState fetchPC = pc[tid];
// Fault code for memory access.
Fault fault = NoFault;
@@ -1034,10 +993,9 @@ DefaultFetch<Impl>::fetch(bool &status_change)
status_change = true;
} else if (fetchStatus[tid] == Running) {
DPRINTF(Fetch, "[tid:%i]: Attempting to translate and read "
- "instruction, starting at PC %08p.\n",
- tid, fetch_PC);
+ "instruction, starting at PC %s.\n", tid, fetchPC);
- bool fetch_success = fetchCacheLine(fetch_PC, fault, tid);
+ bool fetch_success = fetchCacheLine(fetchPC.instAddr(), fault, tid);
if (!fetch_success) {
if (cacheBlocked) {
++icacheStallCycles;
@@ -1075,20 +1033,21 @@ DefaultFetch<Impl>::fetch(bool &status_change)
return;
}
- Addr next_PC = fetch_PC;
- Addr next_NPC = fetch_NPC;
- Addr next_MicroPC = fetch_MicroPC;
+ TheISA::PCState nextPC = fetchPC;
InstSeqNum inst_seq;
MachInst inst;
ExtMachInst ext_inst;
- // @todo: Fix this hack.
- unsigned offset = (fetch_PC & cacheBlkMask) & ~3;
StaticInstPtr staticInst = NULL;
StaticInstPtr macroop = NULL;
if (fault == NoFault) {
+ //XXX Masking out pal mode bit. This will break x86. Alpha needs
+ //to pull the pal mode bit ouf ot the instruction address.
+ unsigned offset = (fetchPC.instAddr() & ~1) - cacheDataPC[tid];
+ assert(offset < cacheBlkSize);
+
// If the read of the first instruction was successful, then grab the
// instructions from the rest of the cache line and put them into the
// queue heading to decode.
@@ -1104,15 +1063,6 @@ DefaultFetch<Impl>::fetch(bool &status_change)
numInst < fetchWidth &&
!predicted_branch) {
- // If we're branching after this instruction, quite fetching
- // from the same block then.
- predicted_branch =
- (fetch_PC + sizeof(TheISA::MachInst) != fetch_NPC);
- if (predicted_branch) {
- DPRINTF(Fetch, "Branch detected with PC = %#x, NPC = %#x\n",
- fetch_PC, fetch_NPC);
- }
-
// Make sure this is a valid index.
assert(offset <= cacheBlkSize - instSize);
@@ -1122,16 +1072,16 @@ DefaultFetch<Impl>::fetch(bool &status_change)
(&cacheData[tid][offset]));
predecoder.setTC(cpu->thread[tid]->getTC());
- predecoder.moreBytes(fetch_PC, fetch_PC, inst);
+ predecoder.moreBytes(fetchPC, fetchPC.instAddr(), inst);
- ext_inst = predecoder.getExtMachInst();
- staticInst = StaticInstPtr(ext_inst, fetch_PC);
+ ext_inst = predecoder.getExtMachInst(fetchPC);
+ staticInst = StaticInstPtr(ext_inst, fetchPC.instAddr());
if (staticInst->isMacroop())
macroop = staticInst;
}
do {
if (macroop) {
- staticInst = macroop->fetchMicroop(fetch_MicroPC);
+ staticInst = macroop->fetchMicroop(fetchPC.microPC());
if (staticInst->isLastMicroop())
macroop = NULL;
}
@@ -1141,8 +1091,7 @@ DefaultFetch<Impl>::fetch(bool &status_change)
// Create a new DynInst from the instruction fetched.
DynInstPtr instruction = new DynInst(staticInst,
- fetch_PC, fetch_NPC, fetch_MicroPC,
- next_PC, next_NPC, next_MicroPC,
+ fetchPC, nextPC,
inst_seq, cpu);
instruction->setTid(tid);
@@ -1150,27 +1099,32 @@ DefaultFetch<Impl>::fetch(bool &status_change)
instruction->setThreadState(cpu->thread[tid]);
- DPRINTF(Fetch, "[tid:%i]: Instruction PC %#x (%d) created "
- "[sn:%lli]\n", tid, instruction->readPC(),
- instruction->readMicroPC(), inst_seq);
+ DPRINTF(Fetch, "[tid:%i]: Instruction PC %s (%d) created "
+ "[sn:%lli]\n", tid, instruction->pcState(),
+ instruction->microPC(), inst_seq);
//DPRINTF(Fetch, "[tid:%i]: MachInst is %#x\n", tid, ext_inst);
- DPRINTF(Fetch, "[tid:%i]: Instruction is: %s\n",
- tid, instruction->staticInst->disassemble(fetch_PC));
+ DPRINTF(Fetch, "[tid:%i]: Instruction is: %s\n", tid,
+ instruction->staticInst->
+ disassemble(fetchPC.instAddr()));
#if TRACING_ON
instruction->traceData =
cpu->getTracer()->getInstRecord(curTick, cpu->tcBase(tid),
- instruction->staticInst, instruction->readPC(),
- macroop, instruction->readMicroPC());
+ instruction->staticInst, fetchPC, macroop);
#else
instruction->traceData = NULL;
#endif
- ///FIXME This needs to be more robust in dealing with delay slots
+ // If we're branching after this instruction, quite fetching
+ // from the same block then.
+ predicted_branch = fetchPC.branching();
predicted_branch |=
- lookupAndUpdateNextPC(instruction, next_PC, next_NPC, next_MicroPC);
+ lookupAndUpdateNextPC(instruction, nextPC);
+ if (predicted_branch) {
+ DPRINTF(Fetch, "Branch detected with PC = %s\n", fetchPC);
+ }
// Add instruction to the CPU's list of instructions.
instruction->setInstListIt(cpu->addInst(instruction));
@@ -1185,9 +1139,7 @@ DefaultFetch<Impl>::fetch(bool &status_change)
++fetchedInsts;
// Move to the next instruction, unless we have a branch.
- fetch_PC = next_PC;
- fetch_NPC = next_NPC;
- fetch_MicroPC = next_MicroPC;
+ fetchPC = nextPC;
if (instruction->isQuiesce()) {
DPRINTF(Fetch, "Quiesce instruction encountered, halting fetch!",
@@ -1202,7 +1154,8 @@ DefaultFetch<Impl>::fetch(bool &status_change)
} while (staticInst->isMicroop() &&
!staticInst->isLastMicroop() &&
numInst < fetchWidth);
- offset += instSize;
+ //XXX Masking out pal mode bit.
+ offset = (fetchPC.instAddr() & ~1) - cacheDataPC[tid];
}
if (predicted_branch) {
@@ -1224,10 +1177,8 @@ DefaultFetch<Impl>::fetch(bool &status_change)
// Now that fetching is completed, update the PC to signify what the next
// cycle will be.
if (fault == NoFault) {
- PC[tid] = next_PC;
- nextPC[tid] = next_NPC;
- microPC[tid] = next_MicroPC;
- DPRINTF(Fetch, "[tid:%i]: Setting PC to %08p.\n", tid, next_PC);
+ pc[tid] = nextPC;
+ DPRINTF(Fetch, "[tid:%i]: Setting PC to %s.\n", tid, nextPC);
} else {
// We shouldn't be in an icache miss and also have a fault (an ITB
// miss)
@@ -1245,11 +1196,10 @@ DefaultFetch<Impl>::fetch(bool &status_change)
ext_inst = TheISA::NoopMachInst;
// Create a new DynInst from the dummy nop.
- DynInstPtr instruction = new DynInst(ext_inst,
- fetch_PC, fetch_NPC, fetch_MicroPC,
- next_PC, next_NPC, next_MicroPC,
+ DynInstPtr instruction = new DynInst(ext_inst, fetchPC, nextPC,
inst_seq, cpu);
- instruction->setPredTarg(next_NPC, next_NPC + instSize, 0);
+ TheISA::advancePC(nextPC, instruction->staticInst);
+ instruction->setPredTarg(nextPC);
instruction->setTid(tid);
instruction->setASID(tid);
@@ -1272,8 +1222,8 @@ DefaultFetch<Impl>::fetch(bool &status_change)
fetchStatus[tid] = TrapPending;
status_change = true;
- DPRINTF(Fetch, "[tid:%i]: fault (%s) detected @ PC %08p",
- tid, fault->name(), PC[tid]);
+ DPRINTF(Fetch, "[tid:%i]: fault (%s) detected @ PC %s",
+ tid, fault->name(), pc[tid]);
}
}
diff --git a/src/cpu/o3/iew_impl.hh b/src/cpu/o3/iew_impl.hh
index 2089913ef..608e70cde 100644
--- a/src/cpu/o3/iew_impl.hh
+++ b/src/cpu/o3/iew_impl.hh
@@ -449,27 +449,18 @@ template<class Impl>
void
DefaultIEW<Impl>::squashDueToBranch(DynInstPtr &inst, ThreadID tid)
{
- DPRINTF(IEW, "[tid:%i]: Squashing from a specific instruction, PC: %#x "
- "[sn:%i].\n", tid, inst->readPC(), inst->seqNum);
+ DPRINTF(IEW, "[tid:%i]: Squashing from a specific instruction, PC: %s "
+ "[sn:%i].\n", tid, inst->pcState(), inst->seqNum);
toCommit->squash[tid] = true;
toCommit->squashedSeqNum[tid] = inst->seqNum;
- toCommit->mispredPC[tid] = inst->readPC();
+ toCommit->mispredPC[tid] = inst->instAddr();
toCommit->branchMispredict[tid] = true;
-#if ISA_HAS_DELAY_SLOT
- int instSize = sizeof(TheISA::MachInst);
- toCommit->branchTaken[tid] =
- !(inst->readNextPC() + instSize == inst->readNextNPC() &&
- (inst->readNextPC() == inst->readPC() + instSize ||
- inst->readNextPC() == inst->readPC() + 2 * instSize));
-#else
- toCommit->branchTaken[tid] = inst->readNextPC() !=
- (inst->readPC() + sizeof(TheISA::MachInst));
-#endif
- toCommit->nextPC[tid] = inst->readNextPC();
- toCommit->nextNPC[tid] = inst->readNextNPC();
- toCommit->nextMicroPC[tid] = inst->readNextMicroPC();
+ toCommit->branchTaken[tid] = inst->pcState().branching();
+ TheISA::PCState pc = inst->pcState();
+ TheISA::advancePC(pc, inst->staticInst);
+ toCommit->pc[tid] = pc;
toCommit->includeSquashInst[tid] = false;
@@ -481,12 +472,13 @@ void
DefaultIEW<Impl>::squashDueToMemOrder(DynInstPtr &inst, ThreadID tid)
{
DPRINTF(IEW, "[tid:%i]: Squashing from a specific instruction, "
- "PC: %#x [sn:%i].\n", tid, inst->readPC(), inst->seqNum);
+ "PC: %s [sn:%i].\n", tid, inst->pcState(), inst->seqNum);
toCommit->squash[tid] = true;
toCommit->squashedSeqNum[tid] = inst->seqNum;
- toCommit->nextPC[tid] = inst->readNextPC();
- toCommit->nextNPC[tid] = inst->readNextNPC();
+ TheISA::PCState pc = inst->pcState();
+ TheISA::advancePC(pc, inst->staticInst);
+ toCommit->pc[tid] = pc;
toCommit->branchMispredict[tid] = false;
toCommit->includeSquashInst[tid] = false;
@@ -499,12 +491,11 @@ void
DefaultIEW<Impl>::squashDueToMemBlocked(DynInstPtr &inst, ThreadID tid)
{
DPRINTF(IEW, "[tid:%i]: Memory blocked, squashing load and younger insts, "
- "PC: %#x [sn:%i].\n", tid, inst->readPC(), inst->seqNum);
+ "PC: %s [sn:%i].\n", tid, inst->pcState(), inst->seqNum);
toCommit->squash[tid] = true;
toCommit->squashedSeqNum[tid] = inst->seqNum;
- toCommit->nextPC[tid] = inst->readPC();
- toCommit->nextNPC[tid] = inst->readNextPC();
+ toCommit->pc[tid] = inst->pcState();
toCommit->branchMispredict[tid] = false;
// Must include the broadcasted SN in the squash.
@@ -628,9 +619,9 @@ DefaultIEW<Impl>::skidInsert(ThreadID tid)
insts[tid].pop();
- DPRINTF(Decode,"[tid:%i]: Inserting [sn:%lli] PC:%#x into "
+ DPRINTF(Decode,"[tid:%i]: Inserting [sn:%lli] PC:%s into "
"dispatch skidBuffer %i\n",tid, inst->seqNum,
- inst->readPC(),tid);
+ inst->pcState(),tid);
skidBuffer[tid].push(inst);
}
@@ -986,9 +977,9 @@ DefaultIEW<Impl>::dispatchInsts(ThreadID tid)
// Make sure there's a valid instruction there.
assert(inst);
- DPRINTF(IEW, "[tid:%i]: Issue: Adding PC %#x [sn:%lli] [tid:%i] to "
+ DPRINTF(IEW, "[tid:%i]: Issue: Adding PC %s [sn:%lli] [tid:%i] to "
"IQ.\n",
- tid, inst->readPC(), inst->seqNum, inst->threadNumber);
+ tid, inst->pcState(), inst->seqNum, inst->threadNumber);
// Be sure to mark these instructions as ready so that the
// commit stage can go ahead and execute them, and mark
@@ -1165,7 +1156,7 @@ DefaultIEW<Impl>::printAvailableInsts()
if (inst%3==0) std::cout << "\n\t";
- std::cout << "PC: " << fromIssue->insts[inst]->readPC()
+ std::cout << "PC: " << fromIssue->insts[inst]->pcState()
<< " TN: " << fromIssue->insts[inst]->threadNumber
<< " SN: " << fromIssue->insts[inst]->seqNum << " | ";
@@ -1205,8 +1196,8 @@ DefaultIEW<Impl>::executeInsts()
DynInstPtr inst = instQueue.getInstToExecute();
- DPRINTF(IEW, "Execute: Processing PC %#x, [tid:%i] [sn:%i].\n",
- inst->readPC(), inst->threadNumber,inst->seqNum);
+ DPRINTF(IEW, "Execute: Processing PC %s, [tid:%i] [sn:%i].\n",
+ inst->pcState(), inst->threadNumber,inst->seqNum);
// Check if the instruction is squashed; if so then skip it
if (inst->isSquashed()) {
@@ -1298,10 +1289,9 @@ DefaultIEW<Impl>::executeInsts()
DPRINTF(IEW, "Execute: Branch mispredict detected.\n");
DPRINTF(IEW, "Predicted target was PC:%#x, NPC:%#x.\n",
- inst->readPredPC(), inst->readPredNPC());
- DPRINTF(IEW, "Execute: Redirecting fetch to PC: %#x,"
- " NPC: %#x.\n", inst->readNextPC(),
- inst->readNextNPC());
+ inst->predInstAddr(), inst->predNextInstAddr());
+ DPRINTF(IEW, "Execute: Redirecting fetch to PC: %s.\n",
+ inst->pcState(), inst->nextInstAddr());
// If incorrect, then signal the ROB that it must be squashed.
squashDueToBranch(inst, tid);
@@ -1318,16 +1308,11 @@ DefaultIEW<Impl>::executeInsts()
DynInstPtr violator;
violator = ldstQueue.getMemDepViolator(tid);
- DPRINTF(IEW, "LDSTQ detected a violation. Violator PC: %#x "
- "[sn:%lli], inst PC: %#x [sn:%lli]. Addr is: %#x.\n",
- violator->readPC(), violator->seqNum,
- inst->readPC(), inst->seqNum, inst->physEffAddr);
- // Ensure the violating instruction is older than
- // current squash
-/* if (fetchRedirect[tid] &&
- violator->seqNum >= toCommit->squashedSeqNum[tid] + 1)
- continue;
-*/
+ DPRINTF(IEW, "LDSTQ detected a violation. Violator PC: %s "
+ "[sn:%lli], inst PC: %s [sn:%lli]. Addr is: %#x.\n",
+ violator->pcState(), violator->seqNum,
+ inst->pcState(), inst->seqNum, inst->physEffAddr);
+
fetchRedirect[tid] = true;
// Tell the instruction queue that a violation has occured.
@@ -1342,8 +1327,8 @@ DefaultIEW<Impl>::executeInsts()
fetchRedirect[tid] = true;
DPRINTF(IEW, "Load operation couldn't execute because the "
- "memory system is blocked. PC: %#x [sn:%lli]\n",
- inst->readPC(), inst->seqNum);
+ "memory system is blocked. PC: %s [sn:%lli]\n",
+ inst->pcState(), inst->seqNum);
squashDueToMemBlocked(inst, tid);
}
@@ -1356,8 +1341,9 @@ DefaultIEW<Impl>::executeInsts()
DynInstPtr violator = ldstQueue.getMemDepViolator(tid);
DPRINTF(IEW, "LDSTQ detected a violation. Violator PC: "
- "%#x, inst PC: %#x. Addr is: %#x.\n",
- violator->readPC(), inst->readPC(), inst->physEffAddr);
+ "%s, inst PC: %s. Addr is: %#x.\n",
+ violator->pcState(), inst->pcState(),
+ inst->physEffAddr);
DPRINTF(IEW, "Violation will not be handled because "
"already squashing\n");
@@ -1366,8 +1352,8 @@ DefaultIEW<Impl>::executeInsts()
if (ldstQueue.loadBlocked(tid) &&
!ldstQueue.isLoadBlockedHandled(tid)) {
DPRINTF(IEW, "Load operation couldn't execute because the "
- "memory system is blocked. PC: %#x [sn:%lli]\n",
- inst->readPC(), inst->seqNum);
+ "memory system is blocked. PC: %s [sn:%lli]\n",
+ inst->pcState(), inst->seqNum);
DPRINTF(IEW, "Blocked load will not be handled because "
"already squashing\n");
@@ -1408,8 +1394,8 @@ DefaultIEW<Impl>::writebackInsts()
DynInstPtr inst = toCommit->insts[inst_num];
ThreadID tid = inst->threadNumber;
- DPRINTF(IEW, "Sending instructions to commit, [sn:%lli] PC %#x.\n",
- inst->seqNum, inst->readPC());
+ DPRINTF(IEW, "Sending instructions to commit, [sn:%lli] PC %s.\n",
+ inst->seqNum, inst->pcState());
iewInstsToCommit[tid]++;
@@ -1613,10 +1599,10 @@ DefaultIEW<Impl>::checkMisprediction(DynInstPtr &inst)
DPRINTF(IEW, "Execute: Branch mispredict detected.\n");
DPRINTF(IEW, "Predicted target was PC:%#x, NPC:%#x.\n",
- inst->readPredPC(), inst->readPredNPC());
+ inst->predInstAddr(), inst->predNextInstAddr());
DPRINTF(IEW, "Execute: Redirecting fetch to PC: %#x,"
- " NPC: %#x.\n", inst->readNextPC(),
- inst->readNextNPC());
+ " NPC: %#x.\n", inst->nextInstAddr(),
+ inst->nextInstAddr());
// If incorrect, then signal the ROB that it must be squashed.
squashDueToBranch(inst, tid);
diff --git a/src/cpu/o3/inst_queue_impl.hh b/src/cpu/o3/inst_queue_impl.hh
index 3d5eadf84..b944979f2 100644
--- a/src/cpu/o3/inst_queue_impl.hh
+++ b/src/cpu/o3/inst_queue_impl.hh
@@ -504,8 +504,8 @@ InstructionQueue<Impl>::insert(DynInstPtr &new_inst)
// Make sure the instruction is valid
assert(new_inst);
- DPRINTF(IQ, "Adding instruction [sn:%lli] PC %#x to the IQ.\n",
- new_inst->seqNum, new_inst->readPC());
+ DPRINTF(IQ, "Adding instruction [sn:%lli] PC %s to the IQ.\n",
+ new_inst->seqNum, new_inst->pcState());
assert(freeEntries != 0);
@@ -547,9 +547,9 @@ InstructionQueue<Impl>::insertNonSpec(DynInstPtr &new_inst)
nonSpecInsts[new_inst->seqNum] = new_inst;
- DPRINTF(IQ, "Adding non-speculative instruction [sn:%lli] PC %#x "
+ DPRINTF(IQ, "Adding non-speculative instruction [sn:%lli] PC %s "
"to the IQ.\n",
- new_inst->seqNum, new_inst->readPC());
+ new_inst->seqNum, new_inst->pcState());
assert(freeEntries != 0);
@@ -767,9 +767,9 @@ InstructionQueue<Impl>::scheduleReadyInsts()
}
}
- DPRINTF(IQ, "Thread %i: Issuing instruction PC %#x "
+ DPRINTF(IQ, "Thread %i: Issuing instruction PC %s "
"[sn:%lli]\n",
- tid, issuing_inst->readPC(),
+ tid, issuing_inst->pcState(),
issuing_inst->seqNum);
readyInsts[op_class].pop();
@@ -910,7 +910,7 @@ InstructionQueue<Impl>::wakeDependents(DynInstPtr &completed_inst)
while (dep_inst) {
DPRINTF(IQ, "Waking up a dependent instruction, [sn:%lli] "
- "PC%#x.\n", dep_inst->seqNum, dep_inst->readPC());
+ "PC %s.\n", dep_inst->seqNum, dep_inst->pcState());
// Might want to give more information to the instruction
// so that it knows which of its source registers is
@@ -955,8 +955,8 @@ InstructionQueue<Impl>::addReadyMemInst(DynInstPtr &ready_inst)
}
DPRINTF(IQ, "Instruction is ready to issue, putting it onto "
- "the ready list, PC %#x opclass:%i [sn:%lli].\n",
- ready_inst->readPC(), op_class, ready_inst->seqNum);
+ "the ready list, PC %s opclass:%i [sn:%lli].\n",
+ ready_inst->pcState(), op_class, ready_inst->seqNum);
}
template <class Impl>
@@ -981,8 +981,8 @@ InstructionQueue<Impl>::completeMemInst(DynInstPtr &completed_inst)
{
ThreadID tid = completed_inst->threadNumber;
- DPRINTF(IQ, "Completing mem instruction PC:%#x [sn:%lli]\n",
- completed_inst->readPC(), completed_inst->seqNum);
+ DPRINTF(IQ, "Completing mem instruction PC: %s [sn:%lli]\n",
+ completed_inst->pcState(), completed_inst->seqNum);
++freeEntries;
@@ -1050,9 +1050,8 @@ InstructionQueue<Impl>::doSquash(ThreadID tid)
(squashed_inst->isMemRef() &&
!squashed_inst->memOpDone)) {
- DPRINTF(IQ, "[tid:%i]: Instruction [sn:%lli] PC %#x "
- "squashed.\n",
- tid, squashed_inst->seqNum, squashed_inst->readPC());
+ DPRINTF(IQ, "[tid:%i]: Instruction [sn:%lli] PC %s squashed.\n",
+ tid, squashed_inst->seqNum, squashed_inst->pcState());
// Remove the instruction from the dependency list.
if (!squashed_inst->isNonSpeculative() &&
@@ -1147,9 +1146,9 @@ InstructionQueue<Impl>::addToDependents(DynInstPtr &new_inst)
if (src_reg >= numPhysRegs) {
continue;
} else if (regScoreboard[src_reg] == false) {
- DPRINTF(IQ, "Instruction PC %#x has src reg %i that "
+ DPRINTF(IQ, "Instruction PC %s has src reg %i that "
"is being added to the dependency chain.\n",
- new_inst->readPC(), src_reg);
+ new_inst->pcState(), src_reg);
dependGraph.insert(src_reg, new_inst);
@@ -1157,9 +1156,9 @@ InstructionQueue<Impl>::addToDependents(DynInstPtr &new_inst)
// was added to the dependency graph.
return_val = true;
} else {
- DPRINTF(IQ, "Instruction PC %#x has src reg %i that "
+ DPRINTF(IQ, "Instruction PC %s has src reg %i that "
"became ready before it reached the IQ.\n",
- new_inst->readPC(), src_reg);
+ new_inst->pcState(), src_reg);
// Mark a register ready within the instruction.
new_inst->markSrcRegReady(src_reg_idx);
}
@@ -1228,8 +1227,8 @@ InstructionQueue<Impl>::addIfReady(DynInstPtr &inst)
OpClass op_class = inst->opClass();
DPRINTF(IQ, "Instruction is ready to issue, putting it onto "
- "the ready list, PC %#x opclass:%i [sn:%lli].\n",
- inst->readPC(), op_class, inst->seqNum);
+ "the ready list, PC %s opclass:%i [sn:%lli].\n",
+ inst->pcState(), op_class, inst->seqNum);
readyInsts[op_class].push(inst);
@@ -1299,7 +1298,7 @@ InstructionQueue<Impl>::dumpLists()
cprintf("Non speculative list: ");
while (non_spec_it != non_spec_end_it) {
- cprintf("%#x [sn:%lli]", (*non_spec_it).second->readPC(),
+ cprintf("%s [sn:%lli]", (*non_spec_it).second->pcState(),
(*non_spec_it).second->seqNum);
++non_spec_it;
}
@@ -1348,9 +1347,9 @@ InstructionQueue<Impl>::dumpInsts()
}
}
- cprintf("PC:%#x\n[sn:%lli]\n[tid:%i]\n"
+ cprintf("PC: %s\n[sn:%lli]\n[tid:%i]\n"
"Issued:%i\nSquashed:%i\n",
- (*inst_list_it)->readPC(),
+ (*inst_list_it)->pcState(),
(*inst_list_it)->seqNum,
(*inst_list_it)->threadNumber,
(*inst_list_it)->isIssued(),
@@ -1390,9 +1389,9 @@ InstructionQueue<Impl>::dumpInsts()
}
}
- cprintf("PC:%#x\n[sn:%lli]\n[tid:%i]\n"
+ cprintf("PC: %s\n[sn:%lli]\n[tid:%i]\n"
"Issued:%i\nSquashed:%i\n",
- (*inst_list_it)->readPC(),
+ (*inst_list_it)->pcState(),
(*inst_list_it)->seqNum,
(*inst_list_it)->threadNumber,
(*inst_list_it)->isIssued(),
diff --git a/src/cpu/o3/lsq_unit.hh b/src/cpu/o3/lsq_unit.hh
index a9047558d..372e76b71 100644
--- a/src/cpu/o3/lsq_unit.hh
+++ b/src/cpu/o3/lsq_unit.hh
@@ -530,8 +530,8 @@ LSQUnit<Impl>::read(Request *req, Request *sreqLow, Request *sreqHigh,
(load_idx != loadHead || !load_inst->isAtCommit())) {
iewStage->rescheduleMemInst(load_inst);
++lsqRescheduledLoads;
- DPRINTF(LSQUnit, "Uncachable load [sn:%lli] PC %#x\n",
- load_inst->seqNum, load_inst->readPC());
+ DPRINTF(LSQUnit, "Uncachable load [sn:%lli] PC %s\n",
+ load_inst->seqNum, load_inst->pcState());
// Must delete request now that it wasn't handed off to
// memory. This is quite ugly. @todo: Figure out the proper
@@ -687,8 +687,8 @@ LSQUnit<Impl>::read(Request *req, Request *sreqLow, Request *sreqHigh,
}
// If there's no forwarding case, then go access memory
- DPRINTF(LSQUnit, "Doing memory access for inst [sn:%lli] PC %#x\n",
- load_inst->seqNum, load_inst->readPC());
+ DPRINTF(LSQUnit, "Doing memory access for inst [sn:%lli] PC %s\n",
+ load_inst->seqNum, load_inst->pcState());
assert(!load_inst->memData);
load_inst->memData = new uint8_t[64];
diff --git a/src/cpu/o3/lsq_unit_impl.hh b/src/cpu/o3/lsq_unit_impl.hh
index 8aa7fe397..345d3ea69 100644
--- a/src/cpu/o3/lsq_unit_impl.hh
+++ b/src/cpu/o3/lsq_unit_impl.hh
@@ -352,8 +352,8 @@ LSQUnit<Impl>::insertLoad(DynInstPtr &load_inst)
assert((loadTail + 1) % LQEntries != loadHead);
assert(loads < LQEntries);
- DPRINTF(LSQUnit, "Inserting load PC %#x, idx:%i [sn:%lli]\n",
- load_inst->readPC(), loadTail, load_inst->seqNum);
+ DPRINTF(LSQUnit, "Inserting load PC %s, idx:%i [sn:%lli]\n",
+ load_inst->pcState(), loadTail, load_inst->seqNum);
load_inst->lqIdx = loadTail;
@@ -378,8 +378,8 @@ LSQUnit<Impl>::insertStore(DynInstPtr &store_inst)
assert((storeTail + 1) % SQEntries != storeHead);
assert(stores < SQEntries);
- DPRINTF(LSQUnit, "Inserting store PC %#x, idx:%i [sn:%lli]\n",
- store_inst->readPC(), storeTail, store_inst->seqNum);
+ DPRINTF(LSQUnit, "Inserting store PC %s, idx:%i [sn:%lli]\n",
+ store_inst->pcState(), storeTail, store_inst->seqNum);
store_inst->sqIdx = storeTail;
store_inst->lqIdx = loadTail;
@@ -444,8 +444,8 @@ LSQUnit<Impl>::executeLoad(DynInstPtr &inst)
// Execute a specific load.
Fault load_fault = NoFault;
- DPRINTF(LSQUnit, "Executing load PC %#x, [sn:%lli]\n",
- inst->readPC(),inst->seqNum);
+ DPRINTF(LSQUnit, "Executing load PC %s, [sn:%lli]\n",
+ inst->pcState(),inst->seqNum);
assert(!inst->isSquashed());
@@ -519,8 +519,8 @@ LSQUnit<Impl>::executeStore(DynInstPtr &store_inst)
int store_idx = store_inst->sqIdx;
- DPRINTF(LSQUnit, "Executing store PC %#x [sn:%lli]\n",
- store_inst->readPC(), store_inst->seqNum);
+ DPRINTF(LSQUnit, "Executing store PC %s [sn:%lli]\n",
+ store_inst->pcState(), store_inst->seqNum);
assert(!store_inst->isSquashed());
@@ -531,8 +531,8 @@ LSQUnit<Impl>::executeStore(DynInstPtr &store_inst)
Fault store_fault = store_inst->initiateAcc();
if (storeQueue[store_idx].size == 0) {
- DPRINTF(LSQUnit,"Fault on Store PC %#x, [sn:%lli],Size = 0\n",
- store_inst->readPC(),store_inst->seqNum);
+ DPRINTF(LSQUnit,"Fault on Store PC %s, [sn:%lli],Size = 0\n",
+ store_inst->pcState(), store_inst->seqNum);
return store_fault;
}
@@ -593,8 +593,8 @@ LSQUnit<Impl>::commitLoad()
{
assert(loadQueue[loadHead]);
- DPRINTF(LSQUnit, "Committing head load instruction, PC %#x\n",
- loadQueue[loadHead]->readPC());
+ DPRINTF(LSQUnit, "Committing head load instruction, PC %s\n",
+ loadQueue[loadHead]->pcState());
loadQueue[loadHead] = NULL;
@@ -631,8 +631,8 @@ LSQUnit<Impl>::commitStores(InstSeqNum &youngest_inst)
break;
}
DPRINTF(LSQUnit, "Marking store as able to write back, PC "
- "%#x [sn:%lli]\n",
- storeQueue[store_idx].inst->readPC(),
+ "%s [sn:%lli]\n",
+ storeQueue[store_idx].inst->pcState(),
storeQueue[store_idx].inst->seqNum);
storeQueue[store_idx].canWB = true;
@@ -757,9 +757,9 @@ LSQUnit<Impl>::writebackStores()
req = sreqLow;
}
- DPRINTF(LSQUnit, "D-Cache: Writing back store idx:%i PC:%#x "
+ DPRINTF(LSQUnit, "D-Cache: Writing back store idx:%i PC:%s "
"to Addr:%#x, data:%#x [sn:%lli]\n",
- storeWBIdx, inst->readPC(),
+ storeWBIdx, inst->pcState(),
req->getPaddr(), (int)*(inst->memData),
inst->seqNum);
@@ -861,9 +861,9 @@ LSQUnit<Impl>::squash(const InstSeqNum &squashed_num)
decrLdIdx(load_idx);
while (loads != 0 && loadQueue[load_idx]->seqNum > squashed_num) {
- DPRINTF(LSQUnit,"Load Instruction PC %#x squashed, "
+ DPRINTF(LSQUnit,"Load Instruction PC %s squashed, "
"[sn:%lli]\n",
- loadQueue[load_idx]->readPC(),
+ loadQueue[load_idx]->pcState(),
loadQueue[load_idx]->seqNum);
if (isStalled() && load_idx == stallingLoadIdx) {
@@ -906,9 +906,9 @@ LSQUnit<Impl>::squash(const InstSeqNum &squashed_num)
break;
}
- DPRINTF(LSQUnit,"Store Instruction PC %#x squashed, "
+ DPRINTF(LSQUnit,"Store Instruction PC %s squashed, "
"idx:%i [sn:%lli]\n",
- storeQueue[store_idx].inst->readPC(),
+ storeQueue[store_idx].inst->pcState(),
store_idx, storeQueue[store_idx].inst->seqNum);
// I don't think this can happen. It should have been cleared
@@ -1156,7 +1156,7 @@ LSQUnit<Impl>::dumpInsts()
int load_idx = loadHead;
while (load_idx != loadTail && loadQueue[load_idx]) {
- cprintf("%#x ", loadQueue[load_idx]->readPC());
+ cprintf("%s ", loadQueue[load_idx]->pcState());
incrLdIdx(load_idx);
}
@@ -1167,7 +1167,7 @@ LSQUnit<Impl>::dumpInsts()
int store_idx = storeHead;
while (store_idx != storeTail && storeQueue[store_idx].inst) {
- cprintf("%#x ", storeQueue[store_idx].inst->readPC());
+ cprintf("%s ", storeQueue[store_idx].inst->pcState());
incrStIdx(store_idx);
}
diff --git a/src/cpu/o3/mem_dep_unit_impl.hh b/src/cpu/o3/mem_dep_unit_impl.hh
index 5f5e71624..fdea84ed5 100644
--- a/src/cpu/o3/mem_dep_unit_impl.hh
+++ b/src/cpu/o3/mem_dep_unit_impl.hh
@@ -171,7 +171,7 @@ MemDepUnit<MemDepPred, Impl>::insert(DynInstPtr &inst)
storeBarrierSN);
producing_store = storeBarrierSN;
} else {
- producing_store = depPred.checkInst(inst->readPC());
+ producing_store = depPred.checkInst(inst->instAddr());
}
MemDepEntryPtr store_entry = NULL;
@@ -191,7 +191,7 @@ MemDepUnit<MemDepPred, Impl>::insert(DynInstPtr &inst)
// are ready.
if (!store_entry) {
DPRINTF(MemDepUnit, "No dependency for inst PC "
- "%#x [sn:%lli].\n", inst->readPC(), inst->seqNum);
+ "%s [sn:%lli].\n", inst->pcState(), inst->seqNum);
inst_entry->memDepReady = true;
@@ -203,8 +203,8 @@ MemDepUnit<MemDepPred, Impl>::insert(DynInstPtr &inst)
} else {
// Otherwise make the instruction dependent on the store/barrier.
DPRINTF(MemDepUnit, "Adding to dependency list; "
- "inst PC %#x is dependent on [sn:%lli].\n",
- inst->readPC(), producing_store);
+ "inst PC %s is dependent on [sn:%lli].\n",
+ inst->pcState(), producing_store);
if (inst->readyToIssue()) {
inst_entry->regsReady = true;
@@ -224,10 +224,10 @@ MemDepUnit<MemDepPred, Impl>::insert(DynInstPtr &inst)
}
if (inst->isStore()) {
- DPRINTF(MemDepUnit, "Inserting store PC %#x [sn:%lli].\n",
- inst->readPC(), inst->seqNum);
+ DPRINTF(MemDepUnit, "Inserting store PC %s [sn:%lli].\n",
+ inst->pcState(), inst->seqNum);
- depPred.insertStore(inst->readPC(), inst->seqNum, inst->threadNumber);
+ depPred.insertStore(inst->instAddr(), inst->seqNum, inst->threadNumber);
++insertedStores;
} else if (inst->isLoad()) {
@@ -260,10 +260,10 @@ MemDepUnit<MemDepPred, Impl>::insertNonSpec(DynInstPtr &inst)
// Might want to turn this part into an inline function or something.
// It's shared between both insert functions.
if (inst->isStore()) {
- DPRINTF(MemDepUnit, "Inserting store PC %#x [sn:%lli].\n",
- inst->readPC(), inst->seqNum);
+ DPRINTF(MemDepUnit, "Inserting store PC %s [sn:%lli].\n",
+ inst->pcState(), inst->seqNum);
- depPred.insertStore(inst->readPC(), inst->seqNum, inst->threadNumber);
+ depPred.insertStore(inst->instAddr(), inst->seqNum, inst->threadNumber);
++insertedStores;
} else if (inst->isLoad()) {
@@ -313,8 +313,8 @@ void
MemDepUnit<MemDepPred, Impl>::regsReady(DynInstPtr &inst)
{
DPRINTF(MemDepUnit, "Marking registers as ready for "
- "instruction PC %#x [sn:%lli].\n",
- inst->readPC(), inst->seqNum);
+ "instruction PC %s [sn:%lli].\n",
+ inst->pcState(), inst->seqNum);
MemDepEntryPtr inst_entry = findInHash(inst);
@@ -336,8 +336,8 @@ void
MemDepUnit<MemDepPred, Impl>::nonSpecInstReady(DynInstPtr &inst)
{
DPRINTF(MemDepUnit, "Marking non speculative "
- "instruction PC %#x as ready [sn:%lli].\n",
- inst->readPC(), inst->seqNum);
+ "instruction PC %s as ready [sn:%lli].\n",
+ inst->pcState(), inst->seqNum);
MemDepEntryPtr inst_entry = findInHash(inst);
@@ -363,9 +363,8 @@ MemDepUnit<MemDepPred, Impl>::replay(DynInstPtr &inst)
MemDepEntryPtr inst_entry = findInHash(temp_inst);
- DPRINTF(MemDepUnit, "Replaying mem instruction PC %#x "
- "[sn:%lli].\n",
- temp_inst->readPC(), temp_inst->seqNum);
+ DPRINTF(MemDepUnit, "Replaying mem instruction PC %s [sn:%lli].\n",
+ temp_inst->pcState(), temp_inst->seqNum);
moveToReady(inst_entry);
@@ -377,9 +376,8 @@ template <class MemDepPred, class Impl>
void
MemDepUnit<MemDepPred, Impl>::completed(DynInstPtr &inst)
{
- DPRINTF(MemDepUnit, "Completed mem instruction PC %#x "
- "[sn:%lli].\n",
- inst->readPC(), inst->seqNum);
+ DPRINTF(MemDepUnit, "Completed mem instruction PC %s [sn:%lli].\n",
+ inst->pcState(), inst->seqNum);
ThreadID tid = inst->threadNumber;
@@ -507,10 +505,10 @@ MemDepUnit<MemDepPred, Impl>::violation(DynInstPtr &store_inst,
DynInstPtr &violating_load)
{
DPRINTF(MemDepUnit, "Passing violating PCs to store sets,"
- " load: %#x, store: %#x\n", violating_load->readPC(),
- store_inst->readPC());
+ " load: %#x, store: %#x\n", violating_load->instAddr(),
+ store_inst->instAddr());
// Tell the memory dependence unit of the violation.
- depPred.violation(violating_load->readPC(), store_inst->readPC());
+ depPred.violation(violating_load->instAddr(), store_inst->instAddr());
}
template <class MemDepPred, class Impl>
@@ -518,9 +516,9 @@ void
MemDepUnit<MemDepPred, Impl>::issue(DynInstPtr &inst)
{
DPRINTF(MemDepUnit, "Issuing instruction PC %#x [sn:%lli].\n",
- inst->readPC(), inst->seqNum);
+ inst->instAddr(), inst->seqNum);
- depPred.issued(inst->readPC(), inst->seqNum, inst->isStore());
+ depPred.issued(inst->instAddr(), inst->seqNum, inst->isStore());
}
template <class MemDepPred, class Impl>
@@ -559,9 +557,9 @@ MemDepUnit<MemDepPred, Impl>::dumpLists()
int num = 0;
while (inst_list_it != instList[tid].end()) {
- cprintf("Instruction:%i\nPC:%#x\n[sn:%i]\n[tid:%i]\nIssued:%i\n"
+ cprintf("Instruction:%i\nPC: %s\n[sn:%i]\n[tid:%i]\nIssued:%i\n"
"Squashed:%i\n\n",
- num, (*inst_list_it)->readPC(),
+ num, (*inst_list_it)->pcState(),
(*inst_list_it)->seqNum,
(*inst_list_it)->threadNumber,
(*inst_list_it)->isIssued(),
diff --git a/src/cpu/o3/rename_impl.hh b/src/cpu/o3/rename_impl.hh
index 7f796c4c8..4b321d099 100644
--- a/src/cpu/o3/rename_impl.hh
+++ b/src/cpu/o3/rename_impl.hh
@@ -591,15 +591,14 @@ DefaultRename<Impl>::renameInsts(ThreadID tid)
insts_to_rename.pop_front();
if (renameStatus[tid] == Unblocking) {
- DPRINTF(Rename,"[tid:%u]: Removing [sn:%lli] PC:%#x from rename "
- "skidBuffer\n",
- tid, inst->seqNum, inst->readPC());
+ DPRINTF(Rename,"[tid:%u]: Removing [sn:%lli] PC:%s from rename "
+ "skidBuffer\n", tid, inst->seqNum, inst->pcState());
}
if (inst->isSquashed()) {
- DPRINTF(Rename, "[tid:%u]: instruction %i with PC %#x is "
- "squashed, skipping.\n",
- tid, inst->seqNum, inst->readPC());
+ DPRINTF(Rename, "[tid:%u]: instruction %i with PC %s is "
+ "squashed, skipping.\n", tid, inst->seqNum,
+ inst->pcState());
++renameSquashedInsts;
@@ -610,8 +609,7 @@ DefaultRename<Impl>::renameInsts(ThreadID tid)
}
DPRINTF(Rename, "[tid:%u]: Processing instruction [sn:%lli] with "
- "PC %#x.\n",
- tid, inst->seqNum, inst->readPC());
+ "PC %s.\n", tid, inst->seqNum, inst->pcState());
// Handle serializeAfter/serializeBefore instructions.
// serializeAfter marks the next instruction as serializeBefore.
@@ -716,8 +714,8 @@ DefaultRename<Impl>::skidInsert(ThreadID tid)
assert(tid == inst->threadNumber);
- DPRINTF(Rename, "[tid:%u]: Inserting [sn:%lli] PC:%#x into Rename "
- "skidBuffer\n", tid, inst->seqNum, inst->readPC());
+ DPRINTF(Rename, "[tid:%u]: Inserting [sn:%lli] PC: %s into Rename "
+ "skidBuffer\n", tid, inst->seqNum, inst->pcState());
++renameSkidInsts;
@@ -731,7 +729,7 @@ DefaultRename<Impl>::skidInsert(ThreadID tid)
for(it = skidBuffer[tid].begin(); it != skidBuffer[tid].end(); it++)
{
warn("[tid:%u]: %s [sn:%i].\n", tid,
- (*it)->staticInst->disassemble(inst->readPC()),
+ (*it)->staticInst->disassemble(inst->instAddr()),
(*it)->seqNum);
}
panic("Skidbuffer Exceeded Max Size");
@@ -1287,8 +1285,7 @@ DefaultRename<Impl>::checkSignalsAndUpdate(ThreadID tid)
unblock(tid);
DPRINTF(Rename, "[tid:%u]: Processing instruction [%lli] with "
- "PC %#x.\n",
- tid, serial_inst->seqNum, serial_inst->readPC());
+ "PC %s.\n", tid, serial_inst->seqNum, serial_inst->pcState());
// Put instruction into queue here.
serial_inst->clearSerializeBefore();
diff --git a/src/cpu/o3/rob_impl.hh b/src/cpu/o3/rob_impl.hh
index cf0080b48..37f1c5504 100644
--- a/src/cpu/o3/rob_impl.hh
+++ b/src/cpu/o3/rob_impl.hh
@@ -204,7 +204,7 @@ ROB<Impl>::insertInst(DynInstPtr &inst)
{
assert(inst);
- DPRINTF(ROB, "Adding inst PC %#x to the ROB.\n", inst->readPC());
+ DPRINTF(ROB, "Adding inst PC %s to the ROB.\n", inst->pcState());
assert(numInstsInROB != numEntries);
@@ -247,7 +247,7 @@ ROB<Impl>::retireHead(ThreadID tid)
assert(head_inst->readyToCommit());
DPRINTF(ROB, "[tid:%u]: Retiring head instruction, "
- "instruction PC %#x,[sn:%lli]\n", tid, head_inst->readPC(),
+ "instruction PC %s, [sn:%lli]\n", tid, head_inst->pcState(),
head_inst->seqNum);
--numInstsInROB;
@@ -338,9 +338,9 @@ ROB<Impl>::doSquash(ThreadID tid)
(*squashIt[tid])->seqNum > squashedSeqNum[tid];
++numSquashed)
{
- DPRINTF(ROB, "[tid:%u]: Squashing instruction PC %#x, seq num %i.\n",
+ DPRINTF(ROB, "[tid:%u]: Squashing instruction PC %s, seq num %i.\n",
(*squashIt[tid])->threadNumber,
- (*squashIt[tid])->readPC(),
+ (*squashIt[tid])->pcState(),
(*squashIt[tid])->seqNum);
// Mark the instruction as squashed, and ready to commit so that
diff --git a/src/cpu/o3/thread_context.hh b/src/cpu/o3/thread_context.hh
index b7790cfda..4e559000b 100755
--- a/src/cpu/o3/thread_context.hh
+++ b/src/cpu/o3/thread_context.hh
@@ -172,29 +172,24 @@ class O3ThreadContext : public ThreadContext
virtual void setFloatRegBits(int reg_idx, FloatRegBits val);
- /** Reads this thread's PC. */
- virtual uint64_t readPC()
- { return cpu->readPC(thread->threadId()); }
-
- /** Sets this thread's PC. */
- virtual void setPC(uint64_t val);
-
- /** Reads this thread's next PC. */
- virtual uint64_t readNextPC()
- { return cpu->readNextPC(thread->threadId()); }
+ /** Reads this thread's PC state. */
+ virtual TheISA::PCState pcState()
+ { return cpu->pcState(thread->threadId()); }
- /** Sets this thread's next PC. */
- virtual void setNextPC(uint64_t val);
+ /** Sets this thread's PC state. */
+ virtual void pcState(const TheISA::PCState &val);
- virtual uint64_t readMicroPC()
- { return cpu->readMicroPC(thread->threadId()); }
-
- virtual void setMicroPC(uint64_t val);
+ /** Reads this thread's PC. */
+ virtual Addr instAddr()
+ { return cpu->instAddr(thread->threadId()); }
- virtual uint64_t readNextMicroPC()
- { return cpu->readNextMicroPC(thread->threadId()); }
+ /** Reads this thread's next PC. */
+ virtual Addr nextInstAddr()
+ { return cpu->nextInstAddr(thread->threadId()); }
- virtual void setNextMicroPC(uint64_t val);
+ /** Reads this thread's next PC. */
+ virtual MicroPC microPC()
+ { return cpu->microPC(thread->threadId()); }
/** Reads a miscellaneous register. */
virtual MiscReg readMiscRegNoEffect(int misc_reg)
@@ -247,15 +242,6 @@ class O3ThreadContext : public ThreadContext
}
#endif
- virtual uint64_t readNextNPC()
- {
- return this->cpu->readNextNPC(this->thread->threadId());
- }
-
- virtual void setNextNPC(uint64_t val)
- {
- this->cpu->setNextNPC(val, this->thread->threadId());
- }
};
#endif
diff --git a/src/cpu/o3/thread_context_impl.hh b/src/cpu/o3/thread_context_impl.hh
index 0b7a2b172..367442830 100755
--- a/src/cpu/o3/thread_context_impl.hh
+++ b/src/cpu/o3/thread_context_impl.hh
@@ -248,11 +248,7 @@ O3ThreadContext<Impl>::copyArchRegs(ThreadContext *tc)
// Then finally set the PC, the next PC, the nextNPC, the micropc, and the
// next micropc.
- cpu->setPC(tc->readPC(), tid);
- cpu->setNextPC(tc->readNextPC(), tid);
- cpu->setNextNPC(tc->readNextNPC(), tid);
- cpu->setMicroPC(tc->readMicroPC(), tid);
- cpu->setNextMicroPC(tc->readNextMicroPC(), tid);
+ cpu->pcState(tc->pcState(), tid);
#if !FULL_SYSTEM
this->thread->funcExeInst = tc->readFuncExeInst();
#endif
@@ -327,45 +323,9 @@ O3ThreadContext<Impl>::setFloatRegBits(int reg_idx, FloatRegBits val)
template <class Impl>
void
-O3ThreadContext<Impl>::setPC(uint64_t val)
+O3ThreadContext<Impl>::pcState(const TheISA::PCState &val)
{
- cpu->setPC(val, thread->threadId());
-
- // Squash if we're not already in a state update mode.
- if (!thread->trapPending && !thread->inSyscall) {
- cpu->squashFromTC(thread->threadId());
- }
-}
-
-template <class Impl>
-void
-O3ThreadContext<Impl>::setNextPC(uint64_t val)
-{
- cpu->setNextPC(val, thread->threadId());
-
- // Squash if we're not already in a state update mode.
- if (!thread->trapPending && !thread->inSyscall) {
- cpu->squashFromTC(thread->threadId());
- }
-}
-
-template <class Impl>
-void
-O3ThreadContext<Impl>::setMicroPC(uint64_t val)
-{
- cpu->setMicroPC(val, thread->threadId());
-
- // Squash if we're not already in a state update mode.
- if (!thread->trapPending && !thread->inSyscall) {
- cpu->squashFromTC(thread->threadId());
- }
-}
-
-template <class Impl>
-void
-O3ThreadContext<Impl>::setNextMicroPC(uint64_t val)
-{
- cpu->setNextMicroPC(val, thread->threadId());
+ cpu->pcState(val, thread->threadId());
// Squash if we're not already in a state update mode.
if (!thread->trapPending && !thread->inSyscall) {
diff --git a/src/cpu/pc_event.cc b/src/cpu/pc_event.cc
index 79f5277d5..533d61498 100644
--- a/src/cpu/pc_event.cc
+++ b/src/cpu/pc_event.cc
@@ -83,7 +83,7 @@ PCEventQueue::schedule(PCEvent *event)
bool
PCEventQueue::doService(ThreadContext *tc)
{
- Addr pc = tc->readPC() & ~0x3;
+ Addr pc = tc->instAddr() & ~0x3;
int serviced = 0;
range_t range = equal_range(pc);
for (iterator i = range.first; i != range.second; ++i) {
@@ -91,7 +91,7 @@ PCEventQueue::doService(ThreadContext *tc)
// another event. This for example, prevents two invocations
// of the SkipFuncEvent. Maybe we should have separate PC
// event queues for each processor?
- if (pc != (tc->readPC() & ~0x3))
+ if (pc != (tc->instAddr() & ~0x3))
continue;
DPRINTF(PCEvent, "PC based event serviced at %#x: %s\n",
diff --git a/src/cpu/pred/btb.cc b/src/cpu/pred/btb.cc
index c6a5e23f9..e87cc6dc2 100644
--- a/src/cpu/pred/btb.cc
+++ b/src/cpu/pred/btb.cc
@@ -68,25 +68,25 @@ DefaultBTB::reset()
inline
unsigned
-DefaultBTB::getIndex(const Addr &inst_PC)
+DefaultBTB::getIndex(Addr instPC)
{
// Need to shift PC over by the word offset.
- return (inst_PC >> instShiftAmt) & idxMask;
+ return (instPC >> instShiftAmt) & idxMask;
}
inline
Addr
-DefaultBTB::getTag(const Addr &inst_PC)
+DefaultBTB::getTag(Addr instPC)
{
- return (inst_PC >> tagShiftAmt) & tagMask;
+ return (instPC >> tagShiftAmt) & tagMask;
}
bool
-DefaultBTB::valid(const Addr &inst_PC, ThreadID tid)
+DefaultBTB::valid(Addr instPC, ThreadID tid)
{
- unsigned btb_idx = getIndex(inst_PC);
+ unsigned btb_idx = getIndex(instPC);
- Addr inst_tag = getTag(inst_PC);
+ Addr inst_tag = getTag(instPC);
assert(btb_idx < numEntries);
@@ -102,12 +102,12 @@ DefaultBTB::valid(const Addr &inst_PC, ThreadID tid)
// @todo Create some sort of return struct that has both whether or not the
// address is valid, and also the address. For now will just use addr = 0 to
// represent invalid entry.
-Addr
-DefaultBTB::lookup(const Addr &inst_PC, ThreadID tid)
+TheISA::PCState
+DefaultBTB::lookup(Addr instPC, ThreadID tid)
{
- unsigned btb_idx = getIndex(inst_PC);
+ unsigned btb_idx = getIndex(instPC);
- Addr inst_tag = getTag(inst_PC);
+ Addr inst_tag = getTag(instPC);
assert(btb_idx < numEntries);
@@ -121,14 +121,14 @@ DefaultBTB::lookup(const Addr &inst_PC, ThreadID tid)
}
void
-DefaultBTB::update(const Addr &inst_PC, const Addr &target, ThreadID tid)
+DefaultBTB::update(Addr instPC, const TheISA::PCState &target, ThreadID tid)
{
- unsigned btb_idx = getIndex(inst_PC);
+ unsigned btb_idx = getIndex(instPC);
assert(btb_idx < numEntries);
btb[btb_idx].tid = tid;
btb[btb_idx].valid = true;
btb[btb_idx].target = target;
- btb[btb_idx].tag = getTag(inst_PC);
+ btb[btb_idx].tag = getTag(instPC);
}
diff --git a/src/cpu/pred/btb.hh b/src/cpu/pred/btb.hh
index 6557522e0..814b23872 100644
--- a/src/cpu/pred/btb.hh
+++ b/src/cpu/pred/btb.hh
@@ -31,8 +31,10 @@
#ifndef __CPU_O3_BTB_HH__
#define __CPU_O3_BTB_HH__
+#include "arch/types.hh"
#include "base/misc.hh"
#include "base/types.hh"
+#include "config/the_isa.hh"
class DefaultBTB
{
@@ -41,14 +43,13 @@ class DefaultBTB
{
BTBEntry()
: tag(0), target(0), valid(false)
- {
- }
+ {}
/** The entry's tag. */
Addr tag;
/** The entry's target. */
- Addr target;
+ TheISA::PCState target;
/** The entry's thread id. */
ThreadID tid;
@@ -74,21 +75,21 @@ class DefaultBTB
* @param tid The thread id.
* @return Returns the target of the branch.
*/
- Addr lookup(const Addr &inst_PC, ThreadID tid);
+ TheISA::PCState lookup(Addr instPC, ThreadID tid);
/** Checks if a branch is in the BTB.
* @param inst_PC The address of the branch to look up.
* @param tid The thread id.
* @return Whether or not the branch exists in the BTB.
*/
- bool valid(const Addr &inst_PC, ThreadID tid);
+ bool valid(Addr instPC, ThreadID tid);
/** Updates the BTB with the target of a branch.
* @param inst_PC The address of the branch being updated.
* @param target_PC The target address of the branch.
* @param tid The thread id.
*/
- void update(const Addr &inst_PC, const Addr &target_PC,
+ void update(Addr instPC, const TheISA::PCState &targetPC,
ThreadID tid);
private:
@@ -96,13 +97,13 @@ class DefaultBTB
* @param inst_PC The branch to look up.
* @return Returns the index into the BTB.
*/
- inline unsigned getIndex(const Addr &inst_PC);
+ inline unsigned getIndex(Addr instPC);
/** Returns the tag bits of a given address.
* @param inst_PC The branch's address.
* @return Returns the tag bits.
*/
- inline Addr getTag(const Addr &inst_PC);
+ inline Addr getTag(Addr instPC);
/** The actual BTB. */
std::vector<BTBEntry> btb;
diff --git a/src/cpu/pred/ras.cc b/src/cpu/pred/ras.cc
index 6373e5de3..0ba09bfae 100644
--- a/src/cpu/pred/ras.cc
+++ b/src/cpu/pred/ras.cc
@@ -34,13 +34,8 @@ void
ReturnAddrStack::init(unsigned _numEntries)
{
numEntries = _numEntries;
- usedEntries = 0;
- tos = 0;
-
addrStack.resize(numEntries);
-
- for (unsigned i = 0; i < numEntries; ++i)
- addrStack[i] = 0;
+ reset();
}
void
@@ -49,11 +44,11 @@ ReturnAddrStack::reset()
usedEntries = 0;
tos = 0;
for (unsigned i = 0; i < numEntries; ++i)
- addrStack[i] = 0;
+ addrStack[i].set(0);
}
void
-ReturnAddrStack::push(const Addr &return_addr)
+ReturnAddrStack::push(const TheISA::PCState &return_addr)
{
incrTos();
@@ -76,9 +71,9 @@ ReturnAddrStack::pop()
void
ReturnAddrStack::restore(unsigned top_entry_idx,
- const Addr &restored_target)
+ const TheISA::PCState &restored)
{
tos = top_entry_idx;
- addrStack[tos] = restored_target;
+ addrStack[tos] = restored;
}
diff --git a/src/cpu/pred/ras.hh b/src/cpu/pred/ras.hh
index a36faf79a..ab92b34c2 100644
--- a/src/cpu/pred/ras.hh
+++ b/src/cpu/pred/ras.hh
@@ -33,7 +33,9 @@
#include <vector>
+#include "arch/types.hh"
#include "base/types.hh"
+#include "config/the_isa.hh"
/** Return address stack class, implements a simple RAS. */
class ReturnAddrStack
@@ -52,7 +54,7 @@ class ReturnAddrStack
void reset();
/** Returns the top address on the RAS. */
- Addr top()
+ TheISA::PCState top()
{ return addrStack[tos]; }
/** Returns the index of the top of the RAS. */
@@ -60,7 +62,7 @@ class ReturnAddrStack
{ return tos; }
/** Pushes an address onto the RAS. */
- void push(const Addr &return_addr);
+ void push(const TheISA::PCState &return_addr);
/** Pops the top address from the RAS. */
void pop();
@@ -68,9 +70,9 @@ class ReturnAddrStack
/** Changes index to the top of the RAS, and replaces the top address with
* a new target.
* @param top_entry_idx The index of the RAS that will now be the top.
- * @param restored_target The new target address of the new top of the RAS.
+ * @param restored The new target address of the new top of the RAS.
*/
- void restore(unsigned top_entry_idx, const Addr &restored_target);
+ void restore(unsigned top_entry_idx, const TheISA::PCState &restored);
bool empty() { return usedEntries == 0; }
@@ -85,7 +87,7 @@ class ReturnAddrStack
{ tos = (tos == 0 ? numEntries - 1 : tos - 1); }
/** The RAS itself. */
- std::vector<Addr> addrStack;
+ std::vector<TheISA::PCState> addrStack;
/** The number of entries in the RAS. */
unsigned numEntries;
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);
diff --git a/src/cpu/simple_thread.cc b/src/cpu/simple_thread.cc
index bd796428a..15fac8677 100644
--- a/src/cpu/simple_thread.cc
+++ b/src/cpu/simple_thread.cc
@@ -193,11 +193,7 @@ SimpleThread::serialize(ostream &os)
ThreadState::serialize(os);
SERIALIZE_ARRAY(floatRegs.i, TheISA::NumFloatRegs);
SERIALIZE_ARRAY(intRegs, TheISA::NumIntRegs);
- SERIALIZE_SCALAR(microPC);
- SERIALIZE_SCALAR(nextMicroPC);
- SERIALIZE_SCALAR(PC);
- SERIALIZE_SCALAR(nextPC);
- SERIALIZE_SCALAR(nextNPC);
+ _pcState.serialize(os);
// thread_num and cpu_id are deterministic from the config
//
@@ -213,11 +209,7 @@ SimpleThread::unserialize(Checkpoint *cp, const std::string &section)
ThreadState::unserialize(cp, section);
UNSERIALIZE_ARRAY(floatRegs.i, TheISA::NumFloatRegs);
UNSERIALIZE_ARRAY(intRegs, TheISA::NumIntRegs);
- UNSERIALIZE_SCALAR(microPC);
- UNSERIALIZE_SCALAR(nextMicroPC);
- UNSERIALIZE_SCALAR(PC);
- UNSERIALIZE_SCALAR(nextPC);
- UNSERIALIZE_SCALAR(nextNPC);
+ _pcState.unserialize(cp, section);
// thread_num and cpu_id are deterministic from the config
//
diff --git a/src/cpu/simple_thread.hh b/src/cpu/simple_thread.hh
index e4a7b7a77..48077a9b9 100644
--- a/src/cpu/simple_thread.hh
+++ b/src/cpu/simple_thread.hh
@@ -106,27 +106,7 @@ class SimpleThread : public ThreadState
TheISA::IntReg intRegs[TheISA::NumIntRegs];
TheISA::ISA isa; // one "instance" of the current ISA.
- /** The current microcode pc for the currently executing macro
- * operation.
- */
- MicroPC microPC;
-
- /** The next microcode pc for the currently executing macro
- * operation.
- */
- MicroPC nextMicroPC;
-
- /** The current pc.
- */
- Addr PC;
-
- /** The next pc.
- */
- Addr nextPC;
-
- /** The next next pc.
- */
- Addr nextNPC;
+ TheISA::PCState _pcState;
/** Did this instruction execute or is it predicated false */
bool predicate;
@@ -245,9 +225,7 @@ class SimpleThread : public ThreadState
void clearArchRegs()
{
- microPC = 0;
- nextMicroPC = 1;
- PC = nextPC = nextNPC = 0;
+ _pcState = 0;
memset(intRegs, 0, sizeof(intRegs));
memset(floatRegs.i, 0, sizeof(floatRegs.i));
isa.clear();
@@ -313,60 +291,34 @@ class SimpleThread : public ThreadState
reg_idx, flatIndex, val, floatRegs.f[flatIndex]);
}
- uint64_t readPC()
- {
- return PC;
- }
-
- void setPC(uint64_t val)
- {
- PC = val;
- }
-
- uint64_t readMicroPC()
- {
- return microPC;
- }
-
- void setMicroPC(uint64_t val)
- {
- microPC = val;
- }
-
- uint64_t readNextPC()
+ TheISA::PCState
+ pcState()
{
- return nextPC;
+ return _pcState;
}
- void setNextPC(uint64_t val)
+ void
+ pcState(const TheISA::PCState &val)
{
- nextPC = val;
+ _pcState = val;
}
- uint64_t readNextMicroPC()
+ Addr
+ instAddr()
{
- return nextMicroPC;
+ return _pcState.instAddr();
}
- void setNextMicroPC(uint64_t val)
+ Addr
+ nextInstAddr()
{
- nextMicroPC = val;
+ return _pcState.nextInstAddr();
}
- uint64_t readNextNPC()
+ MicroPC
+ microPC()
{
-#if ISA_HAS_DELAY_SLOT
- return nextNPC;
-#else
- return nextPC + sizeof(TheISA::MachInst);
-#endif
- }
-
- void setNextNPC(uint64_t val)
- {
-#if ISA_HAS_DELAY_SLOT
- nextNPC = val;
-#endif
+ return _pcState.microPC();
}
bool readPredicate()
diff --git a/src/cpu/static_inst.cc b/src/cpu/static_inst.cc
index 2c4fc8ab9..f2a72c96a 100644
--- a/src/cpu/static_inst.cc
+++ b/src/cpu/static_inst.cc
@@ -68,7 +68,8 @@ StaticInst::dumpDecodeCacheStats()
}
bool
-StaticInst::hasBranchTarget(Addr pc, ThreadContext *tc, Addr &tgt) const
+StaticInst::hasBranchTarget(const TheISA::PCState &pc, ThreadContext *tc,
+ TheISA::PCState &tgt) const
{
if (isDirectCtrl()) {
tgt = branchTarget(pc);
@@ -84,21 +85,21 @@ StaticInst::hasBranchTarget(Addr pc, ThreadContext *tc, Addr &tgt) const
}
StaticInstPtr
-StaticInst::fetchMicroop(MicroPC micropc)
+StaticInst::fetchMicroop(MicroPC upc) const
{
panic("StaticInst::fetchMicroop() called on instruction "
"that is not microcoded.");
}
-Addr
-StaticInst::branchTarget(Addr branchPC) const
+TheISA::PCState
+StaticInst::branchTarget(const TheISA::PCState &pc) const
{
panic("StaticInst::branchTarget() called on instruction "
"that is not a PC-relative branch.");
M5_DUMMY_RETURN;
}
-Addr
+TheISA::PCState
StaticInst::branchTarget(ThreadContext *tc) const
{
panic("StaticInst::branchTarget() called on instruction "
diff --git a/src/cpu/static_inst.hh b/src/cpu/static_inst.hh
index 6474bbf9c..b219fafd6 100644
--- a/src/cpu/static_inst.hh
+++ b/src/cpu/static_inst.hh
@@ -35,6 +35,7 @@
#include <string>
#include "arch/isa_traits.hh"
+#include "arch/types.hh"
#include "arch/registers.hh"
#include "config/the_isa.hh"
#include "base/hashmap.hh"
@@ -70,28 +71,6 @@ namespace Trace {
class InstRecord;
}
-typedef uint16_t MicroPC;
-
-static const MicroPC MicroPCRomBit = 1 << (sizeof(MicroPC) * 8 - 1);
-
-static inline MicroPC
-romMicroPC(MicroPC upc)
-{
- return upc | MicroPCRomBit;
-}
-
-static inline MicroPC
-normalMicroPC(MicroPC upc)
-{
- return upc & ~MicroPCRomBit;
-}
-
-static inline bool
-isRomMicroPC(MicroPC upc)
-{
- return MicroPCRomBit & upc;
-}
-
/**
* Base, ISA-independent static instruction class.
*
@@ -392,18 +371,20 @@ class StaticInst : public StaticInstBase
*/
#include "cpu/static_inst_exec_sigs.hh"
+ virtual void advancePC(TheISA::PCState &pcState) const = 0;
+
/**
* Return the microop that goes with a particular micropc. This should
* only be defined/used in macroops which will contain microops
*/
- virtual StaticInstPtr fetchMicroop(MicroPC micropc);
+ virtual StaticInstPtr fetchMicroop(MicroPC upc) const;
/**
* Return the target address for a PC-relative branch.
* Invalid if not a PC-relative branch (i.e. isDirectCtrl()
* should be true).
*/
- virtual Addr branchTarget(Addr branchPC) const;
+ virtual TheISA::PCState branchTarget(const TheISA::PCState &pc) const;
/**
* Return the target address for an indirect branch (jump). The
@@ -412,13 +393,14 @@ class StaticInst : public StaticInstBase
* execute the branch in question. Invalid if not an indirect
* branch (i.e. isIndirectCtrl() should be true).
*/
- virtual Addr branchTarget(ThreadContext *tc) const;
+ virtual TheISA::PCState branchTarget(ThreadContext *tc) const;
/**
* Return true if the instruction is a control transfer, and if so,
* return the target address as well.
*/
- bool hasBranchTarget(Addr pc, ThreadContext *tc, Addr &tgt) const;
+ bool hasBranchTarget(const TheISA::PCState &pc, ThreadContext *tc,
+ TheISA::PCState &tgt) const;
/**
* Return string representation of disassembled instruction.
diff --git a/src/cpu/thread_context.cc b/src/cpu/thread_context.cc
index f2083ef08..c4960ea30 100644
--- a/src/cpu/thread_context.cc
+++ b/src/cpu/thread_context.cc
@@ -65,16 +65,8 @@ ThreadContext::compare(ThreadContext *one, ThreadContext *two)
}
#endif
- Addr pc1 = one->readPC();
- Addr pc2 = two->readPC();
- if (pc1 != pc2)
- panic("PCs doesn't match, one: %#x, two: %#x", pc1, pc2);
-
- Addr npc1 = one->readNextPC();
- Addr npc2 = two->readNextPC();
- if (npc1 != npc2)
- panic("NPCs doesn't match, one: %#x, two: %#x", npc1, npc2);
-
+ if (!(one->pcState() == two->pcState()))
+ panic("PC state doesn't match.");
int id1 = one->cpuId();
int id2 = two->cpuId();
if (id1 != id2)
diff --git a/src/cpu/thread_context.hh b/src/cpu/thread_context.hh
index 753fa2146..1c70ef59a 100644
--- a/src/cpu/thread_context.hh
+++ b/src/cpu/thread_context.hh
@@ -192,25 +192,15 @@ class ThreadContext
virtual void setFloatRegBits(int reg_idx, FloatRegBits val) = 0;
- virtual uint64_t readPC() = 0;
+ virtual TheISA::PCState pcState() = 0;
- virtual void setPC(uint64_t val) = 0;
+ virtual void pcState(const TheISA::PCState &val) = 0;
- virtual uint64_t readNextPC() = 0;
+ virtual Addr instAddr() = 0;
- virtual void setNextPC(uint64_t val) = 0;
+ virtual Addr nextInstAddr() = 0;
- virtual uint64_t readNextNPC() = 0;
-
- virtual void setNextNPC(uint64_t val) = 0;
-
- virtual uint64_t readMicroPC() = 0;
-
- virtual void setMicroPC(uint64_t val) = 0;
-
- virtual uint64_t readNextMicroPC() = 0;
-
- virtual void setNextMicroPC(uint64_t val) = 0;
+ virtual MicroPC microPC() = 0;
virtual MiscReg readMiscRegNoEffect(int misc_reg) = 0;
@@ -377,25 +367,13 @@ class ProxyThreadContext : public ThreadContext
void setFloatRegBits(int reg_idx, FloatRegBits val)
{ actualTC->setFloatRegBits(reg_idx, val); }
- uint64_t readPC() { return actualTC->readPC(); }
-
- void setPC(uint64_t val) { actualTC->setPC(val); }
-
- uint64_t readNextPC() { return actualTC->readNextPC(); }
-
- void setNextPC(uint64_t val) { actualTC->setNextPC(val); }
-
- uint64_t readNextNPC() { return actualTC->readNextNPC(); }
-
- void setNextNPC(uint64_t val) { actualTC->setNextNPC(val); }
-
- uint64_t readMicroPC() { return actualTC->readMicroPC(); }
-
- void setMicroPC(uint64_t val) { actualTC->setMicroPC(val); }
+ TheISA::PCState pcState() { return actualTC->pcState(); }
- uint64_t readNextMicroPC() { return actualTC->readMicroPC(); }
+ void pcState(const TheISA::PCState &val) { actualTC->pcState(val); }
- void setNextMicroPC(uint64_t val) { actualTC->setNextMicroPC(val); }
+ Addr instAddr() { return actualTC->instAddr(); }
+ Addr nextInstAddr() { return actualTC->nextInstAddr(); }
+ MicroPC microPC() { return actualTC->microPC(); }
bool readPredicate() { return actualTC->readPredicate(); }