From 069b38c0d546708491d0da84668ba32f82ca7cb8 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Sun, 31 Jan 2010 18:27:58 -0500 Subject: inorder: track last branch committed when threads are switching in/out the CPU, we need to keep track of special cases like branches. Add appropriate variables in ThreadState t track this and then use these variables when updating pc after context switch --- src/cpu/inorder/resources/fetch_seq_unit.cc | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) (limited to 'src/cpu/inorder/resources') diff --git a/src/cpu/inorder/resources/fetch_seq_unit.cc b/src/cpu/inorder/resources/fetch_seq_unit.cc index c217f972e..ba86a91f0 100644 --- a/src/cpu/inorder/resources/fetch_seq_unit.cc +++ b/src/cpu/inorder/resources/fetch_seq_unit.cc @@ -348,11 +348,23 @@ FetchSeqUnit::updateAfterContextSwitch(DynInstPtr inst, ThreadID tid) { pcValid[tid] = true; - PC[tid] = inst->readNextPC(); - nextPC[tid] = inst->readNextNPC(); - nextNPC[tid] = inst->readNextNPC() + instSize; - - - DPRINTF(InOrderFetchSeq, "[tid:%i]: Updating PC:%08p NPC:%08p NNPC:%08p.\n", - tid, PC[tid], nextPC[tid], nextNPC[tid]); + if (cpu->thread[tid]->lastGradIsBranch) { + /** This function assumes that the instruction causing the context + * switch was right after the branch. Thus, if it's not, then + * we are updating incorrectly here + */ + assert(cpu->thread[tid]->lastBranchNextPC == inst->readPC()); + + PC[tid] = cpu->thread[tid]->lastBranchNextNPC; + nextPC[tid] = PC[tid] + instSize; + nextNPC[tid] = nextPC[tid] + instSize; + } else { + PC[tid] = inst->readNextPC(); + nextPC[tid] = inst->readNextNPC(); + nextNPC[tid] = inst->readNextNPC() + instSize; + } + + DPRINTF(InOrderFetchSeq, "[tid:%i]: Updating PCs due to Context Switch." + "Assigning PC:%08p NPC:%08p NNPC:%08p.\n", tid, PC[tid], + nextPC[tid], nextNPC[tid]); } -- cgit v1.2.3