/*
 * 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 <string>

#include "base/cprintf.hh"
#include "base/debug.hh"
#include "base/intmath.hh"
#include "base/types.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
};

class RegId;

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;
};

class RegClass
{
  private:
    size_t _numRegs;
    const RegIndex _zeroReg;
    size_t _regBytes;
    // 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;

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

  public:
    RegClass(size_t num_regs, const debug::Flag &debug_flag,
            RegIndex new_zero=-1, size_t reg_bytes=sizeof(RegVal)) :
        _numRegs(num_regs), _zeroReg(new_zero), _regBytes(reg_bytes),
        _regShift(ceilLog2(reg_bytes)), debugFlag(debug_flag)
    {}
    RegClass(size_t num_regs, RegClassOps &new_ops,
            const debug::Flag &debug_flag, RegIndex new_zero=-1,
            size_t reg_bytes=sizeof(RegVal)) :
        RegClass(num_regs, debug_flag, new_zero, reg_bytes)
    {
        _ops = &new_ops;
    }

    size_t numRegs() const { return _numRegs; }
    RegIndex zeroReg() const { return _zeroReg; }
    size_t regBytes() const { return _regBytes; }
    size_t regShift() const { return _regShift; }
    const debug::Flag &debug() const { return debugFlag; }

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

/** 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:
    static const char* regClassStrings[];
    RegClassType regClass;
    RegIndex regIdx;
    int numPinnedWrites;

    friend struct std::hash<RegId>;

  public:
    RegId() : RegId(InvalidRegClass, 0) {}

    explicit RegId(RegClassType reg_class, RegIndex reg_idx)
        : regClass(reg_class), regIdx(reg_idx), numPinnedWrites(0)
    {}

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

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

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

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

    /** @return true if it is of the specified class. */
    bool is(RegClassType reg_class) const { return regClass == reg_class; }

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

    /** Class accessor */
    RegClassType classValue() const { return regClass; }
    /** Return a const char* with the register class name. */
    const char* className() const { return regClassStrings[regClass]; }

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

    friend std::ostream&
    operator<<(std::ostream& os, const RegId& rid)
    {
        return os << rid.className() << "{" << rid.index() << "}";
    }
};

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(RegClassType _regClass, RegIndex _regIdx,
              RegIndex _flatIdx)
        : RegId(_regClass, _regIdx), flatIdx(_flatIdx),
          numPinnedWritesToComplete(0), pinned(false)
    {}

    /** Visible RegId methods */
    /** @{ */
    using RegId::index;
    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.regClass);

        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__
