diff options
author | Korey Sewell <ksewell@umich.edu> | 2011-06-19 21:43:35 -0400 |
---|---|---|
committer | Korey Sewell <ksewell@umich.edu> | 2011-06-19 21:43:35 -0400 |
commit | b195da9345c00c2961558f80715660c0c0a629fc (patch) | |
tree | 0e3c2dee853e7aa46db1a592b62a9d7934c00c69 /src/cpu/inorder/resources/execution_unit.cc | |
parent | d5d4e47f76ec254b89c6b884f5fcbf340d4fed49 (diff) | |
download | gem5-b195da9345c00c2961558f80715660c0c0a629fc.tar.xz |
inorder: use setupSquash for misspeculation
implement a clean interface to handle branch misprediction and eventually all pipeline
flushing
Diffstat (limited to 'src/cpu/inorder/resources/execution_unit.cc')
-rw-r--r-- | src/cpu/inorder/resources/execution_unit.cc | 94 |
1 files changed, 19 insertions, 75 deletions
diff --git a/src/cpu/inorder/resources/execution_unit.cc b/src/cpu/inorder/resources/execution_unit.cc index ca1f4ade4..4363f125d 100644 --- a/src/cpu/inorder/resources/execution_unit.cc +++ b/src/cpu/inorder/resources/execution_unit.cc @@ -143,87 +143,30 @@ ExecutionUnit::execute(int slot_num) inst->setExecuted(); if (fault == NoFault) { - // If branch is mispredicted, then signal squash - // throughout all stages behind the pipeline stage - // that got squashed. if (inst->mispredicted()) { - int stage_num = exec_req->getStageNum(); - ThreadID tid = inst->readTid(); - // If it's a branch ... - if (inst->isDirectCtrl()) { - assert(!inst->isIndirectCtrl()); - - TheISA::PCState pc = inst->pcState(); - TheISA::advancePC(pc, inst->staticInst); - inst->setPredTarg(pc); - - if (inst->predTaken() && inst->isCondDelaySlot()) { - assert(0 && "Not Handling Conditional Delay Slots (1)"); - inst->bdelaySeqNum = seq_num; - DPRINTF(InOrderExecute, "[tid:%i]: Conditional" - " branch inst [sn:%i] PC %s mis" - "predicted as taken.\n", tid, - seq_num, inst->pcState()); - } else if (!inst->predTaken() && inst->isCondDelaySlot()) { - assert(0 && "Not Handling Conditional Delay Slots (2)"); - inst->bdelaySeqNum = seq_num; - inst->procDelaySlotOnMispred = true; - - DPRINTF(InOrderExecute, "[tid:%i]: Conditional" - " branch inst [sn:%i] PC %s mis" - "predicted as not taken.\n", tid, - seq_num, inst->pcState()); - } else { - inst->bdelaySeqNum = seq_num; - - DPRINTF(InOrderExecute, "[tid:%i]: " - "Misprediction detected at " - "[sn:%i] PC %s,\n\t squashing after " - "delay slot instruction [sn:%i].\n", - tid, seq_num, inst->pcState(), - inst->bdelaySeqNum); - DPRINTF(InOrderStall, "STALL: [tid:%i]: Branch" - " misprediction at %s\n", - tid, inst->pcState()); - } - - DPRINTF(InOrderExecute, "[tid:%i] Redirecting " - "fetch to %s.\n", tid, - inst->readPredTarg()); - - } else if (inst->isIndirectCtrl()){ - TheISA::PCState pc = inst->pcState(); - TheISA::advancePC(pc, inst->staticInst); - inst->seqNum = seq_num; - inst->setPredTarg(pc); - - inst->bdelaySeqNum = seq_num; + assert(inst->isControl()); - DPRINTF(InOrderExecute, "[tid:%i] Redirecting" - " fetch to %s.\n", tid, - inst->readPredTarg()); - } else { - panic("Non-control instruction (%s) mispredict" - "ing?!!", inst->staticInst->getName()); - } - - DPRINTF(InOrderExecute, "[tid:%i] Squashing will " - "start from stage %i.\n", tid, stage_num); - - cpu->pipelineStage[stage_num]->squashDueToBranch(inst, - tid); + // Set up Squash Generated By this Misprediction + unsigned stage_num = exec_req->getStageNum(); + ThreadID tid = inst->readTid(); + TheISA::PCState pc = inst->pcState(); + TheISA::advancePC(pc, inst->staticInst); + inst->setPredTarg(pc); + inst->setSquashInfo(stage_num); - inst->squashingStage = stage_num; + setupSquash(inst, stage_num, tid); - // Squash throughout other resources - cpu->resPool->scheduleEvent((InOrderCPU::CPUEventType) - ResourcePool::SquashAll, - inst, 0, 0, tid); + DPRINTF(InOrderExecute, "[tid:%i]: [sn:%i] Squashing from " + "stage %i. Redirecting fetch to %s.\n", tid, + inst->seqNum, stage_num, pc); + DPRINTF(InOrderStall, "STALL: [tid:%i]: Branch" + " misprediction at %s\n", tid, inst->pcState()); if (inst->predTaken()) { predictedTakenIncorrect++; DPRINTF(InOrderExecute, "[tid:%i] [sn:%i] %s ..." - "PC %s ... Mispredicts! (Taken)\n", + "PC %s ... Mispredicts! " + "(Prediction: Taken)\n", tid, inst->seqNum, inst->staticInst->disassemble( inst->instAddr()), @@ -231,7 +174,8 @@ ExecutionUnit::execute(int slot_num) } else { predictedNotTakenIncorrect++; DPRINTF(InOrderExecute, "[tid:%i] [sn:%i] %s ..." - "PC %s ... Mispredicts! (Not Taken)\n", + "PC %s ... Mispredicts! " + "(Prediction: Not Taken)\n", tid, inst->seqNum, inst->staticInst->disassemble( inst->instAddr()), @@ -247,7 +191,7 @@ ExecutionUnit::execute(int slot_num) exec_req->done(); } else { warn("inst [sn:%i] had a %s fault", seq_num, fault->name()); - + inst->fault = fault; exec_req->done(); } } else { |