1 //===-- llvm/MC/Register.h --------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLVM_MC_REGISTER_H 10 #define LLVM_MC_REGISTER_H 11 12 #include "llvm/ADT/DenseMapInfo.h" 13 #include <cassert> 14 15 namespace llvm { 16 17 /// An unsigned integer type large enough to represent all physical registers, 18 /// but not necessarily virtual registers. 19 using MCPhysReg = uint16_t; 20 21 /// Wrapper class representing physical registers. Should be passed by value. 22 class MCRegister { 23 unsigned Reg; 24 25 public: Reg(Val)26 constexpr MCRegister(unsigned Val = 0): Reg(Val) {} 27 28 // Register numbers can represent physical registers, virtual registers, and 29 // sometimes stack slots. The unsigned values are divided into these ranges: 30 // 31 // 0 Not a register, can be used as a sentinel. 32 // [1;2^30) Physical registers assigned by TableGen. 33 // [2^30;2^31) Stack slots. (Rarely used.) 34 // [2^31;2^32) Virtual registers assigned by MachineRegisterInfo. 35 // 36 // Further sentinels can be allocated from the small negative integers. 37 // DenseMapInfo<unsigned> uses -1u and -2u. 38 static_assert(std::numeric_limits<decltype(Reg)>::max() >= 0xFFFFFFFF, 39 "Reg isn't large enough to hold full range."); 40 static constexpr unsigned NoRegister = 0u; 41 static constexpr unsigned FirstPhysicalReg = 1u; 42 static constexpr unsigned FirstStackSlot = 1u << 30; 43 static constexpr unsigned VirtualRegFlag = 1u << 31; 44 45 /// This is the portion of the positive number space that is not a physical 46 /// register. StackSlot values do not exist in the MC layer, see 47 /// Register::isStackSlot() for the more information on them. 48 /// 49 /// Note that isVirtualRegister() and isPhysicalRegister() cannot handle stack 50 /// slots, so if a variable may contains a stack slot, always check 51 /// isStackSlot() first. isStackSlot(unsigned Reg)52 static bool isStackSlot(unsigned Reg) { 53 return !(Reg & VirtualRegFlag) && 54 uint32_t(Reg & ~VirtualRegFlag) >= FirstStackSlot; 55 } 56 57 /// Return true if the specified register number is in 58 /// the physical register namespace. isPhysicalRegister(unsigned Reg)59 static bool isPhysicalRegister(unsigned Reg) { 60 assert(!isStackSlot(Reg) && "Not a register! Check isStackSlot() first."); 61 return Reg >= FirstPhysicalReg && !(Reg & VirtualRegFlag); 62 } 63 64 /// Return true if the specified register number is in the physical register 65 /// namespace. isPhysical()66 bool isPhysical() const { 67 return isPhysicalRegister(Reg); 68 } 69 70 constexpr operator unsigned() const { 71 return Reg; 72 } 73 id()74 unsigned id() const { 75 return Reg; 76 } 77 isValid()78 bool isValid() const { return Reg != NoRegister; } 79 80 /// Comparisons between register objects 81 bool operator==(const MCRegister &Other) const { return Reg == Other.Reg; } 82 bool operator!=(const MCRegister &Other) const { return Reg != Other.Reg; } 83 84 /// Comparisons against register constants. E.g. 85 /// * R == AArch64::WZR 86 /// * R == 0 87 /// * R == VirtRegMap::NO_PHYS_REG 88 bool operator==(unsigned Other) const { return Reg == Other; } 89 bool operator!=(unsigned Other) const { return Reg != Other; } 90 bool operator==(int Other) const { return Reg == unsigned(Other); } 91 bool operator!=(int Other) const { return Reg != unsigned(Other); } 92 // MSVC requires that we explicitly declare these two as well. 93 bool operator==(MCPhysReg Other) const { return Reg == unsigned(Other); } 94 bool operator!=(MCPhysReg Other) const { return Reg != unsigned(Other); } 95 }; 96 97 // Provide DenseMapInfo for MCRegister 98 template<> struct DenseMapInfo<MCRegister> { 99 static inline unsigned getEmptyKey() { 100 return DenseMapInfo<unsigned>::getEmptyKey(); 101 } 102 static inline unsigned getTombstoneKey() { 103 return DenseMapInfo<unsigned>::getTombstoneKey(); 104 } 105 static unsigned getHashValue(const MCRegister &Val) { 106 return DenseMapInfo<unsigned>::getHashValue(Val.id()); 107 } 108 static bool isEqual(const MCRegister &LHS, const MCRegister &RHS) { 109 return DenseMapInfo<unsigned>::isEqual(LHS.id(), RHS.id()); 110 } 111 }; 112 113 } 114 115 #endif // ifndef LLVM_MC_REGISTER_H 116