diff options
-rw-r--r-- | arch/alpha/isa/decoder.isa | 16 | ||||
-rw-r--r-- | cpu/base_dyn_inst.hh | 3 | ||||
-rw-r--r-- | cpu/o3/iew_impl.hh | 8 | ||||
-rw-r--r-- | cpu/o3/inst_queue_impl.hh | 1 | ||||
-rw-r--r-- | cpu/o3/lsq_unit_impl.hh | 7 | ||||
-rw-r--r-- | cpu/o3/rename_impl.hh | 12 | ||||
-rw-r--r-- | cpu/static_inst.hh | 8 |
7 files changed, 35 insertions, 20 deletions
diff --git a/arch/alpha/isa/decoder.isa b/arch/alpha/isa/decoder.isa index 48ced0eff..b3744a43d 100644 --- a/arch/alpha/isa/decoder.isa +++ b/arch/alpha/isa/decoder.isa @@ -73,7 +73,7 @@ decode OPCODE default Unknown::unknown() { uint64_t tmp = write_result; // see stq_c Ra = (tmp == 0 || tmp == 1) ? tmp : Ra; - }}, mem_flags = LOCKED); + }}, mem_flags = LOCKED, inst_flags = IsStoreConditional); 0x2f: stq_c({{ Mem.uq = Ra; }}, {{ uint64_t tmp = write_result; @@ -85,7 +85,7 @@ decode OPCODE default Unknown::unknown() { // mailbox access, and we don't update the // result register at all. Ra = (tmp == 0 || tmp == 1) ? tmp : Ra; - }}, mem_flags = LOCKED); + }}, mem_flags = LOCKED, inst_flags = IsStoreConditional); } format IntegerOperate { @@ -591,8 +591,8 @@ decode OPCODE default Unknown::unknown() { 0x02e: fcmovle({{ Fc = (Fa <= 0) ? Fb : Fc; }}); 0x02f: fcmovgt({{ Fc = (Fa > 0) ? Fb : Fc; }}); - 0x024: mt_fpcr({{ FPCR = Fa.uq; }}); - 0x025: mf_fpcr({{ Fa.uq = FPCR; }}); + 0x024: mt_fpcr({{ FPCR = Fa.uq; }}, IsIprAccess); + 0x025: mf_fpcr({{ Fa.uq = FPCR; }}, IsIprAccess); } } @@ -696,9 +696,9 @@ decode OPCODE default Unknown::unknown() { xc->syscall(); }}, IsNonSpeculative); // Read uniq reg into ABI return value register (r0) - 0x9e: rduniq({{ R0 = Runiq; }}); + 0x9e: rduniq({{ R0 = Runiq; }}, IsIprAccess); // Write uniq reg with value from ABI arg register (r16) - 0x9f: wruniq({{ Runiq = R16; }}); + 0x9f: wruniq({{ Runiq = R16; }}, IsIprAccess); } } #endif @@ -735,7 +735,7 @@ decode OPCODE default Unknown::unknown() { format HwMoveIPR { 1: hw_mfpr({{ Ra = xc->readMiscRegWithEffect(ipr_index, fault); - }}); + }}, IsIprAccess); } } @@ -745,7 +745,7 @@ decode OPCODE default Unknown::unknown() { 1: hw_mtpr({{ xc->setMiscRegWithEffect(ipr_index, Ra); if (traceData) { traceData->setData(Ra); } - }}); + }}, IsIprAccess); } } diff --git a/cpu/base_dyn_inst.hh b/cpu/base_dyn_inst.hh index cd754dc3c..9403faec3 100644 --- a/cpu/base_dyn_inst.hh +++ b/cpu/base_dyn_inst.hh @@ -334,6 +334,8 @@ class BaseDynInst : public FastAlloc, public RefCounted bool isMemRef() const { return staticInst->isMemRef(); } bool isLoad() const { return staticInst->isLoad(); } bool isStore() const { return staticInst->isStore(); } + bool isStoreConditional() const + { return staticInst->isStoreConditional(); } bool isInstPrefetch() const { return staticInst->isInstPrefetch(); } bool isDataPrefetch() const { return staticInst->isDataPrefetch(); } bool isCopy() const { return staticInst->isCopy(); } @@ -356,6 +358,7 @@ class BaseDynInst : public FastAlloc, public RefCounted bool isWriteBarrier() const { return staticInst->isWriteBarrier(); } bool isNonSpeculative() const { return staticInst->isNonSpeculative(); } bool isQuiesce() const { return staticInst->isQuiesce(); } + bool isIprAccess() const { return staticInst->isIprAccess(); } bool isUnverifiable() const { return staticInst->isUnverifiable(); } /** Temporarily sets this instruction as a serialize before instruction. */ diff --git a/cpu/o3/iew_impl.hh b/cpu/o3/iew_impl.hh index 59f4055a6..cf28f2efc 100644 --- a/cpu/o3/iew_impl.hh +++ b/cpu/o3/iew_impl.hh @@ -1100,10 +1100,10 @@ DefaultIEW<Impl>::dispatchInsts(unsigned tid) ++iewDispStoreInsts; - if (inst->isNonSpeculative()) { - // Non-speculative stores (namely store conditionals) - // need to be set as "canCommit()" so that commit can - // process them when they reach the head of commit. + if (inst->isStoreConditional()) { + // Store conditionals need to be set as "canCommit()" + // so that commit can process them when they reach the + // head of commit. inst->setCanCommit(); instQueue.insertNonSpec(inst); add_to_iq = false; diff --git a/cpu/o3/inst_queue_impl.hh b/cpu/o3/inst_queue_impl.hh index ed57ac257..71541b4f8 100644 --- a/cpu/o3/inst_queue_impl.hh +++ b/cpu/o3/inst_queue_impl.hh @@ -1041,6 +1041,7 @@ InstructionQueue<Impl>::doSquash(unsigned tid) // Remove the instruction from the dependency list. if (!squashed_inst->isNonSpeculative() && + !squashed_inst->isStoreConditional() && !squashed_inst->isMemBarrier() && !squashed_inst->isWriteBarrier()) { diff --git a/cpu/o3/lsq_unit_impl.hh b/cpu/o3/lsq_unit_impl.hh index f0b4405ed..7974ddaad 100644 --- a/cpu/o3/lsq_unit_impl.hh +++ b/cpu/o3/lsq_unit_impl.hh @@ -424,10 +424,9 @@ LSQUnit<Impl>::executeStore(DynInstPtr &store_inst) assert(store_fault == NoFault); - if (store_inst->isNonSpeculative()) { - // Nonspeculative accesses (namely store conditionals) - // need to set themselves as able to writeback if we - // haven't had a fault by here. + if (store_inst->isStoreConditional()) { + // Store conditionals need to set themselves as able to + // writeback if we haven't had a fault by here. storeQueue[store_idx].canWB = true; ++storesToWB; diff --git a/cpu/o3/rename_impl.hh b/cpu/o3/rename_impl.hh index 081581c92..b4f1077d1 100644 --- a/cpu/o3/rename_impl.hh +++ b/cpu/o3/rename_impl.hh @@ -594,7 +594,14 @@ DefaultRename<Impl>::renameInsts(unsigned tid) // serializeAfter marks the next instruction as serializeBefore. // serializeBefore makes the instruction wait in rename until the ROB // is empty. - if (inst->isSerializeBefore() && !inst->isSerializeHandled()) { + + // In this model, IPR accesses are serialize before + // instructions, and store conditionals are serialize after + // instructions. This is mainly due to lack of support for + // out-of-order operations of either of those classes of + // instructions. + if ((inst->isIprAccess() || inst->isSerializeBefore()) && + !inst->isSerializeHandled()) { DPRINTF(Rename, "Serialize before instruction encountered.\n"); if (!inst->isTempSerializeBefore()) { @@ -613,7 +620,8 @@ DefaultRename<Impl>::renameInsts(unsigned tid) blockThisCycle = true; break; - } else if (inst->isSerializeAfter() && !inst->isSerializeHandled()) { + } else if ((inst->isStoreConditional() || inst->isSerializeAfter()) && + !inst->isSerializeHandled()) { DPRINTF(Rename, "Serialize after instruction encountered.\n"); renamedSerializing++; diff --git a/cpu/static_inst.hh b/cpu/static_inst.hh index 0b8fe2f18..b9d782b7b 100644 --- a/cpu/static_inst.hh +++ b/cpu/static_inst.hh @@ -103,6 +103,7 @@ class StaticInstBase : public RefCounted IsMemRef, ///< References memory (load, store, or prefetch). IsLoad, ///< Reads from memory (load or prefetch). IsStore, ///< Writes to memory. + IsStoreConditional, ///< Store conditional instruction. IsInstPrefetch, ///< Instruction-cache prefetch. IsDataPrefetch, ///< Data-cache prefetch. IsCopy, ///< Fast Cache block copy @@ -127,9 +128,10 @@ class StaticInstBase : public RefCounted IsWriteBarrier, ///< Is a write barrier IsNonSpeculative, ///< Should not be executed speculatively - IsQuiesce, + IsQuiesce, ///< Is a quiesce instruction - IsUnverifiable, + IsIprAccess, ///< Accesses IPRs + IsUnverifiable, ///< Can't be verified by a checker NumFlags }; @@ -193,6 +195,7 @@ class StaticInstBase : public RefCounted bool isMemRef() const { return flags[IsMemRef]; } bool isLoad() const { return flags[IsLoad]; } bool isStore() const { return flags[IsStore]; } + bool isStoreConditional() const { return flags[IsStoreConditional]; } bool isInstPrefetch() const { return flags[IsInstPrefetch]; } bool isDataPrefetch() const { return flags[IsDataPrefetch]; } bool isCopy() const { return flags[IsCopy];} @@ -218,6 +221,7 @@ class StaticInstBase : public RefCounted bool isWriteBarrier() const { return flags[IsWriteBarrier]; } bool isNonSpeculative() const { return flags[IsNonSpeculative]; } bool isQuiesce() const { return flags[IsQuiesce]; } + bool isIprAccess() const { return flags[IsIprAccess]; } bool isUnverifiable() const { return flags[IsUnverifiable]; } //@} |