/*
 * Copyright (c) 2016-2019 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) 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.
 */

#ifndef __CPU__REG_CLASS_HH__
#define __CPU__REG_CLASS_HH__

#include <cstddef>
#include <iterator>
#include <string>

#include "base/cprintf.hh"
#include "base/debug.hh"
#include "base/intmath.hh"
#include "base/types.hh"
#include "debug/InvalidReg.hh"

namespace gem5
{

/** Enumerate the classes of registers. */
enum RegClassType
{
    IntRegClass,        ///< Integer register
    FloatRegClass,      ///< Floating-point register
    /** Vector Register. */
    VecRegClass,
    /** Vector Register Native Elem lane. */
    VecElemClass,
    VecPredRegClass,
    CCRegClass,         ///< Condition-code register
    MiscRegClass,       ///< Control (misc) register
    InvalidRegClass = -1
};

// "Standard" register class names. Using these is encouraged but optional.
inline constexpr char IntRegClassName[] = "integer";
inline constexpr char FloatRegClassName[] = "floating_point";
inline constexpr char VecRegClassName[] = "vector";
inline constexpr char VecElemClassName[] = "vector_element";
inline constexpr char VecPredRegClassName[] = "vector_predicate";
inline constexpr char CCRegClassName[] = "condition_code";
inline constexpr char MiscRegClassName[] = "miscellaneous";

class RegClass;
class RegClassIterator;
class BaseISA;

/** Register ID: describe an architectural register with its class and index.
 * This structure is used instead of just the register index to disambiguate
 * between different classes of registers. For example, a integer register with
 * index 3 is represented by Regid(IntRegClass, 3).
 */
class RegId
{
  protected:
    const RegClass *_regClass = nullptr;
    RegIndex regIdx;
    int numPinnedWrites;

    friend struct std::hash<RegId>;
    friend class RegClassIterator;

  public:
    inline constexpr RegId();

    constexpr RegId(const RegClass &reg_class, RegIndex reg_idx)
        : _regClass(&reg_class), regIdx(reg_idx), numPinnedWrites(0)
    {}

    constexpr operator RegIndex() const
    {
        return index();
    }

    constexpr bool
    operator==(const RegId& that) const
    {
        return classValue() == that.classValue() && regIdx == that.index();
    }

    constexpr bool
    operator!=(const RegId& that) const
    {
        return !(*this==that);
    }

    /** Order operator.
     * The order is required to implement maps with key type RegId
     */
    constexpr bool
    operator<(const RegId& that) const
    {
        return classValue() < that.classValue() ||
            (classValue() == that.classValue() && (regIdx < that.index()));
    }

    /**
     * Return true if this register can be renamed
     */
    constexpr bool
    isRenameable() const
    {
        return classValue() != MiscRegClass && classValue() != InvalidRegClass;
    }

    /** @return true if it is of the specified class. */
    inline constexpr bool is(RegClassType reg_class) const;

    /** Index accessors */
    /** @{ */
    constexpr RegIndex index() const { return regIdx; }

    /** Class accessor */
    constexpr const RegClass &regClass() const { return *_regClass; }
    inline constexpr RegClassType classValue() const;
    /** Return a const char* with the register class name. */
    inline constexpr const char* className() const;

    inline constexpr bool isFlat() const;
    inline RegId flatten(const BaseISA &isa) const;

    int getNumPinnedWrites() const { return numPinnedWrites; }
    void setNumPinnedWrites(int num_writes) { numPinnedWrites = num_writes; }

    friend inline std::ostream& operator<<(std::ostream& os, const RegId& rid);
};

class RegClassOps
{
  public:
    /** Print the name of the register specified in id. */
    virtual std::string regName(const RegId &id) const;
    /** Print the value of a register pointed to by val of size size. */
    virtual std::string valString(const void *val, size_t size) const;
    /** Flatten register id id using information in the ISA object isa. */
    virtual RegId
    flatten(const BaseISA &isa, const RegId &id) const
    {
        return id;
    }
};

class RegClassIterator;

class RegClass
{
  private:
    RegClassType _type;
    const char *_name;

    size_t _numRegs;
    size_t _regBytes = sizeof(RegVal);
    // This is how much to shift an index by to get an offset of a register in
    // a register file from the register index, which would otherwise need to
    // be calculated with a multiply.
    size_t _regShift = ceilLog2(sizeof(RegVal));

    static inline RegClassOps defaultOps;
    const RegClassOps *_ops = &defaultOps;
    const debug::Flag &debugFlag;

    bool _flat = true;

  public:
    constexpr RegClass(RegClassType type, const char *new_name,
            size_t num_regs, const debug::Flag &debug_flag) :
        _type(type), _name(new_name), _numRegs(num_regs), debugFlag(debug_flag)
    {}

    constexpr RegClass
    needsFlattening() const
    {
        RegClass reg_class = *this;
        reg_class._flat = false;
        return reg_class;
    }

    constexpr RegClass
    ops(const RegClassOps &new_ops) const
    {
        RegClass reg_class = *this;
        reg_class._ops = &new_ops;
        return reg_class;
    }

    template <class RegType>
    constexpr RegClass
    regType() const
    {
        RegClass reg_class = *this;
        reg_class._regBytes = sizeof(RegType);
        reg_class._regShift = ceilLog2(reg_class._regBytes);
        return reg_class;
    }

    constexpr RegClassType type() const { return _type; }
    constexpr const char *name() const { return _name; }
    constexpr size_t numRegs() const { return _numRegs; }
    constexpr size_t regBytes() const { return _regBytes; }
    constexpr size_t regShift() const { return _regShift; }
    constexpr const debug::Flag &debug() const { return debugFlag; }
    constexpr bool isFlat() const { return _flat; }

    std::string regName(const RegId &id) const { return _ops->regName(id); }
    std::string
    valString(const void *val) const
    {
        return _ops->valString(val, regBytes());
    }
    RegId
    flatten(const BaseISA &isa, const RegId &id) const
    {
        return isFlat() ? id : _ops->flatten(isa, id);
    }

    using iterator = RegClassIterator;

    inline iterator begin() const;
    inline iterator end() const;

    inline constexpr RegId operator[](RegIndex idx) const;
};

inline constexpr RegClass
    invalidRegClass(InvalidRegClass, "invalid", 0, debug::InvalidReg);

constexpr RegId::RegId() : RegId(invalidRegClass, 0) {}

constexpr bool
RegId::is(RegClassType reg_class) const
{
    return _regClass->type() == reg_class;
}

constexpr RegClassType RegId::classValue() const { return _regClass->type(); }
constexpr const char* RegId::className() const { return _regClass->name(); }

constexpr bool RegId::isFlat() const { return _regClass->isFlat(); }
RegId
RegId::flatten(const BaseISA &isa) const
{
    return _regClass->flatten(isa, *this);
}

std::ostream&
operator<<(std::ostream& os, const RegId& rid)
{
    return os << rid.regClass().regName(rid);
}

class RegClassIterator
{
  private:
    RegId id;

    RegClassIterator(const RegClass &reg_class, RegIndex idx) :
        id(reg_class, idx)
    {}

    friend class RegClass;

  public:
    using iterator_category = std::forward_iterator_tag;
    using difference_type = std::size_t;
    using value_type = const RegId;
    using pointer = value_type *;
    using reference = value_type &;

    reference operator*() const { return id; }
    pointer operator->() { return &id; }

    RegClassIterator &
    operator++()
    {
        id.regIdx++;
        return *this;
    }

    RegClassIterator
    operator++(int)
    {
        auto tmp = *this;
        ++(*this);
        return tmp;
    }

    bool
    operator==(const RegClassIterator &other) const
    {
        return id == other.id;
    }

    bool
    operator!=(const RegClassIterator &other) const
    {
        return id != other.id;
    }
};

RegClassIterator
RegClass::begin() const
{
    return RegClassIterator(*this, 0);
}

RegClassIterator
RegClass::end() const
{
    return RegClassIterator(*this, numRegs());
}

constexpr RegId
RegClass::operator[](RegIndex idx) const
{
    return RegId(*this, idx);
}

template <typename ValueType>
class TypedRegClassOps : public RegClassOps
{
  public:
    std::string
    valString(const void *val, size_t size) const override
    {
        assert(size == sizeof(ValueType));
        return csprintf("%s", *(const ValueType *)val);
    }
};

template <typename ValueType>
class VecElemRegClassOps : public TypedRegClassOps<ValueType>
{
  protected:
    size_t elemsPerVec;

  public:
    explicit VecElemRegClassOps(size_t elems_per_vec) :
        elemsPerVec(elems_per_vec)
    {}

    std::string
    regName(const RegId &id) const override
    {
        RegIndex reg_idx = id.index() / elemsPerVec;
        RegIndex elem_idx = id.index() % elemsPerVec;
        return csprintf("v%d[%d]", reg_idx, elem_idx);
    }
};

/** Physical register ID.
 * Like a register ID but physical. The inheritance is private because the
 * only relationship between this types is functional, and it is done to
 * prevent code replication. */
class PhysRegId : private RegId
{
  private:
    RegIndex flatIdx;
    int numPinnedWritesToComplete;
    bool pinned;

  public:
    explicit PhysRegId() : RegId(invalidRegClass, -1), flatIdx(-1),
                           numPinnedWritesToComplete(0)
    {}

    /** Scalar PhysRegId constructor. */
    explicit PhysRegId(const RegClass &reg_class, RegIndex _regIdx,
              RegIndex _flatIdx)
        : RegId(reg_class, _regIdx), flatIdx(_flatIdx),
          numPinnedWritesToComplete(0), pinned(false)
    {}

    /** Visible RegId methods */
    /** @{ */
    using RegId::index;
    using RegId::regClass;
    using RegId::classValue;
    using RegId::className;
    using RegId::is;
     /** @} */
    /**
     * Explicit forward methods, to prevent comparisons of PhysRegId with
     * RegIds.
     */
    /** @{ */
    bool
    operator<(const PhysRegId& that) const
    {
        return RegId::operator<(that);
    }

    bool
    operator==(const PhysRegId& that) const
    {
        return RegId::operator==(that);
    }

    bool
    operator!=(const PhysRegId& that) const
    {
        return RegId::operator!=(that);
    }
    /** @} */

    /**
     * Returns true if this register is always associated to the same
     * architectural register.
     */
    bool isFixedMapping() const { return !isRenameable(); }

    /** Flat index accessor */
    const RegIndex& flatIndex() const { return flatIdx; }

    int getNumPinnedWrites() const { return numPinnedWrites; }

    void
    setNumPinnedWrites(int numWrites)
    {
        // An instruction with a pinned destination reg can get
        // squashed. The numPinnedWrites counter may be zero when
        // the squash happens but we need to know if the dest reg
        // was pinned originally in order to reset counters properly
        // for a possible re-rename using the same physical reg (which
        // may be required in case of a mem access order violation).
        pinned = (numWrites != 0);
        numPinnedWrites = numWrites;
    }

    void decrNumPinnedWrites() { --numPinnedWrites; }
    void incrNumPinnedWrites() { ++numPinnedWrites; }

    bool isPinned() const { return pinned; }

    int
    getNumPinnedWritesToComplete() const
    {
        return numPinnedWritesToComplete;
    }

    void
    setNumPinnedWritesToComplete(int numWrites)
    {
        numPinnedWritesToComplete = numWrites;
    }

    void decrNumPinnedWritesToComplete() { --numPinnedWritesToComplete; }
    void incrNumPinnedWritesToComplete() { ++numPinnedWritesToComplete; }
};

using PhysRegIdPtr = PhysRegId*;

} // namespace gem5

namespace std
{
template<>
struct hash<gem5::RegId>
{
    size_t
    operator()(const gem5::RegId& reg_id) const
    {
        // Extract unique integral values for the effective fields of a RegId.
        const size_t index = static_cast<size_t>(reg_id.index());
        const size_t class_num = static_cast<size_t>(reg_id.classValue());

        const size_t shifted_class_num =
            class_num << (sizeof(gem5::RegIndex) << 3);

        // Concatenate the class_num to the end of the flat_index, in order to
        // maximize information retained.
        const size_t concatenated_hash = index | shifted_class_num;

        // If RegIndex is larger than size_t, then class_num will not be
        // considered by this hash function, so we may wish to perform a
        // different operation to include that information in the hash.
        static_assert(sizeof(gem5::RegIndex) < sizeof(size_t),
            "sizeof(RegIndex) should be less than sizeof(size_t)");

        return concatenated_hash;
    }
};
} // namespace std

#endif // __CPU__REG_CLASS_HH__
