+ allFlags = getFlags(source)
+ code = code_formatter()
+
+ # file header boilerplate
+ code('''\
+/*
+ * DO NOT EDIT THIS FILE!
+ *
+ * Automatically generated from traceflags.py
+ */
+
+#ifndef __BASE_TRACE_FLAGS_HH__
+#define __BASE_TRACE_FLAGS_HH__
+
+namespace Trace {
+
+enum Flags {''')
+
+ # Generate the enum. Base flags come first, then compound flags.
+ idx = 0
+ code.indent()
+ for flag, compound, desc in allFlags:
+ if not compound:
+ code('$flag = $idx,')
+ idx += 1
+
+ numBaseFlags = idx
+ code('NumFlags = $idx,')
+ code.dedent()
+ code()
+
+ # put a comment in here to separate base from compound flags
+ code('''
+// The remaining enum values are *not* valid indices for Trace::flags.
+// They are "compound" flags, which correspond to sets of base
+// flags, and are used by changeFlag.''')
+
+ code.indent()
+ code('All = $idx,')
+ idx += 1
+ for flag, compound, desc in allFlags:
+ if compound:
+ code('$flag = $idx,')
+ idx += 1
+
+ numCompoundFlags = idx - numBaseFlags
+ code('NumCompoundFlags = $numCompoundFlags')
+ code.dedent()
+
+ # trailer boilerplate
+ code('''\
+}; // enum Flags
+
+// Array of strings for SimpleEnumParam
+extern const char *flagStrings[];
+extern const int numFlagStrings;
+
+// Array of arraay pointers: for each compound flag, gives the list of
+// base flags to set. Inidividual flag arrays are terminated by -1.
+extern const Flags *compoundFlags[];
+
+/* namespace Trace */ }
+
+#endif // __BASE_TRACE_FLAGS_HH__
+''')
+
+ code.write(str(target[0]))
+
+flags = map(Value, trace_flags.values())
+env.Command('base/traceflags.py', flags, traceFlagsPy)
+PySource('m5', 'base/traceflags.py')
+
+env.Command('base/traceflags.hh', flags, traceFlagsHH)
+env.Command('base/traceflags.cc', flags, traceFlagsCC)
+Source('base/traceflags.cc')
+
+# Embed python files. All .py files that have been indicated by a
+# PySource() call in a SConscript need to be embedded into the M5
+# library. To do that, we compile the file to byte code, marshal the
+# byte code, compress it, and then generate a c++ file that
+# inserts the result into an array.
+def embedPyFile(target, source, env):
+ def c_str(string):
+ if string is None:
+ return "0"
+ return '"%s"' % string
+
+ '''Action function to compile a .py into a code object, marshal
+ it, compress it, and stick it into an asm file so the code appears
+ as just bytes with a label in the data section'''
+
+ src = file(str(source[0]), 'r').read()
+
+ pysource = PySource.tnodes[source[0]]
+ compiled = compile(src, pysource.abspath, 'exec')
+ marshalled = marshal.dumps(compiled)
+ compressed = zlib.compress(marshalled)
+ data = compressed
+ sym = pysource.symname
+
+ code = code_formatter()
+ code('''\
+#include "sim/init.hh"
+
+namespace {
+
+const char data_${sym}[] = {
+''')
+ code.indent()
+ step = 16
+ for i in xrange(0, len(data), step):
+ x = array.array('B', data[i:i+step])
+ code(''.join('%d,' % d for d in x))
+ code.dedent()
+
+ code('''};
+
+EmbeddedPython embedded_${sym}(
+ ${{c_str(pysource.arcname)}},
+ ${{c_str(pysource.abspath)}},
+ ${{c_str(pysource.modpath)}},
+ data_${sym},
+ ${{len(data)}},
+ ${{len(marshalled)}});
+
+/* namespace */ }
+''')
+ code.write(str(target[0]))
+
+for source in PySource.all:
+ env.Command(source.cpp, source.tnode, embedPyFile)
+ Source(source.cpp)