# Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
# Copyright (c) 2009 The Hewlett-Packard Development Company
# Copyright (c) 2013 Advanced Micro Devices, Inc.
# 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.

from slicc.ast.ExprAST import ExprAST
from slicc.symbols import Func, Type

class FuncCallExprAST(ExprAST):
    def __init__(self, slicc, proc_name, exprs):
        super(FuncCallExprAST, self).__init__(slicc)
        self.proc_name = proc_name
        self.exprs = exprs

    def __repr__(self):
        return "[FuncCallExpr: %s %s]" % (self.proc_name, self.exprs)

    def generate(self, code):
        machine = self.state_machine

        if self.proc_name == "DPRINTF":
            # Code for inserting the location of the DPRINTF()
            # statement in the .sm file in the statement it self.
            # 'self.exprs[0].location' represents the location.
            # 'format' represents the second argument of the
            # original DPRINTF() call. It is left unmodified.
            # str_list is used for concatenating the argument
            # list following the format specifier. A DPRINTF()
            # call may or may not contain any arguments following
            # the format specifier. These two cases need to be
            # handled differently. Hence the check whether or not
            # the str_list is empty.

            dflag = "%s" % (self.exprs[0].name)
            machine.addDebugFlag(dflag)
            format = "%s" % (self.exprs[1].inline())
            format_length = len(format)
            str_list = []

            for i in range(2, len(self.exprs)):
                str_list.append("%s" % self.exprs[i].inline())

            if len(str_list) == 0:
                code('DPRINTF($0, "$1: $2")',
                     dflag, self.exprs[0].location, format[2:format_length-2])
            else:
                code('DPRINTF($0, "$1: $2", $3)',
                     dflag,
                     self.exprs[0].location, format[2:format_length-2],
                     ', '.join(str_list))

            return self.symtab.find("void", Type)

        if self.proc_name == "DPRINTFN":
            format = "%s" % (self.exprs[0].inline())
            format_length = len(format)
            str_list = []

            for i in range(1, len(self.exprs)):
                str_list.append("%s" % self.exprs[i].inline())

            if len(str_list) == 0:
                code('DPRINTFN("$0: $1")',
                     self.exprs[0].location, format[2:format_length-2])
            else:
                code('DPRINTFN("$0: $1", $2)',
                     self.exprs[0].location, format[2:format_length-2],
                     ', '.join(str_list))

            return self.symtab.find("void", Type)

        # hack for adding comments to profileTransition
        if self.proc_name == "APPEND_TRANSITION_COMMENT":
            # FIXME - check for number of parameters
            code("APPEND_TRANSITION_COMMENT($0)", self.exprs[0].inline())
            return self.symtab.find("void", Type)

        func_name_args = self.proc_name

        for expr in self.exprs:
            actual_type,param_code = expr.inline(True)
            func_name_args += "_" + str(actual_type.ident)

        # Look up the function in the symbol table
        func = self.symtab.find(func_name_args, Func)

        # Check the types and get the code for the parameters
        if func is None:
            self.error("Unrecognized function name: '%s'", func_name_args)

        cvec, type_vec = func.checkArguments(self.exprs)

        # OK, the semantics of "trigger" here is that, ports in the
        # machine have different priorities. We always check the first
        # port for doable transitions. If nothing/stalled, we pick one
        # from the next port.
        #
        # One thing we have to be careful as the SLICC protocol
        # writter is : If a port have two or more transitions can be
        # picked from in one cycle, they must be independent.
        # Otherwise, if transition A and B mean to be executed in
        # sequential, and A get stalled, transition B can be issued
        # erroneously. In practice, in most case, there is only one
        # transition should be executed in one cycle for a given
        # port. So as most of current protocols.

        if self.proc_name == "trigger":
            code('''
{
''')
            if machine.TBEType != None and machine.EntryType != None:
                code('''
    TransitionResult result = doTransition(${{cvec[0]}}, ${{cvec[2]}}, ${{cvec[3]}}, ${{cvec[1]}});
''')
            elif machine.TBEType != None:
                code('''
    TransitionResult result = doTransition(${{cvec[0]}}, ${{cvec[2]}}, ${{cvec[1]}});
''')
            elif machine.EntryType != None:
                code('''
    TransitionResult result = doTransition(${{cvec[0]}}, ${{cvec[2]}}, ${{cvec[1]}});
''')
            else:
                code('''
    TransitionResult result = doTransition(${{cvec[0]}}, ${{cvec[1]}});
''')

            code('''
    if (result == TransitionResult_Valid) {
        counter++;
        continue; // Check the first port again
    }

    if (result == TransitionResult_ResourceStall ||
        result == TransitionResult_ProtocolStall) {
        scheduleEvent(Cycles(1));

        // Cannot do anything with this transition, go check next doable transition (mostly likely of next port)
    }
}
''')
        elif self.proc_name == "error":
            code("$0", self.exprs[0].embedError(cvec[0]))
        elif self.proc_name == "assert":
            error = self.exprs[0].embedError('"assert failure"')
            code('''
#ifndef NDEBUG
if (!(${{cvec[0]}})) {
    $error
}
#endif
''')

        elif self.proc_name == "set_cache_entry":
            code("set_cache_entry(m_cache_entry_ptr, %s);" %(cvec[0]));
        elif self.proc_name == "unset_cache_entry":
            code("unset_cache_entry(m_cache_entry_ptr);");
        elif self.proc_name == "set_tbe":
            code("set_tbe(m_tbe_ptr, %s);" %(cvec[0]));
        elif self.proc_name == "unset_tbe":
            code("unset_tbe(m_tbe_ptr);");
        elif self.proc_name == "stallPort":
            code("scheduleEvent(Cycles(1));")

        else:
            # Normal function
            if "external" not in func and not func.isInternalMachineFunc:
                self.error("Invalid function")

            params = ""
            first_param = True

            for (param_code, type) in zip(cvec, type_vec):
                if first_param:
                    params = str(param_code)
                    first_param  = False
                else:
                    params += ', '
                    params += str(param_code);

            fix = code.nofix()
            code('(${{func.c_name}}($params))')
            code.fix(fix)

        return func.return_type
