/*
 * Copyright 2019 Google Inc.
 *
 * 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.
 */

#ifndef __SIM_GUEST_ABI_DEFINITION_HH__
#define __SIM_GUEST_ABI_DEFINITION_HH__

#include "base/compiler.hh"

namespace gem5
{

class ThreadContext;

GEM5_DEPRECATED_NAMESPACE(GuestABI, guest_abi);
namespace guest_abi
{

/*
 * To implement an ABI, a subclass needs to implement a system of
 * specializations of these two templates Result and Argument, and define a
 * "State" type.
 *
 * The State type carries information about, for instance, how many
 * integer registers have been consumed gathering earlier arguments. It
 * may contain multiple elements if there are multiple dimensions to track,
 * for instance the number of integer and floating point registers used so far.
 *
 * Result and Argument are class templates instead of function templates so
 * that they can be partially specialized if necessary. C++ doesn't let you
 * partially specialize function templates because that conflicts with
 * template resolution using the function's arguments. Since we already know
 * what type we want and we don't need argument based resolution, we can just
 * wrap the desired functionality in classes and sidestep the problem.
 *
 * Also note that these templates have an "Enabled" parameter to support
 * std::enable_if style conditional specializations.
 */

template <typename ABI, typename Ret, typename Enabled=void>
struct Result
{
    /*
     * Store result "ret" into the state accessible through tc. Optionally
     * accept "state" in case it holds some signature wide information.
     *
     * Note that the declaration below is only to document the expected
     * signature and is commented out so it won't be used by accident.
     * Specializations of this Result class should define their own version
     * of this method which actually does something.
     *
     * static void store(ThreadContext *tc, const Ret &ret);
     * static void store(ThreadContext *tc, const Ret &ret,
     *                   typename ABI::State &state);
     */

    /*
     * Prepare for a result of type Ret. This might mean, for instance,
     * allocating an argument register for a result pointer.
     *
     * This method can be excluded if no preparation is necessary.
     *
     * static void prepare(ThreadContext *tc, typename ABI::State &state);
     */
};

/*
 * This partial specialization prevents having to special case 'void' when
 * working with return types.
 */
template <typename ABI>
struct Result<ABI, void>
{};

template <typename ABI, typename Arg, typename Enabled=void>
struct Argument
{
    /*
     * Retrieve an argument of type Arg from the state accessible through tc,
     * assuming the state represented by "state" has already been used.
     * Also update state to account for this argument as well.
     *
     * Like Result::store above, the declaration below is only to document
     * the expected method signature.
     *
     * static Arg get(ThreadContext *tc, typename ABI::State &state);
     */

    /*
     * Prepare for an argument of type Arg. This might mean, for instance,
     * allocating an argument register for a result pointer.
     *
     * This method can be excluded if no preparation is necessary.
     *
     * static void allocate(ThreadContext *tc, typename ABI::State &state);
     */
};

} // namespace guest_abi
} // namespace gem5

#endif // __SIM_GUEST_ABI_DEFINITION_HH__
