ARM/O3: store the result of the predicate evaluation in DynInst or Threadstate.
[gem5.git] / SConstruct
index bfd93f26f336d9e4459371585473480a45a1fdd1..d210fc5b97289d546d2fe076fec38795d57f4725 100644 (file)
@@ -96,6 +96,7 @@ For more details, see:
 """
     raise
 
 """
     raise
 
+# Global Python includes
 import os
 import re
 import subprocess
 import os
 import re
 import subprocess
@@ -106,55 +107,18 @@ from os.path import abspath, basename, dirname, expanduser, normpath
 from os.path import exists,  isdir, isfile
 from os.path import join as joinpath, split as splitpath
 
 from os.path import exists,  isdir, isfile
 from os.path import join as joinpath, split as splitpath
 
+# SCons includes
 import SCons
 import SCons.Node
 
 import SCons
 import SCons.Node
 
-def read_command(cmd, **kwargs):
-    """run the command cmd, read the results and return them
-    this is sorta like `cmd` in shell"""
-    from subprocess import Popen, PIPE, STDOUT
-
-    if isinstance(cmd, str):
-        cmd = cmd.split()
-
-    no_exception = 'exception' in kwargs
-    exception = kwargs.pop('exception', None)
+extra_python_paths = [
+    Dir('src/python').srcnode().abspath, # M5 includes
+    Dir('ext/ply').srcnode().abspath, # ply is used by several files
+    ]
     
     
-    kwargs.setdefault('shell', False)
-    kwargs.setdefault('stdout', PIPE)
-    kwargs.setdefault('stderr', STDOUT)
-    kwargs.setdefault('close_fds', True)
-    try:
-        subp = Popen(cmd, **kwargs)
-    except Exception, e:
-        if no_exception:
-            return exception
-        raise
-
-    return subp.communicate()[0]
-
-# helper function: compare arrays or strings of version numbers.
-# E.g., compare_version((1,3,25), (1,4,1)')
-# returns -1, 0, 1 if v1 is <, ==, > v2
-def compare_versions(v1, v2):
-    def make_version_list(v):
-        if isinstance(v, (list,tuple)):
-            return v
-        elif isinstance(v, str):
-            return map(lambda x: int(re.match('\d+', x).group()), v.split('.'))
-        else:
-            raise TypeError
-
-    v1 = make_version_list(v1)
-    v2 = make_version_list(v2)
-    # Compare corresponding elements of lists
-    for n1,n2 in zip(v1, v2):
-        if n1 < n2: return -1
-        if n1 > n2: return  1
-    # all corresponding values are equal... see if one has extra values
-    if len(v1) < len(v2): return -1
-    if len(v1) > len(v2): return  1
-    return 0
+sys.path[1:1] = extra_python_paths
+
+from m5.util import compareVersions, readCommand
 
 ########################################################################
 #
 
 ########################################################################
 #
@@ -162,7 +126,7 @@ def compare_versions(v1, v2):
 #
 ########################################################################
 use_vars = set([ 'AS', 'AR', 'CC', 'CXX', 'HOME', 'LD_LIBRARY_PATH', 'PATH',
 #
 ########################################################################
 use_vars = set([ 'AS', 'AR', 'CC', 'CXX', 'HOME', 'LD_LIBRARY_PATH', 'PATH',
-                 'RANLIB' ])
+                 'PYTHONPATH', 'RANLIB' ])
 
 use_env = {}
 for key,val in os.environ.iteritems():
 
 use_env = {}
 for key,val in os.environ.iteritems():
@@ -173,6 +137,10 @@ main = Environment(ENV=use_env)
 main.root = Dir(".")         # The current directory (where this file lives).
 main.srcdir = Dir("src")     # The source directory
 
 main.root = Dir(".")         # The current directory (where this file lives).
 main.srcdir = Dir("src")     # The source directory
 
+# add useful python code PYTHONPATH so it can be used by subprocesses
+# as well
+main.AppendENVPath('PYTHONPATH', extra_python_paths)
+
 ########################################################################
 #
 # Mercurial Stuff.
 ########################################################################
 #
 # Mercurial Stuff.
@@ -217,7 +185,7 @@ if hgdir.exists():
     # 1) Grab repository revision if we know it.
     cmd = "hg id -n -i -t -b"
     try:
     # 1) Grab repository revision if we know it.
     cmd = "hg id -n -i -t -b"
     try:
-        hg_info = read_command(cmd, cwd=main.root.abspath).strip()
+        hg_info = readCommand(cmd, cwd=main.root.abspath).strip()
     except OSError:
         print mercurial_bin_not_found
 
     except OSError:
         print mercurial_bin_not_found
 
@@ -345,8 +313,8 @@ global_sticky_vars.AddVariables(
     ('BATCH', 'Use batch pool for build and tests', False),
     ('BATCH_CMD', 'Batch pool submission command name', 'qdo'),
     ('EXTRAS', 'Add Extra directories to the compilation', '',
     ('BATCH', 'Use batch pool for build and tests', False),
     ('BATCH_CMD', 'Batch pool submission command name', 'qdo'),
     ('EXTRAS', 'Add Extra directories to the compilation', '',
-     PathListAllExist, PathListMakeAbsolute)
-    )    
+     PathListAllExist, PathListMakeAbsolute),
+    )
 
 # base help text
 help_text = '''
 
 # base help text
 help_text = '''
@@ -355,11 +323,11 @@ Usage: scons [scons options] [build options] [target(s)]
 Global sticky options:
 '''
 
 Global sticky options:
 '''
 
-help_text += global_sticky_vars.GenerateHelpText(main)
-
 # Update main environment with values from ARGUMENTS & global_sticky_vars_file
 global_sticky_vars.Update(main)
 
 # Update main environment with values from ARGUMENTS & global_sticky_vars_file
 global_sticky_vars.Update(main)
 
+help_text += global_sticky_vars.GenerateHelpText(main)
+
 # Save sticky variable settings back to current variables file
 global_sticky_vars.Save(global_sticky_vars_file, main)
 
 # Save sticky variable settings back to current variables file
 global_sticky_vars.Save(global_sticky_vars_file, main)
 
@@ -377,11 +345,8 @@ Export('extras_dir_list')
 # the ext directory should be on the #includes path
 main.Append(CPPPATH=[Dir('ext')])
 
 # the ext directory should be on the #includes path
 main.Append(CPPPATH=[Dir('ext')])
 
-# M5_PLY is used by isa_parser.py to find the PLY package.
-main.Append(ENV = { 'M5_PLY' : Dir('ext/ply').abspath })
-
-CXX_version = read_command([main['CXX'],'--version'], exception=False)
-CXX_V = read_command([main['CXX'],'-V'], exception=False)
+CXX_version = readCommand([main['CXX'],'--version'], exception=False)
+CXX_V = readCommand([main['CXX'],'-V'], exception=False)
 
 main['GCC'] = CXX_version and CXX_version.find('g++') >= 0
 main['SUNCC'] = CXX_V and CXX_V.find('Sun C++') >= 0
 
 main['GCC'] = CXX_version and CXX_version.find('g++') >= 0
 main['SUNCC'] = CXX_V and CXX_V.find('Sun C++') >= 0
@@ -394,7 +359,7 @@ if main['GCC'] + main['SUNCC'] + main['ICC'] > 1:
 if main['GCC']:
     main.Append(CCFLAGS='-pipe')
     main.Append(CCFLAGS='-fno-strict-aliasing')
 if main['GCC']:
     main.Append(CCFLAGS='-pipe')
     main.Append(CCFLAGS='-fno-strict-aliasing')
-    main.Append(CCFLAGS=Split('-Wall -Wno-sign-compare -Werror -Wundef'))
+    main.Append(CCFLAGS=['-Wall', '-Wno-sign-compare', '-Wundef'])
     main.Append(CXXFLAGS='-Wno-deprecated')
 elif main['ICC']:
     pass #Fix me... add warning flags once we clean up icc warnings
     main.Append(CXXFLAGS='-Wno-deprecated')
 elif main['ICC']:
     pass #Fix me... add warning flags once we clean up icc warnings
@@ -410,6 +375,10 @@ else:
     print '       Please fix SConstruct and src/SConscript and try again.'
     Exit(1)
 
     print '       Please fix SConstruct and src/SConscript and try again.'
     Exit(1)
 
+# Set up common yacc/bison flags (needed for Ruby)
+main['YACCFLAGS'] = '-d'
+main['YACCHXXFILESUFFIX'] = '.hh'
+
 # Do this after we save setting back, or else we'll tack on an
 # extra 'qdo' every time we run scons.
 if main['BATCH']:
 # Do this after we save setting back, or else we'll tack on an
 # extra 'qdo' every time we run scons.
 if main['BATCH']:
@@ -421,7 +390,7 @@ if main['BATCH']:
 
 if sys.platform == 'cygwin':
     # cygwin has some header file issues...
 
 if sys.platform == 'cygwin':
     # cygwin has some header file issues...
-    main.Append(CCFLAGS=Split("-Wno-uninitialized"))
+    main.Append(CCFLAGS="-Wno-uninitialized")
 
 # Check for SWIG
 if not main.has_key('SWIG'):
 
 # Check for SWIG
 if not main.has_key('SWIG'):
@@ -430,7 +399,7 @@ if not main.has_key('SWIG'):
     Exit(1)
 
 # Check for appropriate SWIG version
     Exit(1)
 
 # Check for appropriate SWIG version
-swig_version = read_command(('swig', '-version'), exception='').split()
+swig_version = readCommand(('swig', '-version'), exception='').split()
 # First 3 words should be "SWIG Version x.y.z"
 if len(swig_version) < 3 or \
         swig_version[0] != 'SWIG' or swig_version[1] != 'Version':
 # First 3 words should be "SWIG Version x.y.z"
 if len(swig_version) < 3 or \
         swig_version[0] != 'SWIG' or swig_version[1] != 'Version':
@@ -438,7 +407,7 @@ if len(swig_version) < 3 or \
     Exit(1)
 
 min_swig_version = '1.3.28'
     Exit(1)
 
 min_swig_version = '1.3.28'
-if compare_versions(swig_version[2], min_swig_version) < 0:
+if compareVersions(swig_version[2], min_swig_version) < 0:
     print 'Error: SWIG version', min_swig_version, 'or newer required.'
     print '       Installed version:', swig_version[2]
     Exit(1)
     print 'Error: SWIG version', min_swig_version, 'or newer required.'
     print '       Installed version:', swig_version[2]
     Exit(1)
@@ -509,8 +478,8 @@ conf.CheckLeading()
 try:
     import platform
     uname = platform.uname()
 try:
     import platform
     uname = platform.uname()
-    if uname[0] == 'Darwin' and compare_versions(uname[2], '9.0.0') >= 0:
-        if int(read_command('sysctl -n hw.cpu64bit_capable')[0]):
+    if uname[0] == 'Darwin' and compareVersions(uname[2], '9.0.0') >= 0:
+        if int(readCommand('sysctl -n hw.cpu64bit_capable')[0]):
             main.Append(CCFLAGS='-arch x86_64')
             main.Append(CFLAGS='-arch x86_64')
             main.Append(LINKFLAGS='-arch x86_64')
             main.Append(CCFLAGS='-arch x86_64')
             main.Append(CFLAGS='-arch x86_64')
             main.Append(LINKFLAGS='-arch x86_64')
@@ -546,7 +515,8 @@ from distutils import sysconfig
 
 py_getvar = sysconfig.get_config_var
 
 
 py_getvar = sysconfig.get_config_var
 
-py_version = 'python' + py_getvar('VERSION')
+py_debug = getattr(sys, 'pydebug', False)
+py_version = 'python' + py_getvar('VERSION') + (py_debug and "_d" or "")
 
 py_general_include = sysconfig.get_python_inc()
 py_platform_include = sysconfig.get_python_inc(plat_specific=True)
 
 py_general_include = sysconfig.get_python_inc()
 py_platform_include = sysconfig.get_python_inc(plat_specific=True)
@@ -610,9 +580,9 @@ have_mysql = bool(mysql_config)
 
 # Check MySQL version.
 if have_mysql:
 
 # Check MySQL version.
 if have_mysql:
-    mysql_version = read_command(mysql_config + ' --version')
+    mysql_version = readCommand(mysql_config + ' --version')
     min_mysql_version = '4.1'
     min_mysql_version = '4.1'
-    if compare_versions(mysql_version, min_mysql_version) < 0:
+    if compareVersions(mysql_version, min_mysql_version) < 0:
         print 'Warning: MySQL', min_mysql_version, 'or newer required.'
         print '         Version', mysql_version, 'detected.'
         have_mysql = False
         print 'Warning: MySQL', min_mysql_version, 'or newer required.'
         print '         Version', mysql_version, 'detected.'
         have_mysql = False
@@ -642,10 +612,34 @@ main = conf.Finish()
 all_isa_list = [ ]
 Export('all_isa_list')
 
 all_isa_list = [ ]
 Export('all_isa_list')
 
-# Define the universe of supported CPU models
-all_cpu_list = [ ]
-default_cpus = [ ]
-Export('all_cpu_list', 'default_cpus')
+class CpuModel(object):
+    '''The CpuModel class encapsulates everything the ISA parser needs to
+    know about a particular CPU model.'''
+
+    # Dict of available CPU model objects.  Accessible as CpuModel.dict.
+    dict = {}
+    list = []
+    defaults = []
+
+    # Constructor.  Automatically adds models to CpuModel.dict.
+    def __init__(self, name, filename, includes, strings, default=False):
+        self.name = name           # name of model
+        self.filename = filename   # filename for output exec code
+        self.includes = includes   # include files needed in exec file
+        # The 'strings' dict holds all the per-CPU symbols we can
+        # substitute into templates etc.
+        self.strings = strings
+
+        # This cpu is enabled by default
+        self.default = default
+
+        # Add self to dict
+        if name in CpuModel.dict:
+            raise AttributeError, "CpuModel '%s' already registered" % name
+        CpuModel.dict[name] = self
+        CpuModel.list.append(name)
+
+Export('CpuModel')
 
 # Sticky variables get saved in the variables file so they persist from
 # one invocation to the next (unless overridden, in which case the new
 
 # Sticky variables get saved in the variables file so they persist from
 # one invocation to the next (unless overridden, in which case the new
@@ -670,13 +664,13 @@ for bdir in [ base_dir ] + extras_dir_list:
             SConscript(joinpath(root, 'SConsopts'))
 
 all_isa_list.sort()
             SConscript(joinpath(root, 'SConsopts'))
 
 all_isa_list.sort()
-all_cpu_list.sort()
-default_cpus.sort()
 
 sticky_vars.AddVariables(
     EnumVariable('TARGET_ISA', 'Target ISA', 'alpha', all_isa_list),
     BoolVariable('FULL_SYSTEM', 'Full-system support', False),
 
 sticky_vars.AddVariables(
     EnumVariable('TARGET_ISA', 'Target ISA', 'alpha', all_isa_list),
     BoolVariable('FULL_SYSTEM', 'Full-system support', False),
-    ListVariable('CPU_MODELS', 'CPU models', default_cpus, all_cpu_list),
+    ListVariable('CPU_MODELS', 'CPU models',
+                 sorted(n for n,m in CpuModel.dict.iteritems() if m.default),
+                 sorted(CpuModel.list)),
     BoolVariable('NO_FAST_ALLOC', 'Disable fast object allocator', False),
     BoolVariable('FAST_ALLOC_DEBUG', 'Enable fast object allocator debugging',
                  False),
     BoolVariable('NO_FAST_ALLOC', 'Disable fast object allocator', False),
     BoolVariable('FAST_ALLOC_DEBUG', 'Enable fast object allocator debugging',
                  False),
@@ -694,6 +688,7 @@ sticky_vars.AddVariables(
     BoolVariable('USE_FENV', 'Use <fenv.h> IEEE mode control', have_fenv),
     BoolVariable('USE_CHECKER', 'Use checker for detailed CPU models', False),
     BoolVariable('CP_ANNOTATE', 'Enable critical path annotation capability', False),
     BoolVariable('USE_FENV', 'Use <fenv.h> IEEE mode control', have_fenv),
     BoolVariable('USE_CHECKER', 'Use checker for detailed CPU models', False),
     BoolVariable('CP_ANNOTATE', 'Enable critical path annotation capability', False),
+    BoolVariable('RUBY', 'Build with Ruby', False),
     )
 
 nonsticky_vars.AddVariables(
     )
 
 nonsticky_vars.AddVariables(
@@ -772,17 +767,10 @@ def make_switching_dir(dname, switch_headers, env):
     # list of ISAs from env['ALL_ISA_LIST'].
     def gen_switch_hdr(target, source, env):
         fname = str(target[0])
     # list of ISAs from env['ALL_ISA_LIST'].
     def gen_switch_hdr(target, source, env):
         fname = str(target[0])
-        bname = basename(fname)
         f = open(fname, 'w')
         f = open(fname, 'w')
-        f.write('#include "arch/isa_specific.hh"\n')
-        cond = '#if'
-        for isa in all_isa_list:
-            f.write('%s THE_ISA == %s_ISA\n#include "%s/%s/%s"\n'
-                    % (cond, isa.upper(), dname, isa, bname))
-            cond = '#elif'
-        f.write('#else\n#error "THE_ISA not set"\n#endif\n')
+        isa = env['TARGET_ISA'].lower()
+        print >>f, '#include "%s/%s/%s"' % (dname, isa, basename(fname))
         f.close()
         f.close()
-        return 0
 
     # String to print when generating header
     def gen_switch_hdr_string(target, source, env):
 
     # String to print when generating header
     def gen_switch_hdr_string(target, source, env):