reg_class.hh revision 13762
19913Ssteve.reinhardt@amd.com/*
213610Sgiacomo.gabrielli@arm.com * Copyright (c) 2016-2017 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 {
8012106SRekai.GonzalezAlberquilla@arm.com  private:
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;
8612858Sradwang@ucdavis.edu    friend struct std::hash<RegId>;
8712106SRekai.GonzalezAlberquilla@arm.com  public:
8813020Sshunhsingou@google.com    RegId() : regClass(IntRegClass), regIdx(0), elemIdx(-1) {}
8912104Snathanael.premillieu@arm.com    RegId(RegClass reg_class, RegIndex reg_idx)
9012109SRekai.GonzalezAlberquilla@arm.com        : regClass(reg_class), regIdx(reg_idx), elemIdx(-1)
9112109SRekai.GonzalezAlberquilla@arm.com    {
9212109SRekai.GonzalezAlberquilla@arm.com        panic_if(regClass == VecElemClass,
9312109SRekai.GonzalezAlberquilla@arm.com                "Creating vector physical index w/o element index");
9412109SRekai.GonzalezAlberquilla@arm.com    }
9512109SRekai.GonzalezAlberquilla@arm.com
9612109SRekai.GonzalezAlberquilla@arm.com    explicit RegId(RegClass reg_class, RegIndex reg_idx, ElemIndex elem_idx)
9712109SRekai.GonzalezAlberquilla@arm.com        : regClass(reg_class), regIdx(reg_idx), elemIdx(elem_idx)
9812109SRekai.GonzalezAlberquilla@arm.com    {
9912109SRekai.GonzalezAlberquilla@arm.com        panic_if(regClass != VecElemClass,
10012109SRekai.GonzalezAlberquilla@arm.com                "Creating non-vector physical index w/ element index");
10112109SRekai.GonzalezAlberquilla@arm.com    }
1029913Ssteve.reinhardt@amd.com
10312104Snathanael.premillieu@arm.com    bool operator==(const RegId& that) const {
10412109SRekai.GonzalezAlberquilla@arm.com        return regClass == that.classValue() && regIdx == that.index()
10512109SRekai.GonzalezAlberquilla@arm.com                                             && elemIdx == that.elemIndex();
1069913Ssteve.reinhardt@amd.com    }
1079913Ssteve.reinhardt@amd.com
10812104Snathanael.premillieu@arm.com    bool operator!=(const RegId& that) const {
10912104Snathanael.premillieu@arm.com        return !(*this==that);
11012104Snathanael.premillieu@arm.com    }
11112104Snathanael.premillieu@arm.com
11212106SRekai.GonzalezAlberquilla@arm.com    /** Order operator.
11312106SRekai.GonzalezAlberquilla@arm.com     * The order is required to implement maps with key type RegId
11412104Snathanael.premillieu@arm.com     */
11512106SRekai.GonzalezAlberquilla@arm.com    bool operator<(const RegId& that) const {
11612106SRekai.GonzalezAlberquilla@arm.com        return regClass < that.classValue() ||
11712109SRekai.GonzalezAlberquilla@arm.com            (regClass == that.classValue() && (
11812109SRekai.GonzalezAlberquilla@arm.com                   regIdx < that.index() ||
11912109SRekai.GonzalezAlberquilla@arm.com                   (regIdx == that.index() && elemIdx < that.elemIndex())));
12012104Snathanael.premillieu@arm.com    }
12112104Snathanael.premillieu@arm.com
12212104Snathanael.premillieu@arm.com    /**
12312104Snathanael.premillieu@arm.com     * Return true if this register can be renamed
12412104Snathanael.premillieu@arm.com     */
12512106SRekai.GonzalezAlberquilla@arm.com    bool isRenameable() const
12612104Snathanael.premillieu@arm.com    {
12712104Snathanael.premillieu@arm.com        return regClass != MiscRegClass;
12812104Snathanael.premillieu@arm.com    }
12912104Snathanael.premillieu@arm.com
13012106SRekai.GonzalezAlberquilla@arm.com    /**
13112106SRekai.GonzalezAlberquilla@arm.com     * Check if this is the zero register.
13212106SRekai.GonzalezAlberquilla@arm.com     * Returns true if this register is a zero register (needs to have a
13312106SRekai.GonzalezAlberquilla@arm.com     * constant zero value throughout the execution).
13412106SRekai.GonzalezAlberquilla@arm.com     */
13512106SRekai.GonzalezAlberquilla@arm.com
13612857Sradwang@ucdavis.edu    inline bool isZeroReg() const
13712857Sradwang@ucdavis.edu    {
13812857Sradwang@ucdavis.edu        return ((regClass == IntRegClass && regIdx == TheISA::ZeroReg) ||
13912857Sradwang@ucdavis.edu               (THE_ISA == ALPHA_ISA && regClass == FloatRegClass &&
14012857Sradwang@ucdavis.edu                regIdx == TheISA::ZeroReg));
14112857Sradwang@ucdavis.edu    }
14212106SRekai.GonzalezAlberquilla@arm.com
14312106SRekai.GonzalezAlberquilla@arm.com    /** @return true if it is an integer physical register. */
14412106SRekai.GonzalezAlberquilla@arm.com    bool isIntReg() const { return regClass == IntRegClass; }
14512106SRekai.GonzalezAlberquilla@arm.com
14612106SRekai.GonzalezAlberquilla@arm.com    /** @return true if it is a floating-point physical register. */
14712106SRekai.GonzalezAlberquilla@arm.com    bool isFloatReg() const { return regClass == FloatRegClass; }
14812106SRekai.GonzalezAlberquilla@arm.com
14912106SRekai.GonzalezAlberquilla@arm.com    /** @Return true if it is a  condition-code physical register. */
15012109SRekai.GonzalezAlberquilla@arm.com    bool isVecReg() const { return regClass == VecRegClass; }
15112109SRekai.GonzalezAlberquilla@arm.com
15212109SRekai.GonzalezAlberquilla@arm.com    /** @Return true if it is a  condition-code physical register. */
15312109SRekai.GonzalezAlberquilla@arm.com    bool isVecElem() const { return regClass == VecElemClass; }
15412109SRekai.GonzalezAlberquilla@arm.com
15513610Sgiacomo.gabrielli@arm.com    /** @Return true if it is a predicate physical register. */
15613610Sgiacomo.gabrielli@arm.com    bool isVecPredReg() const { return regClass == VecPredRegClass; }
15713610Sgiacomo.gabrielli@arm.com
15812109SRekai.GonzalezAlberquilla@arm.com    /** @Return true if it is a  condition-code physical register. */
15912106SRekai.GonzalezAlberquilla@arm.com    bool isCCReg() const { return regClass == CCRegClass; }
16012106SRekai.GonzalezAlberquilla@arm.com
16112106SRekai.GonzalezAlberquilla@arm.com    /** @Return true if it is a  condition-code physical register. */
16212106SRekai.GonzalezAlberquilla@arm.com    bool isMiscReg() const { return regClass == MiscRegClass; }
16312106SRekai.GonzalezAlberquilla@arm.com
16412109SRekai.GonzalezAlberquilla@arm.com    /**
16512109SRekai.GonzalezAlberquilla@arm.com     * Return true if this register can be renamed
16612109SRekai.GonzalezAlberquilla@arm.com     */
16712109SRekai.GonzalezAlberquilla@arm.com    bool isRenameable()
16812109SRekai.GonzalezAlberquilla@arm.com    {
16912109SRekai.GonzalezAlberquilla@arm.com        return regClass != MiscRegClass;
17012109SRekai.GonzalezAlberquilla@arm.com    }
17112109SRekai.GonzalezAlberquilla@arm.com
17212106SRekai.GonzalezAlberquilla@arm.com    /** Index accessors */
17312106SRekai.GonzalezAlberquilla@arm.com    /** @{ */
17412106SRekai.GonzalezAlberquilla@arm.com    const RegIndex& index() const { return regIdx; }
17512106SRekai.GonzalezAlberquilla@arm.com    RegIndex& index() { return regIdx; }
17612106SRekai.GonzalezAlberquilla@arm.com
17712106SRekai.GonzalezAlberquilla@arm.com    /** Index flattening.
17812106SRekai.GonzalezAlberquilla@arm.com     * Required to be able to use a vector for the register mapping.
17912106SRekai.GonzalezAlberquilla@arm.com     */
18012857Sradwang@ucdavis.edu    inline RegIndex flatIndex() const
18112857Sradwang@ucdavis.edu    {
18212857Sradwang@ucdavis.edu        switch (regClass) {
18312857Sradwang@ucdavis.edu          case IntRegClass:
18412857Sradwang@ucdavis.edu          case FloatRegClass:
18512857Sradwang@ucdavis.edu          case VecRegClass:
18613610Sgiacomo.gabrielli@arm.com          case VecPredRegClass:
18712857Sradwang@ucdavis.edu          case CCRegClass:
18812857Sradwang@ucdavis.edu          case MiscRegClass:
18912857Sradwang@ucdavis.edu            return regIdx;
19012857Sradwang@ucdavis.edu          case VecElemClass:
19112857Sradwang@ucdavis.edu            return Scale*regIdx + elemIdx;
19212857Sradwang@ucdavis.edu        }
19312857Sradwang@ucdavis.edu        panic("Trying to flatten a register without class!");
19412857Sradwang@ucdavis.edu        return -1;
19512857Sradwang@ucdavis.edu    }
19612106SRekai.GonzalezAlberquilla@arm.com    /** @} */
19712106SRekai.GonzalezAlberquilla@arm.com
19812109SRekai.GonzalezAlberquilla@arm.com    /** Elem accessor */
19912109SRekai.GonzalezAlberquilla@arm.com    const RegIndex& elemIndex() const { return elemIdx; }
20012106SRekai.GonzalezAlberquilla@arm.com    /** Class accessor */
20112106SRekai.GonzalezAlberquilla@arm.com    const RegClass& classValue() const { return regClass; }
20212106SRekai.GonzalezAlberquilla@arm.com    /** Return a const char* with the register class name. */
20312106SRekai.GonzalezAlberquilla@arm.com    const char* className() const { return regClassStrings[regClass]; }
20412106SRekai.GonzalezAlberquilla@arm.com
20512106SRekai.GonzalezAlberquilla@arm.com    friend std::ostream&
20612106SRekai.GonzalezAlberquilla@arm.com    operator<<(std::ostream& os, const RegId& rid) {
20712106SRekai.GonzalezAlberquilla@arm.com        return os << rid.className() << "{" << rid.index() << "}";
20812106SRekai.GonzalezAlberquilla@arm.com    }
20912104Snathanael.premillieu@arm.com};
21012858Sradwang@ucdavis.edu
21113762SAndrea.Mondelli@ucf.edu/** Physical register index type.
21213762SAndrea.Mondelli@ucf.edu * Although the Impl might be a better for this, but there are a few classes
21313762SAndrea.Mondelli@ucf.edu * that need this typedef yet are not templated on the Impl.
21413762SAndrea.Mondelli@ucf.edu */
21513762SAndrea.Mondelli@ucf.eduusing PhysRegIndex = short int;
21613762SAndrea.Mondelli@ucf.edu
21713762SAndrea.Mondelli@ucf.edu/** Physical register ID.
21813762SAndrea.Mondelli@ucf.edu * Like a register ID but physical. The inheritance is private because the
21913762SAndrea.Mondelli@ucf.edu * only relationship between this types is functional, and it is done to
22013762SAndrea.Mondelli@ucf.edu * prevent code replication. */
22113762SAndrea.Mondelli@ucf.educlass PhysRegId : private RegId {
22213762SAndrea.Mondelli@ucf.edu  private:
22313762SAndrea.Mondelli@ucf.edu    PhysRegIndex flatIdx;
22413762SAndrea.Mondelli@ucf.edu
22513762SAndrea.Mondelli@ucf.edu  public:
22613762SAndrea.Mondelli@ucf.edu    explicit PhysRegId() : RegId(IntRegClass, -1), flatIdx(-1) {}
22713762SAndrea.Mondelli@ucf.edu
22813762SAndrea.Mondelli@ucf.edu    /** Scalar PhysRegId constructor. */
22913762SAndrea.Mondelli@ucf.edu    explicit PhysRegId(RegClass _regClass, PhysRegIndex _regIdx,
23013762SAndrea.Mondelli@ucf.edu              PhysRegIndex _flatIdx)
23113762SAndrea.Mondelli@ucf.edu        : RegId(_regClass, _regIdx), flatIdx(_flatIdx)
23213762SAndrea.Mondelli@ucf.edu    {}
23313762SAndrea.Mondelli@ucf.edu
23413762SAndrea.Mondelli@ucf.edu    /** Vector PhysRegId constructor (w/ elemIndex). */
23513762SAndrea.Mondelli@ucf.edu    explicit PhysRegId(RegClass _regClass, PhysRegIndex _regIdx,
23613762SAndrea.Mondelli@ucf.edu              ElemIndex elem_idx, PhysRegIndex flat_idx)
23713762SAndrea.Mondelli@ucf.edu        : RegId(_regClass, _regIdx, elem_idx), flatIdx(flat_idx) { }
23813762SAndrea.Mondelli@ucf.edu
23913762SAndrea.Mondelli@ucf.edu    /** Visible RegId methods */
24013762SAndrea.Mondelli@ucf.edu    /** @{ */
24113762SAndrea.Mondelli@ucf.edu    using RegId::index;
24213762SAndrea.Mondelli@ucf.edu    using RegId::classValue;
24313762SAndrea.Mondelli@ucf.edu    using RegId::isZeroReg;
24413762SAndrea.Mondelli@ucf.edu    using RegId::className;
24513762SAndrea.Mondelli@ucf.edu    using RegId::elemIndex;
24613762SAndrea.Mondelli@ucf.edu     /** @} */
24713762SAndrea.Mondelli@ucf.edu    /**
24813762SAndrea.Mondelli@ucf.edu     * Explicit forward methods, to prevent comparisons of PhysRegId with
24913762SAndrea.Mondelli@ucf.edu     * RegIds.
25013762SAndrea.Mondelli@ucf.edu     */
25113762SAndrea.Mondelli@ucf.edu    /** @{ */
25213762SAndrea.Mondelli@ucf.edu    bool operator<(const PhysRegId& that) const {
25313762SAndrea.Mondelli@ucf.edu        return RegId::operator<(that);
25413762SAndrea.Mondelli@ucf.edu    }
25513762SAndrea.Mondelli@ucf.edu
25613762SAndrea.Mondelli@ucf.edu    bool operator==(const PhysRegId& that) const {
25713762SAndrea.Mondelli@ucf.edu        return RegId::operator==(that);
25813762SAndrea.Mondelli@ucf.edu    }
25913762SAndrea.Mondelli@ucf.edu
26013762SAndrea.Mondelli@ucf.edu    bool operator!=(const PhysRegId& that) const {
26113762SAndrea.Mondelli@ucf.edu        return RegId::operator!=(that);
26213762SAndrea.Mondelli@ucf.edu    }
26313762SAndrea.Mondelli@ucf.edu    /** @} */
26413762SAndrea.Mondelli@ucf.edu
26513762SAndrea.Mondelli@ucf.edu    /** @return true if it is an integer physical register. */
26613762SAndrea.Mondelli@ucf.edu    bool isIntPhysReg() const { return isIntReg(); }
26713762SAndrea.Mondelli@ucf.edu
26813762SAndrea.Mondelli@ucf.edu    /** @return true if it is a floating-point physical register. */
26913762SAndrea.Mondelli@ucf.edu    bool isFloatPhysReg() const { return isFloatReg(); }
27013762SAndrea.Mondelli@ucf.edu
27113762SAndrea.Mondelli@ucf.edu    /** @Return true if it is a  condition-code physical register. */
27213762SAndrea.Mondelli@ucf.edu    bool isCCPhysReg() const { return isCCReg(); }
27313762SAndrea.Mondelli@ucf.edu
27413762SAndrea.Mondelli@ucf.edu    /** @Return true if it is a vector physical register. */
27513762SAndrea.Mondelli@ucf.edu    bool isVectorPhysReg() const { return isVecReg(); }
27613762SAndrea.Mondelli@ucf.edu
27713762SAndrea.Mondelli@ucf.edu    /** @Return true if it is a vector element physical register. */
27813762SAndrea.Mondelli@ucf.edu    bool isVectorPhysElem() const { return isVecElem(); }
27913762SAndrea.Mondelli@ucf.edu
28013762SAndrea.Mondelli@ucf.edu    /** @return true if it is a vector predicate physical register. */
28113762SAndrea.Mondelli@ucf.edu    bool isVecPredPhysReg() const { return isVecPredReg(); }
28213762SAndrea.Mondelli@ucf.edu
28313762SAndrea.Mondelli@ucf.edu    /** @Return true if it is a  condition-code physical register. */
28413762SAndrea.Mondelli@ucf.edu    bool isMiscPhysReg() const { return isMiscReg(); }
28513762SAndrea.Mondelli@ucf.edu
28613762SAndrea.Mondelli@ucf.edu    /**
28713762SAndrea.Mondelli@ucf.edu     * Returns true if this register is always associated to the same
28813762SAndrea.Mondelli@ucf.edu     * architectural register.
28913762SAndrea.Mondelli@ucf.edu     */
29013762SAndrea.Mondelli@ucf.edu    bool isFixedMapping() const
29113762SAndrea.Mondelli@ucf.edu    {
29213762SAndrea.Mondelli@ucf.edu        return !isRenameable();
29313762SAndrea.Mondelli@ucf.edu    }
29413762SAndrea.Mondelli@ucf.edu
29513762SAndrea.Mondelli@ucf.edu    /** Flat index accessor */
29613762SAndrea.Mondelli@ucf.edu    const PhysRegIndex& flatIndex() const { return flatIdx; }
29713762SAndrea.Mondelli@ucf.edu
29813762SAndrea.Mondelli@ucf.edu    static PhysRegId elemId(const PhysRegId* vid, ElemIndex elem)
29913762SAndrea.Mondelli@ucf.edu    {
30013762SAndrea.Mondelli@ucf.edu        assert(vid->isVectorPhysReg());
30113762SAndrea.Mondelli@ucf.edu        return PhysRegId(VecElemClass, vid->index(), elem);
30213762SAndrea.Mondelli@ucf.edu    }
30313762SAndrea.Mondelli@ucf.edu};
30413762SAndrea.Mondelli@ucf.edu
30513762SAndrea.Mondelli@ucf.edu/** Constant pointer definition.
30613762SAndrea.Mondelli@ucf.edu * PhysRegIds only need to be created once and then we can just share
30713762SAndrea.Mondelli@ucf.edu * pointers */
30813762SAndrea.Mondelli@ucf.eduusing PhysRegIdPtr = const PhysRegId*;
30913762SAndrea.Mondelli@ucf.edu
31012858Sradwang@ucdavis.edunamespace std
31112858Sradwang@ucdavis.edu{
31212858Sradwang@ucdavis.edutemplate<>
31312858Sradwang@ucdavis.edustruct hash<RegId>
31412858Sradwang@ucdavis.edu{
31512858Sradwang@ucdavis.edu    size_t operator()(const RegId& reg_id) const
31612858Sradwang@ucdavis.edu    {
31712858Sradwang@ucdavis.edu        // Extract unique integral values for the effective fields of a RegId.
31812858Sradwang@ucdavis.edu        const size_t flat_index = static_cast<size_t>(reg_id.flatIndex());
31912858Sradwang@ucdavis.edu        const size_t class_num = static_cast<size_t>(reg_id.regClass);
32012858Sradwang@ucdavis.edu
32112858Sradwang@ucdavis.edu        const size_t shifted_class_num = class_num << (sizeof(RegIndex) << 3);
32212858Sradwang@ucdavis.edu
32312858Sradwang@ucdavis.edu        // Concatenate the class_num to the end of the flat_index, in order to
32412858Sradwang@ucdavis.edu        // maximize information retained.
32512858Sradwang@ucdavis.edu        const size_t concatenated_hash = flat_index | shifted_class_num;
32612858Sradwang@ucdavis.edu
32712858Sradwang@ucdavis.edu        // If RegIndex is larger than size_t, then class_num will not be
32812858Sradwang@ucdavis.edu        // considered by this hash function, so we may wish to perform a
32912858Sradwang@ucdavis.edu        // different operation to include that information in the hash.
33012858Sradwang@ucdavis.edu        static_assert(sizeof(RegIndex) < sizeof(size_t),
33112858Sradwang@ucdavis.edu            "sizeof(RegIndex) should be less than sizeof(size_t)");
33212858Sradwang@ucdavis.edu
33312858Sradwang@ucdavis.edu        return concatenated_hash;
33412858Sradwang@ucdavis.edu    }
33512858Sradwang@ucdavis.edu};
33612858Sradwang@ucdavis.edu}
33712858Sradwang@ucdavis.edu
3389913Ssteve.reinhardt@amd.com#endif // __CPU__REG_CLASS_HH__
339