Index: src/IceRegistersARM32.h |
diff --git a/src/IceRegistersARM32.h b/src/IceRegistersARM32.h |
index f43312192237f599a79ab5b11b5cf270ba85ff84..0caa9ccdf4e225ccfd0e40bcd6838c36bbb4011b 100644 |
--- a/src/IceRegistersARM32.h |
+++ b/src/IceRegistersARM32.h |
@@ -23,7 +23,39 @@ |
namespace Ice { |
namespace ARM32 { |
+/// SizeOf is used to obtain the size of an initializer list as a constexpr |
+/// expression. This is only needed until our C++ library is updated to |
+/// C++ 14 -- which defines constexpr members to std::initializer_list. |
+class SizeOf { |
+ SizeOf(const SizeOf &) = delete; |
+ SizeOf &operator=(const SizeOf &) = delete; |
+ |
+public: |
+ constexpr SizeOf() : Size(0) {} |
+ template <typename... T> |
+ explicit constexpr SizeOf(T...) |
+ : Size(__length<T...>::value) {} |
+ constexpr SizeT size() const { return Size; } |
+ |
+private: |
+ template <typename T, typename... U> struct __length { |
Jim Stichnoth
2016/01/06 19:41:41
I believe that identifiers containing adjacent und
|
+ static constexpr std::size_t value = 1 + __length<U...>::value; |
+ }; |
+ |
+ template <typename T> struct __length<T> { |
+ static constexpr std::size_t value = 1; |
+ }; |
+ |
+ const std::size_t Size; |
+}; |
+ |
class RegARM32 { |
+private: |
+ RegARM32() = delete; |
+ RegARM32(const RegARM32 &) = delete; |
+ RegARM32 &operator=(const RegARM32 &) = delete; |
+ ~RegARM32() = delete; |
+ |
public: |
/// An enum of every register. The enum value may not match the encoding used |
/// to binary encode register operands in instructions. |
@@ -83,30 +115,61 @@ public: |
Encoded_Not_QReg = -1 |
}; |
+ 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.
|
+ const char *Name; |
+ int32_t Encoding : 10; |
+ int32_t CCArg : 6; |
+ int32_t Scratch : 1; |
+ int32_t Preserved : 1; |
+ int32_t StackPtr : 1; |
+ int32_t FramePtr : 1; |
+ int32_t IsGPR : 1; |
+ int32_t IsInt : 1; |
+ int32_t IsI64Pair : 1; |
+ int32_t IsFP32 : 1; |
+ int32_t IsFP64 : 1; |
+ int32_t IsVec128 : 1; |
+#define NUM_ALIASES_BITS 3 |
+ SizeT NumAliases : (NUM_ALIASES_BITS + 1); |
+ uint16_t Aliases[1 << NUM_ALIASES_BITS]; |
+#undef NUM_ALIASES_BITS |
+ } Table[Reg_NUM] = { |
+#define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ |
+ isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ |
+ { \ |
+ name, encode, cc_arg, scratch, preserved, stackptr, frameptr, isGPR, \ |
+ isInt, isI64Pair, isFP32, isFP64, isVec128, \ |
+ (SizeOf alias_init).size(), alias_init \ |
+ } \ |
+ , |
+ REGARM32_TABLE |
+#undef X |
+ }; |
+ |
static inline GPRRegister getEncodedGPR(int32_t RegNum) { |
assert(Reg_GPR_First <= RegNum); |
assert(RegNum <= Reg_GPR_Last); |
- return GPRRegister(RegNum - Reg_GPR_First); |
+ return GPRRegister(Table[RegNum].Encoding); |
} |
static inline GPRRegister getI64PairFirstGPRNum(int32_t RegNum) { |
assert(Reg_I64PAIR_First <= RegNum); |
assert(RegNum <= Reg_I64PAIR_Last); |
- return GPRRegister(2 * (RegNum - Reg_I64PAIR_First + Reg_GPR_First)); |
+ return GPRRegister(Table[RegNum].Encoding); |
} |
static inline GPRRegister getI64PairSecondGPRNum(int32_t RegNum) { |
assert(Reg_I64PAIR_First <= RegNum); |
assert(RegNum <= Reg_I64PAIR_Last); |
- return GPRRegister(2 * (RegNum - Reg_I64PAIR_First + Reg_GPR_First) + 1); |
+ return GPRRegister(Table[RegNum].Encoding + 1); |
} |
static inline bool isI64RegisterPair(int32_t RegNum) { |
- return Reg_I64PAIR_First <= RegNum && RegNum <= Reg_I64PAIR_Last; |
+ return Table[RegNum].IsI64Pair; |
} |
static inline bool isEncodedSReg(int32_t RegNum) { |
- return Reg_SREG_First <= RegNum && RegNum <= Reg_SREG_Last; |
+ return Table[RegNum].IsFP32; |
} |
static inline SizeT getNumSRegs() { |
@@ -116,22 +179,25 @@ public: |
static inline SRegister getEncodedSReg(int32_t RegNum) { |
assert(Reg_SREG_First <= RegNum); |
assert(RegNum <= Reg_SREG_Last); |
- return SRegister(RegNum - Reg_SREG_First); |
+ return SRegister(Table[RegNum].Encoding); |
} |
static inline DRegister getEncodedDReg(int32_t RegNum) { |
assert(Reg_DREG_First <= RegNum); |
assert(RegNum <= Reg_DREG_Last); |
- return DRegister(RegNum - Reg_DREG_First); |
+ return DRegister(Table[RegNum].Encoding); |
} |
static inline QRegister getEncodedQReg(int32_t RegNum) { |
assert(Reg_QREG_First <= RegNum); |
assert(RegNum <= Reg_QREG_Last); |
- return QRegister(RegNum - Reg_QREG_First); |
+ return QRegister(Table[RegNum].Encoding); |
} |
- static const char *RegNames[]; |
+ static inline IceString getRegName(SizeT RegNum) { |
+ assert(RegNum < Reg_NUM); |
+ return Table[RegNum].Name; |
+ } |
}; |
// Extend enum RegClass with ARM32-specific register classes (if any). |