reg_class.hh revision 12858
19913Ssteve.reinhardt@amd.com/*
212104Snathanael.premillieu@arm.com * Copyright (c) 2016 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,
639920Syasuko.eckert@amd.com    CCRegClass,         ///< Condition-code register
649913Ssteve.reinhardt@amd.com    MiscRegClass        ///< Control (misc) register
659913Ssteve.reinhardt@amd.com};
669913Ssteve.reinhardt@amd.com
6712106SRekai.GonzalezAlberquilla@arm.com/** Number of register classes.
6812106SRekai.GonzalezAlberquilla@arm.com * This value is not part of the enum, because putting it there makes the
6912106SRekai.GonzalezAlberquilla@arm.com * compiler complain about unhandled cases in some switch statements.
7012106SRekai.GonzalezAlberquilla@arm.com */
719913Ssteve.reinhardt@amd.comconst int NumRegClasses = MiscRegClass + 1;
729913Ssteve.reinhardt@amd.com
7312106SRekai.GonzalezAlberquilla@arm.com/** Register ID: describe an architectural register with its class and index.
7412106SRekai.GonzalezAlberquilla@arm.com * This structure is used instead of just the register index to disambiguate
7512106SRekai.GonzalezAlberquilla@arm.com * between different classes of registers. For example, a integer register with
7612106SRekai.GonzalezAlberquilla@arm.com * index 3 is represented by Regid(IntRegClass, 3).
7712106SRekai.GonzalezAlberquilla@arm.com */
7812106SRekai.GonzalezAlberquilla@arm.comclass RegId {
7912106SRekai.GonzalezAlberquilla@arm.com  private:
8012106SRekai.GonzalezAlberquilla@arm.com    static const char* regClassStrings[];
8112104Snathanael.premillieu@arm.com    RegClass regClass;
8212104Snathanael.premillieu@arm.com    RegIndex regIdx;
8312109SRekai.GonzalezAlberquilla@arm.com    ElemIndex elemIdx;
8412109SRekai.GonzalezAlberquilla@arm.com    static constexpr size_t Scale = TheISA::NumVecElemPerVecReg;
8512858Sradwang@ucdavis.edu    friend struct std::hash<RegId>;
8612106SRekai.GonzalezAlberquilla@arm.com  public:
8712104Snathanael.premillieu@arm.com    RegId() {};
8812104Snathanael.premillieu@arm.com    RegId(RegClass reg_class, RegIndex reg_idx)
8912109SRekai.GonzalezAlberquilla@arm.com        : regClass(reg_class), regIdx(reg_idx), elemIdx(-1)
9012109SRekai.GonzalezAlberquilla@arm.com    {
9112109SRekai.GonzalezAlberquilla@arm.com        panic_if(regClass == VecElemClass,
9212109SRekai.GonzalezAlberquilla@arm.com                "Creating vector physical index w/o element index");
9312109SRekai.GonzalezAlberquilla@arm.com    }
9412109SRekai.GonzalezAlberquilla@arm.com
9512109SRekai.GonzalezAlberquilla@arm.com    explicit RegId(RegClass reg_class, RegIndex reg_idx, ElemIndex elem_idx)
9612109SRekai.GonzalezAlberquilla@arm.com        : regClass(reg_class), regIdx(reg_idx), elemIdx(elem_idx)
9712109SRekai.GonzalezAlberquilla@arm.com    {
9812109SRekai.GonzalezAlberquilla@arm.com        panic_if(regClass != VecElemClass,
9912109SRekai.GonzalezAlberquilla@arm.com                "Creating non-vector physical index w/ element index");
10012109SRekai.GonzalezAlberquilla@arm.com    }
1019913Ssteve.reinhardt@amd.com
10212104Snathanael.premillieu@arm.com    bool operator==(const RegId& that) const {
10312109SRekai.GonzalezAlberquilla@arm.com        return regClass == that.classValue() && regIdx == that.index()
10412109SRekai.GonzalezAlberquilla@arm.com                                             && elemIdx == that.elemIndex();
1059913Ssteve.reinhardt@amd.com    }
1069913Ssteve.reinhardt@amd.com
10712104Snathanael.premillieu@arm.com    bool operator!=(const RegId& that) const {
10812104Snathanael.premillieu@arm.com        return !(*this==that);
10912104Snathanael.premillieu@arm.com    }
11012104Snathanael.premillieu@arm.com
11112106SRekai.GonzalezAlberquilla@arm.com    /** Order operator.
11212106SRekai.GonzalezAlberquilla@arm.com     * The order is required to implement maps with key type RegId
11312104Snathanael.premillieu@arm.com     */
11412106SRekai.GonzalezAlberquilla@arm.com    bool operator<(const RegId& that) const {
11512106SRekai.GonzalezAlberquilla@arm.com        return regClass < that.classValue() ||
11612109SRekai.GonzalezAlberquilla@arm.com            (regClass == that.classValue() && (
11712109SRekai.GonzalezAlberquilla@arm.com                   regIdx < that.index() ||
11812109SRekai.GonzalezAlberquilla@arm.com                   (regIdx == that.index() && elemIdx < that.elemIndex())));
11912104Snathanael.premillieu@arm.com    }
12012104Snathanael.premillieu@arm.com
12112104Snathanael.premillieu@arm.com    /**
12212104Snathanael.premillieu@arm.com     * Return true if this register can be renamed
12312104Snathanael.premillieu@arm.com     */
12412106SRekai.GonzalezAlberquilla@arm.com    bool isRenameable() const
12512104Snathanael.premillieu@arm.com    {
12612104Snathanael.premillieu@arm.com        return regClass != MiscRegClass;
12712104Snathanael.premillieu@arm.com    }
12812104Snathanael.premillieu@arm.com
12912106SRekai.GonzalezAlberquilla@arm.com    /**
13012106SRekai.GonzalezAlberquilla@arm.com     * Check if this is the zero register.
13112106SRekai.GonzalezAlberquilla@arm.com     * Returns true if this register is a zero register (needs to have a
13212106SRekai.GonzalezAlberquilla@arm.com     * constant zero value throughout the execution).
13312106SRekai.GonzalezAlberquilla@arm.com     */
13412106SRekai.GonzalezAlberquilla@arm.com
13512857Sradwang@ucdavis.edu    inline bool isZeroReg() const
13612857Sradwang@ucdavis.edu    {
13712857Sradwang@ucdavis.edu        return ((regClass == IntRegClass && regIdx == TheISA::ZeroReg) ||
13812857Sradwang@ucdavis.edu               (THE_ISA == ALPHA_ISA && regClass == FloatRegClass &&
13912857Sradwang@ucdavis.edu                regIdx == TheISA::ZeroReg));
14012857Sradwang@ucdavis.edu    }
14112106SRekai.GonzalezAlberquilla@arm.com
14212106SRekai.GonzalezAlberquilla@arm.com    /** @return true if it is an integer physical register. */
14312106SRekai.GonzalezAlberquilla@arm.com    bool isIntReg() const { return regClass == IntRegClass; }
14412106SRekai.GonzalezAlberquilla@arm.com
14512106SRekai.GonzalezAlberquilla@arm.com    /** @return true if it is a floating-point physical register. */
14612106SRekai.GonzalezAlberquilla@arm.com    bool isFloatReg() const { return regClass == FloatRegClass; }
14712106SRekai.GonzalezAlberquilla@arm.com
14812106SRekai.GonzalezAlberquilla@arm.com    /** @Return true if it is a  condition-code physical register. */
14912109SRekai.GonzalezAlberquilla@arm.com    bool isVecReg() const { return regClass == VecRegClass; }
15012109SRekai.GonzalezAlberquilla@arm.com
15112109SRekai.GonzalezAlberquilla@arm.com    /** @Return true if it is a  condition-code physical register. */
15212109SRekai.GonzalezAlberquilla@arm.com    bool isVecElem() const { return regClass == VecElemClass; }
15312109SRekai.GonzalezAlberquilla@arm.com
15412109SRekai.GonzalezAlberquilla@arm.com    /** @Return true if it is a  condition-code physical register. */
15512106SRekai.GonzalezAlberquilla@arm.com    bool isCCReg() const { return regClass == CCRegClass; }
15612106SRekai.GonzalezAlberquilla@arm.com
15712106SRekai.GonzalezAlberquilla@arm.com    /** @Return true if it is a  condition-code physical register. */
15812106SRekai.GonzalezAlberquilla@arm.com    bool isMiscReg() const { return regClass == MiscRegClass; }
15912106SRekai.GonzalezAlberquilla@arm.com
16012109SRekai.GonzalezAlberquilla@arm.com    /**
16112109SRekai.GonzalezAlberquilla@arm.com     * Return true if this register can be renamed
16212109SRekai.GonzalezAlberquilla@arm.com     */
16312109SRekai.GonzalezAlberquilla@arm.com    bool isRenameable()
16412109SRekai.GonzalezAlberquilla@arm.com    {
16512109SRekai.GonzalezAlberquilla@arm.com        return regClass != MiscRegClass;
16612109SRekai.GonzalezAlberquilla@arm.com    }
16712109SRekai.GonzalezAlberquilla@arm.com
16812106SRekai.GonzalezAlberquilla@arm.com    /** Index accessors */
16912106SRekai.GonzalezAlberquilla@arm.com    /** @{ */
17012106SRekai.GonzalezAlberquilla@arm.com    const RegIndex& index() const { return regIdx; }
17112106SRekai.GonzalezAlberquilla@arm.com    RegIndex& index() { return regIdx; }
17212106SRekai.GonzalezAlberquilla@arm.com
17312106SRekai.GonzalezAlberquilla@arm.com    /** Index flattening.
17412106SRekai.GonzalezAlberquilla@arm.com     * Required to be able to use a vector for the register mapping.
17512106SRekai.GonzalezAlberquilla@arm.com     */
17612857Sradwang@ucdavis.edu    inline RegIndex flatIndex() const
17712857Sradwang@ucdavis.edu    {
17812857Sradwang@ucdavis.edu        switch (regClass) {
17912857Sradwang@ucdavis.edu          case IntRegClass:
18012857Sradwang@ucdavis.edu          case FloatRegClass:
18112857Sradwang@ucdavis.edu          case VecRegClass:
18212857Sradwang@ucdavis.edu          case CCRegClass:
18312857Sradwang@ucdavis.edu          case MiscRegClass:
18412857Sradwang@ucdavis.edu            return regIdx;
18512857Sradwang@ucdavis.edu          case VecElemClass:
18612857Sradwang@ucdavis.edu            return Scale*regIdx + elemIdx;
18712857Sradwang@ucdavis.edu        }
18812857Sradwang@ucdavis.edu        panic("Trying to flatten a register without class!");
18912857Sradwang@ucdavis.edu        return -1;
19012857Sradwang@ucdavis.edu    }
19112106SRekai.GonzalezAlberquilla@arm.com    /** @} */
19212106SRekai.GonzalezAlberquilla@arm.com
19312109SRekai.GonzalezAlberquilla@arm.com    /** Elem accessor */
19412109SRekai.GonzalezAlberquilla@arm.com    const RegIndex& elemIndex() const { return elemIdx; }
19512106SRekai.GonzalezAlberquilla@arm.com    /** Class accessor */
19612106SRekai.GonzalezAlberquilla@arm.com    const RegClass& classValue() const { return regClass; }
19712106SRekai.GonzalezAlberquilla@arm.com    /** Return a const char* with the register class name. */
19812106SRekai.GonzalezAlberquilla@arm.com    const char* className() const { return regClassStrings[regClass]; }
19912106SRekai.GonzalezAlberquilla@arm.com
20012106SRekai.GonzalezAlberquilla@arm.com    friend std::ostream&
20112106SRekai.GonzalezAlberquilla@arm.com    operator<<(std::ostream& os, const RegId& rid) {
20212106SRekai.GonzalezAlberquilla@arm.com        return os << rid.className() << "{" << rid.index() << "}";
20312106SRekai.GonzalezAlberquilla@arm.com    }
20412104Snathanael.premillieu@arm.com};
20512858Sradwang@ucdavis.edu
20612858Sradwang@ucdavis.edunamespace std
20712858Sradwang@ucdavis.edu{
20812858Sradwang@ucdavis.edutemplate<>
20912858Sradwang@ucdavis.edustruct hash<RegId>
21012858Sradwang@ucdavis.edu{
21112858Sradwang@ucdavis.edu    size_t operator()(const RegId& reg_id) const
21212858Sradwang@ucdavis.edu    {
21312858Sradwang@ucdavis.edu        // Extract unique integral values for the effective fields of a RegId.
21412858Sradwang@ucdavis.edu        const size_t flat_index = static_cast<size_t>(reg_id.flatIndex());
21512858Sradwang@ucdavis.edu        const size_t class_num = static_cast<size_t>(reg_id.regClass);
21612858Sradwang@ucdavis.edu
21712858Sradwang@ucdavis.edu        const size_t shifted_class_num = class_num << (sizeof(RegIndex) << 3);
21812858Sradwang@ucdavis.edu
21912858Sradwang@ucdavis.edu        // Concatenate the class_num to the end of the flat_index, in order to
22012858Sradwang@ucdavis.edu        // maximize information retained.
22112858Sradwang@ucdavis.edu        const size_t concatenated_hash = flat_index | shifted_class_num;
22212858Sradwang@ucdavis.edu
22312858Sradwang@ucdavis.edu        // If RegIndex is larger than size_t, then class_num will not be
22412858Sradwang@ucdavis.edu        // considered by this hash function, so we may wish to perform a
22512858Sradwang@ucdavis.edu        // different operation to include that information in the hash.
22612858Sradwang@ucdavis.edu        static_assert(sizeof(RegIndex) < sizeof(size_t),
22712858Sradwang@ucdavis.edu            "sizeof(RegIndex) should be less than sizeof(size_t)");
22812858Sradwang@ucdavis.edu
22912858Sradwang@ucdavis.edu        return concatenated_hash;
23012858Sradwang@ucdavis.edu    }
23112858Sradwang@ucdavis.edu};
23212858Sradwang@ucdavis.edu}
23312858Sradwang@ucdavis.edu
2349913Ssteve.reinhardt@amd.com#endif // __CPU__REG_CLASS_HH__
235