summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cpu/o3/commit.hh3
-rw-r--r--src/cpu/o3/commit_impl.hh26
-rw-r--r--src/cpu/o3/fetch_impl.hh1
3 files changed, 22 insertions, 8 deletions
diff --git a/src/cpu/o3/commit.hh b/src/cpu/o3/commit.hh
index f35928b08..094518655 100644
--- a/src/cpu/o3/commit.hh
+++ b/src/cpu/o3/commit.hh
@@ -441,6 +441,9 @@ class DefaultCommit
/** Rename map interface. */
RenameMap *renameMap[Impl::MaxThreads];
+ /** True if last committed microop can be followed by an interrupt */
+ bool canHandleInterrupts;
+
/** Updates commit stats based on this instruction. */
void updateComInstStats(DynInstPtr &inst);
diff --git a/src/cpu/o3/commit_impl.hh b/src/cpu/o3/commit_impl.hh
index a9b795933..446c8e6f3 100644
--- a/src/cpu/o3/commit_impl.hh
+++ b/src/cpu/o3/commit_impl.hh
@@ -105,7 +105,8 @@ DefaultCommit<Impl>::DefaultCommit(O3CPU *_cpu, DerivO3CPUParams *params)
numThreads(params->numThreads),
drainPending(false),
switchedOut(false),
- trapLatency(params->trapLatency)
+ trapLatency(params->trapLatency),
+ canHandleInterrupts(true)
{
_status = Active;
_nextStatus = Inactive;
@@ -714,7 +715,7 @@ DefaultCommit<Impl>::handleInterrupt()
// Wait until all in flight instructions are finished before enterring
// the interrupt.
- if (cpu->instList.empty()) {
+ if (canHandleInterrupts && cpu->instList.empty()) {
// Squash or record that I need to squash this cycle if
// an interrupt needed to be handled.
DPRINTF(Commit, "Interrupt detected.\n");
@@ -743,7 +744,10 @@ DefaultCommit<Impl>::handleInterrupt()
interrupt = NoFault;
} else {
- DPRINTF(Commit, "Interrupt pending, waiting for ROB to empty.\n");
+ DPRINTF(Commit, "Interrupt pending: instruction is %sin "
+ "flight, ROB is %sempty\n",
+ canHandleInterrupts ? "not " : "",
+ cpu->instList.empty() ? "" : "not " );
}
}
@@ -775,11 +779,6 @@ void
DefaultCommit<Impl>::commit()
{
if (FullSystem) {
- // Check for any interrupt that we've already squashed for and
- // start processing it.
- if (interrupt != NoFault)
- handleInterrupt();
-
// Check if we have a interrupt and get read to handle it
if (cpu->checkInterrupts(cpu->tcBase(0)))
propagateInterrupt();
@@ -936,6 +935,11 @@ DefaultCommit<Impl>::commitInsts()
// Commit as many instructions as possible until the commit bandwidth
// limit is reached, or it becomes impossible to commit any more.
while (num_committed < commitWidth) {
+ // Check for any interrupt that we've already squashed for
+ // and start processing it.
+ if (interrupt != NoFault)
+ handleInterrupt();
+
int commit_thread = getCommittingThread();
if (commit_thread == -1 || !rob->isHeadReady(commit_thread))
@@ -992,6 +996,12 @@ DefaultCommit<Impl>::commitInsts()
cpu->instDone(tid);
}
+ if (tid == 0) {
+ canHandleInterrupts = (!head_inst->isDelayedCommit()) &&
+ ((THE_ISA != ALPHA_ISA) ||
+ (!(pc[0].instAddr() & 0x3)));
+ }
+
// Updates misc. registers.
head_inst->updateMiscRegs();
diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh
index 48c21917a..72d9e960e 100644
--- a/src/cpu/o3/fetch_impl.hh
+++ b/src/cpu/o3/fetch_impl.hh
@@ -1144,6 +1144,7 @@ DefaultFetch<Impl>::fetch(bool &status_change)
// an delayed commit micro-op currently (delayed commit instructions
// are not interruptable by interrupts, only faults)
++fetchMiscStallCycles;
+ DPRINTF(Fetch, "[tid:%i]: Fetch is stalled!\n", tid);
return;
}
} else {