diff options
Diffstat (limited to 'src/cpu/o3/decode_impl.hh')
-rw-r--r-- | src/cpu/o3/decode_impl.hh | 25 |
1 files changed, 17 insertions, 8 deletions
diff --git a/src/cpu/o3/decode_impl.hh b/src/cpu/o3/decode_impl.hh index 26ed40c67..79a0bfdbf 100644 --- a/src/cpu/o3/decode_impl.hh +++ b/src/cpu/o3/decode_impl.hh @@ -282,6 +282,10 @@ DefaultDecode<Impl>::squash(DynInstPtr &inst, unsigned tid) toFetch->decodeInfo[tid].doneSeqNum = inst->seqNum; toFetch->decodeInfo[tid].squash = true; toFetch->decodeInfo[tid].nextPC = inst->branchTarget(); + ///FIXME There needs to be a way to set the nextPC and nextNPC + ///explicitly for ISAs with delay slots. + toFetch->decodeInfo[tid].nextNPC = + inst->branchTarget() + sizeof(TheISA::MachInst); #if ISA_HAS_DELAY_SLOT toFetch->decodeInfo[tid].branchTaken = inst->readNextNPC() != (inst->readNextPC() + sizeof(TheISA::MachInst)); @@ -743,9 +747,9 @@ DefaultDecode<Impl>::decodeInsts(unsigned tid) // Ensure that if it was predicted as a branch, it really is a // branch. - if (inst->predTaken() && !inst->isControl()) { - DPRINTF(Decode, "PredPC : %#x != NextPC: %#x\n",inst->predPC, - inst->nextPC + 4); + if (inst->readPredTaken() && !inst->isControl()) { + DPRINTF(Decode, "PredPC : %#x != NextPC: %#x\n", + inst->readPredPC(), inst->readNextPC() + 4); panic("Instruction predicted as a branch!"); @@ -762,26 +766,29 @@ DefaultDecode<Impl>::decodeInsts(unsigned tid) if (inst->isDirectCtrl() && inst->isUncondCtrl()) { ++decodeBranchResolved; - if (inst->branchTarget() != inst->readPredTarg()) { + if (inst->branchTarget() != inst->readPredPC()) { ++decodeBranchMispred; // Might want to set some sort of boolean and just do // a check at the end #if !ISA_HAS_DELAY_SLOT squash(inst, inst->threadNumber); - inst->setPredTarg(inst->branchTarget()); + Addr target = inst->branchTarget(); + inst->setPredTarg(target, target + sizeof(TheISA::MachInst)); break; #else // If mispredicted as taken, then ignore delay slot // instruction... else keep delay slot and squash // after it is sent to rename - if (inst->predTaken() && inst->isCondDelaySlot()) { + if (inst->readPredTaken() && inst->isCondDelaySlot()) { DPRINTF(Decode, "[tid:%i]: Conditional delay slot inst." "[sn:%i] PC %#x mispredicted as taken.\n", tid, inst->seqNum, inst->PC); bdelayDoneSeqNum[tid] = inst->seqNum; squash(inst, inst->threadNumber); - inst->setPredTarg(inst->branchTarget()); + Addr target = inst->branchTarget(); + inst->setPredTarg(target, + target + sizeof(TheISA::MachInst)); break; } else { DPRINTF(Decode, "[tid:%i]: Misprediction detected at " @@ -800,7 +807,9 @@ DefaultDecode<Impl>::decodeInsts(unsigned tid) if (squashAfterDelaySlot[tid]) { assert(!inst->isSquashed()); squash(squashInst[tid], squashInst[tid]->threadNumber); - squashInst[tid]->setPredTarg(squashInst[tid]->branchTarget()); + Addr target = squashInst[tid]->branchTarget(); + squashInst[tid]->setPredTarg(target, + target + sizeof(TheISA::MachInst)); assert(!inst->isSquashed()); break; } |