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_MCREGISTER_H |
10 | #define LLVM_MC_MCREGISTER_H |
11 | |
12 | #include "llvm/ADT/DenseMapInfo.h" |
13 | #include "llvm/ADT/Hashing.h" |
14 | #include <cassert> |
15 | #include <limits> |
16 | |
17 | namespace llvm { |
18 | |
19 | /// An unsigned integer type large enough to represent all physical registers, |
20 | /// but not necessarily virtual registers. |
21 | using MCPhysReg = uint16_t; |
22 | |
23 | /// Register units are used to compute register aliasing. Every register has at |
24 | /// least one register unit, but it can have more. Two registers overlap if and |
25 | /// only if they have a common register unit. |
26 | /// |
27 | /// A target with a complicated sub-register structure will typically have many |
28 | /// fewer register units than actual registers. MCRI::getNumRegUnits() returns |
29 | /// the number of register units in the target. |
30 | using MCRegUnit = unsigned; |
31 | |
32 | /// Wrapper class representing physical registers. Should be passed by value. |
33 | class MCRegister { |
34 | friend hash_code hash_value(const MCRegister &); |
35 | unsigned Reg; |
36 | |
37 | public: |
38 | constexpr MCRegister(unsigned Val = 0) : Reg(Val) {} |
39 | |
40 | // Register numbers can represent physical registers, virtual registers, and |
41 | // sometimes stack slots. The unsigned values are divided into these ranges: |
42 | // |
43 | // 0 Not a register, can be used as a sentinel. |
44 | // [1;2^30) Physical registers assigned by TableGen. |
45 | // [2^30;2^31) Stack slots. (Rarely used.) |
46 | // [2^31;2^32) Virtual registers assigned by MachineRegisterInfo. |
47 | // |
48 | // Further sentinels can be allocated from the small negative integers. |
49 | // DenseMapInfo<unsigned> uses -1u and -2u. |
50 | static_assert(std::numeric_limits<decltype(Reg)>::max() >= 0xFFFFFFFF, |
51 | "Reg isn't large enough to hold full range." ); |
52 | static constexpr unsigned NoRegister = 0u; |
53 | static constexpr unsigned FirstPhysicalReg = 1u; |
54 | static constexpr unsigned FirstStackSlot = 1u << 30; |
55 | static constexpr unsigned VirtualRegFlag = 1u << 31; |
56 | |
57 | /// This is the portion of the positive number space that is not a physical |
58 | /// register. StackSlot values do not exist in the MC layer, see |
59 | /// Register::isStackSlot() for the more information on them. |
60 | /// |
61 | static constexpr bool isStackSlot(unsigned Reg) { |
62 | return FirstStackSlot <= Reg && Reg < VirtualRegFlag; |
63 | } |
64 | |
65 | /// Return true if the specified register number is in |
66 | /// the physical register namespace. |
67 | static constexpr bool isPhysicalRegister(unsigned Reg) { |
68 | return FirstPhysicalReg <= Reg && Reg < FirstStackSlot; |
69 | } |
70 | |
71 | constexpr operator unsigned() const { return Reg; } |
72 | |
73 | /// Check the provided unsigned value is a valid MCRegister. |
74 | static MCRegister from(unsigned Val) { |
75 | assert(Val == NoRegister || isPhysicalRegister(Val)); |
76 | return MCRegister(Val); |
77 | } |
78 | |
79 | constexpr unsigned id() const { return Reg; } |
80 | |
81 | constexpr bool isValid() const { return Reg != NoRegister; } |
82 | |
83 | /// Comparisons between register objects |
84 | constexpr bool operator==(const MCRegister &Other) const { |
85 | return Reg == Other.Reg; |
86 | } |
87 | constexpr bool operator!=(const MCRegister &Other) const { |
88 | return Reg != Other.Reg; |
89 | } |
90 | |
91 | /// Comparisons against register constants. E.g. |
92 | /// * R == AArch64::WZR |
93 | /// * R == 0 |
94 | /// * R == VirtRegMap::NO_PHYS_REG |
95 | constexpr bool operator==(unsigned Other) const { return Reg == Other; } |
96 | constexpr bool operator!=(unsigned Other) const { return Reg != Other; } |
97 | constexpr bool operator==(int Other) const { return Reg == unsigned(Other); } |
98 | constexpr bool operator!=(int Other) const { return Reg != unsigned(Other); } |
99 | // MSVC requires that we explicitly declare these two as well. |
100 | constexpr bool operator==(MCPhysReg Other) const { |
101 | return Reg == unsigned(Other); |
102 | } |
103 | constexpr bool operator!=(MCPhysReg Other) const { |
104 | return Reg != unsigned(Other); |
105 | } |
106 | }; |
107 | |
108 | // Provide DenseMapInfo for MCRegister |
109 | template <> struct DenseMapInfo<MCRegister> { |
110 | static inline unsigned getEmptyKey() { |
111 | return DenseMapInfo<unsigned>::getEmptyKey(); |
112 | } |
113 | static inline unsigned getTombstoneKey() { |
114 | return DenseMapInfo<unsigned>::getTombstoneKey(); |
115 | } |
116 | static unsigned getHashValue(const MCRegister &Val) { |
117 | return DenseMapInfo<unsigned>::getHashValue(Val: Val.id()); |
118 | } |
119 | static bool isEqual(const MCRegister &LHS, const MCRegister &RHS) { |
120 | return DenseMapInfo<unsigned>::isEqual(LHS: LHS.id(), RHS: RHS.id()); |
121 | } |
122 | }; |
123 | |
124 | inline hash_code hash_value(const MCRegister &Reg) { |
125 | return hash_value(value: Reg.id()); |
126 | } |
127 | } // namespace llvm |
128 | |
129 | #endif // LLVM_MC_MCREGISTER_H |
130 | |