reg_class.hh revision 13020
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: 8713020Sshunhsingou@google.com RegId() : regClass(IntRegClass), regIdx(0), elemIdx(-1) {} 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