19913Ssteve.reinhardt@amd.com/*
214176Sciro.santilli@arm.com * Copyright (c) 2016-2019 ARM Limited
312104Snathanael.premillieu@arm.com * All rights reserved
412104Snathanael.premillieu@arm.com *
512104Snathanael.premillieu@arm.com * The license below extends only to copyright in the software and shall
612104Snathanael.premillieu@arm.com * not be construed as granting a license to any other intellectual
712104Snathanael.premillieu@arm.com * property including but not limited to intellectual property relating
812104Snathanael.premillieu@arm.com * to a hardware implementation of the functionality of the software
912104Snathanael.premillieu@arm.com * licensed hereunder.  You may use the software subject to the license
1012104Snathanael.premillieu@arm.com * terms below provided that you ensure that this notice is replicated
1112104Snathanael.premillieu@arm.com * unmodified and in its entirety in all distributions of the software,
1212104Snathanael.premillieu@arm.com * modified or unmodified, in source code or in binary form.
1312104Snathanael.premillieu@arm.com *
149913Ssteve.reinhardt@amd.com * Copyright (c) 2013 Advanced Micro Devices, Inc.
159913Ssteve.reinhardt@amd.com * All rights reserved
169913Ssteve.reinhardt@amd.com *.
179913Ssteve.reinhardt@amd.com * Redistribution and use in source and binary forms, with or without
189913Ssteve.reinhardt@amd.com * modification, are permitted provided that the following conditions are
199913Ssteve.reinhardt@amd.com * met: redistributions of source code must retain the above copyright
209913Ssteve.reinhardt@amd.com * notice, this list of conditions and the following disclaimer;
219913Ssteve.reinhardt@amd.com * redistributions in binary form must reproduce the above copyright
229913Ssteve.reinhardt@amd.com * notice, this list of conditions and the following disclaimer in the
239913Ssteve.reinhardt@amd.com * documentation and/or other materials provided with the distribution;
249913Ssteve.reinhardt@amd.com * neither the name of the copyright holders nor the names of its
259913Ssteve.reinhardt@amd.com * contributors may be used to endorse or promote products derived from
269913Ssteve.reinhardt@amd.com * this software without specific prior written permission.
279913Ssteve.reinhardt@amd.com *
289913Ssteve.reinhardt@amd.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
299913Ssteve.reinhardt@amd.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
309913Ssteve.reinhardt@amd.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
319913Ssteve.reinhardt@amd.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
329913Ssteve.reinhardt@amd.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
339913Ssteve.reinhardt@amd.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
349913Ssteve.reinhardt@amd.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
359913Ssteve.reinhardt@amd.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
369913Ssteve.reinhardt@amd.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
379913Ssteve.reinhardt@amd.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
389913Ssteve.reinhardt@amd.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
399913Ssteve.reinhardt@amd.com *
409913Ssteve.reinhardt@amd.com * Authors: Steve Reinhardt
4112104Snathanael.premillieu@arm.com *          Nathanael Premillieu
4212109SRekai.GonzalezAlberquilla@arm.com *          Rekai Gonzalez
439913Ssteve.reinhardt@amd.com */
449913Ssteve.reinhardt@amd.com
459913Ssteve.reinhardt@amd.com#ifndef __CPU__REG_CLASS_HH__
469913Ssteve.reinhardt@amd.com#define __CPU__REG_CLASS_HH__
479913Ssteve.reinhardt@amd.com
489913Ssteve.reinhardt@amd.com#include <cassert>
499913Ssteve.reinhardt@amd.com#include <cstddef>
509913Ssteve.reinhardt@amd.com
5112104Snathanael.premillieu@arm.com#include "arch/generic/types.hh"
529913Ssteve.reinhardt@amd.com#include "arch/registers.hh"
539913Ssteve.reinhardt@amd.com#include "config/the_isa.hh"
549913Ssteve.reinhardt@amd.com
5512106SRekai.GonzalezAlberquilla@arm.com/** Enumerate the classes of registers. */
569913Ssteve.reinhardt@amd.comenum RegClass {
579913Ssteve.reinhardt@amd.com    IntRegClass,        ///< Integer register
589913Ssteve.reinhardt@amd.com    FloatRegClass,      ///< Floating-point register
5912109SRekai.GonzalezAlberquilla@arm.com    /** Vector Register. */
6012109SRekai.GonzalezAlberquilla@arm.com    VecRegClass,
6112109SRekai.GonzalezAlberquilla@arm.com    /** Vector Register Native Elem lane. */
6212109SRekai.GonzalezAlberquilla@arm.com    VecElemClass,
6313610Sgiacomo.gabrielli@arm.com    VecPredRegClass,
649920Syasuko.eckert@amd.com    CCRegClass,         ///< Condition-code register
659913Ssteve.reinhardt@amd.com    MiscRegClass        ///< Control (misc) register
669913Ssteve.reinhardt@amd.com};
679913Ssteve.reinhardt@amd.com
6812106SRekai.GonzalezAlberquilla@arm.com/** Number of register classes.
6912106SRekai.GonzalezAlberquilla@arm.com * This value is not part of the enum, because putting it there makes the
7012106SRekai.GonzalezAlberquilla@arm.com * compiler complain about unhandled cases in some switch statements.
7112106SRekai.GonzalezAlberquilla@arm.com */
729913Ssteve.reinhardt@amd.comconst int NumRegClasses = MiscRegClass + 1;
739913Ssteve.reinhardt@amd.com
7412106SRekai.GonzalezAlberquilla@arm.com/** Register ID: describe an architectural register with its class and index.
7512106SRekai.GonzalezAlberquilla@arm.com * This structure is used instead of just the register index to disambiguate
7612106SRekai.GonzalezAlberquilla@arm.com * between different classes of registers. For example, a integer register with
7712106SRekai.GonzalezAlberquilla@arm.com * index 3 is represented by Regid(IntRegClass, 3).
7812106SRekai.GonzalezAlberquilla@arm.com */
7912106SRekai.GonzalezAlberquilla@arm.comclass RegId {
8014025Sgiacomo.gabrielli@arm.com  protected:
8112106SRekai.GonzalezAlberquilla@arm.com    static const char* regClassStrings[];
8212104Snathanael.premillieu@arm.com    RegClass regClass;
8312104Snathanael.premillieu@arm.com    RegIndex regIdx;
8412109SRekai.GonzalezAlberquilla@arm.com    ElemIndex elemIdx;
8512109SRekai.GonzalezAlberquilla@arm.com    static constexpr size_t Scale = TheISA::NumVecElemPerVecReg;
8614025Sgiacomo.gabrielli@arm.com    int numPinnedWrites;
8714025Sgiacomo.gabrielli@arm.com
8812858Sradwang@ucdavis.edu    friend struct std::hash<RegId>;
8914025Sgiacomo.gabrielli@arm.com
9012106SRekai.GonzalezAlberquilla@arm.com  public:
9114176Sciro.santilli@arm.com    RegId() : RegId(IntRegClass, 0) {}
9214176Sciro.santilli@arm.com
9312104Snathanael.premillieu@arm.com    RegId(RegClass reg_class, RegIndex reg_idx)
9414176Sciro.santilli@arm.com        : RegId(reg_class, reg_idx, ILLEGAL_ELEM_INDEX) {}
9512109SRekai.GonzalezAlberquilla@arm.com
9612109SRekai.GonzalezAlberquilla@arm.com    explicit RegId(RegClass reg_class, RegIndex reg_idx, ElemIndex elem_idx)
9714025Sgiacomo.gabrielli@arm.com        : regClass(reg_class), regIdx(reg_idx), elemIdx(elem_idx),
9814176Sciro.santilli@arm.com          numPinnedWrites(0) {
9914176Sciro.santilli@arm.com        if (elemIdx == ILLEGAL_ELEM_INDEX) {
10014176Sciro.santilli@arm.com            panic_if(regClass == VecElemClass,
10114176Sciro.santilli@arm.com                    "Creating vector physical index w/o element index");
10214176Sciro.santilli@arm.com        } else {
10314176Sciro.santilli@arm.com            panic_if(regClass != VecElemClass,
10414176Sciro.santilli@arm.com                    "Creating non-vector physical index w/ element index");
10514176Sciro.santilli@arm.com        }
10612109SRekai.GonzalezAlberquilla@arm.com    }
1079913Ssteve.reinhardt@amd.com
10812104Snathanael.premillieu@arm.com    bool operator==(const RegId& that) const {
10912109SRekai.GonzalezAlberquilla@arm.com        return regClass == that.classValue() && regIdx == that.index()
11012109SRekai.GonzalezAlberquilla@arm.com                                             && elemIdx == that.elemIndex();
1119913Ssteve.reinhardt@amd.com    }
1129913Ssteve.reinhardt@amd.com
11312104Snathanael.premillieu@arm.com    bool operator!=(const RegId& that) const {
11412104Snathanael.premillieu@arm.com        return !(*this==that);
11512104Snathanael.premillieu@arm.com    }
11612104Snathanael.premillieu@arm.com
11712106SRekai.GonzalezAlberquilla@arm.com    /** Order operator.
11812106SRekai.GonzalezAlberquilla@arm.com     * The order is required to implement maps with key type RegId
11912104Snathanael.premillieu@arm.com     */
12012106SRekai.GonzalezAlberquilla@arm.com    bool operator<(const RegId& that) const {
12112106SRekai.GonzalezAlberquilla@arm.com        return regClass < that.classValue() ||
12212109SRekai.GonzalezAlberquilla@arm.com            (regClass == that.classValue() && (
12312109SRekai.GonzalezAlberquilla@arm.com                   regIdx < that.index() ||
12412109SRekai.GonzalezAlberquilla@arm.com                   (regIdx == that.index() && elemIdx < that.elemIndex())));
12512104Snathanael.premillieu@arm.com    }
12612104Snathanael.premillieu@arm.com
12712104Snathanael.premillieu@arm.com    /**
12812104Snathanael.premillieu@arm.com     * Return true if this register can be renamed
12912104Snathanael.premillieu@arm.com     */
13012106SRekai.GonzalezAlberquilla@arm.com    bool isRenameable() const
13112104Snathanael.premillieu@arm.com    {
13212104Snathanael.premillieu@arm.com        return regClass != MiscRegClass;
13312104Snathanael.premillieu@arm.com    }
13412104Snathanael.premillieu@arm.com
13512106SRekai.GonzalezAlberquilla@arm.com    /**
13612106SRekai.GonzalezAlberquilla@arm.com     * Check if this is the zero register.
13712106SRekai.GonzalezAlberquilla@arm.com     * Returns true if this register is a zero register (needs to have a
13812106SRekai.GonzalezAlberquilla@arm.com     * constant zero value throughout the execution).
13912106SRekai.GonzalezAlberquilla@arm.com     */
14012106SRekai.GonzalezAlberquilla@arm.com
14112857Sradwang@ucdavis.edu    inline bool isZeroReg() const
14212857Sradwang@ucdavis.edu    {
14312857Sradwang@ucdavis.edu        return ((regClass == IntRegClass && regIdx == TheISA::ZeroReg) ||
14412857Sradwang@ucdavis.edu               (THE_ISA == ALPHA_ISA && regClass == FloatRegClass &&
14512857Sradwang@ucdavis.edu                regIdx == TheISA::ZeroReg));
14612857Sradwang@ucdavis.edu    }
14712106SRekai.GonzalezAlberquilla@arm.com
14812106SRekai.GonzalezAlberquilla@arm.com    /** @return true if it is an integer physical register. */
14912106SRekai.GonzalezAlberquilla@arm.com    bool isIntReg() const { return regClass == IntRegClass; }
15012106SRekai.GonzalezAlberquilla@arm.com
15112106SRekai.GonzalezAlberquilla@arm.com    /** @return true if it is a floating-point physical register. */
15212106SRekai.GonzalezAlberquilla@arm.com    bool isFloatReg() const { return regClass == FloatRegClass; }
15312106SRekai.GonzalezAlberquilla@arm.com
15412106SRekai.GonzalezAlberquilla@arm.com    /** @Return true if it is a  condition-code physical register. */
15512109SRekai.GonzalezAlberquilla@arm.com    bool isVecReg() const { return regClass == VecRegClass; }
15612109SRekai.GonzalezAlberquilla@arm.com
15712109SRekai.GonzalezAlberquilla@arm.com    /** @Return true if it is a  condition-code physical register. */
15812109SRekai.GonzalezAlberquilla@arm.com    bool isVecElem() const { return regClass == VecElemClass; }
15912109SRekai.GonzalezAlberquilla@arm.com
16013610Sgiacomo.gabrielli@arm.com    /** @Return true if it is a predicate physical register. */
16113610Sgiacomo.gabrielli@arm.com    bool isVecPredReg() const { return regClass == VecPredRegClass; }
16213610Sgiacomo.gabrielli@arm.com
16312109SRekai.GonzalezAlberquilla@arm.com    /** @Return true if it is a  condition-code physical register. */
16412106SRekai.GonzalezAlberquilla@arm.com    bool isCCReg() const { return regClass == CCRegClass; }
16512106SRekai.GonzalezAlberquilla@arm.com
16612106SRekai.GonzalezAlberquilla@arm.com    /** @Return true if it is a  condition-code physical register. */
16712106SRekai.GonzalezAlberquilla@arm.com    bool isMiscReg() const { return regClass == MiscRegClass; }
16812106SRekai.GonzalezAlberquilla@arm.com
16912109SRekai.GonzalezAlberquilla@arm.com    /**
17012109SRekai.GonzalezAlberquilla@arm.com     * Return true if this register can be renamed
17112109SRekai.GonzalezAlberquilla@arm.com     */
17212109SRekai.GonzalezAlberquilla@arm.com    bool isRenameable()
17312109SRekai.GonzalezAlberquilla@arm.com    {
17412109SRekai.GonzalezAlberquilla@arm.com        return regClass != MiscRegClass;
17512109SRekai.GonzalezAlberquilla@arm.com    }
17612109SRekai.GonzalezAlberquilla@arm.com
17712106SRekai.GonzalezAlberquilla@arm.com    /** Index accessors */
17812106SRekai.GonzalezAlberquilla@arm.com    /** @{ */
17912106SRekai.GonzalezAlberquilla@arm.com    const RegIndex& index() const { return regIdx; }
18012106SRekai.GonzalezAlberquilla@arm.com    RegIndex& index() { return regIdx; }
18112106SRekai.GonzalezAlberquilla@arm.com
18212106SRekai.GonzalezAlberquilla@arm.com    /** Index flattening.
18312106SRekai.GonzalezAlberquilla@arm.com     * Required to be able to use a vector for the register mapping.
18412106SRekai.GonzalezAlberquilla@arm.com     */
18512857Sradwang@ucdavis.edu    inline RegIndex flatIndex() const
18612857Sradwang@ucdavis.edu    {
18712857Sradwang@ucdavis.edu        switch (regClass) {
18812857Sradwang@ucdavis.edu          case IntRegClass:
18912857Sradwang@ucdavis.edu          case FloatRegClass:
19012857Sradwang@ucdavis.edu          case VecRegClass:
19113610Sgiacomo.gabrielli@arm.com          case VecPredRegClass:
19212857Sradwang@ucdavis.edu          case CCRegClass:
19312857Sradwang@ucdavis.edu          case MiscRegClass:
19412857Sradwang@ucdavis.edu            return regIdx;
19512857Sradwang@ucdavis.edu          case VecElemClass:
19612857Sradwang@ucdavis.edu            return Scale*regIdx + elemIdx;
19712857Sradwang@ucdavis.edu        }
19812857Sradwang@ucdavis.edu        panic("Trying to flatten a register without class!");
19912857Sradwang@ucdavis.edu        return -1;
20012857Sradwang@ucdavis.edu    }
20112106SRekai.GonzalezAlberquilla@arm.com    /** @} */
20212106SRekai.GonzalezAlberquilla@arm.com
20312109SRekai.GonzalezAlberquilla@arm.com    /** Elem accessor */
20412109SRekai.GonzalezAlberquilla@arm.com    const RegIndex& elemIndex() const { return elemIdx; }
20512106SRekai.GonzalezAlberquilla@arm.com    /** Class accessor */
20612106SRekai.GonzalezAlberquilla@arm.com    const RegClass& classValue() const { return regClass; }
20712106SRekai.GonzalezAlberquilla@arm.com    /** Return a const char* with the register class name. */
20812106SRekai.GonzalezAlberquilla@arm.com    const char* className() const { return regClassStrings[regClass]; }
20912106SRekai.GonzalezAlberquilla@arm.com
21014025Sgiacomo.gabrielli@arm.com    int getNumPinnedWrites() const { return numPinnedWrites; }
21114025Sgiacomo.gabrielli@arm.com    void setNumPinnedWrites(int num_writes) { numPinnedWrites = num_writes; }
21214025Sgiacomo.gabrielli@arm.com
21312106SRekai.GonzalezAlberquilla@arm.com    friend std::ostream&
21412106SRekai.GonzalezAlberquilla@arm.com    operator<<(std::ostream& os, const RegId& rid) {
21512106SRekai.GonzalezAlberquilla@arm.com        return os << rid.className() << "{" << rid.index() << "}";
21612106SRekai.GonzalezAlberquilla@arm.com    }
21712104Snathanael.premillieu@arm.com};
21812858Sradwang@ucdavis.edu
21913762SAndrea.Mondelli@ucf.edu/** Physical register index type.
22013762SAndrea.Mondelli@ucf.edu * Although the Impl might be a better for this, but there are a few classes
22113762SAndrea.Mondelli@ucf.edu * that need this typedef yet are not templated on the Impl.
22213762SAndrea.Mondelli@ucf.edu */
22313762SAndrea.Mondelli@ucf.eduusing PhysRegIndex = short int;
22413762SAndrea.Mondelli@ucf.edu
22513762SAndrea.Mondelli@ucf.edu/** Physical register ID.
22613762SAndrea.Mondelli@ucf.edu * Like a register ID but physical. The inheritance is private because the
22713762SAndrea.Mondelli@ucf.edu * only relationship between this types is functional, and it is done to
22813762SAndrea.Mondelli@ucf.edu * prevent code replication. */
22913762SAndrea.Mondelli@ucf.educlass PhysRegId : private RegId {
23013762SAndrea.Mondelli@ucf.edu  private:
23113762SAndrea.Mondelli@ucf.edu    PhysRegIndex flatIdx;
23214025Sgiacomo.gabrielli@arm.com    int numPinnedWritesToComplete;
23314025Sgiacomo.gabrielli@arm.com    bool pinned;
23413762SAndrea.Mondelli@ucf.edu
23513762SAndrea.Mondelli@ucf.edu  public:
23614025Sgiacomo.gabrielli@arm.com    explicit PhysRegId() : RegId(IntRegClass, -1), flatIdx(-1),
23714025Sgiacomo.gabrielli@arm.com                           numPinnedWritesToComplete(0)
23814025Sgiacomo.gabrielli@arm.com    {}
23913762SAndrea.Mondelli@ucf.edu
24013762SAndrea.Mondelli@ucf.edu    /** Scalar PhysRegId constructor. */
24113762SAndrea.Mondelli@ucf.edu    explicit PhysRegId(RegClass _regClass, PhysRegIndex _regIdx,
24213762SAndrea.Mondelli@ucf.edu              PhysRegIndex _flatIdx)
24314025Sgiacomo.gabrielli@arm.com        : RegId(_regClass, _regIdx), flatIdx(_flatIdx),
24414025Sgiacomo.gabrielli@arm.com          numPinnedWritesToComplete(0), pinned(false)
24513762SAndrea.Mondelli@ucf.edu    {}
24613762SAndrea.Mondelli@ucf.edu
24713762SAndrea.Mondelli@ucf.edu    /** Vector PhysRegId constructor (w/ elemIndex). */
24813762SAndrea.Mondelli@ucf.edu    explicit PhysRegId(RegClass _regClass, PhysRegIndex _regIdx,
24913762SAndrea.Mondelli@ucf.edu              ElemIndex elem_idx, PhysRegIndex flat_idx)
25014025Sgiacomo.gabrielli@arm.com        : RegId(_regClass, _regIdx, elem_idx), flatIdx(flat_idx),
25114025Sgiacomo.gabrielli@arm.com          numPinnedWritesToComplete(0), pinned(false)
25214025Sgiacomo.gabrielli@arm.com    {}
25313762SAndrea.Mondelli@ucf.edu
25413762SAndrea.Mondelli@ucf.edu    /** Visible RegId methods */
25513762SAndrea.Mondelli@ucf.edu    /** @{ */
25613762SAndrea.Mondelli@ucf.edu    using RegId::index;
25713762SAndrea.Mondelli@ucf.edu    using RegId::classValue;
25813762SAndrea.Mondelli@ucf.edu    using RegId::isZeroReg;
25913762SAndrea.Mondelli@ucf.edu    using RegId::className;
26013762SAndrea.Mondelli@ucf.edu    using RegId::elemIndex;
26113762SAndrea.Mondelli@ucf.edu     /** @} */
26213762SAndrea.Mondelli@ucf.edu    /**
26313762SAndrea.Mondelli@ucf.edu     * Explicit forward methods, to prevent comparisons of PhysRegId with
26413762SAndrea.Mondelli@ucf.edu     * RegIds.
26513762SAndrea.Mondelli@ucf.edu     */
26613762SAndrea.Mondelli@ucf.edu    /** @{ */
26713762SAndrea.Mondelli@ucf.edu    bool operator<(const PhysRegId& that) const {
26813762SAndrea.Mondelli@ucf.edu        return RegId::operator<(that);
26913762SAndrea.Mondelli@ucf.edu    }
27013762SAndrea.Mondelli@ucf.edu
27113762SAndrea.Mondelli@ucf.edu    bool operator==(const PhysRegId& that) const {
27213762SAndrea.Mondelli@ucf.edu        return RegId::operator==(that);
27313762SAndrea.Mondelli@ucf.edu    }
27413762SAndrea.Mondelli@ucf.edu
27513762SAndrea.Mondelli@ucf.edu    bool operator!=(const PhysRegId& that) const {
27613762SAndrea.Mondelli@ucf.edu        return RegId::operator!=(that);
27713762SAndrea.Mondelli@ucf.edu    }
27813762SAndrea.Mondelli@ucf.edu    /** @} */
27913762SAndrea.Mondelli@ucf.edu
28013762SAndrea.Mondelli@ucf.edu    /** @return true if it is an integer physical register. */
28113762SAndrea.Mondelli@ucf.edu    bool isIntPhysReg() const { return isIntReg(); }
28213762SAndrea.Mondelli@ucf.edu
28313762SAndrea.Mondelli@ucf.edu    /** @return true if it is a floating-point physical register. */
28413762SAndrea.Mondelli@ucf.edu    bool isFloatPhysReg() const { return isFloatReg(); }
28513762SAndrea.Mondelli@ucf.edu
28613762SAndrea.Mondelli@ucf.edu    /** @Return true if it is a  condition-code physical register. */
28713762SAndrea.Mondelli@ucf.edu    bool isCCPhysReg() const { return isCCReg(); }
28813762SAndrea.Mondelli@ucf.edu
28913762SAndrea.Mondelli@ucf.edu    /** @Return true if it is a vector physical register. */
29013762SAndrea.Mondelli@ucf.edu    bool isVectorPhysReg() const { return isVecReg(); }
29113762SAndrea.Mondelli@ucf.edu
29213762SAndrea.Mondelli@ucf.edu    /** @Return true if it is a vector element physical register. */
29313762SAndrea.Mondelli@ucf.edu    bool isVectorPhysElem() const { return isVecElem(); }
29413762SAndrea.Mondelli@ucf.edu
29513762SAndrea.Mondelli@ucf.edu    /** @return true if it is a vector predicate physical register. */
29613762SAndrea.Mondelli@ucf.edu    bool isVecPredPhysReg() const { return isVecPredReg(); }
29713762SAndrea.Mondelli@ucf.edu
29813762SAndrea.Mondelli@ucf.edu    /** @Return true if it is a  condition-code physical register. */
29913762SAndrea.Mondelli@ucf.edu    bool isMiscPhysReg() const { return isMiscReg(); }
30013762SAndrea.Mondelli@ucf.edu
30113762SAndrea.Mondelli@ucf.edu    /**
30213762SAndrea.Mondelli@ucf.edu     * Returns true if this register is always associated to the same
30313762SAndrea.Mondelli@ucf.edu     * architectural register.
30413762SAndrea.Mondelli@ucf.edu     */
30513762SAndrea.Mondelli@ucf.edu    bool isFixedMapping() const
30613762SAndrea.Mondelli@ucf.edu    {
30713762SAndrea.Mondelli@ucf.edu        return !isRenameable();
30813762SAndrea.Mondelli@ucf.edu    }
30913762SAndrea.Mondelli@ucf.edu
31013762SAndrea.Mondelli@ucf.edu    /** Flat index accessor */
31113762SAndrea.Mondelli@ucf.edu    const PhysRegIndex& flatIndex() const { return flatIdx; }
31213762SAndrea.Mondelli@ucf.edu
31314025Sgiacomo.gabrielli@arm.com    static PhysRegId elemId(PhysRegId* vid, ElemIndex elem)
31413762SAndrea.Mondelli@ucf.edu    {
31513762SAndrea.Mondelli@ucf.edu        assert(vid->isVectorPhysReg());
31613762SAndrea.Mondelli@ucf.edu        return PhysRegId(VecElemClass, vid->index(), elem);
31713762SAndrea.Mondelli@ucf.edu    }
31814025Sgiacomo.gabrielli@arm.com
31914025Sgiacomo.gabrielli@arm.com    int getNumPinnedWrites() const { return numPinnedWrites; }
32014025Sgiacomo.gabrielli@arm.com
32114025Sgiacomo.gabrielli@arm.com    void setNumPinnedWrites(int numWrites)
32214025Sgiacomo.gabrielli@arm.com    {
32314025Sgiacomo.gabrielli@arm.com        // An instruction with a pinned destination reg can get
32414025Sgiacomo.gabrielli@arm.com        // squashed. The numPinnedWrites counter may be zero when
32514025Sgiacomo.gabrielli@arm.com        // the squash happens but we need to know if the dest reg
32614025Sgiacomo.gabrielli@arm.com        // was pinned originally in order to reset counters properly
32714025Sgiacomo.gabrielli@arm.com        // for a possible re-rename using the same physical reg (which
32814025Sgiacomo.gabrielli@arm.com        // may be required in case of a mem access order violation).
32914025Sgiacomo.gabrielli@arm.com        pinned = (numWrites != 0);
33014025Sgiacomo.gabrielli@arm.com        numPinnedWrites = numWrites;
33114025Sgiacomo.gabrielli@arm.com    }
33214025Sgiacomo.gabrielli@arm.com
33314025Sgiacomo.gabrielli@arm.com    void decrNumPinnedWrites() { --numPinnedWrites; }
33414025Sgiacomo.gabrielli@arm.com    void incrNumPinnedWrites() { ++numPinnedWrites; }
33514025Sgiacomo.gabrielli@arm.com
33614025Sgiacomo.gabrielli@arm.com    bool isPinned() const { return pinned; }
33714025Sgiacomo.gabrielli@arm.com
33814025Sgiacomo.gabrielli@arm.com    int getNumPinnedWritesToComplete() const
33914025Sgiacomo.gabrielli@arm.com    {
34014025Sgiacomo.gabrielli@arm.com        return numPinnedWritesToComplete;
34114025Sgiacomo.gabrielli@arm.com    }
34214025Sgiacomo.gabrielli@arm.com
34314025Sgiacomo.gabrielli@arm.com    void setNumPinnedWritesToComplete(int numWrites)
34414025Sgiacomo.gabrielli@arm.com    {
34514025Sgiacomo.gabrielli@arm.com        numPinnedWritesToComplete = numWrites;
34614025Sgiacomo.gabrielli@arm.com    }
34714025Sgiacomo.gabrielli@arm.com
34814025Sgiacomo.gabrielli@arm.com    void decrNumPinnedWritesToComplete() { --numPinnedWritesToComplete; }
34914025Sgiacomo.gabrielli@arm.com    void incrNumPinnedWritesToComplete() { ++numPinnedWritesToComplete; }
35013762SAndrea.Mondelli@ucf.edu};
35113762SAndrea.Mondelli@ucf.edu
35214025Sgiacomo.gabrielli@arm.comusing PhysRegIdPtr = PhysRegId*;
35313762SAndrea.Mondelli@ucf.edu
35412858Sradwang@ucdavis.edunamespace std
35512858Sradwang@ucdavis.edu{
35612858Sradwang@ucdavis.edutemplate<>
35712858Sradwang@ucdavis.edustruct hash<RegId>
35812858Sradwang@ucdavis.edu{
35912858Sradwang@ucdavis.edu    size_t operator()(const RegId& reg_id) const
36012858Sradwang@ucdavis.edu    {
36112858Sradwang@ucdavis.edu        // Extract unique integral values for the effective fields of a RegId.
36212858Sradwang@ucdavis.edu        const size_t flat_index = static_cast<size_t>(reg_id.flatIndex());
36312858Sradwang@ucdavis.edu        const size_t class_num = static_cast<size_t>(reg_id.regClass);
36412858Sradwang@ucdavis.edu
36512858Sradwang@ucdavis.edu        const size_t shifted_class_num = class_num << (sizeof(RegIndex) << 3);
36612858Sradwang@ucdavis.edu
36712858Sradwang@ucdavis.edu        // Concatenate the class_num to the end of the flat_index, in order to
36812858Sradwang@ucdavis.edu        // maximize information retained.
36912858Sradwang@ucdavis.edu        const size_t concatenated_hash = flat_index | shifted_class_num;
37012858Sradwang@ucdavis.edu
37112858Sradwang@ucdavis.edu        // If RegIndex is larger than size_t, then class_num will not be
37212858Sradwang@ucdavis.edu        // considered by this hash function, so we may wish to perform a
37312858Sradwang@ucdavis.edu        // different operation to include that information in the hash.
37412858Sradwang@ucdavis.edu        static_assert(sizeof(RegIndex) < sizeof(size_t),
37512858Sradwang@ucdavis.edu            "sizeof(RegIndex) should be less than sizeof(size_t)");
37612858Sradwang@ucdavis.edu
37712858Sradwang@ucdavis.edu        return concatenated_hash;
37812858Sradwang@ucdavis.edu    }
37912858Sradwang@ucdavis.edu};
38012858Sradwang@ucdavis.edu}
38112858Sradwang@ucdavis.edu
3829913Ssteve.reinhardt@amd.com#endif // __CPU__REG_CLASS_HH__
383