reg_class.hh revision 12109
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;
8512106SRekai.GonzalezAlberquilla@arm.com  public:
8612104Snathanael.premillieu@arm.com    RegId() {};
8712104Snathanael.premillieu@arm.com    RegId(RegClass reg_class, RegIndex reg_idx)
8812109SRekai.GonzalezAlberquilla@arm.com        : regClass(reg_class), regIdx(reg_idx), elemIdx(-1)
8912109SRekai.GonzalezAlberquilla@arm.com    {
9012109SRekai.GonzalezAlberquilla@arm.com        panic_if(regClass == VecElemClass,
9112109SRekai.GonzalezAlberquilla@arm.com                "Creating vector physical index w/o element index");
9212109SRekai.GonzalezAlberquilla@arm.com    }
9312109SRekai.GonzalezAlberquilla@arm.com
9412109SRekai.GonzalezAlberquilla@arm.com    explicit RegId(RegClass reg_class, RegIndex reg_idx, ElemIndex elem_idx)
9512109SRekai.GonzalezAlberquilla@arm.com        : regClass(reg_class), regIdx(reg_idx), elemIdx(elem_idx)
9612109SRekai.GonzalezAlberquilla@arm.com    {
9712109SRekai.GonzalezAlberquilla@arm.com        panic_if(regClass != VecElemClass,
9812109SRekai.GonzalezAlberquilla@arm.com                "Creating non-vector physical index w/ element index");
9912109SRekai.GonzalezAlberquilla@arm.com    }
1009913Ssteve.reinhardt@amd.com
10112104Snathanael.premillieu@arm.com    bool operator==(const RegId& that) const {
10212109SRekai.GonzalezAlberquilla@arm.com        return regClass == that.classValue() && regIdx == that.index()
10312109SRekai.GonzalezAlberquilla@arm.com                                             && elemIdx == that.elemIndex();
1049913Ssteve.reinhardt@amd.com    }
1059913Ssteve.reinhardt@amd.com
10612104Snathanael.premillieu@arm.com    bool operator!=(const RegId& that) const {
10712104Snathanael.premillieu@arm.com        return !(*this==that);
10812104Snathanael.premillieu@arm.com    }
10912104Snathanael.premillieu@arm.com
11012106SRekai.GonzalezAlberquilla@arm.com    /** Order operator.
11112106SRekai.GonzalezAlberquilla@arm.com     * The order is required to implement maps with key type RegId
11212104Snathanael.premillieu@arm.com     */
11312106SRekai.GonzalezAlberquilla@arm.com    bool operator<(const RegId& that) const {
11412106SRekai.GonzalezAlberquilla@arm.com        return regClass < that.classValue() ||
11512109SRekai.GonzalezAlberquilla@arm.com            (regClass == that.classValue() && (
11612109SRekai.GonzalezAlberquilla@arm.com                   regIdx < that.index() ||
11712109SRekai.GonzalezAlberquilla@arm.com                   (regIdx == that.index() && elemIdx < that.elemIndex())));
11812104Snathanael.premillieu@arm.com    }
11912104Snathanael.premillieu@arm.com
12012104Snathanael.premillieu@arm.com    /**
12112104Snathanael.premillieu@arm.com     * Return true if this register can be renamed
12212104Snathanael.premillieu@arm.com     */
12312106SRekai.GonzalezAlberquilla@arm.com    bool isRenameable() const
12412104Snathanael.premillieu@arm.com    {
12512104Snathanael.premillieu@arm.com        return regClass != MiscRegClass;
12612104Snathanael.premillieu@arm.com    }
12712104Snathanael.premillieu@arm.com
12812106SRekai.GonzalezAlberquilla@arm.com    /**
12912106SRekai.GonzalezAlberquilla@arm.com     * Check if this is the zero register.
13012106SRekai.GonzalezAlberquilla@arm.com     * Returns true if this register is a zero register (needs to have a
13112106SRekai.GonzalezAlberquilla@arm.com     * constant zero value throughout the execution).
13212106SRekai.GonzalezAlberquilla@arm.com     */
13312106SRekai.GonzalezAlberquilla@arm.com
13412106SRekai.GonzalezAlberquilla@arm.com    inline bool isZeroReg() const;
13512106SRekai.GonzalezAlberquilla@arm.com
13612106SRekai.GonzalezAlberquilla@arm.com    /** @return true if it is an integer physical register. */
13712106SRekai.GonzalezAlberquilla@arm.com    bool isIntReg() const { return regClass == IntRegClass; }
13812106SRekai.GonzalezAlberquilla@arm.com
13912106SRekai.GonzalezAlberquilla@arm.com    /** @return true if it is a floating-point physical register. */
14012106SRekai.GonzalezAlberquilla@arm.com    bool isFloatReg() const { return regClass == FloatRegClass; }
14112106SRekai.GonzalezAlberquilla@arm.com
14212106SRekai.GonzalezAlberquilla@arm.com    /** @Return true if it is a  condition-code physical register. */
14312109SRekai.GonzalezAlberquilla@arm.com    bool isVecReg() const { return regClass == VecRegClass; }
14412109SRekai.GonzalezAlberquilla@arm.com
14512109SRekai.GonzalezAlberquilla@arm.com    /** @Return true if it is a  condition-code physical register. */
14612109SRekai.GonzalezAlberquilla@arm.com    bool isVecElem() const { return regClass == VecElemClass; }
14712109SRekai.GonzalezAlberquilla@arm.com
14812109SRekai.GonzalezAlberquilla@arm.com    /** @Return true if it is a  condition-code physical register. */
14912106SRekai.GonzalezAlberquilla@arm.com    bool isCCReg() const { return regClass == CCRegClass; }
15012106SRekai.GonzalezAlberquilla@arm.com
15112106SRekai.GonzalezAlberquilla@arm.com    /** @Return true if it is a  condition-code physical register. */
15212106SRekai.GonzalezAlberquilla@arm.com    bool isMiscReg() const { return regClass == MiscRegClass; }
15312106SRekai.GonzalezAlberquilla@arm.com
15412109SRekai.GonzalezAlberquilla@arm.com    /**
15512109SRekai.GonzalezAlberquilla@arm.com     * Return true if this register can be renamed
15612109SRekai.GonzalezAlberquilla@arm.com     */
15712109SRekai.GonzalezAlberquilla@arm.com    bool isRenameable()
15812109SRekai.GonzalezAlberquilla@arm.com    {
15912109SRekai.GonzalezAlberquilla@arm.com        return regClass != MiscRegClass;
16012109SRekai.GonzalezAlberquilla@arm.com    }
16112109SRekai.GonzalezAlberquilla@arm.com
16212106SRekai.GonzalezAlberquilla@arm.com    /** Index accessors */
16312106SRekai.GonzalezAlberquilla@arm.com    /** @{ */
16412106SRekai.GonzalezAlberquilla@arm.com    const RegIndex& index() const { return regIdx; }
16512106SRekai.GonzalezAlberquilla@arm.com    RegIndex& index() { return regIdx; }
16612106SRekai.GonzalezAlberquilla@arm.com
16712106SRekai.GonzalezAlberquilla@arm.com    /** Index flattening.
16812106SRekai.GonzalezAlberquilla@arm.com     * Required to be able to use a vector for the register mapping.
16912106SRekai.GonzalezAlberquilla@arm.com     */
17012106SRekai.GonzalezAlberquilla@arm.com    inline RegIndex flatIndex() const;
17112106SRekai.GonzalezAlberquilla@arm.com    /** @} */
17212106SRekai.GonzalezAlberquilla@arm.com
17312109SRekai.GonzalezAlberquilla@arm.com    /** Elem accessor */
17412109SRekai.GonzalezAlberquilla@arm.com    const RegIndex& elemIndex() const { return elemIdx; }
17512106SRekai.GonzalezAlberquilla@arm.com    /** Class accessor */
17612106SRekai.GonzalezAlberquilla@arm.com    const RegClass& classValue() const { return regClass; }
17712106SRekai.GonzalezAlberquilla@arm.com    /** Return a const char* with the register class name. */
17812106SRekai.GonzalezAlberquilla@arm.com    const char* className() const { return regClassStrings[regClass]; }
17912106SRekai.GonzalezAlberquilla@arm.com
18012106SRekai.GonzalezAlberquilla@arm.com    friend std::ostream&
18112106SRekai.GonzalezAlberquilla@arm.com    operator<<(std::ostream& os, const RegId& rid) {
18212106SRekai.GonzalezAlberquilla@arm.com        return os << rid.className() << "{" << rid.index() << "}";
18312106SRekai.GonzalezAlberquilla@arm.com    }
18412104Snathanael.premillieu@arm.com};
1859913Ssteve.reinhardt@amd.com#endif // __CPU__REG_CLASS_HH__
186