+
+env.Command('python/swig/init.cc',
+ map(Value, sorted(s.module for s in SwigSource.all)),
+ makeSwigInit)
+Source('python/swig/init.cc')
+
+def getFlags(source_flags):
+ flagsMap = {}
+ flagsList = []
+ for s in source_flags:
+ val = eval(s.get_contents())
+ name, compound, desc = val
+ flagsList.append(val)
+ flagsMap[name] = bool(compound)
+
+ for name, compound, desc in flagsList:
+ for flag in compound:
+ if flag not in flagsMap:
+ raise AttributeError, "Trace flag %s not found" % flag
+ if flagsMap[flag]:
+ raise AttributeError, \
+ "Compound flag can't point to another compound flag"
+
+ flagsList.sort()
+ return flagsList
+
+
+# Generate traceflags.py
+def traceFlagsPy(target, source, env):
+ assert(len(target) == 1)
+
+ f = file(str(target[0]), 'w')
+
+ allFlags = getFlags(source)
+
+ print >>f, 'basic = ['
+ for flag, compound, desc in allFlags:
+ if not compound:
+ print >>f, " '%s'," % flag
+ print >>f, " ]"
+ print >>f
+
+ print >>f, 'compound = ['
+ print >>f, " 'All',"
+ for flag, compound, desc in allFlags:
+ if compound:
+ print >>f, " '%s'," % flag
+ print >>f, " ]"
+ print >>f
+
+ print >>f, "all = frozenset(basic + compound)"
+ print >>f
+
+ print >>f, 'compoundMap = {'
+ all = tuple([flag for flag,compound,desc in allFlags if not compound])
+ print >>f, " 'All' : %s," % (all, )
+ for flag, compound, desc in allFlags:
+ if compound:
+ print >>f, " '%s' : %s," % (flag, compound)
+ print >>f, " }"
+ print >>f
+
+ print >>f, 'descriptions = {'
+ print >>f, " 'All' : 'All flags',"
+ for flag, compound, desc in allFlags:
+ print >>f, " '%s' : '%s'," % (flag, desc)
+ print >>f, " }"
+
+ f.close()
+
+def traceFlagsCC(target, source, env):
+ assert(len(target) == 1)
+
+ f = file(str(target[0]), 'w')
+
+ allFlags = getFlags(source)
+
+ # file header
+ print >>f, '''
+/*
+ * DO NOT EDIT THIS FILE! Automatically generated
+ */
+
+#include "base/traceflags.hh"
+
+using namespace Trace;
+
+const char *Trace::flagStrings[] =
+{'''
+
+ # The string array is used by SimpleEnumParam to map the strings
+ # provided by the user to enum values.
+ for flag, compound, desc in allFlags:
+ if not compound:
+ print >>f, ' "%s",' % flag
+
+ print >>f, ' "All",'
+ for flag, compound, desc in allFlags:
+ if compound:
+ print >>f, ' "%s",' % flag
+
+ print >>f, '};'
+ print >>f
+ print >>f, 'const int Trace::numFlagStrings = %d;' % (len(allFlags) + 1)
+ print >>f
+
+ #
+ # Now define the individual compound flag arrays. There is an array
+ # for each compound flag listing the component base flags.
+ #
+ all = tuple([flag for flag,compound,desc in allFlags if not compound])
+ print >>f, 'static const Flags AllMap[] = {'
+ for flag, compound, desc in allFlags:
+ if not compound:
+ print >>f, " %s," % flag
+ print >>f, '};'
+ print >>f
+
+ for flag, compound, desc in allFlags:
+ if not compound:
+ continue
+ print >>f, 'static const Flags %sMap[] = {' % flag
+ for flag in compound:
+ print >>f, " %s," % flag
+ print >>f, " (Flags)-1"
+ print >>f, '};'
+ print >>f
+
+ #
+ # Finally the compoundFlags[] array maps the compound flags
+ # to their individual arrays/
+ #
+ print >>f, 'const Flags *Trace::compoundFlags[] ='
+ print >>f, '{'
+ print >>f, ' AllMap,'
+ for flag, compound, desc in allFlags:
+ if compound:
+ print >>f, ' %sMap,' % flag
+ # file trailer
+ print >>f, '};'
+
+ f.close()
+
+def traceFlagsHH(target, source, env):
+ assert(len(target) == 1)
+
+ f = file(str(target[0]), 'w')
+
+ allFlags = getFlags(source)
+
+ # file header boilerplate
+ print >>f, '''
+/*
+ * 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
+ for flag, compound, desc in allFlags:
+ if not compound:
+ print >>f, ' %s = %d,' % (flag, idx)
+ idx += 1
+
+ numBaseFlags = idx
+ print >>f, ' NumFlags = %d,' % idx
+
+ # put a comment in here to separate base from compound flags
+ print >>f, '''
+// 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.'''
+
+ print >>f, ' All = %d,' % idx
+ idx += 1
+ for flag, compound, desc in allFlags:
+ if compound:
+ print >>f, ' %s = %d,' % (flag, idx)
+ idx += 1
+
+ numCompoundFlags = idx - numBaseFlags
+ print >>f, ' NumCompoundFlags = %d' % numCompoundFlags
+
+ # trailer boilerplate
+ print >>f, '''\
+}; // 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__
+'''
+
+ f.close()
+
+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 an assembly file that
+# inserts the result into the data section with symbols indicating the
+# beginning, and end (and with the size at the end)
+def objectifyPyFile(target, source, env):
+ '''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()
+ dst = file(str(target[0]), 'w')
+
+ pysource = PySource.tnodes[source[0]]
+ compiled = compile(src, pysource.abspath, 'exec')
+ marshalled = marshal.dumps(compiled)
+ compressed = zlib.compress(marshalled)
+ data = compressed
+
+ # Some C/C++ compilers prepend an underscore to global symbol
+ # names, so if they're going to do that, we need to prepend that
+ # leading underscore to globals in the assembly file.
+ if env['LEADING_UNDERSCORE']:
+ sym = '_' + pysource.symname
+ else:
+ sym = pysource.symname
+
+ step = 16
+ print >>dst, ".data"
+ print >>dst, ".globl %s_beg" % sym
+ print >>dst, ".globl %s_end" % sym
+ print >>dst, "%s_beg:" % sym
+ for i in xrange(0, len(data), step):
+ x = array.array('B', data[i:i+step])
+ print >>dst, ".byte", ','.join([str(d) for d in x])
+ print >>dst, "%s_end:" % sym
+ print >>dst, ".long %d" % len(marshalled)
+
+for source in PySource.all:
+ env.Command(source.assembly, source.tnode, objectifyPyFile)
+ Source(source.assembly)
+
+# Generate init_python.cc which creates a bunch of EmbeddedPyModule
+# structs that describe the embedded python code. One such struct
+# contains information about the importer that python uses to get at
+# the embedded files, and then there's a list of all of the rest that
+# the importer uses to load the rest on demand.
+def pythonInit(target, source, env):
+ dst = file(str(target[0]), 'w')
+
+ def dump_mod(sym, endchar=','):
+ def c_str(string):
+ if string is None:
+ return "0"
+ return '"%s"' % string
+ pysource = PySource.symnames[sym]
+ print >>dst, ' { %s,' % c_str(pysource.arcname)
+ print >>dst, ' %s,' % c_str(pysource.abspath)
+ print >>dst, ' %s,' % c_str(pysource.modpath)
+ print >>dst, ' %s_beg, %s_end,' % (sym, sym)
+ print >>dst, ' %s_end - %s_beg,' % (sym, sym)
+ print >>dst, ' *(int *)%s_end }%s' % (sym, endchar)
+
+ print >>dst, '#include "sim/init.hh"'
+
+ for sym in source:
+ sym = sym.get_contents()
+ print >>dst, "extern const char %s_beg[], %s_end[];" % (sym, sym)
+
+ print >>dst, "const EmbeddedPyModule embeddedPyImporter = "
+ dump_mod("PyEMB_importer", endchar=';');
+ print >>dst
+
+ print >>dst, "const EmbeddedPyModule embeddedPyModules[] = {"
+ for i,sym in enumerate(source):
+ sym = sym.get_contents()
+ if sym == "PyEMB_importer":
+ # Skip the importer since we've already exported it
+ continue
+ dump_mod(sym)
+ print >>dst, " { 0, 0, 0, 0, 0, 0, 0 }"
+ print >>dst, "};"
+
+
+env.Command('sim/init_python.cc',
+ map(Value, (s.symname for s in PySource.all)),
+ pythonInit)
+Source('sim/init_python.cc')