diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/cpu/o3/commit.hh | 3 | ||||
-rw-r--r-- | src/cpu/o3/commit_impl.hh | 26 | ||||
-rw-r--r-- | src/cpu/o3/fetch_impl.hh | 1 |
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 { |