Chromium Code Reviews| 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 namespace RegARM32 { |
| 26 /// SizeOf is used to obtain the size of an initializer list as a constexpr | 26 |
| 27 /// expression. This is only needed until our C++ library is updated to | 27 /// An enum of every register. The enum value may not match the encoding used |
| 28 /// C++ 14 -- which defines constexpr members to std::initializer_list. | 28 /// to binary encode register operands in instructions. |
| 29 class SizeOf { | 29 enum AllRegisters { |
| 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 { | |
| 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 | |
| 52 class RegARM32 { | |
| 53 private: | |
| 54 RegARM32() = delete; | |
| 55 RegARM32(const RegARM32 &) = delete; | |
| 56 RegARM32 &operator=(const RegARM32 &) = delete; | |
| 57 ~RegARM32() = delete; | |
| 58 | |
| 59 public: | |
| 60 /// An enum of every register. The enum value may not match the encoding used | |
| 61 /// to binary encode register operands in instructions. | |
| 62 enum AllRegisters { | |
| 63 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ | 30 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ |
| 64 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ | 31 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ |
| 65 val, | 32 val, |
| 66 REGARM32_TABLE | 33 REGARM32_TABLE |
| 67 #undef X | 34 #undef X |
| 68 Reg_NUM, | 35 Reg_NUM, |
| 69 #define X(val, init) val init, | 36 #define X(val, init) val init, |
| 70 REGARM32_TABLE_BOUNDS | 37 REGARM32_TABLE_BOUNDS |
| 71 #undef X | 38 #undef X |
| 72 }; | 39 }; |
| 73 | 40 |
| 74 /// An enum of GPR Registers. The enum value does match the encoding used to | 41 /// An enum of GPR Registers. The enum value does match the encoding used to |
| 75 /// binary encode register operands in instructions. | 42 /// binary encode register operands in instructions. |
| 76 enum GPRRegister { | 43 enum GPRRegister { |
| 77 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ | 44 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ |
| 78 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ | 45 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ |
| 79 Encoded_##val = encode, | 46 Encoded_##val = encode, |
| 80 REGARM32_GPR_TABLE | 47 REGARM32_GPR_TABLE |
| 81 #undef X | 48 #undef X |
| 82 Encoded_Not_GPR = -1 | 49 Encoded_Not_GPR = -1 |
| 83 }; | 50 }; |
| 84 | 51 |
| 85 /// An enum of FP32 S-Registers. The enum value does match the encoding used | 52 /// An enum of FP32 S-Registers. The enum value does match the encoding used |
| 86 /// to binary encode register operands in instructions. | 53 /// to binary encode register operands in instructions. |
| 87 enum SRegister { | 54 enum SRegister { |
| 88 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ | 55 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ |
| 89 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ | 56 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ |
| 90 Encoded_##val = encode, | 57 Encoded_##val = encode, |
| 91 REGARM32_FP32_TABLE | 58 REGARM32_FP32_TABLE |
| 92 #undef X | 59 #undef X |
| 93 Encoded_Not_SReg = -1 | 60 Encoded_Not_SReg = -1 |
| 94 }; | 61 }; |
| 95 | 62 |
| 96 /// An enum of FP64 D-Registers. The enum value does match the encoding used | 63 /// An enum of FP64 D-Registers. The enum value does match the encoding used |
| 97 /// to binary encode register operands in instructions. | 64 /// to binary encode register operands in instructions. |
| 98 enum DRegister { | 65 enum DRegister { |
| 99 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ | 66 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ |
| 100 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ | 67 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ |
| 101 Encoded_##val = encode, | 68 Encoded_##val = encode, |
| 102 REGARM32_FP64_TABLE | 69 REGARM32_FP64_TABLE |
| 103 #undef X | 70 #undef X |
| 104 Encoded_Not_DReg = -1 | 71 Encoded_Not_DReg = -1 |
| 105 }; | 72 }; |
| 106 | 73 |
| 107 /// An enum of 128-bit Q-Registers. The enum value does match the encoding | 74 /// An enum of 128-bit Q-Registers. The enum value does match the encoding |
| 108 /// used to binary encode register operands in instructions. | 75 /// used to binary encode register operands in instructions. |
| 109 enum QRegister { | 76 enum QRegister { |
| 110 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ | 77 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ |
| 111 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ | 78 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ |
| 112 Encoded_##val = encode, | 79 Encoded_##val = encode, |
| 113 REGARM32_VEC128_TABLE | 80 REGARM32_VEC128_TABLE |
| 114 #undef X | 81 #undef X |
| 115 Encoded_Not_QReg = -1 | 82 Encoded_Not_QReg = -1 |
| 116 }; | 83 }; |
| 117 | 84 |
| 118 static constexpr struct TableType { | 85 extern struct RegTableType { |
| 119 const char *Name; | 86 const char *Name; |
| 120 unsigned Encoding : 10; | 87 unsigned Encoding : 10; |
| 121 unsigned CCArg : 6; | 88 unsigned CCArg : 6; |
| 122 unsigned Scratch : 1; | 89 unsigned Scratch : 1; |
| 123 unsigned Preserved : 1; | 90 unsigned Preserved : 1; |
| 124 unsigned StackPtr : 1; | 91 unsigned StackPtr : 1; |
| 125 unsigned FramePtr : 1; | 92 unsigned FramePtr : 1; |
| 126 unsigned IsGPR : 1; | 93 unsigned IsGPR : 1; |
| 127 unsigned IsInt : 1; | 94 unsigned IsInt : 1; |
| 128 unsigned IsI64Pair : 1; | 95 unsigned IsI64Pair : 1; |
| 129 unsigned IsFP32 : 1; | 96 unsigned IsFP32 : 1; |
| 130 unsigned IsFP64 : 1; | 97 unsigned IsFP64 : 1; |
| 131 unsigned IsVec128 : 1; | 98 unsigned IsVec128 : 1; |
| 132 #define NUM_ALIASES_BITS 3 | 99 #define NUM_ALIASES_BITS 3 |
| 133 SizeT NumAliases : (NUM_ALIASES_BITS + 1); | 100 SizeT NumAliases : (NUM_ALIASES_BITS + 1); |
| 134 uint16_t Aliases[1 << NUM_ALIASES_BITS]; | 101 uint16_t Aliases[1 << NUM_ALIASES_BITS]; |
| 135 #undef NUM_ALIASES_BITS | 102 #undef NUM_ALIASES_BITS |
| 136 } Table[Reg_NUM] = { | 103 } RegTable[Reg_NUM]; |
| 137 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ | 104 |
| 138 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ | 105 static inline bool isGPRegister(int32_t RegNum) { |
| 139 { \ | 106 assert(RegNum >= 0); |
| 140 name, encode, cc_arg, scratch, preserved, stackptr, frameptr, isGPR, \ | 107 assert(RegNum < Reg_NUM); |
| 141 isInt, isI64Pair, isFP32, isFP64, isVec128, \ | 108 return RegTable[RegNum].IsGPR; |
| 142 (SizeOf alias_init).size(), alias_init \ | 109 } |
| 143 } \ | 110 |
| 144 , | 111 static constexpr inline SizeT getNumGPRegs() { |
| 145 REGARM32_TABLE | 112 return 0 |
| 146 #undef X | |
| 147 }; | |
| 148 | |
| 149 static inline void assertRegisterDefined(int32_t RegNum) { | |
| 150 (void)RegNum; | |
| 151 assert(RegNum >= 0); | |
| 152 assert(RegNum < Reg_NUM); | |
| 153 } | |
| 154 | |
| 155 static inline bool isGPRegister(int32_t RegNum) { | |
| 156 assertRegisterDefined(RegNum); | |
| 157 return Table[RegNum].IsGPR; | |
| 158 } | |
| 159 | |
| 160 static constexpr SizeT getNumGPRegs() { | |
| 161 return 0 | |
| 162 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ | 113 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ |
| 163 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ | 114 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ |
| 164 +(isGPR) | 115 +(isGPR) |
| 165 REGARM32_TABLE | 116 REGARM32_TABLE |
| 166 #undef X | 117 #undef X |
| 167 ; | 118 ; |
| 168 } | 119 } |
| 169 | 120 |
| 170 static inline GPRRegister getEncodedGPR(int32_t RegNum) { | 121 static inline GPRRegister getEncodedGPR(int32_t RegNum) { |
| 171 assert(isGPRegister(RegNum)); | 122 assert(RegNum >= 0); |
| 172 return GPRRegister(Table[RegNum].Encoding); | 123 assert(RegNum < Reg_NUM); |
| 173 } | 124 return GPRRegister(RegTable[RegNum].Encoding); |
| 174 | 125 } |
| 175 static constexpr SizeT getNumGPRs() { | 126 |
| 176 return 0 | 127 static constexpr inline SizeT getNumGPRs() { |
| 128 return 0 | |
| 177 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ | 129 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ |
| 178 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ | 130 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ |
| 179 +(isGPR) | 131 +(isGPR) |
| 180 REGARM32_TABLE | 132 REGARM32_TABLE |
| 181 #undef X | 133 #undef X |
| 182 ; | 134 ; |
| 183 } | 135 } |
| 184 | 136 |
| 185 static inline bool isGPR(SizeT RegNum) { | 137 static inline bool isGPR(SizeT RegNum) { |
| 186 assertRegisterDefined(RegNum); | 138 assert(RegNum >= 0); |
| 187 return Table[RegNum].IsGPR; | 139 assert(RegNum < Reg_NUM); |
| 188 } | 140 return RegTable[RegNum].IsGPR; |
| 189 | 141 } |
| 190 static inline IceString getGPRName(SizeT RegNum) { | 142 |
| 191 assert(isGPR(RegNum)); | 143 static inline IceString getGPRName(SizeT RegNum) { |
|
Jim Stichnoth
2016/01/15 01:17:15
Remove this because it is identical to getRegName(
Karl
2016/01/15 16:11:19
Done.
| |
| 192 return Table[RegNum].Name; | 144 assert(RegNum >= 0); |
| 193 } | 145 assert(RegNum < Reg_NUM); |
| 194 | 146 return RegTable[RegNum].Name; |
| 195 static inline GPRRegister getI64PairFirstGPRNum(int32_t RegNum) { | 147 } |
| 196 assert(isI64RegisterPair(RegNum)); | 148 |
| 197 return GPRRegister(Table[RegNum].Encoding); | 149 static inline GPRRegister getI64PairFirstGPRNum(int32_t RegNum) { |
| 198 } | 150 assert(RegNum >= 0); |
| 199 | 151 assert(RegNum < Reg_NUM); |
| 200 static inline GPRRegister getI64PairSecondGPRNum(int32_t RegNum) { | 152 return GPRRegister(RegTable[RegNum].Encoding); |
| 201 assert(isI64RegisterPair(RegNum)); | 153 } |
| 202 return GPRRegister(Table[RegNum].Encoding + 1); | 154 |
| 203 } | 155 static inline GPRRegister getI64PairSecondGPRNum(int32_t RegNum) { |
| 204 | 156 assert(RegNum >= 0); |
| 205 static inline bool isI64RegisterPair(int32_t RegNum) { | 157 assert(RegNum < Reg_NUM); |
| 206 assertRegisterDefined(RegNum); | 158 return GPRRegister(RegTable[RegNum].Encoding + 1); |
| 207 return Table[RegNum].IsI64Pair; | 159 } |
| 208 } | 160 |
| 209 | 161 static inline bool isI64RegisterPair(int32_t RegNum) { |
| 210 static inline bool isEncodedSReg(int32_t RegNum) { | 162 assert(RegNum >= 0); |
| 211 assertRegisterDefined(RegNum); | 163 assert(RegNum < Reg_NUM); |
| 212 return Table[RegNum].IsFP32; | 164 return RegTable[RegNum].IsI64Pair; |
| 213 } | 165 } |
| 214 | 166 |
| 215 static constexpr SizeT getNumSRegs() { | 167 static inline bool isEncodedSReg(int32_t RegNum) { |
| 216 return 0 | 168 assert(RegNum >= 0); |
| 169 assert(RegNum < Reg_NUM); | |
| 170 return RegTable[RegNum].IsFP32; | |
| 171 } | |
| 172 | |
| 173 static constexpr inline SizeT getNumSRegs() { | |
| 174 return 0 | |
| 217 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ | 175 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ |
| 218 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ | 176 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ |
| 219 +(isFP32) | 177 +(isFP32) |
| 220 REGARM32_TABLE | 178 REGARM32_TABLE |
| 221 #undef X | 179 #undef X |
| 222 ; | 180 ; |
| 223 } | 181 } |
| 224 | 182 |
| 225 static inline IceString getSRegName(SizeT RegNum) { | 183 static inline IceString getSRegName(SizeT RegNum) { |
|
Jim Stichnoth
2016/01/15 01:17:15
Remove this because it is identical to getRegName(
Karl
2016/01/15 16:11:19
Done.
| |
| 226 assert(isEncodedSReg(RegNum)); | 184 assert(RegNum >= 0); |
| 227 return Table[RegNum].Name; | 185 assert(RegNum < Reg_NUM); |
| 228 } | 186 return RegTable[RegNum].Name; |
| 229 | 187 } |
| 230 static inline SRegister getEncodedSReg(int32_t RegNum) { | 188 |
| 231 assert(isEncodedSReg(RegNum)); | 189 static inline SRegister getEncodedSReg(int32_t RegNum) { |
| 232 return SRegister(Table[RegNum].Encoding); | 190 assert(RegNum >= 0); |
| 233 } | 191 assert(RegNum < Reg_NUM); |
| 234 | 192 return SRegister(RegTable[RegNum].Encoding); |
| 235 static inline bool isEncodedDReg(int32_t RegNum) { | 193 } |
| 236 assertRegisterDefined(RegNum); | 194 |
| 237 return Table[RegNum].IsFP64; | 195 static inline bool isEncodedDReg(int32_t RegNum) { |
| 238 } | 196 assert(RegNum >= 0); |
| 239 | 197 assert(RegNum < Reg_NUM); |
| 240 static constexpr inline SizeT getNumDRegs() { | 198 return RegTable[RegNum].IsFP64; |
| 241 return 0 | 199 } |
| 200 | |
| 201 static constexpr inline SizeT getNumDRegs() { | |
| 202 return 0 | |
| 242 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ | 203 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ |
| 243 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ | 204 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ |
| 244 +(isFP64) | 205 +(isFP64) |
| 245 REGARM32_TABLE | 206 REGARM32_TABLE |
| 246 #undef X | 207 #undef X |
| 247 ; | 208 ; |
| 248 } | 209 } |
| 249 | 210 |
| 250 static inline DRegister getEncodedDReg(int32_t RegNum) { | 211 static inline DRegister getEncodedDReg(int32_t RegNum) { |
| 251 assert(isEncodedDReg(RegNum)); | 212 assert(RegNum >= 0); |
| 252 return DRegister(Table[RegNum].Encoding); | 213 assert(RegNum < Reg_NUM); |
| 253 } | 214 return DRegister(RegTable[RegNum].Encoding); |
| 254 | 215 } |
| 255 static inline bool isEncodedQReg(int32_t RegNum) { | 216 |
| 256 assertRegisterDefined(RegNum); | 217 static inline bool isEncodedQReg(int32_t RegNum) { |
| 257 return Table[RegNum].IsVec128; | 218 assert(RegNum >= 0); |
| 258 } | 219 assert(RegNum < Reg_NUM); |
| 259 | 220 return RegTable[RegNum].IsVec128; |
| 260 static inline QRegister getEncodedQReg(int32_t RegNum) { | 221 } |
| 261 assert(isEncodedQReg(RegNum)); | 222 |
| 262 return QRegister(Table[RegNum].Encoding); | 223 static inline QRegister getEncodedQReg(int32_t RegNum) { |
| 263 } | 224 assert(isEncodedQReg(RegNum)); |
| 264 | 225 return QRegister(RegTable[RegNum].Encoding); |
| 265 static inline IceString getRegName(int32_t RegNum) { | 226 } |
| 266 assertRegisterDefined(RegNum); | 227 |
| 267 return Table[RegNum].Name; | 228 static inline IceString getRegName(int32_t RegNum) { |
| 268 } | 229 assert(RegNum >= 0); |
| 269 }; | 230 assert(RegNum < Reg_NUM); |
| 231 return RegTable[RegNum].Name; | |
| 232 } | |
| 270 | 233 |
| 271 // Extend enum RegClass with ARM32-specific register classes (if any). | 234 // Extend enum RegClass with ARM32-specific register classes (if any). |
| 272 enum RegClassARM32 : uint8_t { RCARM32_NUM = RC_Target }; | 235 enum RegClassARM32 : uint8_t { RCARM32_NUM = RC_Target }; |
| 273 | 236 |
| 237 } // end of namespace RegARM32 | |
| 274 } // end of namespace ARM32 | 238 } // end of namespace ARM32 |
| 275 } // end of namespace Ice | 239 } // end of namespace Ice |
| 276 | 240 |
| 277 #endif // SUBZERO_SRC_ICEREGISTERSARM32_H | 241 #endif // SUBZERO_SRC_ICEREGISTERSARM32_H |
| OLD | NEW |