summaryrefslogtreecommitdiff
path: root/src/cpu
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu')
-rw-r--r--src/cpu/o3/iew_impl.hh62
-rw-r--r--src/cpu/o3/inst_queue_impl.hh18
-rw-r--r--src/cpu/o3/mem_dep_unit_impl.hh10
3 files changed, 62 insertions, 28 deletions
diff --git a/src/cpu/o3/iew_impl.hh b/src/cpu/o3/iew_impl.hh
index f24eaf2c4..4883e5a5c 100644
--- a/src/cpu/o3/iew_impl.hh
+++ b/src/cpu/o3/iew_impl.hh
@@ -1153,19 +1153,6 @@ DefaultIEW<Impl>::dispatchInsts(unsigned tid)
inst->setCanCommit();
instQueue.insertBarrier(inst);
add_to_iq = false;
- } else if (inst->isNonSpeculative()) {
- DPRINTF(IEW, "[tid:%i]: Issue: Nonspeculative instruction "
- "encountered, skipping.\n", tid);
-
- // Same as non-speculative stores.
- inst->setCanCommit();
-
- // Specifically insert it as nonspeculative.
- instQueue.insertNonSpec(inst);
-
- ++iewDispNonSpecInsts;
-
- add_to_iq = false;
} else if (inst->isNop()) {
DPRINTF(IEW, "[tid:%i]: Issue: Nop instruction encountered, "
"skipping.\n", tid);
@@ -1193,6 +1180,20 @@ DefaultIEW<Impl>::dispatchInsts(unsigned tid)
} else {
add_to_iq = true;
}
+ if (inst->isNonSpeculative()) {
+ DPRINTF(IEW, "[tid:%i]: Issue: Nonspeculative instruction "
+ "encountered, skipping.\n", tid);
+
+ // Same as non-speculative stores.
+ inst->setCanCommit();
+
+ // Specifically insert it as nonspeculative.
+ instQueue.insertNonSpec(inst);
+
+ ++iewDispNonSpecInsts;
+
+ add_to_iq = false;
+ }
// If the instruction queue is not full, then add the
// instruction.
@@ -1379,6 +1380,7 @@ DefaultIEW<Impl>::executeInsts()
predictedNotTakenIncorrect++;
}
} else if (ldstQueue.violation(tid)) {
+ assert(inst->isMemRef());
// If there was an ordering violation, then get the
// DynInst that caused the violation. Note that this
// clears the violation signal.
@@ -1391,10 +1393,10 @@ DefaultIEW<Impl>::executeInsts()
// Ensure the violating instruction is older than
// current squash
- if (fetchRedirect[tid] &&
- violator->seqNum >= toCommit->squashedSeqNum[tid])
+/* if (fetchRedirect[tid] &&
+ violator->seqNum >= toCommit->squashedSeqNum[tid] + 1)
continue;
-
+*/
fetchRedirect[tid] = true;
// Tell the instruction queue that a violation has occured.
@@ -1414,6 +1416,33 @@ DefaultIEW<Impl>::executeInsts()
squashDueToMemBlocked(inst, tid);
}
+ } else {
+ // Reset any state associated with redirects that will not
+ // be used.
+ if (ldstQueue.violation(tid)) {
+ assert(inst->isMemRef());
+
+ 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);
+ DPRINTF(IEW, "Violation will not be handled because "
+ "already squashing\n");
+
+ ++memOrderViolationEvents;
+ }
+ 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);
+ DPRINTF(IEW, "Blocked load will not be handled because "
+ "already squashing\n");
+
+ ldstQueue.setLoadBlockedHandled(tid);
+ }
+
}
}
@@ -1563,6 +1592,7 @@ DefaultIEW<Impl>::tick()
//DPRINTF(IEW,"NonspecInst from thread %i",tid);
if (fromCommit->commitInfo[tid].uncached) {
instQueue.replayMemInst(fromCommit->commitInfo[tid].uncachedLoad);
+ fromCommit->commitInfo[tid].uncachedLoad->setAtCommit();
} else {
instQueue.scheduleNonSpec(
fromCommit->commitInfo[tid].nonSpecSeqNum);
diff --git a/src/cpu/o3/inst_queue_impl.hh b/src/cpu/o3/inst_queue_impl.hh
index 98b8fa900..87bf60dfa 100644
--- a/src/cpu/o3/inst_queue_impl.hh
+++ b/src/cpu/o3/inst_queue_impl.hh
@@ -829,6 +829,8 @@ InstructionQueue<Impl>::scheduleNonSpec(const InstSeqNum &inst)
unsigned tid = (*inst_it).second->threadNumber;
+ (*inst_it).second->setAtCommit();
+
(*inst_it).second->setCanIssue();
if (!(*inst_it).second->isMemRef()) {
@@ -960,6 +962,8 @@ template <class Impl>
void
InstructionQueue<Impl>::rescheduleMemInst(DynInstPtr &resched_inst)
{
+ DPRINTF(IQ, "Rescheduling mem inst [sn:%lli]\n", resched_inst->seqNum);
+ resched_inst->clearCanIssue();
memDepUnit[resched_inst->threadNumber].reschedule(resched_inst);
}
@@ -984,7 +988,6 @@ InstructionQueue<Impl>::completeMemInst(DynInstPtr &completed_inst)
completed_inst->memOpDone = true;
memDepUnit[tid].completed(completed_inst);
-
count[tid]--;
}
@@ -1084,16 +1087,21 @@ InstructionQueue<Impl>::doSquash(unsigned tid)
++iqSquashedOperandsExamined;
}
- } else if (!squashed_inst->isStoreConditional() || !squashed_inst->isCompleted()) {
+ } else if (!squashed_inst->isStoreConditional() ||
+ !squashed_inst->isCompleted()) {
NonSpecMapIt ns_inst_it =
nonSpecInsts.find(squashed_inst->seqNum);
assert(ns_inst_it != nonSpecInsts.end());
+ if (ns_inst_it == nonSpecInsts.end()) {
+ assert(squashed_inst->getFault() != NoFault);
+ } else {
- (*ns_inst_it).second = NULL;
+ (*ns_inst_it).second = NULL;
- nonSpecInsts.erase(ns_inst_it);
+ nonSpecInsts.erase(ns_inst_it);
- ++iqSquashedNonSpecRemoved;
+ ++iqSquashedNonSpecRemoved;
+ }
}
// Might want to also clear out the head of the dependency graph.
diff --git a/src/cpu/o3/mem_dep_unit_impl.hh b/src/cpu/o3/mem_dep_unit_impl.hh
index f19980fd5..64558efaa 100644
--- a/src/cpu/o3/mem_dep_unit_impl.hh
+++ b/src/cpu/o3/mem_dep_unit_impl.hh
@@ -214,6 +214,9 @@ MemDepUnit<MemDepPred, Impl>::insert(DynInstPtr &inst)
inst_entry->regsReady = true;
}
+ // Clear the bit saying this instruction can issue.
+ inst->clearCanIssue();
+
// Add this instruction to the list of dependents.
store_entry->dependInsts.push_back(inst_entry);
@@ -357,7 +360,6 @@ void
MemDepUnit<MemDepPred, Impl>::replay(DynInstPtr &inst)
{
DynInstPtr temp_inst;
- bool found_inst = false;
// For now this replay function replays all waiting memory ops.
while (!instsToReplay.empty()) {
@@ -371,14 +373,8 @@ MemDepUnit<MemDepPred, Impl>::replay(DynInstPtr &inst)
moveToReady(inst_entry);
- if (temp_inst == inst) {
- found_inst = true;
- }
-
instsToReplay.pop_front();
}
-
- assert(found_inst);
}
template <class MemDepPred, class Impl>