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.
This commit is contained in:
@@ -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 "
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user