# -*- 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
        locked_mem.hh
        registers.hh
        remote_gdb.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_files = Glob('isa_parser/*.py')
micro_asm_py = File('micro_asm.py')

# import ply here because SCons screws with sys.path when performing actions.
import ply

arch_dir = Dir('.')

def run_parser(target, source, env):
    # Add the current directory to the system path so we can import files.
    sys.path[0:0] = [ arch_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')


    # 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, micro_asm_py] + parser_files
    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' ])
