diff -r 09e9c7c3113d -r 9a5651e7bd5b src/cpu/o3/O3CPU.py --- a/src/cpu/o3/O3CPU.py Fri Jan 13 06:55:34 2012 -0600 +++ b/src/cpu/o3/O3CPU.py Fri Jan 13 06:57:27 2012 -0600 @@ -146,3 +146,4 @@ smtROBThreshold = Param.Int(100, "SMT ROB Threshold Sharing Parameter") smtCommitPolicy = Param.String('RoundRobin', "SMT Commit Policy") + needsTSO = Param.Bool(False, "Memory model") diff -r 09e9c7c3113d -r 9a5651e7bd5b src/cpu/o3/cpu.hh --- a/src/cpu/o3/cpu.hh Fri Jan 13 06:55:34 2012 -0600 +++ b/src/cpu/o3/cpu.hh Fri Jan 13 06:57:27 2012 -0600 @@ -668,6 +668,9 @@ /** Counter of how many stages have completed draining. */ int drainCount; + /** Flag for memory model. */ + bool needsTSO; + /** Pointers to all of the threads in the CPU. */ std::vector thread; diff -r 09e9c7c3113d -r 9a5651e7bd5b src/cpu/o3/cpu.cc --- a/src/cpu/o3/cpu.cc Fri Jan 13 06:55:34 2012 -0600 +++ b/src/cpu/o3/cpu.cc Fri Jan 13 06:57:27 2012 -0600 @@ -206,6 +206,7 @@ globalSeqNum(1), system(params->system), drainCount(0), + needsTSO(params->needsTSO), deferRegistration(params->defer_registration) { if (!deferRegistration) { diff -r 09e9c7c3113d -r 9a5651e7bd5b src/cpu/o3/lsq_unit.hh --- a/src/cpu/o3/lsq_unit.hh Fri Jan 13 06:55:34 2012 -0600 +++ b/src/cpu/o3/lsq_unit.hh Fri Jan 13 06:57:27 2012 -0600 @@ -453,6 +453,9 @@ /** Has the blocked load been handled. */ bool loadBlockedHandled; + /** Whether or not a store is in flight. */ + bool storeInFlight; + /** The sequence number of the blocked load. */ InstSeqNum blockedLoadSeqNum; diff -r 09e9c7c3113d -r 9a5651e7bd5b src/cpu/o3/lsq_unit_impl.hh --- a/src/cpu/o3/lsq_unit_impl.hh Fri Jan 13 06:55:34 2012 -0600 +++ b/src/cpu/o3/lsq_unit_impl.hh Fri Jan 13 06:57:27 2012 -0600 @@ -138,7 +138,7 @@ LSQUnit::LSQUnit() : loads(0), stores(0), storesToWB(0), cacheBlockMask(0), stalled(false), isStoreBlocked(false), isLoadBlocked(false), - loadBlockedHandled(false), hasPendingPkt(false) + loadBlockedHandled(false), storeInFlight(false), hasPendingPkt(false) { } @@ -770,6 +770,7 @@ storeWBIdx != storeTail && storeQueue[storeWBIdx].inst && storeQueue[storeWBIdx].canWB && + ((!cpu->needsTSO) || (!storeInFlight)) && usedPorts < cachePorts) { if (isStoreBlocked || lsq->cacheBlocked()) { @@ -1090,6 +1091,10 @@ #endif } + if (cpu->needsTSO) { + storeInFlight = true; + } + incrStIdx(storeWBIdx); } @@ -1163,6 +1168,10 @@ storeQueue[store_idx].inst->setCompleted(); + if (cpu->needsTSO) { + storeInFlight = false; + } + // Tell the checker we've completed this instruction. Some stores // may get reported twice to the checker, but the checker can // handle that case.