| # -*- mode:python -*- |
| |
| # Copyright (c) 2016-2017 ARM Limited |
| # All rights reserved. |
| # |
| # The license below extends only to copyright in the software and shall |
| # not be construed as granting a license to any other intellectual |
| # property including but not limited to intellectual property relating |
| # to a hardware implementation of the functionality of the software |
| # licensed hereunder. You may use the software subject to the license |
| # terms below provided that you ensure that this notice is replicated |
| # unmodified and in its entirety in all distributions of the software, |
| # modified or unmodified, in source code or in binary form. |
| # |
| # 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. |
| |
| import sys |
| import os |
| import re |
| |
| from gem5_scons import Transform |
| |
| 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. |
| # |
| ################################################################# |
| |
| env.SwitchingHeaders( |
| Split(''' |
| decoder.hh |
| isa.hh |
| isa_traits.hh |
| kernel_stats.hh |
| locked_mem.hh |
| microcode_rom.hh |
| pseudo_inst.hh |
| registers.hh |
| remote_gdb.hh |
| stacktrace.hh |
| types.hh |
| utility.hh |
| '''), |
| env.subst('${TARGET_ISA}')) |
| |
| if env['BUILD_GPU']: |
| env.SwitchingHeaders( |
| Split(''' |
| gpu_decoder.hh |
| gpu_isa.hh |
| gpu_types.hh |
| '''), |
| env.subst('${TARGET_GPU_ISA}')) |
| |
| ################################################################# |
| # |
| # Include architecture-specific files. |
| # |
| ################################################################# |
| |
| # |
| # Build a SCons scanner for ISA files |
| # |
| import SCons.Scanner |
| import SCons.Tool |
| |
| scanner = SCons.Scanner.Classic("ISAScan", |
| [".isa", ".ISA"], |
| "SRCDIR", |
| r'^\s*##include\s+"([\w/.-]*)"') |
| |
| env.Append(SCANNERS=scanner) |
| |
| # Tell scons that when it sees a cc.inc file, it should scan it for includes. |
| SCons.Tool.SourceFileScanner.add_scanner('.cc.inc', SCons.Tool.CScanner) |
| |
| # |
| # Now create a Builder object that uses isa_parser.py to generate C++ |
| # output from the ISA description (*.isa) files. |
| # |
| |
| parser_py = File('isa_parser.py') |
| micro_asm_py = File('micro_asm.py') |
| |
| # import ply here because SCons screws with sys.path when performing actions. |
| import ply |
| |
| def run_parser(target, source, env): |
| # Add the current directory to the system path so we can import files. |
| sys.path[0:0] = [ parser_py.dir.abspath ] |
| import isa_parser |
| |
| parser = isa_parser.ISAParser(target[0].dir.abspath) |
| parser.parse_isa_desc(source[0].abspath) |
| |
| desc_action = MakeAction(run_parser, Transform("ISA DESC", 1)) |
| |
| IsaDescBuilder = Builder(action=desc_action) |
| |
| |
| # ISAs should use this function to set up an IsaDescBuilder and not try to |
| # set one up manually. |
| def ISADesc(desc, decoder_splits=1, exec_splits=1): |
| '''Set up a builder for an ISA description. |
| |
| The decoder_splits and exec_splits parameters let us determine what |
| files the isa parser is actually going to generate. This needs to match |
| what files are actually generated, and there's no specific check for that |
| right now. |
| |
| If the parser itself is responsible for generating a list of its products |
| and their dependencies, then using that output to set up the right |
| dependencies. This is what we used to do. The problem is that scons |
| fundamentally doesn't support using a build product to affect its graph |
| of possible products, dependencies, builders, etc. There are a couple ways |
| to work around that limitation. |
| |
| One option is to compute dependencies while the build phase of scons is |
| running. That method can be quite complicated and cumbersome, because we |
| have to make sure our modifications are made before scons tries to |
| consume them. There's also no guarantee that this mechanism will work since |
| it subverts scons expectations and changes things behind its back. This |
| was implemented previously and constrained the builds parallelism |
| significantly. |
| |
| Another option would be to recursively call scons to have it update the |
| list of products/dependencies during the setup phase of this invocation of |
| scons. The problem with that is that it would be very difficult to make |
| the sub-invocation of scons observe the options passed to the primary one |
| in all possible cases, or to even determine conclusively what the name of |
| the scons executable is in the first place. |
| |
| Possible future changes to the isa parser might make it easier to |
| determine what files it would generate, perhaps because there was a more |
| direct correspondence between input files and output files. Or, if the |
| parser could run quickly and determine what its output files would be |
| without having do actually generate those files, then it could be run |
| unconditionally without slowing down all builds or touching the output |
| files unnecessarily. |
| ''' |
| generated_dir = File(desc).dir.up().Dir('generated') |
| def gen_file(name): |
| return generated_dir.File(name) |
| |
| gen = [] |
| def add_gen(name): |
| gen.append(gen_file(name)) |
| |
| # Tell scons about the various files the ISA parser will generate. |
| add_gen('decoder-g.cc.inc') |
| add_gen('decoder-ns.cc.inc') |
| add_gen('decode-method.cc.inc') |
| |
| add_gen('decoder.hh') |
| add_gen('decoder-g.hh.inc') |
| add_gen('decoder-ns.hh.inc') |
| |
| add_gen('exec-g.cc.inc') |
| add_gen('exec-ns.cc.inc') |
| |
| add_gen('max_inst_regs.hh') |
| |
| |
| # These generated files are also top level sources. |
| def source_gen(name): |
| add_gen(name) |
| Source(gen_file(name)) |
| |
| source_gen('decoder.cc') |
| |
| if decoder_splits == 1: |
| source_gen('inst-constrs.cc') |
| else: |
| for i in range(1, decoder_splits + 1): |
| source_gen('inst-constrs-%d.cc' % i) |
| |
| if exec_splits == 1: |
| source_gen('generic_cpu_exec.cc') |
| else: |
| for i in range(1, exec_splits + 1): |
| source_gen('generic_cpu_exec_%d.cc' % i) |
| |
| # Actually create the builder. |
| sources = [desc, parser_py, micro_asm_py] |
| IsaDescBuilder(target=gen, source=sources, env=env) |
| return gen |
| |
| Export('ISADesc') |
| |
| DebugFlag('IntRegs') |
| DebugFlag('FloatRegs') |
| DebugFlag('VecRegs') |
| DebugFlag('VecPredRegs') |
| DebugFlag('CCRegs') |
| DebugFlag('MiscRegs') |
| CompoundFlag('Registers', [ 'IntRegs', 'FloatRegs', 'VecRegs', 'VecPredRegs', |
| 'CCRegs', 'MiscRegs' ]) |