summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabe Black <gabeblack@google.com>2014-12-05 01:47:35 -0800
committerGabe Black <gabeblack@google.com>2014-12-05 01:47:35 -0800
commitbacbb8ecbcee2b4c5c3fe71f415abc5852ae4a8f (patch)
tree79e771d5209f85f6d3ecf5cafcb5d9e254fa7be0
parentfe48c0a32bf749358eeb95e748f9fc2247cc5480 (diff)
downloadgem5-bacbb8ecbcee2b4c5c3fe71f415abc5852ae4a8f.tar.xz
cpu: Only check for PC events on instruction boundaries.
Only the instruction address is actually checked, so there's no need to check repeatedly while we're working through the microops of a macroop and that's not changing.
-rw-r--r--src/cpu/o3/commit_impl.hh41
-rw-r--r--src/cpu/simple/atomic.cc6
-rw-r--r--src/cpu/simple/timing.cc7
3 files changed, 32 insertions, 22 deletions
diff --git a/src/cpu/o3/commit_impl.hh b/src/cpu/o3/commit_impl.hh
index f0566233c..bb2b17209 100644
--- a/src/cpu/o3/commit_impl.hh
+++ b/src/cpu/o3/commit_impl.hh
@@ -1,4 +1,5 @@
/*
+ * Copyright 2014 Google, Inc.
* Copyright (c) 2010-2014 ARM Limited
* All rights reserved
*
@@ -1105,20 +1106,27 @@ DefaultCommit<Impl>::commitInsts()
}
}
- int count = 0;
- Addr oldpc;
- // Debug statement. Checks to make sure we're not
- // currently updating state while handling PC events.
- assert(!thread[tid]->noSquashFromTC && !thread[tid]->trapPending);
- do {
- oldpc = pc[tid].instAddr();
- cpu->system->pcEventQueue.service(thread[tid]->getTC());
- count++;
- } while (oldpc != pc[tid].instAddr());
- if (count > 1) {
- DPRINTF(Commit,
- "PC skip function event, stopping commit\n");
- break;
+ bool onInstBoundary = !head_inst->isMicroop() ||
+ head_inst->isLastMicroop() ||
+ !head_inst->isDelayedCommit();
+
+ if (onInstBoundary) {
+ int count = 0;
+ Addr oldpc;
+ // Make sure we're not currently updating state while
+ // handling PC events.
+ assert(!thread[tid]->noSquashFromTC &&
+ !thread[tid]->trapPending);
+ do {
+ oldpc = pc[tid].instAddr();
+ cpu->system->pcEventQueue.service(thread[tid]->getTC());
+ count++;
+ } while (oldpc != pc[tid].instAddr());
+ if (count > 1) {
+ DPRINTF(Commit,
+ "PC skip function event, stopping commit\n");
+ break;
+ }
}
// Check if an instruction just enabled interrupts and we've
@@ -1128,9 +1136,8 @@ DefaultCommit<Impl>::commitInsts()
// case squash now to make sure the interrupt is handled.
//
// If we don't do this, we might end up in a live lock situation
- if (!interrupt && avoidQuiesceLiveLock &&
- (!head_inst->isMicroop() || head_inst->isLastMicroop()) &&
- cpu->checkInterrupts(cpu->tcBase(0)))
+ if (!interrupt && avoidQuiesceLiveLock &&
+ onInstBoundary && cpu->checkInterrupts(cpu->tcBase(0)))
squashAfter(tid, head_inst);
} else {
DPRINTF(Commit, "Unable to commit head instruction PC:%s "
diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc
index 8dcae01c5..aeaebcdb8 100644
--- a/src/cpu/simple/atomic.cc
+++ b/src/cpu/simple/atomic.cc
@@ -1,4 +1,5 @@
/*
+ * Copyright 2014 Google, Inc.
* Copyright (c) 2012-2013 ARM Limited
* All rights reserved.
*
@@ -518,10 +519,11 @@ AtomicSimpleCPU::tick()
numCycles++;
ppCycles->notify(1);
- if (!curStaticInst || !curStaticInst->isDelayedCommit())
+ if (!curStaticInst || !curStaticInst->isDelayedCommit()) {
checkForInterrupts();
+ checkPcEventQueue();
+ }
- checkPcEventQueue();
// We must have just got suspended by a PC event
if (_status == Idle) {
tryCompleteDrain();
diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc
index c2bcdee63..c7db5c4f8 100644
--- a/src/cpu/simple/timing.cc
+++ b/src/cpu/simple/timing.cc
@@ -1,4 +1,5 @@
/*
+ * Copyright 2014 Google, Inc.
* Copyright (c) 2010-2013 ARM Limited
* All rights reserved
*
@@ -551,10 +552,10 @@ TimingSimpleCPU::fetch()
{
DPRINTF(SimpleCPU, "Fetch\n");
- if (!curStaticInst || !curStaticInst->isDelayedCommit())
+ if (!curStaticInst || !curStaticInst->isDelayedCommit()) {
checkForInterrupts();
-
- checkPcEventQueue();
+ checkPcEventQueue();
+ }
// We must have just got suspended by a PC event
if (_status == Idle)