/*
 * Copyright (c) 2015-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.
 *
 * 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: Giacomo Gabrielli
 *          Nathanael Premillieu
 *          Rekai Gonzalez
 */

/* Vector Registers layout specification
 *
 * This register type is to be used to model the SIMD registers.
 * It takes into account the possibility that different architectural names
 * may overlap (like for ARMv8 AArch32 for example).
 */

#ifndef __ARCH_GENERIC_VEC_REG_HH__
#define __ARCH_GENERIC_VEC_REG_HH__

#include <assert.h>
#include <array>
#include <iostream>
#include <string>
#include <type_traits>
#include <vector>

#include "base/cprintf.hh"

template <size_t Sz>
class VecRegContainer;

/** Vector Register Abstraction
 * This generic class is a view in a particularization of MVC, to vector
 * registers. There is a VecRegContainer that implements the model, and
 * contains the data. To that model we can interpose different instantiations
 * of VecRegT to view the container as a vector of NumElems elems of type
 * VecElem.
 * @tparam VecElem Type of each element of the vector.
 * @tparam NumElems Amount of components of the vector.
 * @tparam Const Indicate if the underlying container can be modified through
 * the view.
 */
template <typename VecElem, size_t NumElems, bool Const>
class VecRegT
{
    /** Size of the register in bytes. */
    static constexpr size_t SIZE = sizeof(VecElem) * NumElems;
  public:
    /** Container type alias. */
    using Container = typename std::conditional<Const,
                                              const VecRegContainer<SIZE>,
                                              VecRegContainer<SIZE>>::type;
  private:
    /** My type alias. */
    using MyClass = VecRegT<VecElem, NumElems, Const>;
    /** Reference to container. */
    Container& container;

  public:
    /** Constructor. */
    VecRegT(Container& cnt) : container(cnt) {};

    /** Zero the container. */
    template<bool Condition = !Const>
    typename std::enable_if<Condition, void>::type
    zero() { container.zero(); }

    template<bool Condition = !Const>
    typename std::enable_if<Condition, MyClass&>::type
    operator=(const MyClass& that)
    {
        container = that.container;
        return *this;
    }

    /** Index operator. */
    const VecElem& operator[](size_t idx) const
    {
        return container.template raw_ptr<VecElem>()[idx];
    }

    /** Index operator. */
    template<bool Condition = !Const>
    typename std::enable_if<Condition, VecElem&>::type
    operator[](size_t idx)
    {
        return container.template raw_ptr<VecElem>()[idx];
    }

    /** Equality operator.
     * Required to compare thread contexts.
     */
    template<typename VE2, size_t NE2, bool C2>
    bool
    operator==(const VecRegT<VE2, NE2, C2>& that) const
    {
        return container == that.container;
    }
    /** Inequality operator.
     * Required to compare thread contexts.
     */
    template<typename VE2, size_t NE2, bool C2>
    bool
    operator!=(const VecRegT<VE2, NE2, C2>& that) const
    {
        return !operator==(that);
    }

    /** Output stream operator. */
    friend std::ostream&
    operator<<(std::ostream& os, const MyClass& vr)
    {
        /* 0-sized is not allowed */
        os << "[" << std::hex << (uint32_t)vr[0];
        for (uint32_t e = 1; e < vr.SIZE; e++)
            os << " " << std::hex << (uint32_t)vr[e];
        os << ']';
        return os;
    }

    const std::string print() const { return csprintf("%s", *this); }
    /**
     * Cast to VecRegContainer&
     * It is useful to get the reference to the container for ISA tricks,
     * because casting to reference prevents unnecessary copies.
     */
    operator Container&() { return container; }
};

/* Forward declaration. */
template <typename VecElem, bool Const>
class VecLaneT;

/**
 * Vector Register Abstraction
 * This generic class is the model in a particularization of MVC, to vector
 * registers. The model has functionality to create views of itself, or a
 * portion through the method 'as
 * @tparam Sz Size of the container in bytes.
 */
template <size_t Sz>
class VecRegContainer
{
  static_assert(Sz > 0,
          "Cannot create Vector Register Container of zero size");
  public:
    static constexpr size_t SIZE = Sz;
    using Container = std::array<uint8_t,Sz>;
  private:
    Container container;
    using MyClass = VecRegContainer<SIZE>;

  public:
    VecRegContainer() {}
    /* This is required for de-serialisation. */
    VecRegContainer(const std::vector<uint8_t>& that)
    {
        assert(that.size() >= SIZE);
        std::memcpy(container.data(), &that[0], SIZE);
    }

    /** Zero the container. */
    void zero() { memset(container.data(), 0, SIZE); }

    /** Assignment operators. */
    /** @{ */
    /** From VecRegContainer */
    MyClass& operator=(const MyClass& that)
    {
        if (&that == this)
            return *this;
        memcpy(container.data(), that.container.data(), SIZE);
        return *this;
    }

    /** From appropriately sized uint8_t[]. */
    MyClass& operator=(const Container& that)
    {
        std::memcpy(container.data(), that.data(), SIZE);
        return *this;
    }

    /** From vector<uint8_t>.
     * This is required for de-serialisation.
     * */
    MyClass& operator=(const std::vector<uint8_t>& that)
    {
        assert(that.size() >= SIZE);
        std::memcpy(container.data(), that.data(), SIZE);
        return *this;
    }
    /** @} */

    /** Copy the contents into the input buffer. */
    /** @{ */
    /** To appropriately sized uint8_t[] */
    void copyTo(Container& dst) const
    {
        std::memcpy(dst.data(), container.data(), SIZE);
    }

    /** To vector<uint8_t>
     * This is required for serialisation.
     * */
    void copyTo(std::vector<uint8_t>& dst) const
    {
        dst.resize(SIZE);
        std::memcpy(dst.data(), container.data(), SIZE);
    }
    /** @} */

    /** Equality operator.
     * Required to compare thread contexts.
     */
    template<size_t S2>
    inline bool
    operator==(const VecRegContainer<S2>& that) const
    {
        return SIZE == S2 && !memcmp(container.data(), that.container.data(), SIZE);
    }
    /** Inequality operator.
     * Required to compare thread contexts.
     */
    template<size_t S2>
    bool
    operator!=(const VecRegContainer<S2>& that) const
    {
        return !operator==(that);
    }

    const std::string print() const { return csprintf("%s", *this); }
    /** Get pointer to bytes. */
    template <typename Ret>
    const Ret* raw_ptr() const { return (const Ret*)container.data(); }

    template <typename Ret>
    Ret* raw_ptr() { return (Ret*)container.data(); }

    /**
     * View interposers.
     * Create a view of this container as a vector of VecElems with an
     * optional amount of elements. If the amount of elements is provided,
     * the size of the container is checked, to test bounds. If it is not
     * provided, the length is inferred from the container size and the
     * element size.
     * @tparam VecElem Type of each element of the vector for the view.
     * @tparam NumElem Amount of elements in the view.
     */
    /** @{ */
    template <typename VecElem, size_t NumElems = SIZE/sizeof(VecElem)>
    VecRegT<VecElem, NumElems, true> as() const
    {
        static_assert(SIZE % sizeof(VecElem) == 0,
                "VecElem does not evenly divide the register size");
        static_assert(sizeof(VecElem) * NumElems <= SIZE,
                "Viewing VecReg as something bigger than it is");
        return VecRegT<VecElem, NumElems, true>(*this);
    }

    template <typename VecElem, size_t NumElems = SIZE/sizeof(VecElem)>
    VecRegT<VecElem, NumElems, false> as()
    {
        static_assert(SIZE % sizeof(VecElem) == 0,
                "VecElem does not evenly divide the register size");
        static_assert(sizeof(VecElem) * NumElems <= SIZE,
                "Viewing VecReg as something bigger than it is");
        return VecRegT<VecElem, NumElems, false>(*this);
    }

    template <typename VecElem, int LaneIdx>
    VecLaneT<VecElem, false> laneView();
    template <typename VecElem, int LaneIdx>
    VecLaneT<VecElem, true> laneView() const;
    template <typename VecElem>
    VecLaneT<VecElem, false> laneView(int laneIdx);
    template <typename VecElem>
    VecLaneT<VecElem, true> laneView(int laneIdx) const;
    /** @} */
    /**
     * Output operator.
     * Used for serialization.
     */
    friend std::ostream& operator<<(std::ostream& os, const MyClass& v)
    {
        os << "0x";
        for (auto& b: v.container) {
            os << csprintf("%02x", b);
        }
        return os;
    }
};

enum class LaneSize
{
    Empty = 0,
    Byte,
    TwoByte,
    FourByte,
    EightByte,
};

template <LaneSize LS>
class LaneData
{
  public:
    /** Alias to the native type of the appropriate size. */
    using UnderlyingType =
        typename std::conditional<LS == LaneSize::EightByte, uint64_t,
            typename std::conditional<LS == LaneSize::FourByte, uint32_t,
                typename std::conditional<LS == LaneSize::TwoByte, uint16_t,
                    typename std::conditional<LS == LaneSize::Byte, uint8_t,
                    void>::type
                >::type
            >::type
        >::type;
  private:
    static constexpr auto ByteSz = sizeof(UnderlyingType);
    UnderlyingType _val;
    using MyClass = LaneData<LS>;

  public:
    template <typename T> explicit
    LaneData(typename std::enable_if<sizeof(T) == ByteSz, const T&>::type t)
                : _val(t) {}

    template <typename T>
    typename std::enable_if<sizeof(T) == ByteSz, MyClass&>::type
    operator=(const T& that)
    {
        _val = that;
        return *this;
    }
    template<typename T,
             typename std::enable_if<sizeof(T) == ByteSz, int>::type I = 0>
    operator T() const {
        return *static_cast<const T*>(&_val);
    }
};

/** Output operator overload for LaneData<Size>. */
template <LaneSize LS>
inline std::ostream&
operator<<(std::ostream& os, const LaneData<LS>& d)
{
    return os << static_cast<typename LaneData<LS>::UnderlyingType>(d);
}

/** Vector Lane abstraction
 * Another view of a container. This time only a partial part of it is exposed.
 * @tparam VecElem Type of each element of the vector.
 * @tparam Const Indicate if the underlying container can be modified through
 * the view.
 */
/** @{ */
/* General */
template <typename VecElem, bool Const>
class VecLaneT
{
  public:
    /** VecRegContainer friendship to access private VecLaneT constructors.
     * Only VecRegContainers can build VecLanes.
     */
    /** @{ */
    template <size_t Sz>
    template <typename VE>
    friend VecLaneT<VE, true> VecRegContainer<Sz>::template laneView(int) const;

    template <size_t Sz>
    template <typename VE>
    friend VecLaneT<VE, false> VecRegContainer<Sz>::template laneView(int);

    template <size_t Sz>
    template <typename VE, int LaneIdx>
    friend VecLaneT<VE, true> VecRegContainer<Sz>::template laneView() const;

    template <size_t Sz>
    template <typename VE, int LaneIdx>
    friend VecLaneT<VE, false> VecRegContainer<Sz>::template laneView();

    /** My type alias. */
    using MyClass = VecLaneT<VecElem, Const>;

  private:
    using Cont = typename std::conditional<Const,
                                              const VecElem,
                                              VecElem>::type;
    static_assert(!std::is_const<VecElem>::value || Const,
            "Asked for non-const lane of const type!");
    static_assert(std::is_integral<VecElem>::value, "VecElem type is not integral!");
    /** Reference to data. */
    Cont& container;

    /** Constructor */
    VecLaneT(Cont& cont) : container(cont) { }

  public:
    /** Assignment operators.
     * Assignment operators are only enabled if the underlying container is
     * non-constant.
     */
    /** @{ */
    template <bool Assignable = !Const>
    typename std::enable_if<Assignable, MyClass&>::type
    operator=(const VecElem& that) {
        container = that;
        return *this;
    }
    /**
     * Generic.
     * Generic bitwise assignment. Narrowing and widening assignemnts are
     * not allowed, pre-treatment of the rhs is required to conform.
     */
    template <bool Assignable = !Const, typename T>
    typename std::enable_if<Assignable, MyClass&>::type
    operator=(const T& that) {
        static_assert(sizeof(T) >= sizeof(VecElem),
                "Attempt to perform widening bitwise copy.");
        static_assert(sizeof(T) <= sizeof(VecElem),
                "Attempt to perform narrowing bitwise copy.");
        container = static_cast<VecElem>(that);
        return *this;
    }
    /** @} */
    /** Cast to vecElem. */
    operator VecElem() const { return container; }

    /** Constification. */
    template <bool Cond = !Const, typename std::enable_if<Cond, int>::type = 0>
    operator VecLaneT<VecElem, true>()
    {
        return VecLaneT<VecElem, true>(container);
    }
};

namespace std {
    template<>
    template<typename T, bool Const>
    struct add_const<VecLaneT<T, Const>> { typedef VecLaneT<T, true> type; };
}

/** View as the Nth lane of type VecElem. */
template <size_t Sz>
template <typename VecElem, int LaneIdx>
VecLaneT<VecElem, false>
VecRegContainer<Sz>::laneView()
{
    return VecLaneT<VecElem, false>(as<VecElem>()[LaneIdx]);
}

/** View as the const Nth lane of type VecElem. */
template <size_t Sz>
template <typename VecElem, int LaneIdx>
VecLaneT<VecElem, true>
VecRegContainer<Sz>::laneView() const
{
    return VecLaneT<VecElem, true>(as<VecElem>()[LaneIdx]);
}

/** View as the Nth lane of type VecElem. */
template <size_t Sz>
template <typename VecElem>
VecLaneT<VecElem, false>
VecRegContainer<Sz>::laneView(int laneIdx)
{
    return VecLaneT<VecElem, false>(as<VecElem>()[laneIdx]);
}

/** View as the const Nth lane of type VecElem. */
template <size_t Sz>
template <typename VecElem>
VecLaneT<VecElem, true>
VecRegContainer<Sz>::laneView(int laneIdx) const
{
    return VecLaneT<VecElem, true>(as<VecElem>()[laneIdx]);
}

using VecLane8 = VecLaneT<uint8_t, false>;
using VecLane16 = VecLaneT<uint16_t, false>;
using VecLane32 = VecLaneT<uint32_t, false>;
using VecLane64 = VecLaneT<uint64_t, false>;

using ConstVecLane8 = VecLaneT<uint8_t, true>;
using ConstVecLane16 = VecLaneT<uint16_t, true>;
using ConstVecLane32 = VecLaneT<uint32_t, true>;
using ConstVecLane64 = VecLaneT<uint64_t, true>;

/**
 * Calls required for serialization/deserialization
 */
/** @{ */
template <size_t Sz>
inline bool
to_number(const std::string& value, VecRegContainer<Sz>& v)
{
    assert(value[0] == '0' && value[1] == 'x');
    assert(value.size() <= 2 * (sizeof(v) + 1));
    int i = 1; // skip the 0x prefix
    while ((i<<1) < value.size()) {
        std::string byte = value.substr(i<<1, 2);
        v.template raw_ptr<uint8_t>()[i] = stoul(byte, 0, 16);
        i++;
    }
    return true;
}
/** @} */

#endif /* __ARCH_GENERIC_VEC_REG_HH__ */
