From eeeee7c58f26fac9fe9b8606e26ef8e99a28e399 Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Tue, 23 May 2006 14:38:16 -0400 Subject: [PATCH] Add extra flags to help new CPU handle various instructions. IsIprAccess flag may go away in the future (op class can be used to tell this), and the CPU still needs a specific way to identify/deal with syscalls. arch/alpha/isa/decoder.isa: Added a few extra flags to help the new CPU identify various classes of instructions without having to force certain behaviors for all CPUs. cpu/base_dyn_inst.hh: cpu/static_inst.hh: Added extra flags. cpu/o3/iew_impl.hh: cpu/o3/inst_queue_impl.hh: Handle store conditionals specially. cpu/o3/lsq_unit_impl.hh: Extra flags tells if the instruction is a store conditional. cpu/o3/rename_impl.hh: Handle IPR accesses and store conditionals specially. --HG-- extra : convert_revision : 39debec4fa5341ae8a8ab5650bd12730aeb6c04f --- arch/alpha/isa/decoder.isa | 16 ++++++++-------- cpu/base_dyn_inst.hh | 3 +++ cpu/o3/iew_impl.hh | 8 ++++---- cpu/o3/inst_queue_impl.hh | 1 + cpu/o3/lsq_unit_impl.hh | 7 +++---- cpu/o3/rename_impl.hh | 12 ++++++++++-- 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::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::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::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::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::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]; } //@}