/*
 * Copyright (c) 2016 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) 2004-2005 The Regents of The University of Michigan
 * 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.
 *
 * Authors: Kevin Lim
 *          Gabe Black
 */

#ifndef __CPU_O3_REGFILE_HH__
#define __CPU_O3_REGFILE_HH__

#include <vector>

#include "arch/isa_traits.hh"
#include "arch/kernel_stats.hh"
#include "arch/types.hh"
#include "base/trace.hh"
#include "config/the_isa.hh"
#include "cpu/o3/comm.hh"
#include "debug/IEW.hh"
#include "enums/VecRegRenameMode.hh"

class UnifiedFreeList;

/**
 * Simple physical register file class.
 */
class PhysRegFile
{
  private:

    typedef TheISA::IntReg IntReg;
    typedef TheISA::FloatReg FloatReg;
    typedef TheISA::FloatRegBits FloatRegBits;
    typedef TheISA::CCReg CCReg;
    using VecElem = TheISA::VecElem;
    using VecRegContainer = TheISA::VecRegContainer;
    using PhysIds = std::vector<PhysRegId>;
    using VecMode = Enums::VecRegRenameMode;
  public:
    using IdRange = std::pair<PhysIds::const_iterator,
                              PhysIds::const_iterator>;
  private:
    static constexpr auto NumVecElemPerVecReg = TheISA::NumVecElemPerVecReg;

    /** Integer register file. */
    std::vector<IntReg> intRegFile;
    std::vector<PhysRegId> intRegIds;

    /** Floating point register file. */
    std::vector<FloatRegBits> floatRegFile;
    std::vector<PhysRegId> floatRegIds;

    /** Vector register file. */
    std::vector<VecRegContainer> vectorRegFile;
    std::vector<PhysRegId> vecRegIds;
    std::vector<PhysRegId> vecElemIds;

    /** Condition-code register file. */
    std::vector<CCReg> ccRegFile;
    std::vector<PhysRegId> ccRegIds;

    /** Misc Reg Ids */
    std::vector<PhysRegId> miscRegIds;

    /**
     * Number of physical general purpose registers
     */
    unsigned numPhysicalIntRegs;

    /**
     * Number of physical floating point registers
     */
    unsigned numPhysicalFloatRegs;

    /**
     * Number of physical vector registers
     */
    unsigned numPhysicalVecRegs;

    /**
     * Number of physical vector element registers
     */
    unsigned numPhysicalVecElemRegs;

    /**
     * Number of physical CC registers
     */
    unsigned numPhysicalCCRegs;

    /** Total number of physical registers. */
    unsigned totalNumRegs;

    /** Mode in which vector registers are addressed. */
    VecMode vecMode;

  public:
    /**
     * Constructs a physical register file with the specified amount of
     * integer and floating point registers.
     */
    PhysRegFile(unsigned _numPhysicalIntRegs,
                unsigned _numPhysicalFloatRegs,
                unsigned _numPhysicalVecRegs,
                unsigned _numPhysicalCCRegs,
                VecMode vmode
                );

    /**
     * Destructor to free resources
     */
    ~PhysRegFile() {}

    /** Initialize the free list */
    void initFreeList(UnifiedFreeList *freeList);

    /** @return the number of integer physical registers. */
    unsigned numIntPhysRegs() const { return numPhysicalIntRegs; }

    /** @return the number of floating-point physical registers. */
    unsigned numFloatPhysRegs() const { return numPhysicalFloatRegs; }
    /** @return the number of vector physical registers. */
    unsigned numVecPhysRegs() const { return numPhysicalVecRegs; }

    /** @return the number of vector physical registers. */
    unsigned numVecElemPhysRegs() const { return numPhysicalVecElemRegs; }

    /** @return the number of condition-code physical registers. */
    unsigned numCCPhysRegs() const { return numPhysicalCCRegs; }

    /** @return the total number of physical registers. */
    unsigned totalNumPhysRegs() const { return totalNumRegs; }

    /** Gets a misc register PhysRegIdPtr. */
    PhysRegIdPtr getMiscRegId(RegIndex reg_idx) {
        return &miscRegIds[reg_idx];
    }

    /** Reads an integer register. */
    uint64_t readIntReg(PhysRegIdPtr phys_reg) const
    {
        assert(phys_reg->isIntPhysReg());

        DPRINTF(IEW, "RegFile: Access to int register %i, has data "
                "%#x\n", phys_reg->index(), intRegFile[phys_reg->index()]);
        return intRegFile[phys_reg->index()];
    }

    FloatRegBits readFloatRegBits(PhysRegIdPtr phys_reg) const
    {
        assert(phys_reg->isFloatPhysReg());

        FloatRegBits floatRegBits = floatRegFile[phys_reg->index()];

        DPRINTF(IEW, "RegFile: Access to float register %i as int, "
                "has data %#x\n", phys_reg->index(),
                (uint64_t)floatRegBits);

        return floatRegBits;
    }

    /** Reads a vector register. */
    const VecRegContainer& readVecReg(PhysRegIdPtr phys_reg) const
    {
        assert(phys_reg->isVectorPhysReg());

        DPRINTF(IEW, "RegFile: Access to vector register %i, has "
                "data %s\n", int(phys_reg->index()),
                vectorRegFile[phys_reg->index()].as<VecElem>().print());

        return vectorRegFile[phys_reg->index()];
    }

    /** Reads a vector register for modification. */
    VecRegContainer& getWritableVecReg(PhysRegIdPtr phys_reg)
    {
        /* const_cast for not duplicating code above. */
        return const_cast<VecRegContainer&>(readVecReg(phys_reg));
    }

    /** Reads a vector register lane. */
    template <typename VecElem, int LaneIdx>
    VecLaneT<VecElem, true>
    readVecLane(PhysRegIdPtr phys_reg) const
    {
        return readVecReg(phys_reg).laneView<VecElem, LaneIdx>();
    }

    /** Reads a vector register lane. */
    template <typename VecElem>
    VecLaneT<VecElem, true>
    readVecLane(PhysRegIdPtr phys_reg) const
    {
        return readVecReg(phys_reg).laneView<VecElem>(phys_reg->elemIndex());
    }

    /** Get a vector register lane for modification. */
    template <typename LD>
    void
    setVecLane(PhysRegIdPtr phys_reg, const LD& val)
    {
        assert(phys_reg->isVectorPhysReg());

        DPRINTF(IEW, "RegFile: Setting vector register %i[%d] to %lx\n",
                int(phys_reg->index()), phys_reg->elemIndex(), val);

        vectorRegFile[phys_reg->index()].laneView<typename LD::UnderlyingType>(
                phys_reg->elemIndex()) = val;
    }

    /** Reads a vector element. */
    const VecElem& readVecElem(PhysRegIdPtr phys_reg) const
    {
        assert(phys_reg->isVectorPhysElem());
        auto ret = vectorRegFile[phys_reg->index()].as<VecElem>();
        const VecElem& val = ret[phys_reg->elemIndex()];
        DPRINTF(IEW, "RegFile: Access to element %d of vector register %i,"
                " has data %#x\n", phys_reg->elemIndex(),
                int(phys_reg->index()), val);

        return val;
    }

    /** Reads a condition-code register. */
    CCReg readCCReg(PhysRegIdPtr phys_reg)
    {
        assert(phys_reg->isCCPhysReg());

        DPRINTF(IEW, "RegFile: Access to cc register %i, has "
                "data %#x\n", phys_reg->index(),
                ccRegFile[phys_reg->index()]);

        return ccRegFile[phys_reg->index()];
    }

    /** Sets an integer register to the given value. */
    void setIntReg(PhysRegIdPtr phys_reg, uint64_t val)
    {
        assert(phys_reg->isIntPhysReg());

        DPRINTF(IEW, "RegFile: Setting int register %i to %#x\n",
                phys_reg->index(), val);

        if (!phys_reg->isZeroReg())
            intRegFile[phys_reg->index()] = val;
    }

    void setFloatRegBits(PhysRegIdPtr phys_reg, FloatRegBits val)
    {
        assert(phys_reg->isFloatPhysReg());

        DPRINTF(IEW, "RegFile: Setting float register %i to %#x\n",
                phys_reg->index(), (uint64_t)val);

        if (!phys_reg->isZeroReg())
            floatRegFile[phys_reg->index()] = val;
    }

    /** Sets a vector register to the given value. */
    void setVecReg(PhysRegIdPtr phys_reg, const VecRegContainer& val)
    {
        assert(phys_reg->isVectorPhysReg());

        DPRINTF(IEW, "RegFile: Setting vector register %i to %s\n",
                int(phys_reg->index()), val.print());

        vectorRegFile[phys_reg->index()] = val;
    }

    /** Sets a vector register to the given value. */
    void setVecElem(PhysRegIdPtr phys_reg, const VecElem val)
    {
        assert(phys_reg->isVectorPhysElem());

        DPRINTF(IEW, "RegFile: Setting element %d of vector register %i to"
                " %#x\n", phys_reg->elemIndex(), int(phys_reg->index()), val);

        vectorRegFile[phys_reg->index()].as<VecElem>()[phys_reg->elemIndex()] =
                val;
    }

    /** Sets a condition-code register to the given value. */
    void setCCReg(PhysRegIdPtr phys_reg, CCReg val)
    {
        assert(phys_reg->isCCPhysReg());

        DPRINTF(IEW, "RegFile: Setting cc register %i to %#x\n",
                phys_reg->index(), (uint64_t)val);

        ccRegFile[phys_reg->index()] = val;
    }

    /** Get the PhysRegIds of the elems of a vector register.
     * Auxiliary function to transition from Full vector mode to Elem mode.
     */
    IdRange getRegElemIds(PhysRegIdPtr reg);

    /**
     * Get the PhysRegIds of the elems of all vector registers.
     * Auxiliary function to transition from Full vector mode to Elem mode
     * and to initialise the rename map.
     */
    IdRange getRegIds(RegClass cls);

     /**
      * Get the true physical register id.
      * As many parts work with PhysRegIdPtr, we need to be able to produce
      * the pointer out of just class and register idx.
      */
     PhysRegIdPtr getTrueId(PhysRegIdPtr reg);
};


#endif //__CPU_O3_REGFILE_HH__
