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
This commit is contained in:
commit
2162b433ad
|
@ -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 {
|
||||
|
|
|
@ -2872,12 +2872,6 @@ operator/(Temp l, Temp r)
|
|||
return NodePtr(new BinaryNode<std::divides<Result> >(l, r));
|
||||
}
|
||||
|
||||
inline Temp
|
||||
operator%(Temp l, Temp r)
|
||||
{
|
||||
return NodePtr(new BinaryNode<std::modulus<Result> >(l, r));
|
||||
}
|
||||
|
||||
inline Temp
|
||||
operator-(Temp l)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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."
|
||||
|
||||
|
|
|
@ -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."
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 =
|
||||
|
|
|
@ -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 §ion)
|
||||
{
|
||||
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 §ion);
|
||||
};
|
||||
|
||||
|
||||
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 §ion)
|
||||
EtherLink::Link::unserialize(const string &base, Checkpoint *cp,
|
||||
const string §ion)
|
||||
{
|
||||
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 §ion)
|
||||
{
|
||||
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 §ion)
|
|||
Serializable *
|
||||
LinkDelayEvent::createForUnserialize(Checkpoint *cp, const string §ion)
|
||||
{
|
||||
EtherLink::Link *link;
|
||||
UNSERIALIZE_OBJPTR(link);
|
||||
return new LinkDelayEvent(link);
|
||||
return new LinkDelayEvent();
|
||||
}
|
||||
|
||||
REGISTER_SERIALIZEABLE("LinkDelayEvent", LinkDelayEvent)
|
||||
|
|
|
@ -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 §ion);
|
||||
void serialize(const std::string &base, std::ostream &os);
|
||||
void unserialize(const std::string &base, Checkpoint *cp,
|
||||
const std::string §ion);
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -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();
|
||||
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
from Pci import PciDevice
|
||||
|
||||
IdeID = Enum('master', 'slave')
|
||||
class IdeID(Enum): vals = ['master', 'slave']
|
||||
|
||||
simobj IdeDisk(SimObject):
|
||||
type = 'IdeDisk'
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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 = {}
|
||||
|
|
Loading…
Reference in a new issue