Index: src/IceTargetLoweringX8632Traits.h |
diff --git a/src/IceTargetLoweringX8632Traits.h b/src/IceTargetLoweringX8632Traits.h |
index 68725479f315be7548d93c74a67804bd4b313632..1c92bedae9c679635387dba03c6485e2df4bd156 100644 |
--- a/src/IceTargetLoweringX8632Traits.h |
+++ b/src/IceTargetLoweringX8632Traits.h |
@@ -60,8 +60,8 @@ template <> struct MachineTraits<TargetX8632> { |
enum ScaleFactor { TIMES_1 = 0, TIMES_2 = 1, TIMES_4 = 2, TIMES_8 = 3 }; |
using GPRRegister = ::Ice::RegX8632::GPRRegister; |
- using XmmRegister = ::Ice::RegX8632::XmmRegister; |
using ByteRegister = ::Ice::RegX8632::ByteRegister; |
+ using XmmRegister = ::Ice::RegX8632::XmmRegister; |
using X87STRegister = ::Ice::RegX8632::X87STRegister; |
using Cond = ::Ice::CondX86; |
@@ -267,60 +267,161 @@ template <> struct MachineTraits<TargetX8632> { |
static const char *TargetName; |
static constexpr Type WordType = IceType_i32; |
- static IceString getRegName(SizeT RegNum, Type Ty) { |
+ static IceString getRegName(int32_t RegNum) { |
+ static const char *const RegNames[] = { |
+#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
+ isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
+ isTrunc8Rcvr, isAhRcvr, aliases) \ |
+ name, |
+ REGX8632_TABLE |
+#undef X |
+ }; |
+ assert(RegNum >= 0); |
assert(RegNum < RegisterSet::Reg_NUM); |
- static const char *RegNames8[] = { |
-#define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \ |
- frameptr, isI8, isInt, isFP) \ |
- name8, |
+ return RegNames[RegNum]; |
+ } |
+ |
+ static GPRRegister getEncodedGPR(int32_t RegNum) { |
+ static const GPRRegister GPRRegs[] = { |
+#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
+ isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
+ isTrunc8Rcvr, isAhRcvr, aliases) \ |
+ GPRRegister(isGPR ? encode : GPRRegister::Encoded_Not_GPR), |
REGX8632_TABLE |
#undef X |
}; |
+ assert(RegNum >= 0); |
+ assert(RegNum < RegisterSet::Reg_NUM); |
+ assert(GPRRegs[RegNum] != GPRRegister::Encoded_Not_GPR); |
+ return GPRRegs[RegNum]; |
+ } |
- static const char *RegNames16[] = { |
-#define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \ |
- frameptr, isI8, isInt, isFP) \ |
- name16, |
+ static ByteRegister getEncodedByteReg(int32_t RegNum) { |
+ static const ByteRegister ByteRegs[] = { |
+#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
+ isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
+ isTrunc8Rcvr, isAhRcvr, aliases) \ |
+ ByteRegister(is8 ? encode : ByteRegister::Encoded_Not_ByteReg), |
REGX8632_TABLE |
#undef X |
}; |
+ assert(RegNum >= 0); |
+ assert(RegNum < RegisterSet::Reg_NUM); |
+ assert(ByteRegs[RegNum] != ByteRegister::Encoded_Not_ByteReg); |
+ return ByteRegs[RegNum]; |
+ } |
- static const char *RegNames[] = { |
-#define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \ |
- frameptr, isI8, isInt, isFP) \ |
- name, |
+ static XmmRegister getEncodedXmm(int32_t RegNum) { |
+ static const XmmRegister XmmRegs[] = { |
+#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
+ isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
+ isTrunc8Rcvr, isAhRcvr, aliases) \ |
+ XmmRegister(isXmm ? encode : XmmRegister::Encoded_Not_Xmm), |
+ REGX8632_TABLE |
+#undef X |
+ }; |
+ assert(RegNum >= 0); |
+ assert(RegNum < RegisterSet::Reg_NUM); |
+ assert(XmmRegs[RegNum] != XmmRegister::Encoded_Not_Xmm); |
+ return XmmRegs[RegNum]; |
+ } |
+ |
+ static uint32_t getEncoding(int32_t RegNum) { |
+ static const uint32_t Encoding[] = { |
+#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
+ isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
+ isTrunc8Rcvr, isAhRcvr, aliases) \ |
+ encode, |
REGX8632_TABLE |
#undef X |
}; |
+ assert(RegNum >= 0); |
+ assert(RegNum < RegisterSet::Reg_NUM); |
+ return Encoding[RegNum]; |
+ } |
- switch (Ty) { |
- case IceType_i1: |
- case IceType_i8: |
- return RegNames8[RegNum]; |
- case IceType_i16: |
- return RegNames16[RegNum]; |
- default: |
- return RegNames[RegNum]; |
+ static int32_t getBaseReg(int32_t RegNum) { |
+ static const int32_t BaseRegs[] = { |
+#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
+ isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
+ isTrunc8Rcvr, isAhRcvr, aliases) \ |
+ RegisterSet::base, |
+ REGX8632_TABLE |
+#undef X |
+ }; |
+ assert(RegNum >= 0); |
+ assert(RegNum < RegisterSet::Reg_NUM); |
+ return BaseRegs[RegNum]; |
+ } |
+ |
+ // Return a register in RegNum's alias set that is suitable for Ty. |
+ static int32_t getGprForType(Type Ty, int32_t RegNum) { |
+ assert(RegNum != Variable::NoRegister); |
+ // TODO(stichnot): Rewrite this as a table lookup from a table computed in a |
+ // TargetLowering static initializer. |
+ RegNum = getBaseReg(RegNum); |
+ if (Ty == IceType_i8 || Ty == IceType_i1) { |
+ switch (RegNum) { |
+ default: |
+ assert(0); |
+ case RegisterSet::Reg_eax: |
+ return RegisterSet::Reg_al; |
+ case RegisterSet::Reg_ecx: |
+ return RegisterSet::Reg_cl; |
+ case RegisterSet::Reg_edx: |
+ return RegisterSet::Reg_dl; |
+ case RegisterSet::Reg_ebx: |
+ return RegisterSet::Reg_bl; |
+ } |
+ } |
+ if (Ty == IceType_i16) { |
+ switch (RegNum) { |
+ default: |
+ assert(0); |
+ case RegisterSet::Reg_eax: |
+ return RegisterSet::Reg_ax; |
+ case RegisterSet::Reg_ecx: |
+ return RegisterSet::Reg_cx; |
+ case RegisterSet::Reg_edx: |
+ return RegisterSet::Reg_dx; |
+ case RegisterSet::Reg_ebx: |
+ return RegisterSet::Reg_bx; |
+ case RegisterSet::Reg_ebp: |
+ return RegisterSet::Reg_bp; |
+ case RegisterSet::Reg_esi: |
+ return RegisterSet::Reg_si; |
+ case RegisterSet::Reg_edi: |
+ return RegisterSet::Reg_di; |
+ } |
} |
+ return RegNum; |
} |
static void initRegisterSet( |
std::array<llvm::SmallBitVector, IceType_NUM> *TypeToRegisterSet, |
std::array<llvm::SmallBitVector, RegisterSet::Reg_NUM> *RegisterAliases, |
llvm::SmallBitVector *ScratchRegs) { |
- llvm::SmallBitVector IntegerRegisters(RegisterSet::Reg_NUM); |
+ llvm::SmallBitVector IntegerRegistersI32(RegisterSet::Reg_NUM); |
+ llvm::SmallBitVector IntegerRegistersI16(RegisterSet::Reg_NUM); |
llvm::SmallBitVector IntegerRegistersI8(RegisterSet::Reg_NUM); |
llvm::SmallBitVector FloatRegisters(RegisterSet::Reg_NUM); |
llvm::SmallBitVector VectorRegisters(RegisterSet::Reg_NUM); |
llvm::SmallBitVector InvalidRegisters(RegisterSet::Reg_NUM); |
ScratchRegs->resize(RegisterSet::Reg_NUM); |
-#define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \ |
- frameptr, isI8, isInt, isFP) \ |
- (IntegerRegisters)[RegisterSet::val] = isInt; \ |
- (IntegerRegistersI8)[RegisterSet::val] = isI8; \ |
- (FloatRegisters)[RegisterSet::val] = isFP; \ |
- (VectorRegisters)[RegisterSet::val] = isFP; \ |
+#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
+ isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
+ isTrunc8Rcvr, isAhRcvr, aliases) \ |
+ (IntegerRegistersI32)[RegisterSet::val] = is32; \ |
+ (IntegerRegistersI16)[RegisterSet::val] = is16; \ |
+ (IntegerRegistersI8)[RegisterSet::val] = is8; \ |
+ (FloatRegisters)[RegisterSet::val] = isXmm; \ |
+ (VectorRegisters)[RegisterSet::val] = isXmm; \ |
(*RegisterAliases)[RegisterSet::val].resize(RegisterSet::Reg_NUM); \ |
+ for (SizeT RegAlias : aliases) { \ |
+ assert(!(*RegisterAliases)[RegisterSet::val][RegAlias] && \ |
+ "Duplicate alias for " #val); \ |
+ (*RegisterAliases)[RegisterSet::val].set(RegAlias); \ |
+ } \ |
(*RegisterAliases)[RegisterSet::val].set(RegisterSet::val); \ |
(*ScratchRegs)[RegisterSet::val] = scratch; |
REGX8632_TABLE; |
@@ -329,9 +430,9 @@ template <> struct MachineTraits<TargetX8632> { |
(*TypeToRegisterSet)[IceType_void] = InvalidRegisters; |
(*TypeToRegisterSet)[IceType_i1] = IntegerRegistersI8; |
(*TypeToRegisterSet)[IceType_i8] = IntegerRegistersI8; |
- (*TypeToRegisterSet)[IceType_i16] = IntegerRegisters; |
- (*TypeToRegisterSet)[IceType_i32] = IntegerRegisters; |
- (*TypeToRegisterSet)[IceType_i64] = IntegerRegisters; |
+ (*TypeToRegisterSet)[IceType_i16] = IntegerRegistersI16; |
+ (*TypeToRegisterSet)[IceType_i32] = IntegerRegistersI32; |
+ (*TypeToRegisterSet)[IceType_i64] = IntegerRegistersI32; |
(*TypeToRegisterSet)[IceType_f32] = FloatRegisters; |
(*TypeToRegisterSet)[IceType_f64] = FloatRegisters; |
(*TypeToRegisterSet)[IceType_v4i1] = VectorRegisters; |
@@ -348,8 +449,9 @@ template <> struct MachineTraits<TargetX8632> { |
TargetLowering::RegSetMask Exclude) { |
llvm::SmallBitVector Registers(RegisterSet::Reg_NUM); |
-#define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \ |
- frameptr, isI8, isInt, isFP) \ |
+#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
+ isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
+ isTrunc8Rcvr, isAhRcvr, aliases) \ |
if (scratch && (Include & ::Ice::TargetLowering::RegSet_CallerSave)) \ |
Registers[RegisterSet::val] = true; \ |
if (preserved && (Include & ::Ice::TargetLowering::RegSet_CalleeSave)) \ |
@@ -394,15 +496,23 @@ template <> struct MachineTraits<TargetX8632> { |
// Build up the equivalence classes of registers by looking at the register |
// properties as well as whether the registers should be explicitly excluded |
// from shuffling. |
-#define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \ |
- frameptr, isI8, isInt, isFP) \ |
+#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
+ isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
+ isTrunc8Rcvr, isAhRcvr, aliases) \ |
if (ExcludeRegisters[RegisterSet::val]) { \ |
/* val stays the same in the resulting permutation. */ \ |
Permutation[RegisterSet::val] = RegisterSet::val; \ |
++NumPreserved; \ |
} else { \ |
- const uint32_t Index = (scratch << 0) | (preserved << 1) | (isI8 << 2) | \ |
- (isInt << 3) | (isFP << 4); \ |
+ uint32_t AttrKey = 0; \ |
+ uint32_t Index = 0; \ |
+ /* Combine relevant attributes into an equivalence class key. */ \ |
+ Index |= (scratch << (AttrKey++)); \ |
+ Index |= (preserved << (AttrKey++)); \ |
+ Index |= (is8 << (AttrKey++)); \ |
+ Index |= (is16 << (AttrKey++)); \ |
+ Index |= (is32 << (AttrKey++)); \ |
+ Index |= (isXmm << (AttrKey++)); \ |
/* val is assigned to an equivalence class based on its properties. */ \ |
EquivalenceClasses[Index].push_back(RegisterSet::val); \ |
} |
@@ -439,7 +549,7 @@ template <> struct MachineTraits<TargetX8632> { |
if (!First) |
Str << " "; |
First = false; |
- Str << getRegName(Register, IceType_i32); |
+ Str << getRegName(Register); |
} |
Str << "}\n"; |
} |