SConscript revision 12016:893091853afd
16691Stjones1@inf.ed.ac.uk# -*- mode:python -*-
26691Stjones1@inf.ed.ac.uk
36691Stjones1@inf.ed.ac.uk# Copyright (c) 2006 The Regents of The University of Michigan
46691Stjones1@inf.ed.ac.uk# All rights reserved.
56691Stjones1@inf.ed.ac.uk#
66691Stjones1@inf.ed.ac.uk# Redistribution and use in source and binary forms, with or without
76691Stjones1@inf.ed.ac.uk# modification, are permitted provided that the following conditions are
86691Stjones1@inf.ed.ac.uk# met: redistributions of source code must retain the above copyright
96691Stjones1@inf.ed.ac.uk# notice, this list of conditions and the following disclaimer;
106691Stjones1@inf.ed.ac.uk# redistributions in binary form must reproduce the above copyright
116691Stjones1@inf.ed.ac.uk# notice, this list of conditions and the following disclaimer in the
126691Stjones1@inf.ed.ac.uk# documentation and/or other materials provided with the distribution;
136691Stjones1@inf.ed.ac.uk# neither the name of the copyright holders nor the names of its
146691Stjones1@inf.ed.ac.uk# contributors may be used to endorse or promote products derived from
156691Stjones1@inf.ed.ac.uk# this software without specific prior written permission.
166691Stjones1@inf.ed.ac.uk#
176691Stjones1@inf.ed.ac.uk# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
186691Stjones1@inf.ed.ac.uk# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
196691Stjones1@inf.ed.ac.uk# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
206691Stjones1@inf.ed.ac.uk# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
216691Stjones1@inf.ed.ac.uk# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
226691Stjones1@inf.ed.ac.uk# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
236691Stjones1@inf.ed.ac.uk# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
246691Stjones1@inf.ed.ac.uk# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
256691Stjones1@inf.ed.ac.uk# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
266691Stjones1@inf.ed.ac.uk# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
276691Stjones1@inf.ed.ac.uk# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
286691Stjones1@inf.ed.ac.uk#
296691Stjones1@inf.ed.ac.uk# Authors: Steve Reinhardt
306691Stjones1@inf.ed.ac.uk
316691Stjones1@inf.ed.ac.ukimport sys
326691Stjones1@inf.ed.ac.ukimport os
336691Stjones1@inf.ed.ac.ukimport re
346691Stjones1@inf.ed.ac.uk
356691Stjones1@inf.ed.ac.ukImport('*')
366691Stjones1@inf.ed.ac.uk
376691Stjones1@inf.ed.ac.uk#################################################################
386691Stjones1@inf.ed.ac.uk#
396691Stjones1@inf.ed.ac.uk# ISA "switch header" generation.
408232Snate@binkert.org#
416691Stjones1@inf.ed.ac.uk# Auto-generate arch headers that include the right ISA-specific
426691Stjones1@inf.ed.ac.uk# header based on the setting of THE_ISA preprocessor variable.
436691Stjones1@inf.ed.ac.uk#
446691Stjones1@inf.ed.ac.uk#################################################################
456691Stjones1@inf.ed.ac.uk
466691Stjones1@inf.ed.ac.ukenv.SwitchingHeaders(
476691Stjones1@inf.ed.ac.uk    Split('''
486691Stjones1@inf.ed.ac.uk        decoder.hh
496691Stjones1@inf.ed.ac.uk        interrupts.hh
506691Stjones1@inf.ed.ac.uk        isa.hh
516691Stjones1@inf.ed.ac.uk        isa_traits.hh
526691Stjones1@inf.ed.ac.uk        kernel_stats.hh
536691Stjones1@inf.ed.ac.uk        locked_mem.hh
546691Stjones1@inf.ed.ac.uk        microcode_rom.hh
556691Stjones1@inf.ed.ac.uk        mmapped_ipr.hh
566691Stjones1@inf.ed.ac.uk        mt.hh
576691Stjones1@inf.ed.ac.uk        process.hh
586691Stjones1@inf.ed.ac.uk        pseudo_inst.hh
596691Stjones1@inf.ed.ac.uk        registers.hh
606691Stjones1@inf.ed.ac.uk        remote_gdb.hh
616691Stjones1@inf.ed.ac.uk        stacktrace.hh
626691Stjones1@inf.ed.ac.uk        tlb.hh
636691Stjones1@inf.ed.ac.uk        types.hh
646691Stjones1@inf.ed.ac.uk        utility.hh
656691Stjones1@inf.ed.ac.uk        vtophys.hh
666691Stjones1@inf.ed.ac.uk        '''),
676691Stjones1@inf.ed.ac.uk    env.subst('${TARGET_ISA}'))
686691Stjones1@inf.ed.ac.uk
696691Stjones1@inf.ed.ac.ukif env['BUILD_GPU']:
706691Stjones1@inf.ed.ac.uk    env.SwitchingHeaders(
716691Stjones1@inf.ed.ac.uk        Split('''
726691Stjones1@inf.ed.ac.uk            gpu_decoder.hh
736691Stjones1@inf.ed.ac.uk            gpu_isa.hh
746691Stjones1@inf.ed.ac.uk            gpu_types.hh
756691Stjones1@inf.ed.ac.uk            '''),
766691Stjones1@inf.ed.ac.uk        env.subst('${TARGET_GPU_ISA}'))
776691Stjones1@inf.ed.ac.uk
786691Stjones1@inf.ed.ac.uk#################################################################
796691Stjones1@inf.ed.ac.uk#
806691Stjones1@inf.ed.ac.uk# Include architecture-specific files.
816691Stjones1@inf.ed.ac.uk#
826691Stjones1@inf.ed.ac.uk#################################################################
836691Stjones1@inf.ed.ac.uk
846691Stjones1@inf.ed.ac.uk#
856691Stjones1@inf.ed.ac.uk# Build a SCons scanner for ISA files
866691Stjones1@inf.ed.ac.uk#
876691Stjones1@inf.ed.ac.ukimport SCons.Scanner
886691Stjones1@inf.ed.ac.uk
896691Stjones1@inf.ed.ac.ukisa_scanner = SCons.Scanner.Classic("ISAScan",
906691Stjones1@inf.ed.ac.uk                                    [".isa", ".ISA"],
916691Stjones1@inf.ed.ac.uk                                    "SRCDIR",
926691Stjones1@inf.ed.ac.uk                                    r'^\s*##include\s+"([\w/.-]*)"')
936691Stjones1@inf.ed.ac.uk
946691Stjones1@inf.ed.ac.ukenv.Append(SCANNERS = isa_scanner)
956691Stjones1@inf.ed.ac.uk
966691Stjones1@inf.ed.ac.uk#
976691Stjones1@inf.ed.ac.uk# Now create a Builder object that uses isa_parser.py to generate C++
986691Stjones1@inf.ed.ac.uk# output from the ISA description (*.isa) files.
996691Stjones1@inf.ed.ac.uk#
1006691Stjones1@inf.ed.ac.uk
1016691Stjones1@inf.ed.ac.ukisa_parser = File('isa_parser.py')
1026691Stjones1@inf.ed.ac.uk
1036691Stjones1@inf.ed.ac.uk# The emitter patches up the sources & targets to include the
1046691Stjones1@inf.ed.ac.uk# autogenerated files as targets and isa parser itself as a source.
1056691Stjones1@inf.ed.ac.ukdef isa_desc_emitter(target, source, env):
1066691Stjones1@inf.ed.ac.uk    # List the isa parser as a source.
1076691Stjones1@inf.ed.ac.uk    source += [
1086691Stjones1@inf.ed.ac.uk        isa_parser,
1096691Stjones1@inf.ed.ac.uk        Value("ExecContext"),
1106691Stjones1@inf.ed.ac.uk        ]
1116691Stjones1@inf.ed.ac.uk
1126691Stjones1@inf.ed.ac.uk    # Specify different targets depending on if we're running the ISA
1136691Stjones1@inf.ed.ac.uk    # parser for its dependency information, or for the generated files.
1146691Stjones1@inf.ed.ac.uk    # (As an optimization, the ISA parser detects the useless second run
1156691Stjones1@inf.ed.ac.uk    # and skips doing any work, if the first run was performed, since it
1166691Stjones1@inf.ed.ac.uk    # always generates all its files). The way we track this in SCons is the
1176691Stjones1@inf.ed.ac.uk    # <arch>_isa_outputs value in the environment (env). If it's unset, we
1186691Stjones1@inf.ed.ac.uk    # don't know what the dependencies are so we ask for generated/inc.d to
1196691Stjones1@inf.ed.ac.uk    # be generated so they can be acquired. If we know what they are, then
1206691Stjones1@inf.ed.ac.uk    # it's because we've already processed inc.d and then claim that our
1216691Stjones1@inf.ed.ac.uk    # outputs (targets) will be thus.
1226691Stjones1@inf.ed.ac.uk    isa = env['TARGET_ISA']
1236691Stjones1@inf.ed.ac.uk    key = '%s_isa_outputs' % isa
1246691Stjones1@inf.ed.ac.uk    if key in env:
1256691Stjones1@inf.ed.ac.uk        targets = [ os.path.join('generated', f) for f in env[key] ]
1266691Stjones1@inf.ed.ac.uk    else:
1276691Stjones1@inf.ed.ac.uk        targets = [ os.path.join('generated','inc.d') ]
1286691Stjones1@inf.ed.ac.uk
1296691Stjones1@inf.ed.ac.uk    def prefix(s):
1306691Stjones1@inf.ed.ac.uk        return os.path.join(target[0].dir.up().abspath, s)
1316691Stjones1@inf.ed.ac.uk
1326691Stjones1@inf.ed.ac.uk    return [ prefix(t) for t in targets ], source
1336691Stjones1@inf.ed.ac.uk
1346691Stjones1@inf.ed.ac.ukARCH_DIR = Dir('.')
1356691Stjones1@inf.ed.ac.uk
1366691Stjones1@inf.ed.ac.uk# import ply here because SCons screws with sys.path when performing actions.
1376691Stjones1@inf.ed.ac.ukimport ply
1386691Stjones1@inf.ed.ac.uk
1396691Stjones1@inf.ed.ac.ukdef isa_desc_action_func(target, source, env):
1406691Stjones1@inf.ed.ac.uk    # Add the current directory to the system path so we can import files
1416691Stjones1@inf.ed.ac.uk    sys.path[0:0] = [ ARCH_DIR.srcnode().abspath ]
1426691Stjones1@inf.ed.ac.uk    import isa_parser
1436691Stjones1@inf.ed.ac.uk
1446691Stjones1@inf.ed.ac.uk    # Skip over the ISA description itself and the parser to the CPU models.
1456691Stjones1@inf.ed.ac.uk    models = [ s.get_contents() for s in source[2:] ]
1466691Stjones1@inf.ed.ac.uk    parser = isa_parser.ISAParser(target[0].dir.abspath)
1477811Ssteve.reinhardt@amd.com    parser.parse_isa_desc(source[0].abspath)
1486691Stjones1@inf.ed.ac.ukisa_desc_action = MakeAction(isa_desc_action_func, Transform("ISA DESC", 1))
1496691Stjones1@inf.ed.ac.uk
150# Also include the CheckerCPU as one of the models if it is being
151# enabled via command line.
152isa_desc_builder = Builder(action=isa_desc_action, emitter=isa_desc_emitter)
153
154env.Append(BUILDERS = { 'ISADesc' : isa_desc_builder })
155
156# The ISA is generated twice: the first time to find out what it generates,
157# and the second time to make scons happy by telling the ISADesc builder
158# what it will make before it builds it.
159def scan_isa_deps(target, source, env):
160    # Process dependency file generated by the ISA parser --
161    # add the listed files to the dependency tree of the build.
162    source = source[0]
163    archbase = source.dir.up().path
164
165    try:
166        depfile = open(source.abspath, 'r')
167    except:
168        print "scan_isa_deps: Can't open ISA deps file '%s' in %s" % \
169              (source.path,os.getcwd())
170        raise
171
172    # Scan through the lines
173    targets = {}
174    for line in depfile:
175        # Read the dependency line with the format
176        # <target file>: [ <dependent file>* ]
177        m = re.match(r'^\s*([^:]+\.([^\.:]+))\s*:\s*(.*)', line)
178        assert(m)
179        targ, extn = m.group(1,2)
180        deps = m.group(3).split()
181
182        files = [ targ ] + deps
183        for f in files:
184            targets[f] = True
185            # Eliminate unnecessary re-generation if we already generated it
186            env.Precious(os.path.join(archbase, 'generated', f))
187
188        files = [ os.path.join(archbase, 'generated', f) for f in files ]
189
190        if extn == 'cc':
191            Source(os.path.join(archbase,'generated', targ))
192    depfile.close()
193    env[env['TARGET_ISA'] + '_isa_outputs'] = targets.keys()
194
195    isa = env.ISADesc(os.path.join(archbase,'isa','main.isa'))
196    for t in targets:
197        env.Depends('#all-isas', isa)
198
199env.Append(BUILDERS = {'ScanISA' :
200                        Builder(action=MakeAction(scan_isa_deps,
201                                                  Transform("NEW DEPS", 1)))})
202
203DebugFlag('IntRegs')
204DebugFlag('FloatRegs')
205DebugFlag('CCRegs')
206DebugFlag('MiscRegs')
207CompoundFlag('Registers', [ 'IntRegs', 'FloatRegs', 'CCRegs', 'MiscRegs' ])
208