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 |
| 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 |