# -*- mode:python -*-

# 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.
#
#################################################################

# List of headers to generate
isa_switch_hdrs = 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
        registers.hh
        remote_gdb.hh
        stacktrace.hh
        tlb.hh
        types.hh
        utility.hh
        vtophys.hh
        ''')

# Set up this directory to support switching headers
make_switching_dir('arch', isa_switch_hdrs, env)

#################################################################
#
# 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('CCRegs')
DebugFlag('MiscRegs')
CompoundFlag('Registers', [ 'IntRegs', 'FloatRegs', 'CCRegs', 'MiscRegs' ])
