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

#ifndef __CPU_O3_REGFILE_HH__
#define __CPU_O3_REGFILE_HH__

#include <vector>

#include "arch/generic/isa.hh"
#include "arch/vecregs.hh"
#include "base/trace.hh"
#include "config/the_isa.hh"
#include "cpu/o3/comm.hh"
#include "debug/IEW.hh"
#include "enums/VecRegRenameMode.hh"

namespace gem5
{

namespace o3
{

class UnifiedFreeList;

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

    using PhysIds = std::vector<PhysRegId>;
    using VecMode = enums::VecRegRenameMode;
  public:
    using IdRange = std::pair<PhysIds::iterator,
                              PhysIds::iterator>;
  private:
    /** Integer register file. */
    std::vector<RegVal> intRegFile;
    std::vector<PhysRegId> intRegIds;
    RegId zeroReg;

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

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

    /** Predicate register file. */
    std::vector<TheISA::VecPredRegContainer> vecPredRegFile;
    std::vector<PhysRegId> vecPredRegIds;

    /** Condition-code register file. */
    std::vector<RegVal> 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 predicate registers
     */
    unsigned numPhysicalVecPredRegs;

    /**
     * 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 _numPhysicalVecPredRegs,
                unsigned _numPhysicalCCRegs,
                const BaseISA::RegClasses &regClasses,
                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 predicate physical registers. */
    unsigned numPredPhysRegs() const { return numPhysicalVecPredRegs; }

    /** @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. */
    RegVal
    readIntReg(PhysRegIdPtr phys_reg) const
    {
        assert(phys_reg->is(IntRegClass));

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

    RegVal
    readFloatReg(PhysRegIdPtr phys_reg) const
    {
        assert(phys_reg->is(FloatRegClass));

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

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

        return floatRegBits;
    }

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

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

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

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

    /** Reads a vector element. */
    const TheISA::VecElem &
    readVecElem(PhysRegIdPtr phys_reg) const
    {
        assert(phys_reg->is(VecElemClass));
        auto ret = vectorRegFile[phys_reg->index()].as<TheISA::VecElem>();
        const TheISA::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 predicate register. */
    const TheISA::VecPredRegContainer&
    readVecPredReg(PhysRegIdPtr phys_reg) const
    {
        assert(phys_reg->is(VecPredRegClass));

        DPRINTF(IEW, "RegFile: Access to predicate register %i, has "
                "data %s\n", int(phys_reg->index()),
                vecPredRegFile[phys_reg->index()]);

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

    TheISA::VecPredRegContainer&
    getWritableVecPredReg(PhysRegIdPtr phys_reg)
    {
        /* const_cast for not duplicating code above. */
        return const_cast<TheISA::VecPredRegContainer&>(
                readVecPredReg(phys_reg));
    }

    /** Reads a condition-code register. */
    RegVal
    readCCReg(PhysRegIdPtr phys_reg)
    {
        assert(phys_reg->is(CCRegClass));

        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, RegVal val)
    {
        assert(phys_reg->is(IntRegClass));

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

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

    void
    setFloatReg(PhysRegIdPtr phys_reg, RegVal val)
    {
        assert(phys_reg->is(FloatRegClass));

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

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

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

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

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

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

        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<TheISA::VecElem>()[
            phys_reg->elemIndex()] = val;
    }

    /** Sets a predicate register to the given value. */
    void
    setVecPredReg(PhysRegIdPtr phys_reg,
            const TheISA::VecPredRegContainer& val)
    {
        assert(phys_reg->is(VecPredRegClass));

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

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

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

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

} // namespace o3
} // namespace gem5

#endif //__CPU_O3_REGFILE_HH__
