diff -r 10a06bd36839 -r 75e54d141aa0 src/cpu/o3/commit.hh --- a/src/cpu/o3/commit.hh Sat Jan 28 22:46:41 2012 -0600 +++ b/src/cpu/o3/commit.hh Sat Jan 28 23:02:31 2012 -0600 @@ -443,6 +443,9 @@ /** 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 -r 10a06bd36839 -r 75e54d141aa0 src/cpu/o3/commit_impl.hh --- a/src/cpu/o3/commit_impl.hh Sat Jan 28 22:46:41 2012 -0600 +++ b/src/cpu/o3/commit_impl.hh Sat Jan 28 23:02:31 2012 -0600 @@ -105,7 +105,8 @@ numThreads(params->numThreads), drainPending(false), switchedOut(false), - trapLatency(params->trapLatency) + trapLatency(params->trapLatency), + canHandleInterrupts(true) { _status = Active; _nextStatus = Inactive; @@ -718,7 +719,7 @@ // 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"); @@ -741,7 +742,10 @@ 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 " ); } } @@ -776,10 +780,6 @@ { #if FULL_SYSTEM - // 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 +936,11 @@ // 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 +997,12 @@ 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 -r 10a06bd36839 -r 75e54d141aa0 src/cpu/o3/fetch_impl.hh --- a/src/cpu/o3/fetch_impl.hh Sat Jan 28 22:46:41 2012 -0600 +++ b/src/cpu/o3/fetch_impl.hh Sat Jan 28 23:02:31 2012 -0600 @@ -1140,6 +1140,7 @@ // 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 {