summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/alpha/isa_desc35
-rw-r--r--cpu/static_inst.hh24
-rw-r--r--dev/etherlink.hh2
-rw-r--r--sim/eventq.hh4
-rw-r--r--sim/serialize.cc4
-rw-r--r--sim/serialize.hh2
-rw-r--r--sim/sim_object.hh2
7 files changed, 52 insertions, 21 deletions
diff --git a/arch/alpha/isa_desc b/arch/alpha/isa_desc
index 51bce65c2..d4636f609 100644
--- a/arch/alpha/isa_desc
+++ b/arch/alpha/isa_desc
@@ -1225,7 +1225,7 @@ declare {{
{
}
- Addr branchTarget(Addr branchPC)
+ Addr branchTarget(Addr branchPC) const
{
return branchPC + 4 + disp;
}
@@ -1287,7 +1287,7 @@ declare {{
{
}
- Addr branchTarget(ExecContext *xc)
+ Addr branchTarget(ExecContext *xc) const
{
Addr NPC = xc->readPC() + 4;
uint64_t Rb = xc->readIntReg(_srcRegIdx[0]);
@@ -2330,10 +2330,6 @@ decode OPCODE default Unknown::unknown() {
// miscellaneous mem-format ops
0x18: decode MEMFUNC {
format WarnUnimpl {
- 0x0000: trapb();
- 0x0400: excb();
- 0x4000: mb();
- 0x4400: wmb();
0x8000: fetch();
0xa000: fetch_m();
0xe800: ecb();
@@ -2347,6 +2343,27 @@ decode OPCODE default Unknown::unknown() {
format BasicOperate {
0xc000: rpcc({{ Ra = curTick; }});
+
+ // All of the barrier instructions below do nothing in
+ // their execute() methods (hence the empty code blocks).
+ // All of their functionality is hard-coded in the
+ // pipeline based on the flags IsSerializing,
+ // IsMemBarrier, and IsWriteBarrier. In the current
+ // detailed CPU model, the execute() function only gets
+ // called at fetch, so there's no way to generate pipeline
+ // behavior at any other stage. Once we go to an
+ // exec-in-exec CPU model we should be able to get rid of
+ // these flags and implement this behavior via the
+ // execute() methods.
+
+ // trapb is just a barrier on integer traps, where excb is
+ // a barrier on integer and FP traps. "EXCB is thus a
+ // superset of TRAPB." (Alpha ARM, Sec 4.11.4) We treat
+ // them the same though.
+ 0x0000: trapb({{ }}, IsSerializing, No_OpClass);
+ 0x0400: excb({{ }}, IsSerializing, No_OpClass);
+ 0x4000: mb({{ }}, IsMemBarrier);
+ 0x4400: wmb({{ }}, IsWriteBarrier);
}
#ifdef FULL_SYSTEM
@@ -2356,13 +2373,13 @@ decode OPCODE default Unknown::unknown() {
if (!xc->misspeculating()) {
xc->regs.intrflag = 0;
}
- }}, No_OpClass);
+ }});
0xf000: rs({{
Ra = xc->regs.intrflag;
if (!xc->misspeculating()) {
xc->regs.intrflag = 1;
}
- }}, No_OpClass);
+ }});
}
#else
format FailUnimpl {
@@ -2476,7 +2493,7 @@ decode OPCODE default Unknown::unknown() {
if (!xc->misspeculating())
AlphaPseudo::m5exit(xc);
}}, No_OpClass);
- 0x30: initparam({{ Ra = xc->cpu->system->init_param; }});
+ 0x30: initparam({{ Ra = cpu->system->init_param; }});
0x40: resetstats({{
if (!xc->misspeculating())
AlphaPseudo::resetstats(xc);
diff --git a/cpu/static_inst.hh b/cpu/static_inst.hh
index f3fd6fa24..5f4bcae3d 100644
--- a/cpu/static_inst.hh
+++ b/cpu/static_inst.hh
@@ -78,6 +78,12 @@ class StaticInstBase : public RefCounted
/// - If IsControl is set, then exactly one of IsDirectControl or
/// IsIndirect Control will be set, and exactly one of
/// IsCondControl or IsUncondControl will be set.
+ /// - IsSerializing, IsMemBarrier, and IsWriteBarrier are
+ /// implemented as flags since in the current model there's no
+ /// other way for instructions to inject behavior into the
+ /// pipeline outside of fetch. Once we go to an exec-in-exec CPU
+ /// model we should be able to get rid of these flags and
+ /// implement this behavior via the execute() methods.
///
enum Flags {
IsNop, ///< Is a no-op (no effect at all).
@@ -99,7 +105,12 @@ class StaticInstBase : public RefCounted
IsCall, ///< Subroutine call.
IsReturn, ///< Subroutine return.
- IsThreadSync, ///< Thread synchronization operation.
+ IsThreadSync, ///< Thread synchronization operation.
+
+ IsSerializing, ///< Serializes pipeline: won't until all
+ /// older instructions have committed.
+ IsMemBarrier, ///< Is a memory barrier
+ IsWriteBarrier, ///< Is a write barrier
NumFlags
};
@@ -178,6 +189,9 @@ class StaticInstBase : public RefCounted
bool isUncondCtrl() const { return flags[IsUncondControl]; }
bool isThreadSync() const { return flags[IsThreadSync]; }
+ bool isSerializing() const { return flags[IsSerializing]; }
+ bool isMemBarrier() const { return flags[IsMemBarrier]; }
+ bool isWriteBarrier() const { return flags[IsWriteBarrier]; }
//@}
/// Operation class. Used to select appropriate function unit in issue.
@@ -216,11 +230,11 @@ class StaticInst : public StaticInstBase
/// Return logical index (architectural reg num) of i'th destination reg.
/// Only the entries from 0 through numDestRegs()-1 are valid.
- RegIndex destRegIdx(int i) { return _destRegIdx[i]; }
+ RegIndex destRegIdx(int i) const { return _destRegIdx[i]; }
/// Return logical index (architectural reg num) of i'th source reg.
/// Only the entries from 0 through numSrcRegs()-1 are valid.
- RegIndex srcRegIdx(int i) { return _srcRegIdx[i]; }
+ RegIndex srcRegIdx(int i) const { return _srcRegIdx[i]; }
/// Pointer to a statically allocated "null" instruction object.
/// Used to give eaCompInst() and memAccInst() something to return
@@ -305,7 +319,7 @@ class StaticInst : public StaticInstBase
* Invalid if not a PC-relative branch (i.e. isDirectCtrl()
* should be true).
*/
- virtual Addr branchTarget(Addr branchPC)
+ virtual Addr branchTarget(Addr branchPC) const
{
panic("StaticInst::branchTarget() called on instruction "
"that is not a PC-relative branch.");
@@ -318,7 +332,7 @@ class StaticInst : public StaticInstBase
* execute the branch in question. Invalid if not an indirect
* branch (i.e. isIndirectCtrl() should be true).
*/
- virtual Addr branchTarget(ExecContext *xc)
+ virtual Addr branchTarget(ExecContext *xc) const
{
panic("StaticInst::branchTarget() called on instruction "
"that is not an indirect branch.");
diff --git a/dev/etherlink.hh b/dev/etherlink.hh
index 895bac2e1..e1a7957ee 100644
--- a/dev/etherlink.hh
+++ b/dev/etherlink.hh
@@ -89,7 +89,7 @@ class EtherLink : public SimObject
Link(const std::string &name, double rate, EtherDump *dump);
~Link() {}
- virtual std::string name() const { return objName; }
+ virtual const std::string name() const { return objName; }
bool busy() const { return (bool)packet; }
bool transmit(PacketPtr &packet);
diff --git a/sim/eventq.hh b/sim/eventq.hh
index 36cb402a8..31bf9d652 100644
--- a/sim/eventq.hh
+++ b/sim/eventq.hh
@@ -153,7 +153,7 @@ class Event : public Serializable, public FastAlloc
~Event() {}
- virtual std::string name() const {
+ virtual const std::string name() const {
return csprintf("Event_%x", (uintptr_t)this);
}
@@ -257,7 +257,7 @@ class EventQueue : public Serializable
: objName(n), head(NULL)
{}
- virtual std::string name() const { return objName; }
+ virtual const std::string name() const { return objName; }
// schedule the given event on this queue
void schedule(Event *ev);
diff --git a/sim/serialize.cc b/sim/serialize.cc
index 180cc38a0..d836e7c20 100644
--- a/sim/serialize.cc
+++ b/sim/serialize.cc
@@ -186,7 +186,7 @@ INSTANTIATE_PARAM_TEMPLATES(string)
class Globals : public Serializable
{
public:
- string name() const;
+ const string name() const;
void serialize(ostream& os);
void unserialize(Checkpoint *cp);
};
@@ -194,7 +194,7 @@ class Globals : public Serializable
/// The one and only instance of the Globals class.
Globals globals;
-string
+const string
Globals::name() const
{
return "Globals";
diff --git a/sim/serialize.hh b/sim/serialize.hh
index 9ab2fa833..43dbd2c85 100644
--- a/sim/serialize.hh
+++ b/sim/serialize.hh
@@ -111,7 +111,7 @@ class Serializable
virtual ~Serializable() {}
// manditory virtual function, so objects must provide names
- virtual std::string name() const = 0;
+ virtual const std::string name() const = 0;
virtual void serialize(std::ostream& os) {}
virtual void unserialize(Checkpoint *cp, const std::string &section) {}
diff --git a/sim/sim_object.hh b/sim/sim_object.hh
index 165931b2b..aaaafc04b 100644
--- a/sim/sim_object.hh
+++ b/sim/sim_object.hh
@@ -63,7 +63,7 @@ class SimObject : public Serializable
virtual ~SimObject() {}
- virtual std::string name() const { return objName; }
+ virtual const std::string name() const { return objName; }
// initialization pass of all objects. Gets invoked by SimInit()
virtual void init();