Lift register and condition code enums out into their own file.

Lift the enums out of IceInstX8632.h and IceTargetLoweringX8632.h.
This will later allow the assembler to share the enum values and
use them as encodings where appropriate. E.g., to avoid having a separate
enum in:
https://codereview.chromium.org/476323004/diff/680001/src/assembler_constants_ia32.h

The "all registers" enum is retained, but separate GPRRegister and
XmmRegister enums are created with tags "Encoded_Reg_foo" to represent
the encoded value of register "foo". Functions are added to convert
from the "all registers" namespace to the encoded ones.

Re-order the BrCond so that they match the encoding according to
the "Instruction Subcode" in B.1 of the Intel Manuals.

BUG=none
R=stichnot@chromium.org

Review URL: https://codereview.chromium.org/582113003
diff --git a/src/IceConditionCodesX8632.h b/src/IceConditionCodesX8632.h
new file mode 100644
index 0000000..a930bf8
--- /dev/null
+++ b/src/IceConditionCodesX8632.h
@@ -0,0 +1,46 @@
+//===- subzero/src/IceConditionCodesX8632.h - Condition Codes ---*- C++ -*-===//
+//
+//                        The Subzero Code Generator
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the condition codes for x86-32.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SUBZERO_SRC_ICECONDITIONCODESX8632_H
+#define SUBZERO_SRC_ICECONDITIONCODESX8632_H
+
+#include "IceDefs.h"
+#include "IceInstX8632.def"
+
+namespace Ice {
+
+class CondX86 {
+public:
+  // An enum of condition codes used for branches and cmov. The enum value
+  // should match the value used to encode operands in binary instructions.
+  enum BrCond {
+#define X(tag, encode, opp, dump, emit) tag encode,
+    ICEINSTX8632BR_TABLE
+#undef X
+        Br_None
+  };
+
+  // An enum of condition codes relevant to the CMPPS instruction. The enum
+  // value should match the value used to encode operands in binary
+  // instructions.
+  enum CmppsCond {
+#define X(tag, emit) tag,
+    ICEINSTX8632CMPPS_TABLE
+#undef X
+        Cmpps_Invalid
+  };
+};
+
+} // end of namespace Ice
+
+#endif // SUBZERO_SRC_ICECONDITIONCODESX8632_H
diff --git a/src/IceInstX8632.cpp b/src/IceInstX8632.cpp
index df28696..305be73 100644
--- a/src/IceInstX8632.cpp
+++ b/src/IceInstX8632.cpp
@@ -14,8 +14,10 @@
 
 #include "IceCfg.h"
 #include "IceCfgNode.h"
+#include "IceConditionCodesX8632.h"
 #include "IceInst.h"
 #include "IceInstX8632.h"
+#include "IceRegistersX8632.h"
 #include "IceTargetLoweringX8632.h"
 #include "IceOperand.h"
 
@@ -24,12 +26,12 @@
 namespace {
 
 const struct InstX8632BrAttributes_ {
-  InstX8632::BrCond Opposite;
+  CondX86::BrCond Opposite;
   const char *DisplayString;
   const char *EmitString;
 } InstX8632BrAttributes[] = {
-#define X(tag, opp, dump, emit)                                                \
-  { InstX8632::opp, dump, emit }                                               \
+#define X(tag, encode, opp, dump, emit)                                        \
+  { CondX86::opp, dump, emit }                                                 \
   ,
     ICEINSTX8632BR_TABLE
 #undef X
@@ -131,8 +133,7 @@
 
 InstX8632Br::InstX8632Br(Cfg *Func, const CfgNode *TargetTrue,
                          const CfgNode *TargetFalse,
-                         const InstX8632Label *Label,
-                         InstX8632::BrCond Condition)
+                         const InstX8632Label *Label, CondX86::BrCond Condition)
     : InstX8632(Func, InstX8632::Br, 0, NULL), Condition(Condition),
       TargetTrue(TargetTrue), TargetFalse(TargetFalse), Label(Label) {}
 
@@ -151,7 +152,7 @@
     return false;
 
   // Unconditional branch to the next node can be removed.
-  if (Condition == Br_None && getTargetFalse() == NextNode) {
+  if (Condition == CondX86::Br_None && getTargetFalse() == NextNode) {
     assert(getTargetTrue() == NULL);
     setDeleted();
     return true;
@@ -166,7 +167,7 @@
   // (which was already tested above), then invert the branch
   // condition, swap the targets, and set new fallthrough to NULL.
   if (getTargetTrue() == NextNode) {
-    assert(Condition != Br_None);
+    assert(Condition != CondX86::Br_None);
     Condition = InstX8632BrAttributes[Condition].Opposite;
     TargetTrue = getTargetFalse();
     TargetFalse = NULL;
@@ -182,7 +183,7 @@
 }
 
 InstX8632Cmov::InstX8632Cmov(Cfg *Func, Variable *Dest, Operand *Source,
-                             InstX8632::BrCond Condition)
+                             CondX86::BrCond Condition)
     : InstX8632(Func, InstX8632::Cmov, 2, Dest), Condition(Condition) {
   // The final result is either the original Dest, or Source, so mark
   // both as sources.
@@ -191,7 +192,7 @@
 }
 
 InstX8632Cmpps::InstX8632Cmpps(Cfg *Func, Variable *Dest, Operand *Source,
-                               InstX8632Cmpps::CmppsCond Condition)
+                               CondX86::CmppsCond Condition)
     : InstX8632(Func, InstX8632::Cmpps, 2, Dest), Condition(Condition) {
   addSource(Dest);
   addSource(Source);
@@ -202,7 +203,7 @@
                                    bool Locked)
     : InstX8632Lockable(Func, InstX8632::Cmpxchg, 3,
                         llvm::dyn_cast<Variable>(DestOrAddr), Locked) {
-  assert(Eax->getRegNum() == TargetX8632::Reg_eax);
+  assert(Eax->getRegNum() == RegX8632::Reg_eax);
   addSource(DestOrAddr);
   addSource(Eax);
   addSource(Desired);
@@ -213,10 +214,10 @@
                                        Variable *Ecx, Variable *Ebx,
                                        bool Locked)
     : InstX8632Lockable(Func, InstX8632::Cmpxchg, 5, NULL, Locked) {
-  assert(Edx->getRegNum() == TargetX8632::Reg_edx);
-  assert(Eax->getRegNum() == TargetX8632::Reg_eax);
-  assert(Ecx->getRegNum() == TargetX8632::Reg_ecx);
-  assert(Ebx->getRegNum() == TargetX8632::Reg_ebx);
+  assert(Edx->getRegNum() == RegX8632::Reg_edx);
+  assert(Eax->getRegNum() == RegX8632::Reg_eax);
+  assert(Ecx->getRegNum() == RegX8632::Reg_ecx);
+  assert(Ebx->getRegNum() == RegX8632::Reg_ebx);
   addSource(Addr);
   addSource(Edx);
   addSource(Eax);
@@ -347,7 +348,7 @@
   Ostream &Str = Func->getContext()->getStrEmit();
   Str << "\t";
 
-  if (Condition == Br_None) {
+  if (Condition == CondX86::Br_None) {
     Str << "jmp";
   } else {
     Str << InstX8632BrAttributes[Condition].EmitString;
@@ -356,7 +357,7 @@
   if (Label) {
     Str << "\t" << Label->getName(Func) << "\n";
   } else {
-    if (Condition == Br_None) {
+    if (Condition == CondX86::Br_None) {
       Str << "\t" << getTargetFalse()->getAsmName() << "\n";
     } else {
       Str << "\t" << getTargetTrue()->getAsmName() << "\n";
@@ -371,7 +372,7 @@
   Ostream &Str = Func->getContext()->getStrDump();
   Str << "br ";
 
-  if (Condition == Br_None) {
+  if (Condition == CondX86::Br_None) {
     Str << "label %"
         << (Label ? Label->getName(Func) : getTargetFalse()->getName());
     return;
@@ -422,7 +423,7 @@
   bool EmittedSrc1 = false;
   if (ShiftHack) {
     Variable *ShiftReg = llvm::dyn_cast<Variable>(Inst->getSrc(1));
-    if (ShiftReg && ShiftReg->getRegNum() == TargetX8632::Reg_ecx) {
+    if (ShiftReg && ShiftReg->getRegNum() == RegX8632::Reg_ecx) {
       Str << "cl";
       EmittedSrc1 = true;
     }
@@ -611,7 +612,7 @@
   assert(Inst->getSrcSize() == 3);
   assert(llvm::isa<Variable>(Inst->getSrc(2)));
   assert(llvm::cast<Variable>(Inst->getSrc(2))->getRegNum() ==
-         TargetX8632::Reg_xmm0);
+         RegX8632::Reg_xmm0);
   Str << "\t" << Opcode << "\t";
   Inst->getDest()->emit(Func);
   Str << ", ";
@@ -640,7 +641,7 @@
     // The 8-bit version of imul only allows the form "imul r/m8".
     Variable *Src0 = llvm::dyn_cast<Variable>(getSrc(0));
     (void)Src0;
-    assert(Src0 && Src0->getRegNum() == TargetX8632::Reg_eax);
+    assert(Src0 && Src0->getRegNum() == RegX8632::Reg_eax);
     Str << "\timul\t";
     getSrc(1)->emit(Func);
     Str << "\n";
@@ -662,21 +663,21 @@
   assert(getSrcSize() == 1);
   Operand *Src0 = getSrc(0);
   assert(llvm::isa<Variable>(Src0));
-  assert(llvm::cast<Variable>(Src0)->getRegNum() == TargetX8632::Reg_eax);
+  assert(llvm::cast<Variable>(Src0)->getRegNum() == RegX8632::Reg_eax);
   switch (Src0->getType()) {
   default:
     llvm_unreachable("unexpected source type!");
     break;
   case IceType_i8:
-    assert(getDest()->getRegNum() == TargetX8632::Reg_eax);
+    assert(getDest()->getRegNum() == RegX8632::Reg_eax);
     Str << "\tcbw\n";
     break;
   case IceType_i16:
-    assert(getDest()->getRegNum() == TargetX8632::Reg_edx);
+    assert(getDest()->getRegNum() == RegX8632::Reg_edx);
     Str << "\tcwd\n";
     break;
   case IceType_i32:
-    assert(getDest()->getRegNum() == TargetX8632::Reg_edx);
+    assert(getDest()->getRegNum() == RegX8632::Reg_edx);
     Str << "\tcdq\n";
     break;
   }
@@ -686,9 +687,8 @@
   Ostream &Str = Func->getContext()->getStrEmit();
   assert(getSrcSize() == 2);
   assert(llvm::isa<Variable>(getSrc(0)));
-  assert(llvm::dyn_cast<Variable>(getSrc(0))->getRegNum() ==
-         TargetX8632::Reg_eax);
-  assert(getDest()->getRegNum() == TargetX8632::Reg_eax); // TODO: allow edx?
+  assert(llvm::dyn_cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax);
+  assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx?
   Str << "\tmul\t";
   getSrc(1)->emit(Func);
   Str << "\n";
@@ -712,7 +712,7 @@
   Str << ", ";
   if (Variable *ShiftReg = llvm::dyn_cast<Variable>(getSrc(2))) {
     (void)ShiftReg;
-    assert(ShiftReg->getRegNum() == TargetX8632::Reg_ecx);
+    assert(ShiftReg->getRegNum() == RegX8632::Reg_ecx);
     Str << "cl";
   } else {
     getSrc(2)->emit(Func);
@@ -738,7 +738,7 @@
   Str << ", ";
   if (Variable *ShiftReg = llvm::dyn_cast<Variable>(getSrc(2))) {
     (void)ShiftReg;
-    assert(ShiftReg->getRegNum() == TargetX8632::Reg_ecx);
+    assert(ShiftReg->getRegNum() == RegX8632::Reg_ecx);
     Str << "cl";
   } else {
     getSrc(2)->emit(Func);
@@ -756,7 +756,7 @@
 void InstX8632Cmov::emit(const Cfg *Func) const {
   Ostream &Str = Func->getContext()->getStrEmit();
   Str << "\t";
-  assert(Condition != Br_None);
+  assert(Condition != CondX86::Br_None);
   assert(getDest()->hasReg());
   Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << "\t";
   getDest()->emit(Func);
@@ -777,7 +777,7 @@
 void InstX8632Cmpps::emit(const Cfg *Func) const {
   Ostream &Str = Func->getContext()->getStrEmit();
   assert(getSrcSize() == 2);
-  assert(Condition < Cmpps_Invalid);
+  assert(Condition < CondX86::Cmpps_Invalid);
   Str << "\t";
   Str << "cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps"
       << "\t";
@@ -789,7 +789,7 @@
 
 void InstX8632Cmpps::dump(const Cfg *Func) const {
   Ostream &Str = Func->getContext()->getStrDump();
-  assert(Condition < Cmpps_Invalid);
+  assert(Condition < CondX86::Cmpps_Invalid);
   dumpDest(Func);
   Str << " = cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps"
       << "\t";
diff --git a/src/IceInstX8632.def b/src/IceInstX8632.def
index 16c6fb8..e8ba59a 100644
--- a/src/IceInstX8632.def
+++ b/src/IceInstX8632.def
@@ -16,8 +16,8 @@
 #define SUBZERO_SRC_ICEINSTX8632_DEF
 
 // NOTE: esp is not considered isInt, to avoid register allocating it.
-#define REGX8632_TABLE                                                  \
-  /* val, init, name, name16, name8, scratch, preserved, stackptr,      \
+#define REGX8632_GPR_TABLE                                              \
+  /* val, encode, name, name16, name8, scratch, preserved, stackptr,    \
      frameptr, isI8, isInt, isFP */                                     \
   X(Reg_eax, = 0,             "eax",  "ax", "al", 1, 0, 0, 0, 1, 1, 0)  \
   X(Reg_ecx, = Reg_eax + 1,   "ecx",  "cx", "cl", 1, 0, 0, 0, 1, 1, 0)  \
@@ -26,9 +26,10 @@
   X(Reg_esp, = Reg_eax + 4,   "esp",  "sp", ""  , 0, 0, 1, 0, 0, 0, 0)  \
   X(Reg_ebp, = Reg_eax + 5,   "ebp",  "bp", ""  , 0, 1, 0, 1, 0, 1, 0)  \
   X(Reg_esi, = Reg_eax + 6,   "esi",  "si", ""  , 0, 1, 0, 0, 0, 1, 0)  \
-  X(Reg_edi, = Reg_eax + 7,   "edi",  "di", ""  , 0, 1, 0, 0, 0, 1, 0)  \
-  X(Reg_ah,  = Reg_edi + 1,   "???",  ""  , "ah", 0, 0, 0, 0, 1, 0, 0)  \
-  X(Reg_xmm0, = Reg_ah + 1,   "xmm0", ""  , ""  , 1, 0, 0, 0, 0, 0, 1)  \
+  X(Reg_edi, = Reg_eax + 7,   "edi",  "di", ""  , 0, 1, 0, 0, 0, 1, 0)
+
+#define REGX8632_XMM_TABLE                                              \
+  X(Reg_xmm0, = 0,            "xmm0", ""  , ""  , 1, 0, 0, 0, 0, 0, 1)  \
   X(Reg_xmm1, = Reg_xmm0 + 1, "xmm1", ""  , ""  , 1, 0, 0, 0, 0, 0, 1)  \
   X(Reg_xmm2, = Reg_xmm0 + 2, "xmm2", ""  , ""  , 1, 0, 0, 0, 0, 0, 1)  \
   X(Reg_xmm3, = Reg_xmm0 + 3, "xmm3", ""  , ""  , 1, 0, 0, 0, 0, 0, 1)  \
@@ -36,9 +37,41 @@
   X(Reg_xmm5, = Reg_xmm0 + 5, "xmm5", ""  , ""  , 1, 0, 0, 0, 0, 0, 1)  \
   X(Reg_xmm6, = Reg_xmm0 + 6, "xmm6", ""  , ""  , 1, 0, 0, 0, 0, 0, 1)  \
   X(Reg_xmm7, = Reg_xmm0 + 7, "xmm7", ""  , ""  , 1, 0, 0, 0, 0, 0, 1)  \
-//#define X(val, init, name, name16, name8, scratch, preserved, stackptr,
+//#define X(val, encode, name, name16, name8, scratch, preserved, stackptr,
 //          frameptr, isI8, isInt, isFP)
 
+// We also provide a combined table, so that there is a namespace where
+// all of the registers are considered and have distinct numberings.
+// This is in contrast to the above, where the "encode" is based on how
+// the register numbers will be encoded in binaries and values can overlap.
+#define REGX8632_TABLE                                                  \
+  /* val, encode, name, name16, name8, scratch, preserved, stackptr,    \
+     frameptr, isI8, isInt, isFP */                                     \
+  REGX8632_GPR_TABLE                                                    \
+  X(Reg_ah,  = Reg_eax + 4,   "???",  ""  , "ah", 0, 0, 0, 0, 1, 0, 0)  \
+  REGX8632_XMM_TABLE
+//#define X(val, encode, name, name16, name8, scratch, preserved, stackptr,
+//          frameptr, isI8, isInt, isFP)
+
+#define REGX8632_TABLE_BOUNDS                                           \
+  /* val, init */                                                       \
+  X(Reg_GPR_First, = Reg_eax)                                           \
+  X(Reg_GPR_Last,  = Reg_edi)                                           \
+  X(Reg_XMM_First, = Reg_xmm0)                                          \
+  X(Reg_XMM_Last,  = Reg_xmm7)                                          \
+//define X(val, init)
+
+// We also need the encodings for the Byte registers (other info overlaps
+// what is in the REGX8632_GPR_TABLE).
+#define REGX8632_BYTEREG_TABLE                                          \
+  /* val, encode */                                                     \
+  X(Reg_al, = 0) \
+  X(Reg_cl, = 1) \
+  X(Reg_dl, = 2) \
+  X(Reg_bl, = 3) \
+  X(Reg_ah, = 4)
+//#define X(val, encode)
+
 // X86 segment registers.
 #define SEG_REGX8632_TABLE  \
   /* enum value, name */    \
@@ -51,20 +84,24 @@
 //#define X(val, name)
 
 #define ICEINSTX8632BR_TABLE   \
-  /* enum value, opposite, dump, emit */ \
-  X(Br_a,        Br_be,    "a",  "ja")                \
-  X(Br_ae,       Br_b,     "ae", "jae")               \
-  X(Br_b,        Br_ae,    "b",  "jb")                \
-  X(Br_be,       Br_a,     "be", "jbe")               \
-  X(Br_e,        Br_ne,    "e",  "je")                \
-  X(Br_g,        Br_le,    "g",  "jg")                \
-  X(Br_ge,       Br_l,     "ge", "jge")               \
-  X(Br_l,        Br_ge,    "l",  "jl")                \
-  X(Br_le,       Br_g,     "le", "jle")               \
-  X(Br_ne,       Br_e,     "ne", "jne")               \
-  X(Br_np,       Br_p,     "np", "jnp")               \
-  X(Br_p,        Br_np,    "p",  "jp")                \
-//#define X(tag, opp, dump, emit)
+  /* enum value, encode, opposite, dump, emit */ \
+  X(Br_o,  = 0,       Br_no,    "o",  "jo")                \
+  X(Br_no, = 1,       Br_o,     "no", "jno")               \
+  X(Br_b,  = 2,       Br_ae,    "b",  "jb")                \
+  X(Br_ae, = 3,       Br_b,     "ae", "jae")               \
+  X(Br_e,  = 4,       Br_ne,    "e",  "je")                \
+  X(Br_ne, = 5,       Br_e,     "ne", "jne")               \
+  X(Br_be, = 6,       Br_a,     "be", "jbe")               \
+  X(Br_a,  = 7,       Br_be,    "a",  "ja")                \
+  X(Br_s,  = 8,       Br_ns,    "s",  "js")                \
+  X(Br_ns, = 9,       Br_s,     "ns", "jns")               \
+  X(Br_p,  = 10,      Br_np,    "p",  "jp")                \
+  X(Br_np, = 11,      Br_p,     "np", "jnp")               \
+  X(Br_l,  = 12,      Br_ge,    "l",  "jl")                \
+  X(Br_ge, = 13,      Br_l,     "ge", "jge")               \
+  X(Br_le, = 14,      Br_g,     "le", "jle")               \
+  X(Br_g,  = 15,      Br_le,    "g",  "jg")                \
+//#define X(tag, encode, opp, dump, emit)
 
 #define ICEINSTX8632CMPPS_TABLE \
   /* enum value, emit */        \
diff --git a/src/IceInstX8632.h b/src/IceInstX8632.h
index 09615ce..a24f986 100644
--- a/src/IceInstX8632.h
+++ b/src/IceInstX8632.h
@@ -18,6 +18,7 @@
 
 #include "IceDefs.h"
 #include "IceInst.h"
+#include "IceConditionCodesX8632.h"
 #include "IceInstX8632.def"
 #include "IceOperand.h"
 
@@ -224,13 +225,6 @@
     Xor
   };
 
-  enum BrCond {
-#define X(tag, opp, dump, emit) tag,
-    ICEINSTX8632BR_TABLE
-#undef X
-        Br_None
-  };
-
   static const char *getWidthString(Type Ty);
   virtual void emit(const Cfg *Func) const = 0;
   virtual void dump(const Cfg *Func) const;
@@ -308,7 +302,7 @@
 public:
   // Create a conditional branch to a node.
   static InstX8632Br *create(Cfg *Func, CfgNode *TargetTrue,
-                             CfgNode *TargetFalse, BrCond Condition) {
+                             CfgNode *TargetFalse, CondX86::BrCond Condition) {
     const InstX8632Label *NoLabel = NULL;
     return new (Func->allocate<InstX8632Br>())
         InstX8632Br(Func, TargetTrue, TargetFalse, NoLabel, Condition);
@@ -318,12 +312,13 @@
     const CfgNode *NoCondTarget = NULL;
     const InstX8632Label *NoLabel = NULL;
     return new (Func->allocate<InstX8632Br>())
-        InstX8632Br(Func, NoCondTarget, Target, NoLabel, Br_None);
+        InstX8632Br(Func, NoCondTarget, Target, NoLabel, CondX86::Br_None);
   }
   // Create a non-terminator conditional branch to a node, with a
   // fallthrough to the next instruction in the current node.  This is
   // used for switch lowering.
-  static InstX8632Br *create(Cfg *Func, CfgNode *Target, BrCond Condition) {
+  static InstX8632Br *create(Cfg *Func, CfgNode *Target,
+                             CondX86::BrCond Condition) {
     const CfgNode *NoUncondTarget = NULL;
     const InstX8632Label *NoLabel = NULL;
     return new (Func->allocate<InstX8632Br>())
@@ -332,7 +327,7 @@
   // Create a conditional intra-block branch (or unconditional, if
   // Condition==Br_None) to a label in the current block.
   static InstX8632Br *create(Cfg *Func, InstX8632Label *Label,
-                             BrCond Condition) {
+                             CondX86::BrCond Condition) {
     const CfgNode *NoCondTarget = NULL;
     const CfgNode *NoUncondTarget = NULL;
     return new (Func->allocate<InstX8632Br>())
@@ -357,11 +352,11 @@
 
 private:
   InstX8632Br(Cfg *Func, const CfgNode *TargetTrue, const CfgNode *TargetFalse,
-              const InstX8632Label *Label, BrCond Condition);
+              const InstX8632Label *Label, CondX86::BrCond Condition);
   InstX8632Br(const InstX8632Br &) LLVM_DELETED_FUNCTION;
   InstX8632Br &operator=(const InstX8632Br &) LLVM_DELETED_FUNCTION;
   virtual ~InstX8632Br() {}
-  BrCond Condition;
+  CondX86::BrCond Condition;
   const CfgNode *TargetTrue;
   const CfgNode *TargetFalse;
   const InstX8632Label *Label; // Intra-block branch target
@@ -780,7 +775,7 @@
 class InstX8632Cmov : public InstX8632 {
 public:
   static InstX8632Cmov *create(Cfg *Func, Variable *Dest, Operand *Source,
-                               BrCond Cond) {
+                               CondX86::BrCond Cond) {
     return new (Func->allocate<InstX8632Cmov>())
         InstX8632Cmov(Func, Dest, Source, Cond);
   }
@@ -789,27 +784,21 @@
   static bool classof(const Inst *Inst) { return isClassof(Inst, Cmov); }
 
 private:
-  InstX8632Cmov(Cfg *Func, Variable *Dest, Operand *Source, BrCond Cond);
+  InstX8632Cmov(Cfg *Func, Variable *Dest, Operand *Source,
+                CondX86::BrCond Cond);
   InstX8632Cmov(const InstX8632Cmov &) LLVM_DELETED_FUNCTION;
   InstX8632Cmov &operator=(const InstX8632Cmov &) LLVM_DELETED_FUNCTION;
   virtual ~InstX8632Cmov() {}
 
-  BrCond Condition;
+  CondX86::BrCond Condition;
 };
 
 // Cmpps instruction - compare packed singled-precision floating point
 // values
 class InstX8632Cmpps : public InstX8632 {
 public:
-  enum CmppsCond {
-#define X(tag, emit) tag,
-    ICEINSTX8632CMPPS_TABLE
-#undef X
-    Cmpps_Invalid
-  };
-
   static InstX8632Cmpps *create(Cfg *Func, Variable *Dest, Operand *Source,
-                                CmppsCond Condition) {
+                                CondX86::CmppsCond Condition) {
     return new (Func->allocate<InstX8632Cmpps>())
         InstX8632Cmpps(Func, Dest, Source, Condition);
   }
@@ -818,12 +807,13 @@
   static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpps); }
 
 private:
-  InstX8632Cmpps(Cfg *Func, Variable *Dest, Operand *Source, CmppsCond Cond);
+  InstX8632Cmpps(Cfg *Func, Variable *Dest, Operand *Source,
+                 CondX86::CmppsCond Cond);
   InstX8632Cmpps(const InstX8632Cmpps &) LLVM_DELETED_FUNCTION;
   InstX8632Cmpps &operator=(const InstX8632Cmpps &) LLVM_DELETED_FUNCTION;
   virtual ~InstX8632Cmpps() {}
 
-  CmppsCond Condition;
+  CondX86::CmppsCond Condition;
 };
 
 // Cmpxchg instruction - cmpxchg <dest>, <desired> will compare if <dest>
diff --git a/src/IceRegistersX8632.h b/src/IceRegistersX8632.h
new file mode 100644
index 0000000..effbf36
--- /dev/null
+++ b/src/IceRegistersX8632.h
@@ -0,0 +1,86 @@
+//===- subzero/src/IceRegistersX8632.h - Register information ---*- C++ -*-===//
+//
+//                        The Subzero Code Generator
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the registers and their encodings for x86-32.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SUBZERO_SRC_ICEREGISTERSX8632_H
+#define SUBZERO_SRC_ICEREGISTERSX8632_H
+
+#include "IceDefs.h"
+#include "IceInstX8632.def"
+
+namespace Ice {
+
+class RegX8632 {
+public:
+  // An enum of every register. The enum value may not match the encoding
+  // used to binary encode register operands in instructions.
+  enum AllRegisters {
+#define X(val, encode, name, name16, name8, scratch, preserved, stackptr,      \
+          frameptr, isI8, isInt, isFP)                                         \
+  val,
+    REGX8632_TABLE
+#undef X
+        Reg_NUM,
+#define X(val, init) val init,
+    REGX8632_TABLE_BOUNDS
+#undef X
+  };
+
+  // An enum of GPR Registers. The enum value does match encoding used
+  // to binary encode register operands in instructions.
+  enum GPRRegister {
+#define X(val, encode, name, name16, name8, scratch, preserved, stackptr,      \
+          frameptr, isI8, isInt, isFP)                                         \
+  Encoded_##val encode,
+    REGX8632_GPR_TABLE
+#undef X
+  };
+
+  // An enum of XMM Registers. The enum value does match encoding used
+  // to binary encode register operands in instructions.
+  enum XmmRegister {
+#define X(val, encode, name, name16, name8, scratch, preserved, stackptr,      \
+          frameptr, isI8, isInt, isFP)                                         \
+  Encoded_##val encode,
+    REGX8632_XMM_TABLE
+#undef X
+  };
+
+  // An enum of Byte Registers. The enum value does match encoding used
+  // to binary encode register operands in instructions.
+  enum ByteRegister {
+#define X(val, encode) Encoded_##val encode,
+    REGX8632_BYTEREG_TABLE
+#undef X
+  };
+
+  static GPRRegister getEncodedGPR(int32_t RegNum) {
+    assert(Reg_GPR_First <= RegNum && RegNum <= Reg_GPR_Last);
+    return GPRRegister(RegNum - Reg_GPR_First);
+  }
+
+  static XmmRegister getEncodedXmm(int32_t RegNum) {
+    assert(Reg_XMM_First <= RegNum && RegNum <= Reg_XMM_Last);
+    return XmmRegister(RegNum - Reg_XMM_First);
+  }
+
+  static ByteRegister getEncodedByteReg(int32_t RegNum) {
+    assert(RegNum == Reg_ah || (Reg_GPR_First <= RegNum && RegNum <= Reg_ebx));
+    if (RegNum == Reg_ah)
+      return Encoded_Reg_ah;
+    return ByteRegister(RegNum - Reg_GPR_First);
+  }
+};
+
+} // end of namespace Ice
+
+#endif // SUBZERO_SRC_ICEREGISTERSX8632_H
diff --git a/src/IceTargetLoweringX8632.cpp b/src/IceTargetLoweringX8632.cpp
index 31c11d4..d171739 100644
--- a/src/IceTargetLoweringX8632.cpp
+++ b/src/IceTargetLoweringX8632.cpp
@@ -21,6 +21,7 @@
 #include "IceClFlags.h"
 #include "IceInstX8632.h"
 #include "IceOperand.h"
+#include "IceRegistersX8632.h"
 #include "IceTargetLoweringX8632.def"
 #include "IceTargetLoweringX8632.h"
 #include "llvm/ADT/DenseMap.h"
@@ -51,14 +52,12 @@
 const struct TableFcmp_ {
   uint32_t Default;
   bool SwapScalarOperands;
-  InstX8632::BrCond C1, C2;
+  CondX86::BrCond C1, C2;
   bool SwapVectorOperands;
-  InstX8632Cmpps::CmppsCond Predicate;
+  CondX86::CmppsCond Predicate;
 } TableFcmp[] = {
 #define X(val, dflt, swapS, C1, C2, swapV, pred)                               \
-  {                                                                            \
-    dflt, swapS, InstX8632Br::C1, InstX8632Br::C2, swapV, InstX8632Cmpps::pred \
-  }                                                                            \
+  { dflt, swapS, CondX86::C1, CondX86::C2, swapV, CondX86::pred }              \
   ,
       FCMPX8632_TABLE
 #undef X
@@ -70,10 +69,10 @@
 // x86 conditional branch instruction.
 
 const struct TableIcmp32_ {
-  InstX8632::BrCond Mapping;
+  CondX86::BrCond Mapping;
 } TableIcmp32[] = {
 #define X(val, C_32, C1_64, C2_64, C3_64)                                      \
-  { InstX8632Br::C_32 }                                                        \
+  { CondX86::C_32 }                                                            \
   ,
     ICMPX8632_TABLE
 #undef X
@@ -85,17 +84,17 @@
 // conditional branches are needed.  For the other conditions, three separate
 // conditional branches are needed.
 const struct TableIcmp64_ {
-  InstX8632::BrCond C1, C2, C3;
+  CondX86::BrCond C1, C2, C3;
 } TableIcmp64[] = {
 #define X(val, C_32, C1_64, C2_64, C3_64)                                      \
-  { InstX8632Br::C1_64, InstX8632Br::C2_64, InstX8632Br::C3_64 }               \
+  { CondX86::C1_64, CondX86::C2_64, CondX86::C3_64 }                           \
   ,
     ICMPX8632_TABLE
 #undef X
   };
 const size_t TableIcmp64Size = llvm::array_lengthof(TableIcmp64);
 
-InstX8632::BrCond getIcmp32Mapping(InstIcmp::ICond Cond) {
+CondX86::BrCond getIcmp32Mapping(InstIcmp::ICond Cond) {
   size_t Index = static_cast<size_t>(Cond);
   assert(Index < TableIcmp32Size);
   return TableIcmp32[Index].Mapping;
@@ -264,23 +263,23 @@
     : TargetLowering(Func), InstructionSet(CLInstructionSet),
       IsEbpBasedFrame(false), NeedsStackAlignment(false), FrameSizeLocals(0),
       SpillAreaSizeBytes(0), NextLabelNumber(0), ComputedLiveRanges(false),
-      PhysicalRegisters(VarList(Reg_NUM)) {
+      PhysicalRegisters(VarList(RegX8632::Reg_NUM)) {
   // TODO: Don't initialize IntegerRegisters and friends every time.
   // Instead, initialize in some sort of static initializer for the
   // class.
-  llvm::SmallBitVector IntegerRegisters(Reg_NUM);
-  llvm::SmallBitVector IntegerRegistersI8(Reg_NUM);
-  llvm::SmallBitVector FloatRegisters(Reg_NUM);
-  llvm::SmallBitVector VectorRegisters(Reg_NUM);
-  llvm::SmallBitVector InvalidRegisters(Reg_NUM);
-  ScratchRegs.resize(Reg_NUM);
-#define X(val, init, name, name16, name8, scratch, preserved, stackptr,        \
+  llvm::SmallBitVector IntegerRegisters(RegX8632::Reg_NUM);
+  llvm::SmallBitVector IntegerRegistersI8(RegX8632::Reg_NUM);
+  llvm::SmallBitVector FloatRegisters(RegX8632::Reg_NUM);
+  llvm::SmallBitVector VectorRegisters(RegX8632::Reg_NUM);
+  llvm::SmallBitVector InvalidRegisters(RegX8632::Reg_NUM);
+  ScratchRegs.resize(RegX8632::Reg_NUM);
+#define X(val, encode, name, name16, name8, scratch, preserved, stackptr,      \
           frameptr, isI8, isInt, isFP)                                         \
-  IntegerRegisters[val] = isInt;                                               \
-  IntegerRegistersI8[val] = isI8;                                              \
-  FloatRegisters[val] = isFP;                                                  \
-  VectorRegisters[val] = isFP;                                                 \
-  ScratchRegs[val] = scratch;
+  IntegerRegisters[RegX8632::val] = isInt;                                     \
+  IntegerRegistersI8[RegX8632::val] = isI8;                                    \
+  FloatRegisters[RegX8632::val] = isFP;                                        \
+  VectorRegisters[RegX8632::val] = isFP;                                       \
+  ScratchRegs[RegX8632::val] = scratch;
   REGX8632_TABLE;
 #undef X
   TypeToRegisterSet[IceType_void] = InvalidRegisters;
@@ -460,7 +459,7 @@
 }
 
 IceString TargetX8632::RegNames[] = {
-#define X(val, init, name, name16, name8, scratch, preserved, stackptr,        \
+#define X(val, encode, name, name16, name8, scratch, preserved, stackptr,      \
           frameptr, isI8, isInt, isFP)                                         \
   name,
   REGX8632_TABLE
@@ -480,16 +479,16 @@
 }
 
 IceString TargetX8632::getRegName(SizeT RegNum, Type Ty) const {
-  assert(RegNum < Reg_NUM);
+  assert(RegNum < RegX8632::Reg_NUM);
   static IceString RegNames8[] = {
-#define X(val, init, name, name16, name8, scratch, preserved, stackptr,        \
+#define X(val, encode, name, name16, name8, scratch, preserved, stackptr,      \
           frameptr, isI8, isInt, isFP)                                         \
   name8,
     REGX8632_TABLE
 #undef X
   };
   static IceString RegNames16[] = {
-#define X(val, init, name, name16, name8, scratch, preserved, stackptr,        \
+#define X(val, encode, name, name16, name8, scratch, preserved, stackptr,      \
           frameptr, isI8, isInt, isFP)                                         \
   name16,
     REGX8632_TABLE
@@ -546,7 +545,7 @@
     // Replace Arg in the argument list with the home register.  Then
     // generate an instruction in the prolog to copy the home register
     // to the assigned location of Arg.
-    int32_t RegNum = Reg_xmm0 + NumXmmArgs;
+    int32_t RegNum = RegX8632::Reg_xmm0 + NumXmmArgs;
     ++NumXmmArgs;
     IceString Name = "home_reg:" + Arg->getName();
     const CfgNode *DefNode = NULL;
@@ -782,8 +781,8 @@
     assert((RegsUsed & getRegisterSet(RegSet_FramePointer, RegSet_None))
                .count() == 0);
     PreservedRegsSizeBytes += 4;
-    Variable *ebp = getPhysicalRegister(Reg_ebp);
-    Variable *esp = getPhysicalRegister(Reg_esp);
+    Variable *ebp = getPhysicalRegister(RegX8632::Reg_ebp);
+    Variable *esp = getPhysicalRegister(RegX8632::Reg_esp);
     const bool SuppressStackAdjustment = true;
     _push(ebp, SuppressStackAdjustment);
     _mov(ebp, esp);
@@ -821,7 +820,7 @@
 
   // Generate "sub esp, SpillAreaSizeBytes"
   if (SpillAreaSizeBytes)
-    _sub(getPhysicalRegister(Reg_esp),
+    _sub(getPhysicalRegister(RegX8632::Reg_esp),
          Ctx->getConstantInt32(IceType_i32, SpillAreaSizeBytes));
   Ctx->statsUpdateFrameBytes(SpillAreaSizeBytes);
 
@@ -931,9 +930,9 @@
   Context.init(Node);
   Context.setInsertPoint(InsertPoint);
 
-  Variable *esp = getPhysicalRegister(Reg_esp);
+  Variable *esp = getPhysicalRegister(RegX8632::Reg_esp);
   if (IsEbpBasedFrame) {
-    Variable *ebp = getPhysicalRegister(Reg_ebp);
+    Variable *ebp = getPhysicalRegister(RegX8632::Reg_ebp);
     _mov(esp, ebp);
     _pop(ebp);
   } else {
@@ -947,7 +946,7 @@
       getRegisterSet(RegSet_CalleeSave, RegSet_None);
   for (SizeT i = 0; i < CalleeSaves.size(); ++i) {
     SizeT j = CalleeSaves.size() - i - 1;
-    if (j == Reg_ebp && IsEbpBasedFrame)
+    if (j == RegX8632::Reg_ebp && IsEbpBasedFrame)
       continue;
     if (CalleeSaves[j] && RegsUsed[j]) {
       _pop(getPhysicalRegister(j));
@@ -1104,26 +1103,26 @@
 
 llvm::SmallBitVector TargetX8632::getRegisterSet(RegSetMask Include,
                                                  RegSetMask Exclude) const {
-  llvm::SmallBitVector Registers(Reg_NUM);
+  llvm::SmallBitVector Registers(RegX8632::Reg_NUM);
 
-#define X(val, init, name, name16, name8, scratch, preserved, stackptr,        \
+#define X(val, encode, name, name16, name8, scratch, preserved, stackptr,      \
           frameptr, isI8, isInt, isFP)                                         \
   if (scratch && (Include & RegSet_CallerSave))                                \
-    Registers[val] = true;                                                     \
+    Registers[RegX8632::val] = true;                                           \
   if (preserved && (Include & RegSet_CalleeSave))                              \
-    Registers[val] = true;                                                     \
+    Registers[RegX8632::val] = true;                                           \
   if (stackptr && (Include & RegSet_StackPointer))                             \
-    Registers[val] = true;                                                     \
+    Registers[RegX8632::val] = true;                                           \
   if (frameptr && (Include & RegSet_FramePointer))                             \
-    Registers[val] = true;                                                     \
+    Registers[RegX8632::val] = true;                                           \
   if (scratch && (Exclude & RegSet_CallerSave))                                \
-    Registers[val] = false;                                                    \
+    Registers[RegX8632::val] = false;                                          \
   if (preserved && (Exclude & RegSet_CalleeSave))                              \
-    Registers[val] = false;                                                    \
+    Registers[RegX8632::val] = false;                                          \
   if (stackptr && (Exclude & RegSet_StackPointer))                             \
-    Registers[val] = false;                                                    \
+    Registers[RegX8632::val] = false;                                          \
   if (frameptr && (Exclude & RegSet_FramePointer))                             \
-    Registers[val] = false;
+    Registers[RegX8632::val] = false;
 
   REGX8632_TABLE
 
@@ -1142,7 +1141,7 @@
   NeedsStackAlignment = true;
 
   // TODO(sehr,stichnot): minimize the number of adjustments of esp, etc.
-  Variable *esp = getPhysicalRegister(Reg_esp);
+  Variable *esp = getPhysicalRegister(RegX8632::Reg_esp);
   Operand *TotalSize = legalize(Inst->getSizeInBytes());
   Variable *Dest = Inst->getDest();
   uint32_t AlignmentParam = Inst->getAlignInBytes();
@@ -1233,8 +1232,8 @@
       break;
     case InstArithmetic::Mul: {
       Variable *T_1 = NULL, *T_2 = NULL, *T_3 = NULL;
-      Variable *T_4Lo = makeReg(IceType_i32, Reg_eax);
-      Variable *T_4Hi = makeReg(IceType_i32, Reg_edx);
+      Variable *T_4Lo = makeReg(IceType_i32, RegX8632::Reg_eax);
+      Variable *T_4Hi = makeReg(IceType_i32, RegX8632::Reg_edx);
       // gcc does the following:
       // a=b*c ==>
       //   t1 = b.hi; t1 *=(imul) c.lo
@@ -1251,7 +1250,7 @@
       _imul(T_1, Src1Lo);
       _mov(T_2, Src1Hi);
       _imul(T_2, Src0Lo);
-      _mov(T_3, Src0Lo, Reg_eax);
+      _mov(T_3, Src0Lo, RegX8632::Reg_eax);
       _mul(T_4Lo, T_3, Src1Lo);
       // The mul instruction produces two dest variables, edx:eax.  We
       // create a fake definition of edx to account for this.
@@ -1282,13 +1281,13 @@
       Constant *BitTest = Ctx->getConstantInt32(IceType_i32, 0x20);
       Constant *Zero = Ctx->getConstantZero(IceType_i32);
       InstX8632Label *Label = InstX8632Label::create(Func, this);
-      _mov(T_1, Src1Lo, Reg_ecx);
+      _mov(T_1, Src1Lo, RegX8632::Reg_ecx);
       _mov(T_2, Src0Lo);
       _mov(T_3, Src0Hi);
       _shld(T_3, T_2, T_1);
       _shl(T_2, T_1);
       _test(T_1, BitTest);
-      _br(InstX8632Br::Br_e, Label);
+      _br(CondX86::Br_e, Label);
       // Because of the intra-block control flow, we need to fake a use
       // of T_3 to prevent its earlier definition from being dead-code
       // eliminated in the presence of its later definition.
@@ -1318,13 +1317,13 @@
       Constant *BitTest = Ctx->getConstantInt32(IceType_i32, 0x20);
       Constant *Zero = Ctx->getConstantZero(IceType_i32);
       InstX8632Label *Label = InstX8632Label::create(Func, this);
-      _mov(T_1, Src1Lo, Reg_ecx);
+      _mov(T_1, Src1Lo, RegX8632::Reg_ecx);
       _mov(T_2, Src0Lo);
       _mov(T_3, Src0Hi);
       _shrd(T_2, T_3, T_1);
       _shr(T_3, T_1);
       _test(T_1, BitTest);
-      _br(InstX8632Br::Br_e, Label);
+      _br(CondX86::Br_e, Label);
       // Because of the intra-block control flow, we need to fake a use
       // of T_3 to prevent its earlier definition from being dead-code
       // eliminated in the presence of its later definition.
@@ -1354,13 +1353,13 @@
       Constant *BitTest = Ctx->getConstantInt32(IceType_i32, 0x20);
       Constant *SignExtend = Ctx->getConstantInt32(IceType_i32, 0x1f);
       InstX8632Label *Label = InstX8632Label::create(Func, this);
-      _mov(T_1, Src1Lo, Reg_ecx);
+      _mov(T_1, Src1Lo, RegX8632::Reg_ecx);
       _mov(T_2, Src0Lo);
       _mov(T_3, Src0Hi);
       _shrd(T_2, T_3, T_1);
       _sar(T_3, T_1);
       _test(T_1, BitTest);
-      _br(InstX8632Br::Br_e, Label);
+      _br(CondX86::Br_e, Label);
       // Because of the intra-block control flow, we need to fake a use
       // of T_3 to prevent its earlier definition from being dead-code
       // eliminated in the presence of its later definition.
@@ -1575,7 +1574,7 @@
       // The 8-bit version of imul only allows the form "imul r/m8"
       // where T must be in eax.
       if (Dest->getType() == IceType_i8)
-        _mov(T, Src0, Reg_eax);
+        _mov(T, Src0, RegX8632::Reg_eax);
       else
         _mov(T, Src0);
       _imul(T, Src1);
@@ -1584,21 +1583,21 @@
     case InstArithmetic::Shl:
       _mov(T, Src0);
       if (!llvm::isa<Constant>(Src1))
-        Src1 = legalizeToVar(Src1, false, Reg_ecx);
+        Src1 = legalizeToVar(Src1, false, RegX8632::Reg_ecx);
       _shl(T, Src1);
       _mov(Dest, T);
       break;
     case InstArithmetic::Lshr:
       _mov(T, Src0);
       if (!llvm::isa<Constant>(Src1))
-        Src1 = legalizeToVar(Src1, false, Reg_ecx);
+        Src1 = legalizeToVar(Src1, false, RegX8632::Reg_ecx);
       _shr(T, Src1);
       _mov(Dest, T);
       break;
     case InstArithmetic::Ashr:
       _mov(T, Src0);
       if (!llvm::isa<Constant>(Src1))
-        Src1 = legalizeToVar(Src1, false, Reg_ecx);
+        Src1 = legalizeToVar(Src1, false, RegX8632::Reg_ecx);
       _sar(T, Src1);
       _mov(Dest, T);
       break;
@@ -1609,14 +1608,14 @@
       if (Dest->getType() == IceType_i8) {
         Variable *T_ah = NULL;
         Constant *Zero = Ctx->getConstantZero(IceType_i8);
-        _mov(T, Src0, Reg_eax);
-        _mov(T_ah, Zero, Reg_ah);
+        _mov(T, Src0, RegX8632::Reg_eax);
+        _mov(T_ah, Zero, RegX8632::Reg_ah);
         _div(T, Src1, T_ah);
         _mov(Dest, T);
       } else {
         Constant *Zero = Ctx->getConstantZero(IceType_i32);
-        _mov(T, Src0, Reg_eax);
-        _mov(T_edx, Zero, Reg_edx);
+        _mov(T, Src0, RegX8632::Reg_eax);
+        _mov(T_edx, Zero, RegX8632::Reg_edx);
         _div(T, Src1, T_edx);
         _mov(Dest, T);
       }
@@ -1624,13 +1623,13 @@
     case InstArithmetic::Sdiv:
       Src1 = legalize(Src1, Legal_Reg | Legal_Mem);
       if (Dest->getType() == IceType_i8) {
-        _mov(T, Src0, Reg_eax);
+        _mov(T, Src0, RegX8632::Reg_eax);
         _cbwdq(T, T);
         _idiv(T, Src1, T);
         _mov(Dest, T);
       } else {
-        T_edx = makeReg(IceType_i32, Reg_edx);
-        _mov(T, Src0, Reg_eax);
+        T_edx = makeReg(IceType_i32, RegX8632::Reg_edx);
+        _mov(T, Src0, RegX8632::Reg_eax);
         _cbwdq(T_edx, T);
         _idiv(T, Src1, T_edx);
         _mov(Dest, T);
@@ -1641,14 +1640,14 @@
       if (Dest->getType() == IceType_i8) {
         Variable *T_ah = NULL;
         Constant *Zero = Ctx->getConstantZero(IceType_i8);
-        _mov(T, Src0, Reg_eax);
-        _mov(T_ah, Zero, Reg_ah);
+        _mov(T, Src0, RegX8632::Reg_eax);
+        _mov(T_ah, Zero, RegX8632::Reg_ah);
         _div(T_ah, Src1, T);
         _mov(Dest, T_ah);
       } else {
         Constant *Zero = Ctx->getConstantZero(IceType_i32);
-        _mov(T_edx, Zero, Reg_edx);
-        _mov(T, Src0, Reg_eax);
+        _mov(T_edx, Zero, RegX8632::Reg_edx);
+        _mov(T, Src0, RegX8632::Reg_eax);
         _div(T_edx, Src1, T);
         _mov(Dest, T_edx);
       }
@@ -1656,15 +1655,15 @@
     case InstArithmetic::Srem:
       Src1 = legalize(Src1, Legal_Reg | Legal_Mem);
       if (Dest->getType() == IceType_i8) {
-        Variable *T_ah = makeReg(IceType_i8, Reg_ah);
-        _mov(T, Src0, Reg_eax);
+        Variable *T_ah = makeReg(IceType_i8, RegX8632::Reg_ah);
+        _mov(T, Src0, RegX8632::Reg_eax);
         _cbwdq(T, T);
         Context.insert(InstFakeDef::create(Func, T_ah));
         _idiv(T_ah, Src1, T);
         _mov(Dest, T_ah);
       } else {
-        T_edx = makeReg(IceType_i32, Reg_edx);
-        _mov(T, Src0, Reg_eax);
+        T_edx = makeReg(IceType_i32, RegX8632::Reg_edx);
+        _mov(T, Src0, RegX8632::Reg_eax);
         _cbwdq(T_edx, T);
         _idiv(T_edx, Src1, T);
         _mov(Dest, T_edx);
@@ -1736,7 +1735,7 @@
     Operand *Src0 = legalize(Inst->getCondition(), Legal_Reg | Legal_Mem);
     Constant *Zero = Ctx->getConstantZero(IceType_i32);
     _cmp(Src0, Zero);
-    _br(InstX8632Br::Br_ne, Inst->getTargetTrue(), Inst->getTargetFalse());
+    _br(CondX86::Br_ne, Inst->getTargetTrue(), Inst->getTargetFalse());
   }
 }
 
@@ -1782,7 +1781,7 @@
       if (isVectorType(Arg->getType())) {
         ParameterAreaSizeBytes = applyStackAlignment(ParameterAreaSizeBytes);
       }
-      Variable *esp = Func->getTarget()->getPhysicalRegister(Reg_esp);
+      Variable *esp = Func->getTarget()->getPhysicalRegister(RegX8632::Reg_esp);
       Constant *Loc =
           Ctx->getConstantInt32(IceType_i32, ParameterAreaSizeBytes);
       StackArgLocations.push_back(OperandX8632Mem::create(Func, Ty, esp, Loc));
@@ -1824,7 +1823,7 @@
   // code, as the memory operand displacements may end up being smaller
   // before any stack adjustment is done.
   for (SizeT i = 0, NumXmmArgs = XmmArgs.size(); i < NumXmmArgs; ++i) {
-    Variable *Reg = legalizeToVar(XmmArgs[i], false, Reg_xmm0 + i);
+    Variable *Reg = legalizeToVar(XmmArgs[i], false, RegX8632::Reg_xmm0 + i);
     // Generate a FakeUse of register arguments so that they do not get
     // dead code eliminated as a result of the FakeKill of scratch
     // registers after the call.
@@ -1847,11 +1846,11 @@
     case IceType_i8:
     case IceType_i16:
     case IceType_i32:
-      ReturnReg = makeReg(Dest->getType(), Reg_eax);
+      ReturnReg = makeReg(Dest->getType(), RegX8632::Reg_eax);
       break;
     case IceType_i64:
-      ReturnReg = makeReg(IceType_i32, Reg_eax);
-      ReturnRegHi = makeReg(IceType_i32, Reg_edx);
+      ReturnReg = makeReg(IceType_i32, RegX8632::Reg_eax);
+      ReturnRegHi = makeReg(IceType_i32, RegX8632::Reg_edx);
       break;
     case IceType_f32:
     case IceType_f64:
@@ -1865,7 +1864,7 @@
     case IceType_v8i16:
     case IceType_v4i32:
     case IceType_v4f32:
-      ReturnReg = makeReg(Dest->getType(), Reg_xmm0);
+      ReturnReg = makeReg(Dest->getType(), RegX8632::Reg_xmm0);
       break;
     }
   }
@@ -1880,7 +1879,7 @@
   // Add the appropriate offset to esp.  The call instruction takes care
   // of resetting the stack offset during emission.
   if (ParameterAreaSizeBytes) {
-    Variable *esp = Func->getTarget()->getPhysicalRegister(Reg_esp);
+    Variable *esp = Func->getTarget()->getPhysicalRegister(RegX8632::Reg_esp);
     _add(esp, Ctx->getConstantInt32(IceType_i32, ParameterAreaSizeBytes));
   }
 
@@ -2480,8 +2479,8 @@
 
       switch (Condition) {
       default: {
-        InstX8632Cmpps::CmppsCond Predicate = TableFcmp[Index].Predicate;
-        assert(Predicate != InstX8632Cmpps::Cmpps_Invalid);
+        CondX86::CmppsCond Predicate = TableFcmp[Index].Predicate;
+        assert(Predicate != CondX86::Cmpps_Invalid);
         T = makeReg(Src0RM->getType());
         _movp(T, Src0RM);
         _cmpps(T, Src1RM, Predicate);
@@ -2491,9 +2490,9 @@
         T = makeReg(Src0RM->getType());
         Variable *T2 = makeReg(Src0RM->getType());
         _movp(T, Src0RM);
-        _cmpps(T, Src1RM, InstX8632Cmpps::Cmpps_neq);
+        _cmpps(T, Src1RM, CondX86::Cmpps_neq);
         _movp(T2, Src0RM);
-        _cmpps(T2, Src1RM, InstX8632Cmpps::Cmpps_ord);
+        _cmpps(T2, Src1RM, CondX86::Cmpps_ord);
         _pand(T, T2);
       } break;
       case InstFcmp::Ueq: {
@@ -2501,9 +2500,9 @@
         T = makeReg(Src0RM->getType());
         Variable *T2 = makeReg(Src0RM->getType());
         _movp(T, Src0RM);
-        _cmpps(T, Src1RM, InstX8632Cmpps::Cmpps_eq);
+        _cmpps(T, Src1RM, CondX86::Cmpps_eq);
         _movp(T2, Src0RM);
-        _cmpps(T2, Src1RM, InstX8632Cmpps::Cmpps_unord);
+        _cmpps(T2, Src1RM, CondX86::Cmpps_unord);
         _por(T, T2);
       } break;
       }
@@ -2531,8 +2530,8 @@
     Src0 = Src1;
     Src1 = Tmp;
   }
-  bool HasC1 = (TableFcmp[Index].C1 != InstX8632Br::Br_None);
-  bool HasC2 = (TableFcmp[Index].C2 != InstX8632Br::Br_None);
+  bool HasC1 = (TableFcmp[Index].C1 != CondX86::Br_None);
+  bool HasC2 = (TableFcmp[Index].C2 != CondX86::Br_None);
   if (HasC1) {
     Src0 = legalize(Src0);
     Operand *Src1RM = legalize(Src1, Legal_Reg | Legal_Mem);
@@ -2705,9 +2704,9 @@
       InstX8632Label *Label = InstX8632Label::create(Func, this);
       _mov(Dest, (Condition == InstIcmp::Eq ? Zero : One));
       _cmp(Src0LoRM, Src1LoRI);
-      _br(InstX8632Br::Br_ne, Label);
+      _br(CondX86::Br_ne, Label);
       _cmp(Src0HiRM, Src1HiRI);
-      _br(InstX8632Br::Br_ne, Label);
+      _br(CondX86::Br_ne, Label);
       Context.insert(InstFakeUse::create(Func, Dest));
       _mov(Dest, (Condition == InstIcmp::Eq ? One : Zero));
       Context.insert(Label);
@@ -3160,13 +3159,13 @@
     return;
   }
   case Intrinsics::Stacksave: {
-    Variable *esp = Func->getTarget()->getPhysicalRegister(Reg_esp);
+    Variable *esp = Func->getTarget()->getPhysicalRegister(RegX8632::Reg_esp);
     Variable *Dest = Instr->getDest();
     _mov(Dest, esp);
     return;
   }
   case Intrinsics::Stackrestore: {
-    Variable *esp = Func->getTarget()->getPhysicalRegister(Reg_esp);
+    Variable *esp = Func->getTarget()->getPhysicalRegister(RegX8632::Reg_esp);
     _mov(esp, Instr->getArg(0));
     return;
   }
@@ -3185,10 +3184,10 @@
   if (Expected->getType() == IceType_i64) {
     // Reserve the pre-colored registers first, before adding any more
     // infinite-weight variables from FormMemoryOperand's legalization.
-    Variable *T_edx = makeReg(IceType_i32, Reg_edx);
-    Variable *T_eax = makeReg(IceType_i32, Reg_eax);
-    Variable *T_ecx = makeReg(IceType_i32, Reg_ecx);
-    Variable *T_ebx = makeReg(IceType_i32, Reg_ebx);
+    Variable *T_edx = makeReg(IceType_i32, RegX8632::Reg_edx);
+    Variable *T_eax = makeReg(IceType_i32, RegX8632::Reg_eax);
+    Variable *T_ecx = makeReg(IceType_i32, RegX8632::Reg_ecx);
+    Variable *T_ebx = makeReg(IceType_i32, RegX8632::Reg_ebx);
     _mov(T_eax, loOperand(Expected));
     _mov(T_edx, hiOperand(Expected));
     _mov(T_ebx, loOperand(Desired));
@@ -3202,7 +3201,7 @@
     _mov(DestHi, T_edx);
     return;
   }
-  Variable *T_eax = makeReg(Expected->getType(), Reg_eax);
+  Variable *T_eax = makeReg(Expected->getType(), RegX8632::Reg_eax);
   _mov(T_eax, Expected);
   OperandX8632Mem *Addr = FormMemoryOperand(Ptr, Expected->getType());
   Variable *DesiredReg = legalizeToVar(Desired);
@@ -3271,7 +3270,7 @@
           lowerAssign(PhiAssign);
           Context.advanceNext();
         }
-        _br(InstX8632::Br_e, NextBr->getTargetTrue(), NextBr->getTargetFalse());
+        _br(CondX86::Br_e, NextBr->getTargetTrue(), NextBr->getTargetFalse());
         // Skip over the old compare and branch, by deleting them.
         NextCmp->setDeleted();
         NextBr->setDeleted();
@@ -3398,13 +3397,13 @@
   Val = legalize(Val);
   Type Ty = Val->getType();
   if (Ty == IceType_i64) {
-    Variable *T_edx = makeReg(IceType_i32, Reg_edx);
-    Variable *T_eax = makeReg(IceType_i32, Reg_eax);
+    Variable *T_edx = makeReg(IceType_i32, RegX8632::Reg_edx);
+    Variable *T_eax = makeReg(IceType_i32, RegX8632::Reg_eax);
     OperandX8632Mem *Addr = FormMemoryOperand(Ptr, Ty);
     _mov(T_eax, loOperand(Addr));
     _mov(T_edx, hiOperand(Addr));
-    Variable *T_ecx = makeReg(IceType_i32, Reg_ecx);
-    Variable *T_ebx = makeReg(IceType_i32, Reg_ebx);
+    Variable *T_ecx = makeReg(IceType_i32, RegX8632::Reg_ecx);
+    Variable *T_ebx = makeReg(IceType_i32, RegX8632::Reg_ebx);
     InstX8632Label *Label = InstX8632Label::create(Func, this);
     const bool IsXchg8b = Op_Lo == NULL && Op_Hi == NULL;
     if (!IsXchg8b) {
@@ -3423,7 +3422,7 @@
     }
     const bool Locked = true;
     _cmpxchg8b(Addr, T_edx, T_eax, T_ecx, T_ebx, Locked);
-    _br(InstX8632Br::Br_ne, Label);
+    _br(CondX86::Br_ne, Label);
     if (!IsXchg8b) {
       // If Val is a variable, model the extended live range of Val through
       // the end of the loop, since it will be re-used by the loop.
@@ -3447,7 +3446,7 @@
     return;
   }
   OperandX8632Mem *Addr = FormMemoryOperand(Ptr, Ty);
-  Variable *T_eax = makeReg(Ty, Reg_eax);
+  Variable *T_eax = makeReg(Ty, RegX8632::Reg_eax);
   _mov(T_eax, Addr);
   InstX8632Label *Label = InstX8632Label::create(Func, this);
   Context.insert(Label);
@@ -3458,7 +3457,7 @@
   (this->*Op_Lo)(T, Val);
   const bool Locked = true;
   _cmpxchg(Addr, T_eax, T, Locked);
-  _br(InstX8632Br::Br_ne, Label);
+  _br(CondX86::Br_ne, Label);
   // If Val is a variable, model the extended live range of Val through
   // the end of the loop, since it will be re-used by the loop.
   if (Variable *ValVar = llvm::dyn_cast<Variable>(Val)) {
@@ -3519,7 +3518,7 @@
     Constant *SixtyThree = Ctx->getConstantInt32(IceType_i32, 63);
     _mov(T_Dest, SixtyThree);
   }
-  _cmov(T_Dest, T, InstX8632::Br_ne);
+  _cmov(T_Dest, T, CondX86::Br_ne);
   if (!Cttz) {
     _xor(T_Dest, ThirtyOne);
   }
@@ -3540,7 +3539,7 @@
     _xor(T_Dest2, ThirtyOne);
   }
   _test(SecondVar, SecondVar);
-  _cmov(T_Dest2, T_Dest, InstX8632::Br_e);
+  _cmov(T_Dest2, T_Dest, CondX86::Br_e);
   _mov(DestLo, T_Dest2);
   _mov(DestHi, Ctx->getConstantZero(IceType_i32));
 }
@@ -3867,17 +3866,17 @@
   if (Inst->hasRetValue()) {
     Operand *Src0 = legalize(Inst->getRetValue());
     if (Src0->getType() == IceType_i64) {
-      Variable *eax = legalizeToVar(loOperand(Src0), false, Reg_eax);
-      Variable *edx = legalizeToVar(hiOperand(Src0), false, Reg_edx);
+      Variable *eax = legalizeToVar(loOperand(Src0), false, RegX8632::Reg_eax);
+      Variable *edx = legalizeToVar(hiOperand(Src0), false, RegX8632::Reg_edx);
       Reg = eax;
       Context.insert(InstFakeUse::create(Func, edx));
     } else if (Src0->getType() == IceType_f32 ||
                Src0->getType() == IceType_f64) {
       _fld(Src0);
     } else if (isVectorType(Src0->getType())) {
-      Reg = legalizeToVar(Src0, false, Reg_xmm0);
+      Reg = legalizeToVar(Src0, false, RegX8632::Reg_xmm0);
     } else {
-      _mov(Reg, Src0, Reg_eax);
+      _mov(Reg, Src0, RegX8632::Reg_eax);
     }
   }
   _ret(Reg);
@@ -3886,7 +3885,7 @@
   // eliminated.  TODO: Are there more places where the fake use
   // should be inserted?  E.g. "void f(int n){while(1) g(n);}" may not
   // have a ret instruction.
-  Variable *esp = Func->getTarget()->getPhysicalRegister(Reg_esp);
+  Variable *esp = Func->getTarget()->getPhysicalRegister(RegX8632::Reg_esp);
   Context.insert(InstFakeUse::create(Func, esp));
 }
 
@@ -3909,7 +3908,7 @@
       if (SrcTy == IceType_v4i1 || SrcTy == IceType_v4i32 ||
           SrcTy == IceType_v4f32) {
         Operand *ConditionRM = legalize(Condition, Legal_Reg | Legal_Mem);
-        Variable *xmm0 = makeReg(IceType_v4i32, Reg_xmm0);
+        Variable *xmm0 = makeReg(IceType_v4i32, RegX8632::Reg_xmm0);
         _movp(xmm0, ConditionRM);
         _psll(xmm0, Ctx->getConstantInt32(IceType_i8, 31));
         _movp(T, SrcFRM);
@@ -3919,7 +3918,7 @@
         assert(typeNumElements(SrcTy) == 8 || typeNumElements(SrcTy) == 16);
         Type SignExtTy = Condition->getType() == IceType_v8i1 ? IceType_v8i16
             : IceType_v16i8;
-        Variable *xmm0 = makeReg(SignExtTy, Reg_xmm0);
+        Variable *xmm0 = makeReg(SignExtTy, RegX8632::Reg_xmm0);
         lowerCast(InstCast::create(Func, InstCast::Sext, xmm0, Condition));
         _movp(T, SrcFRM);
         _pblendvb(T, SrcTRM, xmm0);
@@ -3967,7 +3966,7 @@
     _cmp(ConditionRM, Zero);
     _mov(DestLo, SrcLoRI);
     _mov(DestHi, SrcHiRI);
-    _br(InstX8632Br::Br_ne, Label);
+    _br(CondX86::Br_ne, Label);
     Context.insert(InstFakeUse::create(Func, DestLo));
     Context.insert(InstFakeUse::create(Func, DestHi));
     Operand *SrcFLo = loOperand(SrcF);
@@ -3980,7 +3979,7 @@
     _cmp(ConditionRM, Zero);
     SrcT = legalize(SrcT, Legal_Reg | Legal_Imm, true);
     _mov(Dest, SrcT);
-    _br(InstX8632Br::Br_ne, Label);
+    _br(CondX86::Br_ne, Label);
     Context.insert(InstFakeUse::create(Func, Dest));
     SrcF = legalize(SrcF, Legal_Reg | Legal_Imm, true);
     _mov(Dest, SrcF);
@@ -4048,7 +4047,7 @@
     // TODO(stichnot): Correct lowering for IceType_i64.
     Constant *Value = Ctx->getConstantInt32(IceType_i32, Inst->getValue(I));
     _cmp(Src0, Value);
-    _br(InstX8632Br::Br_e, Inst->getLabel(I));
+    _br(CondX86::Br_e, Inst->getLabel(I));
   }
 
   _br(Inst->getLabelDefault());
diff --git a/src/IceTargetLoweringX8632.h b/src/IceTargetLoweringX8632.h
index a104dac..4b87354 100644
--- a/src/IceTargetLoweringX8632.h
+++ b/src/IceTargetLoweringX8632.h
@@ -19,6 +19,7 @@
 #include "IceDefs.h"
 #include "IceTargetLowering.h"
 #include "IceInstX8632.h"
+#include "IceRegistersX8632.h"
 
 namespace Ice {
 
@@ -39,7 +40,7 @@
   }
   virtual bool hasFramePointer() const { return IsEbpBasedFrame; }
   virtual SizeT getFrameOrStackReg() const {
-    return IsEbpBasedFrame ? Reg_ebp : Reg_esp;
+    return IsEbpBasedFrame ? RegX8632::Reg_ebp : RegX8632::Reg_esp;
   }
   virtual size_t typeWidthInBytesOnStack(Type Ty) const {
     // Round up to the next multiple of 4 bytes.  In particular, i1,
@@ -68,15 +69,6 @@
   Operand *loOperand(Operand *Operand);
   Operand *hiOperand(Operand *Operand);
 
-  enum Registers {
-#define X(val, init, name, name16, name8, scratch, preserved, stackptr,        \
-          frameptr, isI8, isInt, isFP)                                         \
-  val init,
-    REGX8632_TABLE
-#undef X
-        Reg_NUM
-  };
-
   enum X86InstructionSet {
     // SSE2 is the PNaCl baseline instruction set.
     SSE2,
@@ -212,7 +204,7 @@
   void _blendvps(Variable *Dest, Operand *Src0, Operand *Src1) {
     Context.insert(InstX8632Blendvps::create(Func, Dest, Src0, Src1));
   }
-  void _br(InstX8632::BrCond Condition, CfgNode *TargetTrue,
+  void _br(CondX86::BrCond Condition, CfgNode *TargetTrue,
            CfgNode *TargetFalse) {
     Context.insert(
         InstX8632Br::create(Func, TargetTrue, TargetFalse, Condition));
@@ -220,10 +212,10 @@
   void _br(CfgNode *Target) {
     Context.insert(InstX8632Br::create(Func, Target));
   }
-  void _br(InstX8632::BrCond Condition, CfgNode *Target) {
+  void _br(CondX86::BrCond Condition, CfgNode *Target) {
     Context.insert(InstX8632Br::create(Func, Target, Condition));
   }
-  void _br(InstX8632::BrCond Condition, InstX8632Label *Label) {
+  void _br(CondX86::BrCond Condition, InstX8632Label *Label) {
     Context.insert(InstX8632Br::create(Func, Label, Condition));
   }
   void _bsf(Variable *Dest, Operand *Src0) {
@@ -238,14 +230,13 @@
   void _cbwdq(Variable *Dest, Operand *Src0) {
     Context.insert(InstX8632Cbwdq::create(Func, Dest, Src0));
   }
-  void _cmov(Variable *Dest, Operand *Src0, InstX8632::BrCond Condition) {
+  void _cmov(Variable *Dest, Operand *Src0, CondX86::BrCond Condition) {
     Context.insert(InstX8632Cmov::create(Func, Dest, Src0, Condition));
   }
   void _cmp(Operand *Src0, Operand *Src1) {
     Context.insert(InstX8632Icmp::create(Func, Src0, Src1));
   }
-  void _cmpps(Variable *Dest, Operand *Src0,
-              InstX8632Cmpps::CmppsCond Condition) {
+  void _cmpps(Variable *Dest, Operand *Src0, CondX86::CmppsCond Condition) {
     Context.insert(InstX8632Cmpps::create(Func, Dest, Src0, Condition));
   }
   void _cmpxchg(Operand *DestOrAddr, Variable *Eax, Variable *Desired,