 Chromium Code Reviews
 Chromium Code Reviews Issue 1419903002:
  Subzero: Refactor x86 register definitions to use the alias mechanism.  (Closed) 
  Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
    
  
    Issue 1419903002:
  Subzero: Refactor x86 register definitions to use the alias mechanism.  (Closed) 
  Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master| Index: src/IceTargetLoweringX8664Traits.h | 
| diff --git a/src/IceTargetLoweringX8664Traits.h b/src/IceTargetLoweringX8664Traits.h | 
| index 0ed40a862001da2e8bccc3239ea8a8f8adf5060f..716e2927e2b99412b0154a6ee55a16d909687228 100644 | 
| --- a/src/IceTargetLoweringX8664Traits.h | 
| +++ b/src/IceTargetLoweringX8664Traits.h | 
| @@ -61,7 +61,6 @@ template <> struct MachineTraits<TargetX8664> { | 
| using GPRRegister = ::Ice::RegX8664::GPRRegister; | 
| using XmmRegister = ::Ice::RegX8664::XmmRegister; | 
| - using ByteRegister = ::Ice::RegX8664::ByteRegister; | 
| using Cond = ::Ice::CondX8664; | 
| @@ -298,53 +297,108 @@ template <> struct MachineTraits<TargetX8664> { | 
| static const char *TargetName; | 
| static constexpr Type WordType = IceType_i64; | 
| - 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, | 
| + REGX8664_TABLE | 
| +#undef X | 
| + }; | 
| + assert(RegNum >= 0); | 
| assert(RegNum < RegisterSet::Reg_NUM); | 
| - static const struct { | 
| - const char *const Name8; | 
| - const char *const Name16; | 
| - const char *const Name /*32*/; | 
| - const char *const Name64; | 
| - } RegNames[] = { | 
| -#define X(val, encode, name64, name32, name16, name8, scratch, preserved, \ | 
| - stackptr, frameptr, isInt, isFP) \ | 
| - { name8, name16, name32, name64 } \ | 
| - , | 
| + 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), | 
| REGX8664_TABLE | 
| #undef X | 
| }; | 
| + assert(RegNum >= 0); | 
| + assert(RegNum < RegisterSet::Reg_NUM); | 
| + assert(GPRRegs[RegNum] != GPRRegister::Encoded_Not_GPR); | 
| + return GPRRegs[RegNum]; | 
| + } | 
| - switch (Ty) { | 
| - case IceType_i1: | 
| - case IceType_i8: | 
| - return RegNames[RegNum].Name8; | 
| - case IceType_i16: | 
| - return RegNames[RegNum].Name16; | 
| - case IceType_i64: | 
| - return RegNames[RegNum].Name64; | 
| - default: | 
| - return RegNames[RegNum].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), | 
| + REGX8664_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, | 
| + REGX8664_TABLE | 
| +#undef X | 
| + }; | 
| + assert(RegNum >= 0); | 
| + assert(RegNum < RegisterSet::Reg_NUM); | 
| + return Encoding[RegNum]; | 
| + } | 
| + | 
| + static inline 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, | 
| + REGX8664_TABLE | 
| +#undef X | 
| + }; | 
| + assert(RegNum >= 0); | 
| + assert(RegNum < RegisterSet::Reg_NUM); | 
| + return BaseRegs[RegNum]; | 
| + } | 
| + | 
| + static int32_t getGprForType(Type, int32_t RegNum) { 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 IntegerRegistersI64(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, name64, name32, name16, name8, scratch, preserved, \ | 
| - stackptr, frameptr, isInt, isFP) \ | 
| - (IntegerRegisters)[RegisterSet::val] = isInt; \ | 
| - (IntegerRegistersI8)[RegisterSet::val] = isInt; \ | 
| - (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) \ | 
| + (IntegerRegistersI64)[RegisterSet::val] = is64; \ | 
| + (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; | 
| REGX8664_TABLE; | 
| @@ -353,9 +407,9 @@ template <> struct MachineTraits<TargetX8664> { | 
| (*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] = IntegerRegistersI64; | 
| (*TypeToRegisterSet)[IceType_f32] = FloatRegisters; | 
| (*TypeToRegisterSet)[IceType_f64] = FloatRegisters; | 
| (*TypeToRegisterSet)[IceType_v4i1] = VectorRegisters; | 
| @@ -372,8 +426,9 @@ template <> struct MachineTraits<TargetX8664> { | 
| TargetLowering::RegSetMask Exclude) { | 
| llvm::SmallBitVector Registers(RegisterSet::Reg_NUM); | 
| -#define X(val, encode, name64, name32, name16, name8, scratch, preserved, \ | 
| - stackptr, frameptr, 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)) \ | 
| @@ -418,15 +473,17 @@ template <> struct MachineTraits<TargetX8664> { | 
| // 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, name64, name32, name16, name8, scratch, preserved, \ | 
| - stackptr, frameptr, 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=*/1 << 2) | (isInt << 3) | (isFP << 4); \ | 
| + const uint32_t Index = (scratch << 0) | (preserved << 1) | (is8 << 2) | \ | 
| 
Karl
2015/10/27 16:13:19
There appears to be patterns in these shifts (is8
 
Jim Stichnoth
2015/10/27 19:14:09
The purpose here was to combine the relevant attri
 | 
| + (is16 << 3) | (is32 << 4) | (is64 << 5) | \ | 
| + (isXmm << 6); \ | 
| /* val is assigned to an equivalence class based on its properties. */ \ | 
| EquivalenceClasses[Index].push_back(RegisterSet::val); \ | 
| } | 
| @@ -463,7 +520,7 @@ template <> struct MachineTraits<TargetX8664> { | 
| if (!First) | 
| Str << " "; | 
| First = false; | 
| - Str << getRegName(Register, IceType_i32); | 
| + Str << getRegName(Register); | 
| } | 
| Str << "}\n"; | 
| } |