# -*- mode:python -*-

# Copyright (c) 2016 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.
#
# 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.
#
#################################################################

env.SwitchingHeaders(
    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
        '''),
    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

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
    # <arch>_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
        # <target file>: [ <dependent file>* ]
        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('VecRegs')
DebugFlag('CCRegs')
DebugFlag('MiscRegs')
CompoundFlag('Registers', [ 'IntRegs', 'FloatRegs', 'CCRegs', 'MiscRegs' ])
