summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Lim <ktlim@umich.edu>2005-03-08 21:03:20 -0500
committerKevin Lim <ktlim@umich.edu>2005-03-08 21:03:20 -0500
commit2162b433adfa596bc0d6515b8157b24cd2599541 (patch)
tree96c01743fc94260c77848a92cefcc0e4e8dbc248
parentbb41c21d6ae3417cfcbfa1bb5ecc9efbae1950ab (diff)
parent550e6a5010602049b9be426ba41939ee7167ccd9 (diff)
downloadgem5-2162b433adfa596bc0d6515b8157b24cd2599541.tar.xz
Hand-merge static_inst.hh. These execute functions are within an external file in the new CPU case.
cpu/static_inst.hh: Hand-merge. These execute functions are within an external file in the new CPU case. --HG-- extra : convert_revision : a34112f471fa31bdd5bb53552ddd704b9571c110
-rw-r--r--arch/alpha/isa_desc126
-rw-r--r--base/statistics.hh6
-rw-r--r--configs/boot/nat-netperf-maerts-client.rcS2
-rw-r--r--configs/boot/nat-netperf-server.rcS3
-rw-r--r--configs/boot/netperf-server.rcS1
-rwxr-xr-xconfigs/boot/nfs-client.rcS2
-rwxr-xr-xconfigs/boot/nfs-server.rcS2
-rw-r--r--cpu/full_cpu/op_class.hh1
-rw-r--r--cpu/simple_cpu/simple_cpu.hh16
-rw-r--r--cpu/static_inst.cc2
-rw-r--r--cpu/static_inst.hh10
-rw-r--r--dev/etherlink.cc98
-rw-r--r--dev/etherlink.hh28
-rw-r--r--objects/CoherenceProtocol.mpy2
-rw-r--r--objects/Ide.mpy2
-rw-r--r--sim/pyconfig/m5config.py382
-rw-r--r--util/pbs/jobfile.py15
17 files changed, 392 insertions, 306 deletions
diff --git a/arch/alpha/isa_desc b/arch/alpha/isa_desc
index 1e92033dc..904af3ef0 100644
--- a/arch/alpha/isa_desc
+++ b/arch/alpha/isa_desc
@@ -187,15 +187,16 @@ output header {{
/// Print a register name for disassembly given the unique
/// dependence tag number (FP or int).
- void printReg(std::ostream &os, int reg);
+ void printReg(std::ostream &os, int reg) const;
- std::string generateDisassembly(Addr pc, const SymbolTable *symtab);
+ std::string
+ generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
}};
output decoder {{
void
- AlphaStaticInst::printReg(std::ostream &os, int reg)
+ AlphaStaticInst::printReg(std::ostream &os, int reg) const
{
if (reg < FP_Base_DepTag) {
ccprintf(os, "r%d", reg);
@@ -206,7 +207,8 @@ output decoder {{
}
std::string
- AlphaStaticInst::generateDisassembly(Addr pc, const SymbolTable *symtab)
+ AlphaStaticInst::generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
{
std::stringstream ss;
@@ -237,7 +239,7 @@ output decoder {{
// Declarations for execute() methods.
def template BasicExecDeclare {{
- Fault execute(%(CPU_exec_context)s *, Trace::InstRecord *);
+ Fault execute(%(CPU_exec_context)s *, Trace::InstRecord *) const;
}};
// Basic instruction class declaration template.
@@ -267,7 +269,7 @@ def template BasicConstructor {{
// Basic instruction class execute method template.
def template BasicExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
- Trace::InstRecord *traceData)
+ Trace::InstRecord *traceData) const
{
Fault fault = No_Fault;
@@ -330,14 +332,16 @@ output header {{
~Nop() { }
- std::string generateDisassembly(Addr pc, const SymbolTable *symtab);
+ std::string
+ generateDisassembly(Addr pc, const SymbolTable *symtab) const;
%(BasicExecDeclare)s
};
}};
output decoder {{
- std::string Nop::generateDisassembly(Addr pc, const SymbolTable *symtab)
+ std::string Nop::generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
{
#ifdef SS_COMPATIBLE_DISASSEMBLY
return originalDisassembly;
@@ -360,7 +364,7 @@ output decoder {{
output exec {{
Fault
- Nop::execute(%(CPU_exec_context)s *, Trace::InstRecord *)
+ Nop::execute(%(CPU_exec_context)s *, Trace::InstRecord *) const
{
return No_Fault;
}
@@ -410,13 +414,14 @@ output header {{
{
}
- std::string generateDisassembly(Addr pc, const SymbolTable *symtab);
+ std::string
+ generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
}};
output decoder {{
std::string
- IntegerImm::generateDisassembly(Addr pc, const SymbolTable *symtab)
+ IntegerImm::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
@@ -588,12 +593,13 @@ output header {{
}
#if defined(linux)
- int getC99RoundingMode(uint64_t fpcr_val);
+ int getC99RoundingMode(uint64_t fpcr_val) const;
#endif
// This differs from the AlphaStaticInst version only in
// printing suffixes for non-default rounding & trapping modes.
- std::string generateDisassembly(Addr pc, const SymbolTable *symtab);
+ std::string
+ generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
}};
@@ -618,7 +624,7 @@ def template FloatingPointDecode {{
output decoder {{
#if defined(linux)
int
- AlphaFP::getC99RoundingMode(uint64_t fpcr_val)
+ AlphaFP::getC99RoundingMode(uint64_t fpcr_val) const
{
if (roundingMode == Dynamic) {
return alphaToC99RoundingMode[bits(fpcr_val, 59, 58)];
@@ -630,7 +636,7 @@ output decoder {{
#endif
std::string
- AlphaFP::generateDisassembly(Addr pc, const SymbolTable *symtab)
+ AlphaFP::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::string mnem_str(mnemonic);
@@ -751,7 +757,8 @@ output header {{
{
}
- std::string generateDisassembly(Addr pc, const SymbolTable *symtab);
+ std::string
+ generateDisassembly(Addr pc, const SymbolTable *symtab) const;
public:
@@ -796,21 +803,22 @@ output header {{
{
}
- std::string generateDisassembly(Addr pc, const SymbolTable *symtab);
+ std::string
+ generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
}};
output decoder {{
std::string
- Memory::generateDisassembly(Addr pc, const SymbolTable *symtab)
+ Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
return csprintf("%-10s %c%d,%d(r%d)", mnemonic,
flags[IsFloating] ? 'f' : 'r', RA, MEMDISP, RB);
}
std::string
- MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab)
+ MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
return csprintf("%-10s (r%d)", mnemonic, RB);
}
@@ -894,7 +902,7 @@ def template LoadStoreConstructor {{
def template EACompExecute {{
Fault
%(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc,
- Trace::InstRecord *traceData)
+ Trace::InstRecord *traceData) const
{
Addr EA;
Fault fault = No_Fault;
@@ -916,7 +924,7 @@ def template EACompExecute {{
def template MemAccExecute {{
Fault
%(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
- Trace::InstRecord *traceData)
+ Trace::InstRecord *traceData) const
{
Addr EA;
Fault fault = No_Fault;
@@ -950,7 +958,7 @@ def template MemAccExecute {{
def template LoadStoreExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
- Trace::InstRecord *traceData)
+ Trace::InstRecord *traceData) const
{
Addr EA;
Fault fault = No_Fault;
@@ -984,7 +992,7 @@ def template LoadStoreExecute {{
def template PrefetchExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
- Trace::InstRecord *traceData)
+ Trace::InstRecord *traceData) const
{
Addr EA;
Fault fault = No_Fault;
@@ -1158,9 +1166,9 @@ output header {{
{
protected:
/// Cached program counter from last disassembly
- Addr cachedPC;
+ mutable Addr cachedPC;
/// Cached symbol table pointer from last disassembly
- const SymbolTable *cachedSymtab;
+ mutable const SymbolTable *cachedSymtab;
/// Constructor
PCDependentDisassembly(const char *mnem, MachInst _machInst,
@@ -1170,7 +1178,8 @@ output header {{
{
}
- const std::string &disassemble(Addr pc, const SymbolTable *symtab);
+ const std::string &
+ disassemble(Addr pc, const SymbolTable *symtab) const;
};
/**
@@ -1192,7 +1201,8 @@ output header {{
Addr branchTarget(Addr branchPC) const;
- std::string generateDisassembly(Addr pc, const SymbolTable *symtab);
+ std::string
+ generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
/**
@@ -1216,7 +1226,8 @@ output header {{
Addr branchTarget(ExecContext *xc) const;
- std::string generateDisassembly(Addr pc, const SymbolTable *symtab);
+ std::string
+ generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
}};
@@ -1236,7 +1247,8 @@ output decoder {{
}
const std::string &
- PCDependentDisassembly::disassemble(Addr pc, const SymbolTable *symtab)
+ PCDependentDisassembly::disassemble(Addr pc,
+ const SymbolTable *symtab) const
{
if (!cachedDisassembly ||
pc != cachedPC || symtab != cachedSymtab)
@@ -1254,7 +1266,7 @@ output decoder {{
}
std::string
- Branch::generateDisassembly(Addr pc, const SymbolTable *symtab)
+ Branch::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
@@ -1292,7 +1304,7 @@ output decoder {{
}
std::string
- Jump::generateDisassembly(Addr pc, const SymbolTable *symtab)
+ Jump::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
@@ -1391,13 +1403,15 @@ output header {{
{
}
- std::string generateDisassembly(Addr pc, const SymbolTable *symtab);
+ std::string
+ generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
}};
output decoder {{
std::string
- EmulatedCallPal::generateDisassembly(Addr pc, const SymbolTable *symtab)
+ EmulatedCallPal::generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
{
#ifdef SS_COMPATIBLE_DISASSEMBLY
return csprintf("%s %s", "call_pal", mnemonic);
@@ -1433,7 +1447,8 @@ output header {{
CallPalBase(const char *mnem, MachInst _machInst,
OpClass __opClass);
- std::string generateDisassembly(Addr pc, const SymbolTable *symtab);
+ std::string
+ generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
}};
@@ -1463,7 +1478,7 @@ output decoder {{
}
std::string
- CallPalBase::generateDisassembly(Addr pc, const SymbolTable *symtab)
+ CallPalBase::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
return csprintf("%-10s %#x", "call_pal", palFunc);
}
@@ -1498,7 +1513,8 @@ output header {{
StaticInstPtr<AlphaISA> _eaCompPtr = nullStaticInstPtr,
StaticInstPtr<AlphaISA> _memAccPtr = nullStaticInstPtr);
- std::string generateDisassembly(Addr pc, const SymbolTable *symtab);
+ std::string
+ generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
}};
@@ -1520,7 +1536,7 @@ output decoder {{
}
std::string
- HwLoadStore::generateDisassembly(Addr pc, const SymbolTable *symtab)
+ HwLoadStore::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
#ifdef SS_COMPATIBLE_DISASSEMBLY
return csprintf("%-10s r%d,%d(r%d)", mnemonic, RA, disp, RB);
@@ -1571,13 +1587,14 @@ output header {{
{
}
- std::string generateDisassembly(Addr pc, const SymbolTable *symtab);
+ std::string
+ generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
}};
output decoder {{
std::string
- HwMoveIPR::generateDisassembly(Addr pc, const SymbolTable *symtab)
+ HwMoveIPR::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
if (_numSrcRegs > 0) {
// must be mtpr
@@ -1593,7 +1610,8 @@ output decoder {{
}};
def format HwMoveIPR(code) {{
- iop = InstObjParams(name, Name, 'HwMoveIPR', CodeBlock(code))
+ iop = InstObjParams(name, Name, 'HwMoveIPR', CodeBlock(code),
+ ['IprAccessOp'])
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
@@ -1628,7 +1646,8 @@ output header {{
%(BasicExecDeclare)s
- std::string generateDisassembly(Addr pc, const SymbolTable *symtab);
+ std::string
+ generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
/**
@@ -1644,7 +1663,7 @@ output header {{
{
private:
/// Have we warned on this instruction yet?
- bool warned;
+ mutable bool warned;
public:
/// Constructor
@@ -1658,19 +1677,22 @@ output header {{
%(BasicExecDeclare)s
- std::string generateDisassembly(Addr pc, const SymbolTable *symtab);
+ std::string
+ generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
}};
output decoder {{
std::string
- FailUnimplemented::generateDisassembly(Addr pc, const SymbolTable *symtab)
+ FailUnimplemented::generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
{
return csprintf("%-10s (unimplemented)", mnemonic);
}
std::string
- WarnUnimplemented::generateDisassembly(Addr pc, const SymbolTable *symtab)
+ WarnUnimplemented::generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
{
#ifdef SS_COMPATIBLE_DISASSEMBLY
return csprintf("%-10s", mnemonic);
@@ -1683,7 +1705,7 @@ output decoder {{
output exec {{
Fault
FailUnimplemented::execute(%(CPU_exec_context)s *xc,
- Trace::InstRecord *traceData)
+ Trace::InstRecord *traceData) const
{
panic("attempt to execute unimplemented instruction '%s' "
"(inst 0x%08x, opcode 0x%x)", mnemonic, machInst, OPCODE);
@@ -1692,7 +1714,7 @@ output exec {{
Fault
WarnUnimplemented::execute(%(CPU_exec_context)s *xc,
- Trace::InstRecord *traceData)
+ Trace::InstRecord *traceData) const
{
if (!warned) {
warn("instruction '%s' unimplemented\n", mnemonic);
@@ -1734,7 +1756,8 @@ output header {{
%(BasicExecDeclare)s
- std::string generateDisassembly(Addr pc, const SymbolTable *symtab);
+ std::string
+ generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
}};
@@ -1745,7 +1768,7 @@ output header {{
output decoder {{
std::string
- Unknown::generateDisassembly(Addr pc, const SymbolTable *symtab)
+ Unknown::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
return csprintf("%-10s (inst 0x%x, opcode 0x%x)",
"unknown", machInst, OPCODE);
@@ -1754,7 +1777,8 @@ output decoder {{
output exec {{
Fault
- Unknown::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData)
+ Unknown::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
{
panic("attempt to execute unknown instruction "
"(inst 0x%08x, opcode 0x%x)", machInst, OPCODE);
@@ -2542,7 +2566,7 @@ decode OPCODE default Unknown::unknown() {
}
format BasicOperate {
- 0x1e: hw_rei({{ xc->hwrei(); }});
+ 0x1e: hw_rei({{ xc->hwrei(); }}, IsSerializing);
// M5 special opcodes use the reserved 0x01 opcode space
0x01: decode M5FUNC {
diff --git a/base/statistics.hh b/base/statistics.hh
index 667a0ed48..98d50a5bc 100644
--- a/base/statistics.hh
+++ b/base/statistics.hh
@@ -2873,12 +2873,6 @@ operator/(Temp l, Temp r)
}
inline Temp
-operator%(Temp l, Temp r)
-{
- return NodePtr(new BinaryNode<std::modulus<Result> >(l, r));
-}
-
-inline Temp
operator-(Temp l)
{
return NodePtr(new UnaryNode<std::negate<Result> >(l));
diff --git a/configs/boot/nat-netperf-maerts-client.rcS b/configs/boot/nat-netperf-maerts-client.rcS
index ab9fd8c4e..ab66b7d4a 100644
--- a/configs/boot/nat-netperf-maerts-client.rcS
+++ b/configs/boot/nat-netperf-maerts-client.rcS
@@ -22,7 +22,7 @@ echo "262143" > /proc/sys/net/core/wmem_default
echo "262143" > /proc/sys/net/core/optmem_max
echo "100000" > /proc/sys/net/core/netdev_max_backlog
-echo -n "waiting for server..."
+echo -n "waiting for natbox..."
/usr/bin/netcat -c -l -p 8000
BINARY=/benchmarks/netperf/netperf
diff --git a/configs/boot/nat-netperf-server.rcS b/configs/boot/nat-netperf-server.rcS
index 5b094b790..69717b7ce 100644
--- a/configs/boot/nat-netperf-server.rcS
+++ b/configs/boot/nat-netperf-server.rcS
@@ -23,7 +23,8 @@ echo "100000" > /proc/sys/net/core/netdev_max_backlog
echo "running netserver..."
/benchmarks/netperf/netserver
-echo -n "signal client to begin..."
+echo -n "signal natbox to begin..."
+sleep 1
echo "server ready" | /usr/bin/netcat -c $NATBOX 8000
echo "done."
diff --git a/configs/boot/netperf-server.rcS b/configs/boot/netperf-server.rcS
index f77ff0ce8..c75d918a2 100644
--- a/configs/boot/netperf-server.rcS
+++ b/configs/boot/netperf-server.rcS
@@ -22,6 +22,7 @@ echo "running netserver..."
/benchmarks/netperf/netserver
echo -n "signal client to begin..."
+sleep 1
echo "server ready" | /usr/bin/netcat -c $CLIENT 8000
echo "done."
diff --git a/configs/boot/nfs-client.rcS b/configs/boot/nfs-client.rcS
index a999fb72c..84d15439f 100755
--- a/configs/boot/nfs-client.rcS
+++ b/configs/boot/nfs-client.rcS
@@ -45,6 +45,6 @@ mkdir /nfs
mount 10.0.0.1:/nfs /nfs
echo "done."
-/bin/bonnie++ -u 99 -s 700 -r 0 -n 0 -f -F -d /nfs
+/bin/bonnie++ -u 99 -s 500 -r 0 -n 0 -f -F -d /nfs
/sbin/m5 exit
diff --git a/configs/boot/nfs-server.rcS b/configs/boot/nfs-server.rcS
index 21b7ab83c..0cb489a9d 100755
--- a/configs/boot/nfs-server.rcS
+++ b/configs/boot/nfs-server.rcS
@@ -38,7 +38,7 @@ echo "done."
# mknod /dev/sda1 b 8 1
#fi
-/sbin/insmod /modules/scsi_debug.ko dev_size_mb=768
+/sbin/insmod /modules/scsi_debug.ko dev_size_mb=512
echo -n "creating partition and formatting..."
#echo "1,767,L" > /tmp/sfdisk.run
diff --git a/cpu/full_cpu/op_class.hh b/cpu/full_cpu/op_class.hh
index a14ccfaed..8e85e8d8a 100644
--- a/cpu/full_cpu/op_class.hh
+++ b/cpu/full_cpu/op_class.hh
@@ -51,6 +51,7 @@ enum OpClass {
FloatSqrtOp, /* floating point square root */
MemReadOp, /* memory read port */
MemWriteOp, /* memory write port */
+ IprAccessOp, /* Internal Processor Register read/write port */
InstPrefetchOp, /* instruction prefetch port (on I-cache) */
Num_OpClasses /* total functional unit classes */
};
diff --git a/cpu/simple_cpu/simple_cpu.hh b/cpu/simple_cpu/simple_cpu.hh
index 0283545f4..c802a1c06 100644
--- a/cpu/simple_cpu/simple_cpu.hh
+++ b/cpu/simple_cpu/simple_cpu.hh
@@ -259,47 +259,47 @@ class SimpleCPU : public BaseCPU
// storage (which is pretty hard to imagine they would have reason
// to do).
- uint64_t readIntReg(StaticInst<TheISA> *si, int idx)
+ uint64_t readIntReg(const StaticInst<TheISA> *si, int idx)
{
return xc->readIntReg(si->srcRegIdx(idx));
}
- float readFloatRegSingle(StaticInst<TheISA> *si, int idx)
+ float readFloatRegSingle(const StaticInst<TheISA> *si, int idx)
{
int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
return xc->readFloatRegSingle(reg_idx);
}
- double readFloatRegDouble(StaticInst<TheISA> *si, int idx)
+ double readFloatRegDouble(const StaticInst<TheISA> *si, int idx)
{
int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
return xc->readFloatRegDouble(reg_idx);
}
- uint64_t readFloatRegInt(StaticInst<TheISA> *si, int idx)
+ uint64_t readFloatRegInt(const StaticInst<TheISA> *si, int idx)
{
int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
return xc->readFloatRegInt(reg_idx);
}
- void setIntReg(StaticInst<TheISA> *si, int idx, uint64_t val)
+ void setIntReg(const StaticInst<TheISA> *si, int idx, uint64_t val)
{
xc->setIntReg(si->destRegIdx(idx), val);
}
- void setFloatRegSingle(StaticInst<TheISA> *si, int idx, float val)
+ void setFloatRegSingle(const StaticInst<TheISA> *si, int idx, float val)
{
int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
xc->setFloatRegSingle(reg_idx, val);
}
- void setFloatRegDouble(StaticInst<TheISA> *si, int idx, double val)
+ void setFloatRegDouble(const StaticInst<TheISA> *si, int idx, double val)
{
int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
xc->setFloatRegDouble(reg_idx, val);
}
- void setFloatRegInt(StaticInst<TheISA> *si, int idx, uint64_t val)
+ void setFloatRegInt(const StaticInst<TheISA> *si, int idx, uint64_t val)
{
int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
xc->setFloatRegInt(reg_idx, val);
diff --git a/cpu/static_inst.cc b/cpu/static_inst.cc
index 7069d89ec..d522dbf5a 100644
--- a/cpu/static_inst.cc
+++ b/cpu/static_inst.cc
@@ -68,7 +68,7 @@ StaticInst<AlphaISA>::nullStaticInstPtr;
template <class ISA>
bool
-StaticInst<ISA>::hasBranchTarget(Addr pc, ExecContext *xc, Addr &tgt)
+StaticInst<ISA>::hasBranchTarget(Addr pc, ExecContext *xc, Addr &tgt) const
{
if (isDirectCtrl()) {
tgt = branchTarget(pc);
diff --git a/cpu/static_inst.hh b/cpu/static_inst.hh
index 25c98b12a..3ac88fd3d 100644
--- a/cpu/static_inst.hh
+++ b/cpu/static_inst.hh
@@ -294,13 +294,13 @@ class StaticInst : public StaticInstBase
* String representation of disassembly (lazily evaluated via
* disassemble()).
*/
- std::string *cachedDisassembly;
+ mutable std::string *cachedDisassembly;
/**
* Internal function to generate disassembly string.
*/
- virtual std::string generateDisassembly(Addr pc,
- const SymbolTable *symtab) = 0;
+ virtual std::string
+ generateDisassembly(Addr pc, const SymbolTable *symtab) const = 0;
/// Constructor.
StaticInst(const char *_mnemonic, MachInst _machInst, OpClass __opClass)
@@ -347,7 +347,7 @@ class StaticInst : public StaticInstBase
* Return true if the instruction is a control transfer, and if so,
* return the target address as well.
*/
- bool hasBranchTarget(Addr pc, ExecContext *xc, Addr &tgt);
+ bool hasBranchTarget(Addr pc, ExecContext *xc, Addr &tgt) const;
/**
* Return string representation of disassembled instruction.
@@ -357,7 +357,7 @@ class StaticInst : public StaticInstBase
* should not be cached, this function should be overridden directly.
*/
virtual const std::string &disassemble(Addr pc,
- const SymbolTable *symtab = 0)
+ const SymbolTable *symtab = 0) const
{
if (!cachedDisassembly)
cachedDisassembly =
diff --git a/dev/etherlink.cc b/dev/etherlink.cc
index 0acc50b0b..94293815d 100644
--- a/dev/etherlink.cc
+++ b/dev/etherlink.cc
@@ -47,32 +47,32 @@
using namespace std;
-EtherLink::EtherLink(const string &name, EtherInt *i1, EtherInt *i2,
+EtherLink::EtherLink(const string &name, EtherInt *peer0, EtherInt *peer1,
Tick speed, Tick dly, EtherDump *dump)
: SimObject(name)
{
double rate = ((double)ticksPerSecond * 8.0) / (double)speed;
Tick delay = US2Ticks(dly);
- link1 = new Link(name + ".link1", rate, delay, dump);
- link2 = new Link(name + ".link2", rate, delay, dump);
+ link[0] = new Link(name + ".link0", this, 0, rate, delay, dump);
+ link[1] = new Link(name + ".link1", this, 1, rate, delay, dump);
- int1 = new Interface(name + ".int1", link1, link2);
- int2 = new Interface(name + ".int2", link2, link1);
+ interface[0] = new Interface(name + ".int0", link[0], link[1]);
+ interface[1] = new Interface(name + ".int1", link[1], link[0]);
- int1->setPeer(i1);
- i1->setPeer(int1);
- int2->setPeer(i2);
- i2->setPeer(int2);
+ interface[0]->setPeer(peer0);
+ peer0->setPeer(interface[0]);
+ interface[1]->setPeer(peer1);
+ peer1->setPeer(interface[1]);
}
EtherLink::~EtherLink()
{
- delete link1;
- delete link2;
+ delete link[0];
+ delete link[1];
- delete int1;
- delete int2;
+ delete interface[0];
+ delete interface[1];
}
EtherLink::Interface::Interface(const string &name, Link *tx, Link *rx)
@@ -82,26 +82,25 @@ EtherLink::Interface::Interface(const string &name, Link *tx, Link *rx)
rx->setRxInt(this);
}
-EtherLink::Link::Link(const string &name, double rate, Tick delay,
- EtherDump *d)
- : objName(name), txint(NULL), rxint(NULL), ticksPerByte(rate),
- linkDelay(delay), dump(d), doneEvent(this)
-{}
+EtherLink::Link::Link(const string &name, EtherLink *p, int num,
+ double rate, Tick delay, EtherDump *d)
+ : objName(name), parent(p), number(num), txint(NULL), rxint(NULL),
+ ticksPerByte(rate), linkDelay(delay), dump(d),
+ doneEvent(this)
+{ }
void
EtherLink::serialize(ostream &os)
{
- nameOut(os, name() + ".link1");
- link1->serialize(os);
- nameOut(os, name() + ".link2");
- link2->serialize(os);
+ link[0]->serialize("link0", os);
+ link[1]->serialize("link1", os);
}
void
EtherLink::unserialize(Checkpoint *cp, const string &section)
{
- link1->unserialize(cp, section + ".link1");
- link2->unserialize(cp, section + ".link2");
+ link[0]->unserialize("link0", cp, section);
+ link[1]->unserialize("link1", cp, section);
}
void
@@ -118,10 +117,9 @@ class LinkDelayEvent : public Event
EtherLink::Link *link;
PacketPtr packet;
- // non-scheduling version for createForUnserialize()
- LinkDelayEvent(EtherLink::Link *link);
-
public:
+ // non-scheduling version for createForUnserialize()
+ LinkDelayEvent();
LinkDelayEvent(EtherLink::Link *link, PacketPtr pkt, Tick when);
void process();
@@ -132,7 +130,6 @@ class LinkDelayEvent : public Event
const string &section);
};
-
void
EtherLink::Link::txDone()
{
@@ -173,43 +170,44 @@ EtherLink::Link::transmit(PacketPtr pkt)
}
void
-EtherLink::Link::serialize(ostream &os)
+EtherLink::Link::serialize(const string &base, ostream &os)
{
bool packet_exists = packet;
- SERIALIZE_SCALAR(packet_exists);
+ paramOut(os, base + ".packet_exists", packet_exists);
+ if (packet_exists)
+ packet->serialize(base + ".packet", os);
bool event_scheduled = doneEvent.scheduled();
- SERIALIZE_SCALAR(event_scheduled);
+ paramOut(os, base + ".event_scheuled", event_scheduled);
if (event_scheduled) {
Tick event_time = doneEvent.when();
- SERIALIZE_SCALAR(event_time);
+ paramOut(os, base + ".event_time", event_time);
}
- if (packet_exists)
- packet->serialize("packet", os);
}
void
-EtherLink::Link::unserialize(Checkpoint *cp, const string &section)
+EtherLink::Link::unserialize(const string &base, Checkpoint *cp,
+ const string &section)
{
bool packet_exists;
- UNSERIALIZE_SCALAR(packet_exists);
+ paramIn(cp, section, base + ".packet_exists", packet_exists);
if (packet_exists) {
packet = new PacketData(16384);
- packet->unserialize("packet", cp, section);
+ packet->unserialize(base + ".packet", cp, section);
}
bool event_scheduled;
- UNSERIALIZE_SCALAR(event_scheduled);
+ paramIn(cp, section, base + ".event_scheduled", event_scheduled);
if (event_scheduled) {
Tick event_time;
- UNSERIALIZE_SCALAR(event_time);
+ paramIn(cp, section, base + ".event_time", event_time);
doneEvent.schedule(event_time);
}
}
-LinkDelayEvent::LinkDelayEvent(EtherLink::Link *l)
- : Event(&mainEventQueue), link(l)
+LinkDelayEvent::LinkDelayEvent()
+ : Event(&mainEventQueue), link(NULL)
{
setFlags(AutoSerialize);
setFlags(AutoDelete);
@@ -234,7 +232,11 @@ LinkDelayEvent::serialize(ostream &os)
{
paramOut(os, "type", string("LinkDelayEvent"));
Event::serialize(os);
- SERIALIZE_OBJPTR(link);
+
+ EtherLink *parent = link->parent;
+ bool number = link->number;
+ SERIALIZE_OBJPTR(parent);
+ SERIALIZE_SCALAR(number);
packet->serialize("packet", os);
}
@@ -244,6 +246,14 @@ void
LinkDelayEvent::unserialize(Checkpoint *cp, const string &section)
{
Event::unserialize(cp, section);
+
+ EtherLink *parent;
+ bool number;
+ UNSERIALIZE_OBJPTR(parent);
+ UNSERIALIZE_SCALAR(number);
+
+ link = parent->link[number];
+
packet = new PacketData(16384);
packet->unserialize("packet", cp, section);
}
@@ -252,9 +262,7 @@ LinkDelayEvent::unserialize(Checkpoint *cp, const string &section)
Serializable *
LinkDelayEvent::createForUnserialize(Checkpoint *cp, const string &section)
{
- EtherLink::Link *link;
- UNSERIALIZE_OBJPTR(link);
- return new LinkDelayEvent(link);
+ return new LinkDelayEvent();
}
REGISTER_SERIALIZEABLE("LinkDelayEvent", LinkDelayEvent)
diff --git a/dev/etherlink.hh b/dev/etherlink.hh
index d5cd7d7c8..28ab61301 100644
--- a/dev/etherlink.hh
+++ b/dev/etherlink.hh
@@ -40,7 +40,7 @@
#include "sim/sim_object.hh"
class EtherDump;
-
+class Checkpoint;
/*
* Model for a fixed bandwidth full duplex ethernet link
*/
@@ -53,10 +53,14 @@ class EtherLink : public SimObject
/*
* Model for a single uni-directional link
*/
- class Link : public Serializable {
+ class Link
+ {
protected:
std::string objName;
+ EtherLink *parent;
+ int number;
+
Interface *txint;
Interface *rxint;
@@ -78,11 +82,11 @@ class EtherLink : public SimObject
void txComplete(PacketPtr packet);
public:
- Link(const std::string &name, double rate, Tick delay,
- EtherDump *dump);
+ Link(const std::string &name, EtherLink *p, int num,
+ double rate, Tick delay, EtherDump *dump);
~Link() {}
- virtual const std::string name() const { return objName; }
+ const std::string name() const { return objName; }
bool busy() const { return (bool)packet; }
bool transmit(PacketPtr packet);
@@ -90,8 +94,9 @@ class EtherLink : public SimObject
void setTxInt(Interface *i) { assert(!txint); txint = i; }
void setRxInt(Interface *i) { assert(!rxint); rxint = i; }
- virtual void serialize(std::ostream &os);
- virtual void unserialize(Checkpoint *cp, const std::string &section);
+ void serialize(const std::string &base, std::ostream &os);
+ void unserialize(const std::string &base, Checkpoint *cp,
+ const std::string &section);
};
/*
@@ -108,14 +113,11 @@ class EtherLink : public SimObject
void sendDone() { peer->sendDone(); }
};
- Link *link1;
- Link *link2;
-
- EtherInt *int1;
- EtherInt *int2;
+ Link *link[2];
+ EtherInt *interface[2];
public:
- EtherLink(const std::string &name, EtherInt *i1, EtherInt *i2,
+ EtherLink(const std::string &name, EtherInt *peer0, EtherInt *peer1,
Tick speed, Tick delay, EtherDump *dump);
virtual ~EtherLink();
diff --git a/objects/CoherenceProtocol.mpy b/objects/CoherenceProtocol.mpy
index ae041b638..f3b0026b7 100644
--- a/objects/CoherenceProtocol.mpy
+++ b/objects/CoherenceProtocol.mpy
@@ -1,4 +1,4 @@
-Coherence = Enum('uni', 'msi', 'mesi', 'mosi', 'moesi')
+class Coherence(Enum): vals = ['uni', 'msi', 'mesi', 'mosi', 'moesi']
simobj CoherenceProtocol(SimObject):
type = 'CoherenceProtocol'
diff --git a/objects/Ide.mpy b/objects/Ide.mpy
index c4aa2aca0..ce760ad96 100644
--- a/objects/Ide.mpy
+++ b/objects/Ide.mpy
@@ -1,6 +1,6 @@
from Pci import PciDevice
-IdeID = Enum('master', 'slave')
+class IdeID(Enum): vals = ['master', 'slave']
simobj IdeDisk(SimObject):
type = 'IdeDisk'
diff --git a/sim/pyconfig/m5config.py b/sim/pyconfig/m5config.py
index 50032476c..7b1719dfa 100644
--- a/sim/pyconfig/m5config.py
+++ b/sim/pyconfig/m5config.py
@@ -25,7 +25,7 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from __future__ import generators
-import os, re, sys, types
+import os, re, sys, types, inspect
noDot = False
try:
import pydot
@@ -172,9 +172,6 @@ def isSubClass(value, cls):
except:
return False
-def isParam(self):
- return isinstance(self, _Param)
-
def isConfigNode(value):
try:
return issubclass(value, ConfigNode)
@@ -204,8 +201,8 @@ def isParamContext(value):
return False
-class_decorator = '_M5M5_SIMOBJECT_'
-expr_decorator = '_M5M5_EXPRESSION_'
+class_decorator = 'M5M5_SIMOBJECT_'
+expr_decorator = 'M5M5_EXPRESSION_'
dot_decorator = '_M5M5_DOT_'
# The metaclass for ConfigNode (and thus for everything that derives
@@ -215,9 +212,11 @@ dot_decorator = '_M5M5_DOT_'
# of that class are instantiated, and provides inherited instance
# behavior).
class MetaConfigNode(type):
- keywords = { 'abstract' : types.BooleanType,
- 'check' : types.FunctionType,
- 'type' : (types.NoneType, types.StringType) }
+ # Attributes that can be set only at initialization time
+ init_keywords = {}
+ # Attributes that can be set any time
+ keywords = { 'check' : types.FunctionType,
+ 'children' : types.ListType }
# __new__ is called before __init__, and is where the statements
# in the body of the class definition get loaded into the class's
@@ -225,71 +224,78 @@ class MetaConfigNode(type):
# and only allow "private" attributes to be passed to the base
# __new__ (starting with underscore).
def __new__(mcls, name, bases, dict):
- priv = { 'abstract' : False,
- # initialize _params and _values dicts to empty
- '_params' : {},
- '_values' : {},
- '_disable' : {} }
-
+ # Copy "private" attributes (including special methods such as __new__)
+ # to the official dict. Everything else goes in _init_dict to be
+ # filtered in __init__.
+ cls_dict = {}
for key,val in dict.items():
- del dict[key]
-
- if key.startswith(expr_decorator):
- key = key[len(expr_decorator):]
-
- if mcls.keywords.has_key(key):
- if not isinstance(val, mcls.keywords[key]):
- raise TypeError, \
- 'keyword %s has the wrong type %s should be %s' % \
- (key, type(val), mcls.keywords[key])
-
- if isinstance(val, types.FunctionType):
- val = classmethod(val)
- priv[key] = val
-
- elif key.startswith('_'):
- priv[key] = val
-
- elif not isNullPointer(val) and isConfigNode(val):
- dict[key] = val()
-
- elif isSimObjSequence(val):
- dict[key] = [ v() for v in val ]
-
- else:
- dict[key] = val
-
- # If your parent has a value in it that's a config node, clone it.
- for base in bases:
- if not isConfigNode(base):
- continue
-
- for key,value in base._values.iteritems():
- if dict.has_key(key):
- continue
-
- if isConfigNode(value):
- priv['_values'][key] = value()
- elif isSimObjSequence(value):
- priv['_values'][key] = [ val() for val in value ]
-
- # entries left in dict will get passed to __init__, where we'll
- # deal with them as params.
- return super(MetaConfigNode, mcls).__new__(mcls, name, bases, priv)
+ if key.startswith('_'):
+ cls_dict[key] = val
+ del dict[key]
+ cls_dict['_init_dict'] = dict
+ return super(MetaConfigNode, mcls).__new__(mcls, name, bases, cls_dict)
# initialization
def __init__(cls, name, bases, dict):
- super(MetaConfigNode, cls).__init__(cls, name, bases, {})
+ super(MetaConfigNode, cls).__init__(name, bases, dict)
+ # initialize required attributes
+ cls._params = {}
+ cls._values = {}
+ cls._enums = {}
+ cls._disable = {}
cls._bases = [c for c in cls.__mro__ if isConfigNode(c)]
+ cls._anon_subclass_counter = 0
+
+ # If your parent has a value in it that's a config node, clone
+ # it. Do this now so if we update any of the values'
+ # attributes we are updating the clone and not the original.
+ for base in cls._bases:
+ for key,val in base._values.iteritems():
+
+ # don't clone if (1) we're about to overwrite it with
+ # a local setting or (2) we've already cloned a copy
+ # from an earlier (more derived) base
+ if cls._init_dict.has_key(key) or cls._values.has_key(key):
+ continue
+
+ if isConfigNode(val):
+ cls._values[key] = val()
+ elif isSimObjSequence(val):
+ cls._values[key] = [ v() for v in val ]
+ elif isNullPointer(val):
+ cls._values[key] = val
+
+ # now process _init_dict items
+ for key,val in cls._init_dict.items():
+ if isinstance(val, _Param):
+ cls._params[key] = val
+
+ # init-time-only keywords
+ elif cls.init_keywords.has_key(key):
+ cls._set_keyword(key, val, cls.init_keywords[key])
+
+ # enums
+ elif isinstance(val, type) and issubclass(val, Enum):
+ cls._enums[key] = val
+
+ # See description of decorators in the importer.py file.
+ # We just strip off the expr_decorator now since we don't
+ # need from this point on.
+ elif key.startswith(expr_decorator):
+ key = key[len(expr_decorator):]
+ # because it had dots into a list so that we can find the
+ # proper variable to modify.
+ key = key.split(dot_decorator)
+ c = cls
+ for item in key[:-1]:
+ c = getattr(c, item)
+ setattr(c, key[-1], val)
+
+ # default: use normal path (ends up in __setattr__)
+ else:
+ setattr(cls, key, val)
- # initialize attributes with values from class definition
- for key,value in dict.iteritems():
- key = key.split(dot_decorator)
- c = cls
- for item in key[:-1]:
- c = getattr(c, item)
- setattr(c, key[-1], value)
def _isvalue(cls, name):
for c in cls._bases:
@@ -323,9 +329,6 @@ class MetaConfigNode(type):
else:
return default
- def _setparam(cls, name, value):
- cls._params[name] = value
-
def _hasvalue(cls, name):
for c in cls._bases:
if c._values.has_key(name):
@@ -341,7 +344,11 @@ class MetaConfigNode(type):
values[p] = v
for p,v in c._params.iteritems():
if not values.has_key(p) and hasattr(v, 'default'):
- v.valid(v.default)
+ try:
+ v.valid(v.default)
+ except TypeError:
+ panic("Invalid default %s for param %s in node %s"
+ % (v.default,p,cls.__name__))
v = v.default
cls._setvalue(p, v)
values[p] = v
@@ -385,12 +392,20 @@ class MetaConfigNode(type):
if cls._isvalue(attr):
return Value(cls, attr)
- if attr == '_cppname' and hasattr(cls, 'type'):
+ if attr == '_cpp_param_decl' and hasattr(cls, 'type'):
return cls.type + '*'
raise AttributeError, \
"object '%s' has no attribute '%s'" % (cls.__name__, attr)
+ def _set_keyword(cls, keyword, val, kwtype):
+ if not isinstance(val, kwtype):
+ raise TypeError, 'keyword %s has bad type %s (expecting %s)' % \
+ (keyword, type(val), kwtype)
+ if isinstance(val, types.FunctionType):
+ val = classmethod(val)
+ type.__setattr__(cls, keyword, val)
+
# Set attribute (called on foo.attr = value when foo is an
# instance of class cls).
def __setattr__(cls, attr, value):
@@ -400,11 +415,7 @@ class MetaConfigNode(type):
return
if cls.keywords.has_key(attr):
- raise TypeError, \
- "keyword '%s' can only be set in a simobj definition" % attr
-
- if isParam(value):
- cls._setparam(attr, value)
+ cls._set_keyword(attr, value, cls.keywords[attr])
return
# must be SimObject param
@@ -418,8 +429,6 @@ class MetaConfigNode(type):
elif isConfigNode(value) or isSimObjSequence(value):
cls._setvalue(attr, value)
else:
- for p,v in cls._getparams().iteritems():
- print p,v
raise AttributeError, \
"Class %s has no parameter %s" % (cls.__name__, attr)
@@ -524,53 +533,59 @@ class ConfigNode(object):
# Specify metaclass. Any class inheriting from ConfigNode will
# get this metaclass.
__metaclass__ = MetaConfigNode
- type = None
def __new__(cls, **kwargs):
- return MetaConfigNode(cls.__name__, (cls, ), kwargs)
-
- # Set attribute. All attribute assignments go through here. Must
- # be private attribute (starts with '_') or valid parameter entry.
- # Basically identical to MetaConfigClass.__setattr__(), except
- # this sets attributes on specific instances rather than on classes.
- #def __setattr__(self, attr, value):
- # if attr.startswith('_'):
- # object.__setattr__(self, attr, value)
- # return
- # not private; look up as param
- # param = self.__class__.lookup_param(attr)
- # if not param:
- # raise AttributeError, \
- # "Class %s has no parameter %s" \
- # % (self.__class__.__name__, attr)
- # It's ok: set attribute by delegating to 'object' class.
- # Note the use of param.make_value() to verify/canonicalize
- # the assigned value.
- # v = param.convert(value)
- # object.__setattr__(self, attr, v)
+ name = cls.__name__ + ("_%d" % cls._anon_subclass_counter)
+ cls._anon_subclass_counter += 1
+ return cls.__metaclass__(name, (cls, ), kwargs)
class ParamContext(ConfigNode):
pass
-# SimObject is a minimal extension of ConfigNode, implementing a
-# hierarchy node that corresponds to an M5 SimObject. It prints out a
-# "type=" line to indicate its SimObject class, prints out the
-# assigned parameters corresponding to its class, and allows
-# parameters to be set by keyword in the constructor. Note that most
-# of the heavy lifting for the SimObject param handling is done in the
-# MetaConfigNode metaclass.
-class SimObject(ConfigNode):
- def _sim_code(cls):
+class MetaSimObject(MetaConfigNode):
+ # init_keywords and keywords are inherited from MetaConfigNode,
+ # with overrides/additions
+ init_keywords = MetaConfigNode.init_keywords
+ init_keywords.update({ 'abstract' : types.BooleanType,
+ 'type' : types.StringType })
+
+ keywords = MetaConfigNode.keywords
+ # no additional keywords
+
+ cpp_classes = []
+
+ # initialization
+ def __init__(cls, name, bases, dict):
+ super(MetaSimObject, cls).__init__(name, bases, dict)
+
+ if hasattr(cls, 'type'):
+ if name == 'SimObject':
+ cls._cpp_base = None
+ elif hasattr(cls._bases[1], 'type'):
+ cls._cpp_base = cls._bases[1].type
+ else:
+ panic("SimObject %s derives from a non-C++ SimObject %s "\
+ "(no 'type')" % (cls, cls_bases[1].__name__))
+
+ # This class corresponds to a C++ class: put it on the global
+ # list of C++ objects to generate param structs, etc.
+ MetaSimObject.cpp_classes.append(cls)
+
+ def _cpp_decl(cls):
name = cls.__name__
+ code = ""
+ code += "\n".join([e.cpp_declare() for e in cls._enums.values()])
+ code += "\n"
param_names = cls._params.keys()
param_names.sort()
- code = "BEGIN_DECLARE_SIM_OBJECT_PARAMS(%s)\n" % name
- decls = [" " + cls._params[pname].sim_decl(pname) \
- for pname in param_names]
- code += "\n".join(decls) + "\n"
- code += "END_DECLARE_SIM_OBJECT_PARAMS(%s)\n\n" % name
+ code += "struct Params"
+ if cls._cpp_base:
+ code += " : public %s::Params" % cls._cpp_base
+ code += " {\n "
+ code += "\n ".join([cls._params[pname].cpp_decl(pname) \
+ for pname in param_names])
+ code += "\n};\n"
return code
- _sim_code = classmethod(_sim_code)
class NodeParam(object):
def __init__(self, name, param, value):
@@ -692,9 +707,11 @@ class Node(object):
# instantiate children in same order they were added for
# backward compatibility (else we can end up with cpu1
# before cpu0).
+ self.children.sort(lambda x,y: cmp(x.name, y.name))
children = [ c.name for c in self.children if not c.paramcontext]
print 'children =', ' '.join(children)
+ self.params.sort(lambda x,y: cmp(x.name, y.name))
for param in self.params:
try:
if param.value is None:
@@ -815,10 +832,13 @@ class Value(object):
# Regular parameter.
class _Param(object):
- def __init__(self, ptype_string, *args, **kwargs):
- self.ptype_string = ptype_string
- # can't eval ptype_string here to get ptype, since the type might
- # not have been defined yet. Do it lazily in __getattr__.
+ def __init__(self, ptype, *args, **kwargs):
+ if isinstance(ptype, types.StringType):
+ self.ptype_string = ptype
+ elif isinstance(ptype, type):
+ self.ptype = ptype
+ else:
+ raise TypeError, "Param type is not a type (%s)" % ptype
if args:
if len(args) == 1:
@@ -869,8 +889,8 @@ class _Param(object):
def set(self, name, instance, value):
instance.__dict__[name] = value
- def sim_decl(self, name):
- return '%s %s;' % (self.ptype._cppname, name)
+ def cpp_decl(self, name):
+ return '%s %s;' % (self.ptype._cpp_param_decl, name)
class _ParamProxy(object):
def __init__(self, type):
@@ -878,7 +898,18 @@ class _ParamProxy(object):
# E.g., Param.Int(5, "number of widgets")
def __call__(self, *args, **kwargs):
- return _Param(self.ptype, *args, **kwargs)
+ # Param type could be defined only in context of caller (e.g.,
+ # for locally defined Enum subclass). Need to go look up the
+ # type in that enclosing scope.
+ caller_frame = inspect.stack()[1][0]
+ ptype = caller_frame.f_locals.get(self.ptype, None)
+ if not ptype: ptype = caller_frame.f_globals.get(self.ptype, None)
+ if not ptype: ptype = globals().get(self.ptype, None)
+ # ptype could still be None due to circular references... we'll
+ # try one more time to evaluate lazily when ptype is first needed.
+ # In the meantime we'll save the type name as a string.
+ if not ptype: ptype = self.ptype
+ return _Param(ptype, *args, **kwargs)
def __getattr__(self, attr):
if attr == '__bases__':
@@ -932,8 +963,8 @@ class _VectorParam(_Param):
else:
return self.ptype._string(value)
- def sim_decl(self, name):
- return 'std::vector<%s> %s;' % (self.ptype._cppname, name)
+ def cpp_decl(self, name):
+ return 'std::vector<%s> %s;' % (self.ptype._cpp_param_decl, name)
class _VectorParamProxy(_ParamProxy):
# E.g., VectorParam.Int(5, "number of widgets")
@@ -983,7 +1014,7 @@ class CheckedInt(type):
def __new__(cls, cppname, min, max):
# New class derives from _CheckedInt base with proper bounding
# parameters
- dict = { '_cppname' : cppname, '_min' : min, '_max' : max }
+ dict = { '_cpp_param_decl' : cppname, '_min' : min, '_max' : max }
return type.__new__(cls, cppname, (_CheckedInt, ), dict)
class CheckedIntType(CheckedInt):
@@ -1039,7 +1070,8 @@ def RangeSize(start, size):
class Range(type):
def __new__(cls, type):
- dict = { '_cppname' : 'Range<%s>' % type._cppname, '_type' : type }
+ dict = { '_cpp_param_decl' : 'Range<%s>' % type._cpp_param_decl,
+ '_type' : type }
clsname = 'Range_' + type.__name__
return super(cls, Range).__new__(cls, clsname, (_Range, ), dict)
@@ -1047,7 +1079,7 @@ AddrRange = Range(Addr)
# Boolean parameter type.
class Bool(object):
- _cppname = 'bool'
+ _cpp_param_decl = 'bool'
def _convert(value):
t = type(value)
if t == bool:
@@ -1075,7 +1107,7 @@ class Bool(object):
# String-valued parameter.
class String(object):
- _cppname = 'string'
+ _cpp_param_decl = 'string'
# Constructor. Value must be Python string.
def _convert(cls,value):
@@ -1115,7 +1147,7 @@ class NextEthernetAddr(object):
self.addr = IncEthernetAddr(self.addr, inc)
class EthernetAddr(object):
- _cppname = 'EthAddr'
+ _cpp_param_decl = 'EthAddr'
def _convert(cls, value):
if value == NextEthernetAddr:
@@ -1147,15 +1179,10 @@ class EthernetAddr(object):
# only one copy of a particular node
class NullSimObject(object):
__metaclass__ = Singleton
- _cppname = 'NULL'
def __call__(cls):
return cls
- def _sim_code(cls):
- pass
- _sim_code = classmethod(_sim_code)
-
def _instantiate(self, parent = None, path = ''):
pass
@@ -1192,12 +1219,48 @@ Null = NULL = NullSimObject()
# derive the new type from the appropriate base class on the fly.
-# Base class for Enum types.
-class _Enum(object):
+# Metaclass for Enum types
+class MetaEnum(type):
+
+ def __init__(cls, name, bases, init_dict):
+ if init_dict.has_key('map'):
+ if not isinstance(cls.map, dict):
+ raise TypeError, "Enum-derived class attribute 'map' " \
+ "must be of type dict"
+ # build list of value strings from map
+ cls.vals = cls.map.keys()
+ cls.vals.sort()
+ elif init_dict.has_key('vals'):
+ if not isinstance(cls.vals, list):
+ raise TypeError, "Enum-derived class attribute 'vals' " \
+ "must be of type list"
+ # build string->value map from vals sequence
+ cls.map = {}
+ for idx,val in enumerate(cls.vals):
+ cls.map[val] = idx
+ else:
+ raise TypeError, "Enum-derived class must define "\
+ "attribute 'map' or 'vals'"
+
+ cls._cpp_param_decl = name
+
+ super(MetaEnum, cls).__init__(name, bases, init_dict)
+
+ def cpp_declare(cls):
+ s = 'enum %s {\n ' % cls.__name__
+ s += ',\n '.join(['%s = %d' % (v,cls.map[v]) for v in cls.vals])
+ s += '\n};\n'
+ return s
+
+# Base class for enum types.
+class Enum(object):
+ __metaclass__ = MetaEnum
+ vals = []
+
def _convert(self, value):
if value not in self.map:
raise TypeError, "Enum param got bad value '%s' (not in %s)" \
- % (value, self.map)
+ % (value, self.vals)
return value
_convert = classmethod(_convert)
@@ -1205,36 +1268,6 @@ class _Enum(object):
def _string(self, value):
return str(value)
_string = classmethod(_string)
-
-# Enum metaclass... calling Enum(foo) generates a new type (class)
-# that derives from _ListEnum or _DictEnum as appropriate.
-class Enum(type):
- # counter to generate unique names for generated classes
- counter = 1
-
- def __new__(cls, *args):
- if len(args) > 1:
- enum_map = args
- else:
- enum_map = args[0]
-
- if isinstance(enum_map, dict):
- map = enum_map
- elif issequence(enum_map):
- map = {}
- for idx,val in enumerate(enum_map):
- map[val] = idx
- else:
- raise TypeError, "Enum map must be list or dict (got %s)" % map
-
- classname = "Enum%04d" % Enum.counter
- Enum.counter += 1
-
- # New class derives from _Enum base, and gets a 'map'
- # attribute containing the specified list or dict.
- return type.__new__(cls, classname, (_Enum, ), { 'map': map })
-
-
#
# "Constants"... handy aliases for various values.
#
@@ -1269,5 +1302,18 @@ def instantiate(root):
dot.write("config.dot")
dot.write_ps("config.ps")
+# SimObject is a minimal extension of ConfigNode, implementing a
+# hierarchy node that corresponds to an M5 SimObject. It prints out a
+# "type=" line to indicate its SimObject class, prints out the
+# assigned parameters corresponding to its class, and allows
+# parameters to be set by keyword in the constructor. Note that most
+# of the heavy lifting for the SimObject param handling is done in the
+# MetaConfigNode metaclass.
+class SimObject(ConfigNode):
+ __metaclass__ = MetaSimObject
+ type = 'SimObject'
+
from objects import *
+cpp_classes = MetaSimObject.cpp_classes
+cpp_classes.sort()
diff --git a/util/pbs/jobfile.py b/util/pbs/jobfile.py
index 570faa61b..83eb81358 100644
--- a/util/pbs/jobfile.py
+++ b/util/pbs/jobfile.py
@@ -26,7 +26,9 @@
#
# Authors: Nathan Binkert
-from os.path import expanduser
+from os.path import expanduser, isfile, join as joinpath
+import sys
+
def crossproduct(options):
number = len(options)
indexes = [ 0 ] * number
@@ -49,9 +51,16 @@ def crossproduct(options):
done = next()
class JobFile(object):
- def __init__(self, file):
+ def __init__(self, jfile):
self.data = {}
- execfile(expanduser(file), self.data)
+ jfile = expanduser(jfile)
+ if not isfile(jfile):
+ for p in sys.path:
+ if isfile(joinpath(p, jfile)):
+ jfile = joinpath(p, jfile)
+ break
+
+ execfile(jfile, self.data)
self.options = self.data['options']
self.environment = self.data['environment']
self.jobinfo = {}