# -*- mode:python -*- # Copyright (c) 2006 The Regents of The University of Michigan # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer; # redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution; # neither the name of the copyright holders nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # Authors: Steve Reinhardt import sys import os import re Import('*') ################################################################# # # ISA "switch header" generation. # # Auto-generate arch headers that include the right ISA-specific # header based on the setting of THE_ISA preprocessor variable. # ################################################################# # List of headers to generate isa_switch_hdrs = Split(''' decoder.hh interrupts.hh isa.hh isa_traits.hh kernel_stats.hh locked_mem.hh microcode_rom.hh mmapped_ipr.hh mt.hh process.hh pseudo_inst.hh registers.hh remote_gdb.hh stacktrace.hh tlb.hh types.hh utility.hh vtophys.hh ''') # Set up this directory to support switching headers make_switching_dir('arch', isa_switch_hdrs, env) if env['BUILD_GPU']: gpu_isa_switch_hdrs = Split(''' gpu_decoder.hh gpu_isa.hh gpu_types.hh ''') make_gpu_switching_dir('arch', gpu_isa_switch_hdrs, env) ################################################################# # # Include architecture-specific files. # ################################################################# # # Build a SCons scanner for ISA files # import SCons.Scanner isa_scanner = SCons.Scanner.Classic("ISAScan", [".isa", ".ISA"], "SRCDIR", r'^\s*##include\s+"([\w/.-]*)"') env.Append(SCANNERS = isa_scanner) # # Now create a Builder object that uses isa_parser.py to generate C++ # output from the ISA description (*.isa) files. # isa_parser = File('isa_parser.py') # The emitter patches up the sources & targets to include the # autogenerated files as targets and isa parser itself as a source. def isa_desc_emitter(target, source, env): # List the isa parser as a source. source += [ isa_parser, Value("ExecContext"), ] # Specify different targets depending on if we're running the ISA # parser for its dependency information, or for the generated files. # (As an optimization, the ISA parser detects the useless second run # and skips doing any work, if the first run was performed, since it # always generates all its files). The way we track this in SCons is the # _isa_outputs value in the environment (env). If it's unset, we # don't know what the dependencies are so we ask for generated/inc.d to # be generated so they can be acquired. If we know what they are, then # it's because we've already processed inc.d and then claim that our # outputs (targets) will be thus. isa = env['TARGET_ISA'] key = '%s_isa_outputs' % isa if key in env: targets = [ os.path.join('generated', f) for f in env[key] ] else: targets = [ os.path.join('generated','inc.d') ] def prefix(s): return os.path.join(target[0].dir.up().abspath, s) return [ prefix(t) for t in targets ], source ARCH_DIR = Dir('.') # import ply here because SCons screws with sys.path when performing actions. import ply def isa_desc_action_func(target, source, env): # Add the current directory to the system path so we can import files sys.path[0:0] = [ ARCH_DIR.srcnode().abspath ] import isa_parser # Skip over the ISA description itself and the parser to the CPU models. models = [ s.get_contents() for s in source[2:] ] parser = isa_parser.ISAParser(target[0].dir.abspath) parser.parse_isa_desc(source[0].abspath) isa_desc_action = MakeAction(isa_desc_action_func, Transform("ISA DESC", 1)) # Also include the CheckerCPU as one of the models if it is being # enabled via command line. isa_desc_builder = Builder(action=isa_desc_action, emitter=isa_desc_emitter) env.Append(BUILDERS = { 'ISADesc' : isa_desc_builder }) # The ISA is generated twice: the first time to find out what it generates, # and the second time to make scons happy by telling the ISADesc builder # what it will make before it builds it. def scan_isa_deps(target, source, env): # Process dependency file generated by the ISA parser -- # add the listed files to the dependency tree of the build. source = source[0] archbase = source.dir.up().path try: depfile = open(source.abspath, 'r') except: print "scan_isa_deps: Can't open ISA deps file '%s' in %s" % \ (source.path,os.getcwd()) raise # Scan through the lines targets = {} for line in depfile: # Read the dependency line with the format # : [ * ] m = re.match(r'^\s*([^:]+\.([^\.:]+))\s*:\s*(.*)', line) assert(m) targ, extn = m.group(1,2) deps = m.group(3).split() files = [ targ ] + deps for f in files: targets[f] = True # Eliminate unnecessary re-generation if we already generated it env.Precious(os.path.join(archbase, 'generated', f)) files = [ os.path.join(archbase, 'generated', f) for f in files ] if extn == 'cc': Source(os.path.join(archbase,'generated', targ)) depfile.close() env[env['TARGET_ISA'] + '_isa_outputs'] = targets.keys() isa = env.ISADesc(os.path.join(archbase,'isa','main.isa')) for t in targets: env.Depends('#all-isas', isa) env.Append(BUILDERS = {'ScanISA' : Builder(action=MakeAction(scan_isa_deps, Transform("NEW DEPS", 1)))}) DebugFlag('IntRegs') DebugFlag('FloatRegs') DebugFlag('CCRegs') DebugFlag('MiscRegs') CompoundFlag('Registers', [ 'IntRegs', 'FloatRegs', 'CCRegs', 'MiscRegs' ])