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 15namespace llvm { 16 17/// An unsigned integer type large enough to represent all physical registers, 18/// but not necessarily virtual registers. 19using MCPhysReg = uint16_t; 20 21/// Wrapper class representing physical registers. Should be passed by value. 22class MCRegister { 23 unsigned Reg; 24 25public: 26 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 39 /// This is the portion of the positive number space that is not a physical 40 /// register. StackSlot values do not exist in the MC layer, see 41 /// Register::isStackSlot() for the more information on them. 42 /// 43 /// Note that isVirtualRegister() and isPhysicalRegister() cannot handle stack 44 /// slots, so if a variable may contains a stack slot, always check 45 /// isStackSlot() first. 46 static bool isStackSlot(unsigned Reg) { 47 return int(Reg) >= (1 << 30); 48 } 49 50 /// Return true if the specified register number is in 51 /// the physical register namespace. 52 static bool isPhysicalRegister(unsigned Reg) { 53 assert(!isStackSlot(Reg) && "Not a register! Check isStackSlot() first."); 54 return int(Reg) > 0; 55 } 56 57 /// Return true if the specified register number is in the physical register 58 /// namespace. 59 bool isPhysical() const { 60 return isPhysicalRegister(Reg); 61 } 62 63 operator unsigned() const { 64 return Reg; 65 } 66 67 unsigned id() const { 68 return Reg; 69 } 70 71 bool isValid() const { 72 return Reg != 0; 73 } 74 75 /// Comparisons between register objects 76 bool operator==(const MCRegister &Other) const { return Reg == Other.Reg; } 77 bool operator!=(const MCRegister &Other) const { return Reg != Other.Reg; } 78 79 /// Comparisons against register constants. E.g. 80 /// * R == AArch64::WZR 81 /// * R == 0 82 /// * R == VirtRegMap::NO_PHYS_REG 83 bool operator==(unsigned Other) const { return Reg == Other; } 84 bool operator!=(unsigned Other) const { return Reg != Other; } 85 bool operator==(int Other) const { return Reg == unsigned(Other); } 86 bool operator!=(int Other) const { return Reg != unsigned(Other); } 87 // MSVC requires that we explicitly declare these two as well. 88 bool operator==(MCPhysReg Other) const { return Reg == unsigned(Other); } 89 bool operator!=(MCPhysReg Other) const { return Reg != unsigned(Other); } 90}; 91 92// Provide DenseMapInfo for MCRegister 93template<> struct DenseMapInfo<MCRegister> { 94 static inline unsigned getEmptyKey() { 95 return DenseMapInfo<unsigned>::getEmptyKey(); 96 } 97 static inline unsigned getTombstoneKey() { 98 return DenseMapInfo<unsigned>::getTombstoneKey(); 99 } 100 static unsigned getHashValue(const MCRegister &Val) { 101 return DenseMapInfo<unsigned>::getHashValue(Val.id()); 102 } 103 static bool isEqual(const MCRegister &LHS, const MCRegister &RHS) { 104 return DenseMapInfo<unsigned>::isEqual(LHS.id(), RHS.id()); 105 } 106}; 107 108} 109 110#endif // ifndef LLVM_MC_REGISTER_H 111