changeset cd9dd7f8125f in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=cd9dd7f8125f
description:
inorder: implement trap handling
diffstat:
src/cpu/inorder/cpu.cc | 23 +++-
src/cpu/inorder/cpu.hh | 35 +++++--
src/cpu/inorder/inorder_dyn_inst.cc | 17 ++-
src/cpu/inorder/inorder_dyn_inst.hh | 4 +-
src/cpu/inorder/pipeline_stage.cc | 41 ++------
src/cpu/inorder/pipeline_stage.hh | 14 +--
src/cpu/inorder/resource.cc | 4 +-
src/cpu/inorder/resource.hh | 3 +
src/cpu/inorder/resource_pool.9stage.cc | 6 +-
src/cpu/inorder/resource_pool.cc | 20 +++-
src/cpu/inorder/resource_pool.hh | 3 +
src/cpu/inorder/resources/agen_unit.cc | 4 +-
src/cpu/inorder/resources/cache_unit.cc | 10 +-
src/cpu/inorder/resources/execution_unit.cc | 8 +-
src/cpu/inorder/resources/fetch_seq_unit.cc | 115 +++++++++++++++-----------
src/cpu/inorder/resources/fetch_seq_unit.hh | 11 +-
src/cpu/inorder/resources/fetch_unit.cc | 7 +
src/cpu/inorder/resources/fetch_unit.hh | 2 +
src/cpu/inorder/resources/graduation_unit.cc | 9 +-
19 files changed, 201 insertions(+), 135 deletions(-)
diffs (truncated from 732 to 300 lines):
diff -r 40d1b3f5bee6 -r cd9dd7f8125f src/cpu/inorder/cpu.cc
--- a/src/cpu/inorder/cpu.cc Sun Jun 19 21:43:35 2011 -0400
+++ b/src/cpu/inorder/cpu.cc Sun Jun 19 21:43:36 2011 -0400
@@ -142,7 +142,8 @@
case Trap:
DPRINTF(InOrderCPU, "Trapping CPU\n");
- cpu->trapCPU(fault, tid, inst);
+ cpu->trap(fault, tid, inst);
+ cpu->resPool->trap(fault, tid, inst);
break;
default:
@@ -451,8 +452,8 @@
if (inst->splitInst)
M.needs(DCache, CacheUnit::InitSecondSplitRead);
} else if ( inst->isStore() ) {
- if ( inst->numSrcRegs() >= 2 ) {
- M.needs(RegManager, UseDefUnit::ReadSrcReg, 1);
+ for (int i = 1; i < inst->numSrcRegs(); i++ ) {
+ M.needs(RegManager, UseDefUnit::ReadSrcReg, i);
}
M.needs(AGEN, AGENUnit::GenerateAddr);
M.needs(DCache, CacheUnit::InitiateWriteData);
@@ -795,14 +796,13 @@
#endif
void
-InOrderCPU::trap(Fault fault, ThreadID tid, DynInstPtr inst, int delay)
+InOrderCPU::trapContext(Fault fault, ThreadID tid, DynInstPtr inst, int delay)
{
- //@ Squash Pipeline during TRAP
scheduleCpuEvent(Trap, fault, tid, inst, delay);
}
void
-InOrderCPU::trapCPU(Fault fault, ThreadID tid, DynInstPtr inst)
+InOrderCPU::trap(Fault fault, ThreadID tid, DynInstPtr inst)
{
fault->invoke(tcBase(tid), inst->staticInst);
}
@@ -1302,11 +1302,18 @@
void
InOrderCPU::instDone(DynInstPtr inst, ThreadID tid)
{
- // Set the CPU's PCs - This contributes to the precise state of the CPU
+ // Set the nextPC to be fetched if this is the last instruction
+ // committed
+ // ========
+ // 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.)
- pcState(inst->pcState(), tid);
+ TheISA::PCState comm_pc = inst->pcState();
+ lastCommittedPC[tid] = comm_pc;
+ TheISA::advancePC(comm_pc, inst->staticInst);
+ pcState(comm_pc, tid);
+ //@todo: may be unnecessary with new-ISA-specific branch handling code
if (inst->isControl()) {
thread[tid]->lastGradIsBranch = true;
thread[tid]->lastBranchPC = inst->pcState();
diff -r 40d1b3f5bee6 -r cd9dd7f8125f src/cpu/inorder/cpu.hh
--- a/src/cpu/inorder/cpu.hh Sun Jun 19 21:43:35 2011 -0400
+++ b/src/cpu/inorder/cpu.hh Sun Jun 19 21:43:36 2011 -0400
@@ -275,6 +275,9 @@
/** Program Counters */
TheISA::PCState pc[ThePipeline::MaxThreads];
+ /** Last Committed PC */
+ TheISA::PCState lastCommittedPC[ThePipeline::MaxThreads];
+
/** The Register File for the CPU */
union {
FloatReg f[ThePipeline::MaxThreads][TheISA::NumFloatRegs];
@@ -430,33 +433,45 @@
bool validDataAddr(Addr addr) { return true; }
#endif
- /** trap() - sets up a trap event on the cpuTraps to handle given fault.
- * trapCPU() - Traps to handle given fault
- */
- void trap(Fault fault, ThreadID tid, DynInstPtr inst, int delay = 0);
- void trapCPU(Fault fault, ThreadID tid, DynInstPtr inst);
+ /** Schedule a trap on the CPU */
+ void trapContext(Fault fault, ThreadID tid, DynInstPtr inst, int delay =
0);
+
+ /** Perform trap to Handle Given Fault */
+ void trap(Fault fault, ThreadID tid, DynInstPtr inst);
+
+ /** Schedule thread activation on the CPU */
+ void activateContext(ThreadID tid, int delay = 0);
/** Add Thread to Active Threads List. */
- void activateContext(ThreadID tid, int delay = 0);
void activateThread(ThreadID tid);
+
+ /** Activate Thread In Each Pipeline Stage */
void activateThreadInPipeline(ThreadID tid);
- /** Add Thread to Active Threads List. */
+ /** Schedule Thread Activation from Ready List */
void activateNextReadyContext(int delay = 0);
+
+ /** Add Thread From Ready List to Active Threads List. */
void activateNextReadyThread();
+ /** Schedule a thread deactivation on the CPU */
+ void deactivateContext(ThreadID tid, int delay = 0);
+
/** Remove from Active Thread List */
- void deactivateContext(ThreadID tid, int delay = 0);
void deactivateThread(ThreadID tid);
+ /** Schedule a thread suspension on the CPU */
+ void suspendContext(ThreadID tid, int delay = 0);
+
/** Suspend Thread, Remove from Active Threads List, Add to Suspend List */
- void suspendContext(ThreadID tid, int delay = 0);
void suspendThread(ThreadID tid);
+ /** Schedule a thread halt on the CPU */
+ void haltContext(ThreadID tid, int delay = 0);
+
/** Halt Thread, Remove from Active Thread List, Place Thread on Halted
* Threads List
*/
- void haltContext(ThreadID tid, int delay = 0);
void haltThread(ThreadID tid);
/** squashFromMemStall() - sets up a squash event
diff -r 40d1b3f5bee6 -r cd9dd7f8125f src/cpu/inorder/inorder_dyn_inst.cc
--- a/src/cpu/inorder/inorder_dyn_inst.cc Sun Jun 19 21:43:35 2011 -0400
+++ b/src/cpu/inorder/inorder_dyn_inst.cc Sun Jun 19 21:43:36 2011 -0400
@@ -54,7 +54,7 @@
InstSeqNum seq_num,
ThreadID tid,
unsigned _asid)
- : seqNum(seq_num), bdelaySeqNum(0), threadNumber(tid), asid(_asid),
+ : seqNum(seq_num), squashSeqNum(0), threadNumber(tid), asid(_asid),
virtProcNumber(0), staticInst(NULL), traceData(NULL), cpu(cpu),
thread(state), fault(NoFault), memData(NULL), loadData(0),
storeData(0), effAddr(0), physEffAddr(0), memReqFlags(0),
@@ -319,7 +319,15 @@
InOrderDynInst::setSquashInfo(unsigned stage_num)
{
squashingStage = stage_num;
- bdelaySeqNum = seqNum;
+
+ // If it's a fault, then we need to squash
+ // the faulting instruction too. Squash
+ // functions squash above a seqNum, so we
+ // decrement here for that case
+ if (fault != NoFault)
+ squashSeqNum = seqNum - 1;
+ else
+ squashSeqNum = seqNum;
#if ISA_HAS_DELAY_SLOT
if (isControl()) {
@@ -329,10 +337,9 @@
// Check to see if we should squash after the
// branch or after a branch delay slot.
if (pc.nextInstAddr() == pc.instAddr() + sizeof(MachInst))
- bdelaySeqNum = seqNum + 1;
+ squashSeqNum = seqNum + 1;
else
- bdelaySeqNum = seqNum;
-
+ squashSeqNum = seqNum;
}
#endif
}
diff -r 40d1b3f5bee6 -r cd9dd7f8125f src/cpu/inorder/inorder_dyn_inst.hh
--- a/src/cpu/inorder/inorder_dyn_inst.hh Sun Jun 19 21:43:35 2011 -0400
+++ b/src/cpu/inorder/inorder_dyn_inst.hh Sun Jun 19 21:43:36 2011 -0400
@@ -122,8 +122,8 @@
/** The sequence number of the instruction. */
InstSeqNum seqNum;
- /** The sequence number of the instruction. */
- InstSeqNum bdelaySeqNum;
+ /** If this instruction is squashing, the number should we squash behind.
*/
+ InstSeqNum squashSeqNum;
enum Status {
RegDepMapEntry, /// Instruction is entered onto the RegDepMap
diff -r 40d1b3f5bee6 -r cd9dd7f8125f src/cpu/inorder/pipeline_stage.cc
--- a/src/cpu/inorder/pipeline_stage.cc Sun Jun 19 21:43:35 2011 -0400
+++ b/src/cpu/inorder/pipeline_stage.cc Sun Jun 19 21:43:36 2011 -0400
@@ -342,43 +342,27 @@
}
void
-PipelineStage::squashDueToBranch(DynInstPtr &inst, ThreadID tid)
+PipelineStage::setupSquash(DynInstPtr inst, ThreadID tid)
{
- if (cpu->squashSeqNum[tid] < inst->seqNum &&
- cpu->lastSquashCycle[tid] == curTick()){
+ if (cpu->lastSquashCycle[tid] == curTick() &&
+ cpu->squashSeqNum[tid] < inst->seqNum){
DPRINTF(Resource, "Ignoring [sn:%i] branch squash signal due to "
"another stage's squash signal for after [sn:%i].\n",
inst->seqNum, cpu->squashSeqNum[tid]);
} else {
- // Send back mispredict information.
- toPrevStages->stageInfo[stageNum][tid].branchMispredict = true;
- toPrevStages->stageInfo[stageNum][tid].predIncorrect = true;
- toPrevStages->stageInfo[stageNum][tid].doneSeqNum = inst->seqNum;
+ InstSeqNum squash_seq_num = inst->squashSeqNum;
+
toPrevStages->stageInfo[stageNum][tid].squash = true;
- toPrevStages->stageInfo[stageNum][tid].nextPC = inst->readPredTarg();
+ toPrevStages->stageInfo[stageNum][tid].doneSeqNum =
+ squash_seq_num;
- toPrevStages->stageInfo[stageNum][tid].branchTaken =
- inst->pcState().branching();
-
-#if ISA_HAS_DELAY_SLOT
- toPrevStages->stageInfo[stageNum][tid].bdelayDoneSeqNum =
- inst->bdelaySeqNum;
-
- InstSeqNum squash_seq_num = inst->bdelaySeqNum;
-#else
- toPrevStages->stageInfo[stageNum][tid].bdelayDoneSeqNum = inst->seqNum;
- InstSeqNum squash_seq_num = inst->seqNum;
-#endif
-
- DPRINTF(InOrderStage, "Target being re-set to %08p\n",
- inst->predInstAddr());
DPRINTF(InOrderStage, "[tid:%i]: Squashing after [sn:%i], "
- "due to [sn:%i] branch.\n", tid, squash_seq_num,
- inst->seqNum);
+ "due to [sn:%i] %s.\n", tid, squash_seq_num,
+ inst->seqNum, inst->instName());
// Save squash num for later stage use
+ cpu->lastSquashCycle[tid] = curTick();
cpu->squashSeqNum[tid] = squash_seq_num;
- cpu->lastSquashCycle[tid] = curTick();
}
}
@@ -398,7 +382,6 @@
for (int i=0; i < insts_from_prev_stage; i++) {
if (prevStage->insts[i]->threadNumber == tid &&
prevStage->insts[i]->seqNum > squash_seq_num) {
- // Change Comment to Annulling previous instruction
DPRINTF(InOrderStage, "[tid:%i]: Squashing instruction, "
"[sn:%i] PC %s.\n",
tid,
@@ -676,7 +659,7 @@
DPRINTF(InOrderStage, "[tid:%u]: Squashing instructions due to "
"squash from stage %u.\n", tid, stage_idx);
InstSeqNum squash_seq_num = fromNextStages->
- stageInfo[stage_idx][tid].bdelayDoneSeqNum;
+ stageInfo[stage_idx][tid].doneSeqNum;
squash(squash_seq_num, tid);
break; //return true;
}
@@ -989,7 +972,7 @@
// Remove Thread From Pipeline & Resource Pool
inst->squashingStage = stageNum;
- inst->bdelaySeqNum = inst->seqNum;
+ inst->squashSeqNum = inst->seqNum;
cpu->squashFromMemStall(inst, tid);
// Switch On Cache Miss
diff -r 40d1b3f5bee6 -r cd9dd7f8125f src/cpu/inorder/pipeline_stage.hh
--- a/src/cpu/inorder/pipeline_stage.hh Sun Jun 19 21:43:35 2011 -0400
+++ b/src/cpu/inorder/pipeline_stage.hh Sun Jun 19 21:43:36 2011 -0400
@@ -227,21 +227,17 @@
public:
void activateThread(ThreadID tid);
- /** Squashes if there is a PC-relative branch that was predicted
- * incorrectly. Sends squash information back to fetch.
- */
- void squashDueToBranch(DynInstPtr &inst, ThreadID tid);
+ /** Setup Squashing Information to be passed back thru the pipeline */
+ void setupSquash(DynInstPtr inst, ThreadID tid);
virtual void squashDueToMemStall(InstSeqNum seq_num, ThreadID tid);
+ /** Perform squash of instructions above seq_num */
+ virtual void squash(InstSeqNum squash_num, ThreadID tid);
+
/** Squash instructions from stage buffer */
void squashPrevStageInsts(InstSeqNum squash_seq_num, ThreadID tid);
- /** Squashes due to commit signalling a squash. Changes status to
- * squashing and clears block/unblock signals as needed.
- */
- virtual void squash(InstSeqNum squash_num, ThreadID tid);
-
void dumpInsts();
protected:
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev