OLD | NEW |
---|---|
1 //===- subzero/src/IceRegistersARM32.h - Register information ---*- C++ -*-===// | 1 //===- subzero/src/IceRegistersARM32.h - Register information ---*- C++ -*-===// |
2 // | 2 // |
3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 /// | 9 /// |
10 /// \file | 10 /// \file |
11 /// \brief Declares the registers and their encodings for ARM32. | 11 /// \brief Declares the registers and their encodings for ARM32. |
12 /// | 12 /// |
13 //===----------------------------------------------------------------------===// | 13 //===----------------------------------------------------------------------===// |
14 | 14 |
15 #ifndef SUBZERO_SRC_ICEREGISTERSARM32_H | 15 #ifndef SUBZERO_SRC_ICEREGISTERSARM32_H |
16 #define SUBZERO_SRC_ICEREGISTERSARM32_H | 16 #define SUBZERO_SRC_ICEREGISTERSARM32_H |
17 | 17 |
18 #include "IceDefs.h" | 18 #include "IceDefs.h" |
19 #include "IceInstARM32.def" | 19 #include "IceInstARM32.def" |
20 #include "IceOperand.h" // RC_Target | 20 #include "IceOperand.h" // RC_Target |
21 #include "IceTypes.h" | 21 #include "IceTypes.h" |
22 | 22 |
23 namespace Ice { | 23 namespace Ice { |
24 namespace ARM32 { | 24 namespace ARM32 { |
25 | 25 |
26 /// SizeOf is used to obtain the size of an initializer list as a constexpr | |
27 /// expression. This is only needed until our C++ library is updated to | |
28 /// C++ 14 -- which defines constexpr members to std::initializer_list. | |
29 class SizeOf { | |
30 SizeOf(const SizeOf &) = delete; | |
31 SizeOf &operator=(const SizeOf &) = delete; | |
32 | |
33 public: | |
34 constexpr SizeOf() : Size(0) {} | |
35 template <typename... T> | |
36 explicit constexpr SizeOf(T...) | |
37 : Size(__length<T...>::value) {} | |
38 constexpr SizeT size() const { return Size; } | |
39 | |
40 private: | |
41 template <typename T, typename... U> struct __length { | |
Jim Stichnoth
2016/01/06 19:41:41
I believe that identifiers containing adjacent und
| |
42 static constexpr std::size_t value = 1 + __length<U...>::value; | |
43 }; | |
44 | |
45 template <typename T> struct __length<T> { | |
46 static constexpr std::size_t value = 1; | |
47 }; | |
48 | |
49 const std::size_t Size; | |
50 }; | |
51 | |
26 class RegARM32 { | 52 class RegARM32 { |
53 private: | |
54 RegARM32() = delete; | |
55 RegARM32(const RegARM32 &) = delete; | |
56 RegARM32 &operator=(const RegARM32 &) = delete; | |
57 ~RegARM32() = delete; | |
58 | |
27 public: | 59 public: |
28 /// An enum of every register. The enum value may not match the encoding used | 60 /// An enum of every register. The enum value may not match the encoding used |
29 /// to binary encode register operands in instructions. | 61 /// to binary encode register operands in instructions. |
30 enum AllRegisters { | 62 enum AllRegisters { |
31 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ | 63 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ |
32 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ | 64 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ |
33 val, | 65 val, |
34 REGARM32_TABLE | 66 REGARM32_TABLE |
35 #undef X | 67 #undef X |
36 Reg_NUM, | 68 Reg_NUM, |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
76 /// used to binary encode register operands in instructions. | 108 /// used to binary encode register operands in instructions. |
77 enum QRegister { | 109 enum QRegister { |
78 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ | 110 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ |
79 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ | 111 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ |
80 Encoded_##val = encode, | 112 Encoded_##val = encode, |
81 REGARM32_VEC128_TABLE | 113 REGARM32_VEC128_TABLE |
82 #undef X | 114 #undef X |
83 Encoded_Not_QReg = -1 | 115 Encoded_Not_QReg = -1 |
84 }; | 116 }; |
85 | 117 |
118 static constexpr struct TableType { | |
Karl
2016/01/04 21:10:45
Why is this a constexpr? Won't functions like getE
John
2016/01/04 21:45:12
resolved offline.
| |
119 const char *Name; | |
120 int32_t Encoding : 10; | |
121 int32_t CCArg : 6; | |
122 int32_t Scratch : 1; | |
123 int32_t Preserved : 1; | |
124 int32_t StackPtr : 1; | |
125 int32_t FramePtr : 1; | |
126 int32_t IsGPR : 1; | |
127 int32_t IsInt : 1; | |
128 int32_t IsI64Pair : 1; | |
129 int32_t IsFP32 : 1; | |
130 int32_t IsFP64 : 1; | |
131 int32_t IsVec128 : 1; | |
132 #define NUM_ALIASES_BITS 3 | |
133 SizeT NumAliases : (NUM_ALIASES_BITS + 1); | |
134 uint16_t Aliases[1 << NUM_ALIASES_BITS]; | |
135 #undef NUM_ALIASES_BITS | |
136 } Table[Reg_NUM] = { | |
137 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ | |
138 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ | |
139 { \ | |
140 name, encode, cc_arg, scratch, preserved, stackptr, frameptr, isGPR, \ | |
141 isInt, isI64Pair, isFP32, isFP64, isVec128, \ | |
142 (SizeOf alias_init).size(), alias_init \ | |
143 } \ | |
144 , | |
145 REGARM32_TABLE | |
146 #undef X | |
147 }; | |
148 | |
86 static inline GPRRegister getEncodedGPR(int32_t RegNum) { | 149 static inline GPRRegister getEncodedGPR(int32_t RegNum) { |
87 assert(Reg_GPR_First <= RegNum); | 150 assert(Reg_GPR_First <= RegNum); |
88 assert(RegNum <= Reg_GPR_Last); | 151 assert(RegNum <= Reg_GPR_Last); |
89 return GPRRegister(RegNum - Reg_GPR_First); | 152 return GPRRegister(Table[RegNum].Encoding); |
90 } | 153 } |
91 | 154 |
92 static inline GPRRegister getI64PairFirstGPRNum(int32_t RegNum) { | 155 static inline GPRRegister getI64PairFirstGPRNum(int32_t RegNum) { |
93 assert(Reg_I64PAIR_First <= RegNum); | 156 assert(Reg_I64PAIR_First <= RegNum); |
94 assert(RegNum <= Reg_I64PAIR_Last); | 157 assert(RegNum <= Reg_I64PAIR_Last); |
95 return GPRRegister(2 * (RegNum - Reg_I64PAIR_First + Reg_GPR_First)); | 158 return GPRRegister(Table[RegNum].Encoding); |
96 } | 159 } |
97 | 160 |
98 static inline GPRRegister getI64PairSecondGPRNum(int32_t RegNum) { | 161 static inline GPRRegister getI64PairSecondGPRNum(int32_t RegNum) { |
99 assert(Reg_I64PAIR_First <= RegNum); | 162 assert(Reg_I64PAIR_First <= RegNum); |
100 assert(RegNum <= Reg_I64PAIR_Last); | 163 assert(RegNum <= Reg_I64PAIR_Last); |
101 return GPRRegister(2 * (RegNum - Reg_I64PAIR_First + Reg_GPR_First) + 1); | 164 return GPRRegister(Table[RegNum].Encoding + 1); |
102 } | 165 } |
103 | 166 |
104 static inline bool isI64RegisterPair(int32_t RegNum) { | 167 static inline bool isI64RegisterPair(int32_t RegNum) { |
105 return Reg_I64PAIR_First <= RegNum && RegNum <= Reg_I64PAIR_Last; | 168 return Table[RegNum].IsI64Pair; |
106 } | 169 } |
107 | 170 |
108 static inline bool isEncodedSReg(int32_t RegNum) { | 171 static inline bool isEncodedSReg(int32_t RegNum) { |
109 return Reg_SREG_First <= RegNum && RegNum <= Reg_SREG_Last; | 172 return Table[RegNum].IsFP32; |
110 } | 173 } |
111 | 174 |
112 static inline SizeT getNumSRegs() { | 175 static inline SizeT getNumSRegs() { |
113 return Reg_SREG_Last + 1 - Reg_SREG_First; | 176 return Reg_SREG_Last + 1 - Reg_SREG_First; |
114 } | 177 } |
115 | 178 |
116 static inline SRegister getEncodedSReg(int32_t RegNum) { | 179 static inline SRegister getEncodedSReg(int32_t RegNum) { |
117 assert(Reg_SREG_First <= RegNum); | 180 assert(Reg_SREG_First <= RegNum); |
118 assert(RegNum <= Reg_SREG_Last); | 181 assert(RegNum <= Reg_SREG_Last); |
119 return SRegister(RegNum - Reg_SREG_First); | 182 return SRegister(Table[RegNum].Encoding); |
120 } | 183 } |
121 | 184 |
122 static inline DRegister getEncodedDReg(int32_t RegNum) { | 185 static inline DRegister getEncodedDReg(int32_t RegNum) { |
123 assert(Reg_DREG_First <= RegNum); | 186 assert(Reg_DREG_First <= RegNum); |
124 assert(RegNum <= Reg_DREG_Last); | 187 assert(RegNum <= Reg_DREG_Last); |
125 return DRegister(RegNum - Reg_DREG_First); | 188 return DRegister(Table[RegNum].Encoding); |
126 } | 189 } |
127 | 190 |
128 static inline QRegister getEncodedQReg(int32_t RegNum) { | 191 static inline QRegister getEncodedQReg(int32_t RegNum) { |
129 assert(Reg_QREG_First <= RegNum); | 192 assert(Reg_QREG_First <= RegNum); |
130 assert(RegNum <= Reg_QREG_Last); | 193 assert(RegNum <= Reg_QREG_Last); |
131 return QRegister(RegNum - Reg_QREG_First); | 194 return QRegister(Table[RegNum].Encoding); |
132 } | 195 } |
133 | 196 |
134 static const char *RegNames[]; | 197 static inline IceString getRegName(SizeT RegNum) { |
198 assert(RegNum < Reg_NUM); | |
199 return Table[RegNum].Name; | |
200 } | |
135 }; | 201 }; |
136 | 202 |
137 // Extend enum RegClass with ARM32-specific register classes (if any). | 203 // Extend enum RegClass with ARM32-specific register classes (if any). |
138 enum RegClassARM32 : uint8_t { RCARM32_NUM = RC_Target }; | 204 enum RegClassARM32 : uint8_t { RCARM32_NUM = RC_Target }; |
139 | 205 |
140 } // end of namespace ARM32 | 206 } // end of namespace ARM32 |
141 } // end of namespace Ice | 207 } // end of namespace Ice |
142 | 208 |
143 #endif // SUBZERO_SRC_ICEREGISTERSARM32_H | 209 #endif // SUBZERO_SRC_ICEREGISTERSARM32_H |
OLD | NEW |