summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAli Saidi <Ali.Saidi@ARM.com>2013-10-31 13:41:13 -0500
committerAli Saidi <Ali.Saidi@ARM.com>2013-10-31 13:41:13 -0500
commit79f81e26416d99104beda28f4d8af333cccc0048 (patch)
treeced0bcc3a1eaa1b9a56749f837481d3363d5ee10
parent2b9b245fb38c9f645c22b9d4d8180aab16aeb69a (diff)
downloadgem5-79f81e26416d99104beda28f4d8af333cccc0048.tar.xz
cpu: Fix O3 issuse with load+barrier instructions.
Fix a problem in the O3 CPU for instructions that are both memory loads and memory barriers (e.g. load acquire) and to uncacheable memory. This combination can confuse the commit stage into commitng an instruction that hasn't executed and got it's value yet. At the same time refactor the code slightly to remove duplication between two of the cases.
-rw-r--r--src/cpu/o3/commit_impl.hh57
1 files changed, 21 insertions, 36 deletions
diff --git a/src/cpu/o3/commit_impl.hh b/src/cpu/o3/commit_impl.hh
index becdfd06c..6664faf95 100644
--- a/src/cpu/o3/commit_impl.hh
+++ b/src/cpu/o3/commit_impl.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2012 ARM Limited
+ * Copyright (c) 2010-2013 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -1111,52 +1111,37 @@ DefaultCommit<Impl>::commitHead(DynInstPtr &head_inst, unsigned inst_num)
// and committed this instruction.
thread[tid]->funcExeInst--;
- if (head_inst->isNonSpeculative() ||
- head_inst->isStoreConditional() ||
- head_inst->isMemBarrier() ||
- head_inst->isWriteBarrier()) {
+ // Make sure we are only trying to commit un-executed instructions we
+ // think are possible.
+ assert(head_inst->isNonSpeculative() || head_inst->isStoreConditional()
+ || head_inst->isMemBarrier() || head_inst->isWriteBarrier() ||
+ (head_inst->isLoad() && head_inst->uncacheable()));
- DPRINTF(Commit, "Encountered a barrier or non-speculative "
- "instruction [sn:%lli] at the head of the ROB, PC %s.\n",
- head_inst->seqNum, head_inst->pcState());
-
- if (inst_num > 0 || iewStage->hasStoresToWB(tid)) {
- DPRINTF(Commit, "Waiting for all stores to writeback.\n");
- return false;
- }
+ DPRINTF(Commit, "Encountered a barrier or non-speculative "
+ "instruction [sn:%lli] at the head of the ROB, PC %s.\n",
+ head_inst->seqNum, head_inst->pcState());
- toIEW->commitInfo[tid].nonSpecSeqNum = head_inst->seqNum;
+ if (inst_num > 0 || iewStage->hasStoresToWB(tid)) {
+ DPRINTF(Commit, "Waiting for all stores to writeback.\n");
+ return false;
+ }
- // Change the instruction so it won't try to commit again until
- // it is executed.
- head_inst->clearCanCommit();
+ toIEW->commitInfo[tid].nonSpecSeqNum = head_inst->seqNum;
- ++commitNonSpecStalls;
+ // Change the instruction so it won't try to commit again until
+ // it is executed.
+ head_inst->clearCanCommit();
- return false;
- } else if (head_inst->isLoad()) {
- if (inst_num > 0 || iewStage->hasStoresToWB(tid)) {
- DPRINTF(Commit, "Waiting for all stores to writeback.\n");
- return false;
- }
-
- assert(head_inst->uncacheable());
+ if (head_inst->isLoad() && head_inst->uncacheable()) {
DPRINTF(Commit, "[sn:%lli]: Uncached load, PC %s.\n",
head_inst->seqNum, head_inst->pcState());
-
- // Send back the non-speculative instruction's sequence
- // number. Tell the lsq to re-execute the load.
- toIEW->commitInfo[tid].nonSpecSeqNum = head_inst->seqNum;
toIEW->commitInfo[tid].uncached = true;
toIEW->commitInfo[tid].uncachedLoad = head_inst;
-
- head_inst->clearCanCommit();
-
- return false;
} else {
- panic("Trying to commit un-executed instruction "
- "of unknown type!\n");
+ ++commitNonSpecStalls;
}
+
+ return false;
}
if (head_inst->isThreadSync()) {