summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/alpha/isa/decoder.isa16
-rw-r--r--cpu/base_dyn_inst.hh3
-rw-r--r--cpu/o3/iew_impl.hh8
-rw-r--r--cpu/o3/inst_queue_impl.hh1
-rw-r--r--cpu/o3/lsq_unit_impl.hh7
-rw-r--r--cpu/o3/rename_impl.hh12
-rw-r--r--cpu/static_inst.hh8
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]; }
//@}