summaryrefslogtreecommitdiff
path: root/src/cpu/o3/decode_impl.hh
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu/o3/decode_impl.hh')
-rw-r--r--src/cpu/o3/decode_impl.hh25
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;
}