1# -*- mode:python -*- 2 3# Copyright (c) 2016-2017 ARM Limited 4# All rights reserved. 5# 6# The license below extends only to copyright in the software and shall 7# not be construed as granting a license to any other intellectual 8# property including but not limited to intellectual property relating 9# to a hardware implementation of the functionality of the software 10# licensed hereunder. You may use the software subject to the license 11# terms below provided that you ensure that this notice is replicated 12# unmodified and in its entirety in all distributions of the software, 13# modified or unmodified, in source code or in binary form. 14# 15# Copyright (c) 2006 The Regents of The University of Michigan 16# All rights reserved. 17# 18# Redistribution and use in source and binary forms, with or without 19# modification, are permitted provided that the following conditions are 20# met: redistributions of source code must retain the above copyright 21# notice, this list of conditions and the following disclaimer; 22# redistributions in binary form must reproduce the above copyright 23# notice, this list of conditions and the following disclaimer in the 24# documentation and/or other materials provided with the distribution; 25# neither the name of the copyright holders nor the names of its 26# contributors may be used to endorse or promote products derived from 27# this software without specific prior written permission. 28# 29# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 30# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 31# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 32# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 33# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 34# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 35# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 36# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 37# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 38# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 39# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 40# 41# Authors: Steve Reinhardt 42 43import sys 44import os 45import re 46 47from gem5_scons import Transform 48 49Import('*') 50 51################################################################# 52# 53# ISA "switch header" generation. 54# 55# Auto-generate arch headers that include the right ISA-specific 56# header based on the setting of THE_ISA preprocessor variable. 57# 58################################################################# 59 60env.SwitchingHeaders( 61 Split(''' 62 decoder.hh 63 interrupts.hh 64 isa.hh 65 isa_traits.hh 66 kernel_stats.hh 67 locked_mem.hh 68 microcode_rom.hh 69 mmapped_ipr.hh 70 process.hh 71 pseudo_inst.hh 72 registers.hh 73 remote_gdb.hh 74 stacktrace.hh 75 types.hh 76 utility.hh 77 vtophys.hh 78 '''), 79 env.subst('${TARGET_ISA}')) 80 81if env['BUILD_GPU']: 82 env.SwitchingHeaders( 83 Split(''' 84 gpu_decoder.hh 85 gpu_isa.hh 86 gpu_types.hh 87 '''), 88 env.subst('${TARGET_GPU_ISA}')) 89 90################################################################# 91# 92# Include architecture-specific files. 93# 94################################################################# 95 96# 97# Build a SCons scanner for ISA files 98# 99import SCons.Scanner 100import SCons.Tool 101 102scanner = SCons.Scanner.Classic("ISAScan", 103 [".isa", ".ISA"], 104 "SRCDIR", 105 r'^\s*##include\s+"([\w/.-]*)"') 106 107env.Append(SCANNERS=scanner) 108 109# Tell scons that when it sees a cc.inc file, it should scan it for includes. 110SCons.Tool.SourceFileScanner.add_scanner('.cc.inc', SCons.Tool.CScanner) 111 112# 113# Now create a Builder object that uses isa_parser.py to generate C++ 114# output from the ISA description (*.isa) files. 115# 116 117parser_py = File('isa_parser.py') 118micro_asm_py = File('micro_asm.py') 119 120# import ply here because SCons screws with sys.path when performing actions. 121import ply 122 123def run_parser(target, source, env): 124 # Add the current directory to the system path so we can import files. 125 sys.path[0:0] = [ parser_py.dir.abspath ] 126 import isa_parser 127 128 parser = isa_parser.ISAParser(target[0].dir.abspath) 129 parser.parse_isa_desc(source[0].abspath) 130 131desc_action = MakeAction(run_parser, Transform("ISA DESC", 1)) 132 133IsaDescBuilder = Builder(action=desc_action) 134 135 136# ISAs should use this function to set up an IsaDescBuilder and not try to 137# set one up manually. 138def ISADesc(desc, decoder_splits=1, exec_splits=1): 139 '''Set up a builder for an ISA description. 140 141 The decoder_splits and exec_splits parameters let us determine what 142 files the isa parser is actually going to generate. This needs to match 143 what files are actually generated, and there's no specific check for that 144 right now. 145 146 If the parser itself is responsible for generating a list of its products 147 and their dependencies, then using that output to set up the right 148 dependencies. This is what we used to do. The problem is that scons 149 fundamentally doesn't support using a build product to affect its graph 150 of possible products, dependencies, builders, etc. There are a couple ways 151 to work around that limitation. 152 153 One option is to compute dependencies while the build phase of scons is 154 running. That method can be quite complicated and cumbersome, because we 155 have to make sure our modifications are made before scons tries to 156 consume them. There's also no guarantee that this mechanism will work since 157 it subverts scons expectations and changes things behind its back. This 158 was implemented previously and constrained the builds parallelism 159 significantly. 160 161 Another option would be to recursively call scons to have it update the 162 list of products/dependencies during the setup phase of this invocation of 163 scons. The problem with that is that it would be very difficult to make 164 the sub-invocation of scons observe the options passed to the primary one 165 in all possible cases, or to even determine conclusively what the name of 166 the scons executable is in the first place. 167 168 Possible future changes to the isa parser might make it easier to 169 determine what files it would generate, perhaps because there was a more 170 direct correspondence between input files and output files. Or, if the 171 parser could run quickly and determine what its output files would be 172 without having do actually generate those files, then it could be run 173 unconditionally without slowing down all builds or touching the output 174 files unnecessarily. 175 ''' 176 generated_dir = File(desc).dir.up().Dir('generated') 177 def gen_file(name): 178 return generated_dir.File(name) 179 180 gen = [] 181 def add_gen(name): 182 gen.append(gen_file(name)) 183 184 # Tell scons about the various files the ISA parser will generate. 185 add_gen('decoder-g.cc.inc') 186 add_gen('decoder-ns.cc.inc') 187 add_gen('decode-method.cc.inc') 188 189 add_gen('decoder.hh') 190 add_gen('decoder-g.hh.inc') 191 add_gen('decoder-ns.hh.inc') 192 193 add_gen('exec-g.cc.inc') 194 add_gen('exec-ns.cc.inc') 195 196 add_gen('max_inst_regs.hh') 197 198 199 # These generated files are also top level sources. 200 def source_gen(name): 201 add_gen(name) 202 Source(gen_file(name)) 203 204 source_gen('decoder.cc') 205 206 if decoder_splits == 1: 207 source_gen('inst-constrs.cc') 208 else: 209 for i in range(1, decoder_splits + 1): 210 source_gen('inst-constrs-%d.cc' % i) 211 212 if exec_splits == 1: 213 source_gen('generic_cpu_exec.cc') 214 else: 215 for i in range(1, exec_splits + 1): 216 source_gen('generic_cpu_exec_%d.cc' % i) 217 218 # Actually create the builder. 219 sources = [desc, parser_py, micro_asm_py] 220 IsaDescBuilder(target=gen, source=sources, env=env) 221 return gen 222 223Export('ISADesc') 224 225DebugFlag('IntRegs') 226DebugFlag('FloatRegs') 227DebugFlag('VecRegs') 228DebugFlag('VecPredRegs') 229DebugFlag('CCRegs') 230DebugFlag('MiscRegs') 231CompoundFlag('Registers', [ 'IntRegs', 'FloatRegs', 'VecRegs', 'VecPredRegs', 232 'CCRegs', 'MiscRegs' ]) 233