diff --git a/src/IceAssemblerX8632.h b/src/IceAssemblerX8632.h
index 6c22a24..fb9eedf 100644
--- a/src/IceAssemblerX8632.h
+++ b/src/IceAssemblerX8632.h
@@ -37,6 +37,9 @@
 
 namespace X8632 {
 
+using Immediate = ::Ice::X86Internal::Immediate;
+using Label = ::Ice::X86Internal::Label;
+
 class AssemblerX8632 : public X86Internal::AssemblerX86Base<TargetX8632> {
   AssemblerX8632(const AssemblerX8632 &) = delete;
   AssemblerX8632 &operator=(const AssemblerX8632 &) = delete;
diff --git a/src/IceAssemblerX86Base.h b/src/IceAssemblerX86Base.h
index e6516f6..8a556f0 100644
--- a/src/IceAssemblerX86Base.h
+++ b/src/IceAssemblerX86Base.h
@@ -948,10 +948,6 @@
 
 } // end of namespace X86Internal
 
-namespace X8632 {
-using Immediate = ::Ice::X86Internal::Immediate;
-using Label = ::Ice::X86Internal::Label;
-} // end of namespace X8632
 } // end of namespace Ice
 
 #include "IceAssemblerX86BaseImpl.h"
diff --git a/src/IceInstX8632.cpp b/src/IceInstX8632.cpp
index fd33c55..c6d6abf 100644
--- a/src/IceInstX8632.cpp
+++ b/src/IceInstX8632.cpp
@@ -8,11 +8,13 @@
 //===----------------------------------------------------------------------===//
 ///
 /// \file
-/// This file implements the InstX8632 and OperandX8632 classes,
-/// primarily the constructors and the dump()/emit() methods.
+/// This file defines X8632 specific data related to X8632 Instructions and
+/// Instruction traits. These are declared in the IceTargetLoweringX8632Traits.h
+/// header file.
+///
+/// This file also defines X8632 operand specific methods (dump and emit.)
 ///
 //===----------------------------------------------------------------------===//
-
 #include "IceInstX8632.h"
 
 #include "IceAssemblerX8632.h"
@@ -26,75 +28,57 @@
 
 namespace Ice {
 
-namespace {
+namespace X86Internal {
 
-const struct InstX8632BrAttributes_ {
-  X8632::Traits::Cond::BrCond Opposite;
-  const char *DisplayString;
-  const char *EmitString;
-} InstX8632BrAttributes[] = {
+const MachineTraits<TargetX8632>::InstBrAttributesType
+    MachineTraits<TargetX8632>::InstBrAttributes[] = {
 #define X(tag, encode, opp, dump, emit)                                        \
   { X8632::Traits::Cond::opp, dump, emit }                                     \
   ,
-    ICEINSTX8632BR_TABLE
+        ICEINSTX8632BR_TABLE
 #undef X
 };
 
-const struct InstX8632CmppsAttributes_ {
-  const char *EmitString;
-} InstX8632CmppsAttributes[] = {
+const MachineTraits<TargetX8632>::InstCmppsAttributesType
+    MachineTraits<TargetX8632>::InstCmppsAttributes[] = {
 #define X(tag, emit)                                                           \
   { emit }                                                                     \
   ,
-    ICEINSTX8632CMPPS_TABLE
+        ICEINSTX8632CMPPS_TABLE
 #undef X
 };
 
-const struct TypeX8632Attributes_ {
-  const char *CvtString;   // i (integer), s (single FP), d (double FP)
-  const char *SdSsString;  // ss, sd, or <blank>
-  const char *PackString;  // b, w, d, or <blank>
-  const char *WidthString; // b, w, l, q, or <blank>
-  const char *FldString;   // s, l, or <blank>
-} TypeX8632Attributes[] = {
+const MachineTraits<TargetX8632>::TypeAttributesType
+    MachineTraits<TargetX8632>::TypeAttributes[] = {
 #define X(tag, elementty, cvt, sdss, pack, width, fld)                         \
   { cvt, sdss, pack, width, fld }                                              \
   ,
-    ICETYPEX8632_TABLE
+        ICETYPEX8632_TABLE
 #undef X
 };
 
-const char *InstX8632SegmentRegNames[] = {
+const char *MachineTraits<TargetX8632>::InstSegmentRegNames[] = {
 #define X(val, name, prefix) name,
     SEG_REGX8632_TABLE
 #undef X
 };
 
-uint8_t InstX8632SegmentPrefixes[] = {
+uint8_t MachineTraits<TargetX8632>::InstSegmentPrefixes[] = {
 #define X(val, name, prefix) prefix,
     SEG_REGX8632_TABLE
 #undef X
 };
 
-} // end of anonymous namespace
-
-const char *InstX8632::getWidthString(Type Ty) {
-  return TypeX8632Attributes[Ty].WidthString;
+void MachineTraits<TargetX8632>::X86Operand::dump(const Cfg *,
+                                                  Ostream &Str) const {
+  if (BuildDefs::dump())
+    Str << "<OperandX8632>";
 }
 
-const char *InstX8632::getFldString(Type Ty) {
-  return TypeX8632Attributes[Ty].FldString;
-}
-
-X8632::Traits::Cond::BrCond
-InstX8632::getOppositeCondition(X8632::Traits::Cond::BrCond Cond) {
-  return InstX8632BrAttributes[Cond].Opposite;
-}
-
-OperandX8632Mem::OperandX8632Mem(Cfg *Func, Type Ty, Variable *Base,
-                                 Constant *Offset, Variable *Index,
-                                 uint16_t Shift, SegmentRegisters SegmentReg)
-    : OperandX8632(kMem, Ty), Base(Base), Offset(Offset), Index(Index),
+MachineTraits<TargetX8632>::X86OperandMem::X86OperandMem(
+    Cfg *Func, Type Ty, Variable *Base, Constant *Offset, Variable *Index,
+    uint16_t Shift, SegmentRegisters SegmentReg)
+    : X86Operand(kMem, Ty), Base(Base), Offset(Offset), Index(Index),
       Shift(Shift), SegmentReg(SegmentReg), Randomized(false) {
   assert(Shift <= 3);
   Vars = nullptr;
@@ -114,2806 +98,13 @@
   }
 }
 
-InstX8632FakeRMW::InstX8632FakeRMW(Cfg *Func, Operand *Data, Operand *Addr,
-                                   InstArithmetic::OpKind Op, Variable *Beacon)
-    : InstX8632(Func, InstX8632::FakeRMW, 3, nullptr), Op(Op) {
-  addSource(Data);
-  addSource(Addr);
-  addSource(Beacon);
-}
-
-InstX8632AdjustStack::InstX8632AdjustStack(Cfg *Func, SizeT Amount,
-                                           Variable *Esp)
-    : InstX8632(Func, InstX8632::Adjuststack, 1, Esp), Amount(Amount) {
-  addSource(Esp);
-}
-
-InstX8632Mul::InstX8632Mul(Cfg *Func, Variable *Dest, Variable *Source1,
-                           Operand *Source2)
-    : InstX8632(Func, InstX8632::Mul, 2, Dest) {
-  addSource(Source1);
-  addSource(Source2);
-}
-
-InstX8632Shld::InstX8632Shld(Cfg *Func, Variable *Dest, Variable *Source1,
-                             Variable *Source2)
-    : InstX8632(Func, InstX8632::Shld, 3, Dest) {
-  addSource(Dest);
-  addSource(Source1);
-  addSource(Source2);
-}
-
-InstX8632Shrd::InstX8632Shrd(Cfg *Func, Variable *Dest, Variable *Source1,
-                             Variable *Source2)
-    : InstX8632(Func, InstX8632::Shrd, 3, Dest) {
-  addSource(Dest);
-  addSource(Source1);
-  addSource(Source2);
-}
-
-InstX8632Label::InstX8632Label(Cfg *Func, TargetX8632 *Target)
-    : InstX8632(Func, InstX8632::Label, 0, nullptr),
-      Number(Target->makeNextLabelNumber()) {}
-
-IceString InstX8632Label::getName(const Cfg *Func) const {
-  return ".L" + Func->getFunctionName() + "$local$__" + std::to_string(Number);
-}
-
-InstX8632Br::InstX8632Br(Cfg *Func, const CfgNode *TargetTrue,
-                         const CfgNode *TargetFalse,
-                         const InstX8632Label *Label,
-                         X8632::Traits::Cond::BrCond Condition)
-    : InstX8632(Func, InstX8632::Br, 0, nullptr), Condition(Condition),
-      TargetTrue(TargetTrue), TargetFalse(TargetFalse), Label(Label) {}
-
-bool InstX8632Br::optimizeBranch(const CfgNode *NextNode) {
-  // If there is no next block, then there can be no fallthrough to
-  // optimize.
-  if (NextNode == nullptr)
-    return false;
-  // Intra-block conditional branches can't be optimized.
-  if (Label)
-    return false;
-  // If there is no fallthrough node, such as a non-default case label
-  // for a switch instruction, then there is no opportunity to
-  // optimize.
-  if (getTargetFalse() == nullptr)
-    return false;
-
-  // Unconditional branch to the next node can be removed.
-  if (Condition == X8632::Traits::Cond::Br_None &&
-      getTargetFalse() == NextNode) {
-    assert(getTargetTrue() == nullptr);
-    setDeleted();
-    return true;
-  }
-  // If the fallthrough is to the next node, set fallthrough to nullptr
-  // to indicate.
-  if (getTargetFalse() == NextNode) {
-    TargetFalse = nullptr;
-    return true;
-  }
-  // If TargetTrue is the next node, and TargetFalse is not nullptr
-  // (which was already tested above), then invert the branch
-  // condition, swap the targets, and set new fallthrough to nullptr.
-  if (getTargetTrue() == NextNode) {
-    assert(Condition != X8632::Traits::Cond::Br_None);
-    Condition = getOppositeCondition(Condition);
-    TargetTrue = getTargetFalse();
-    TargetFalse = nullptr;
-    return true;
-  }
-  return false;
-}
-
-bool InstX8632Br::repointEdge(CfgNode *OldNode, CfgNode *NewNode) {
-  if (TargetFalse == OldNode) {
-    TargetFalse = NewNode;
-    return true;
-  } else if (TargetTrue == OldNode) {
-    TargetTrue = NewNode;
-    return true;
-  }
-  return false;
-}
-
-InstX8632Jmp::InstX8632Jmp(Cfg *Func, Operand *Target)
-    : InstX8632(Func, InstX8632::Jmp, 1, nullptr) {
-  addSource(Target);
-}
-
-InstX8632Call::InstX8632Call(Cfg *Func, Variable *Dest, Operand *CallTarget)
-    : InstX8632(Func, InstX8632::Call, 1, Dest) {
-  HasSideEffects = true;
-  addSource(CallTarget);
-}
-
-InstX8632Cmov::InstX8632Cmov(Cfg *Func, Variable *Dest, Operand *Source,
-                             X8632::Traits::Cond::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.
-  addSource(Dest);
-  addSource(Source);
-}
-
-InstX8632Cmpps::InstX8632Cmpps(Cfg *Func, Variable *Dest, Operand *Source,
-                               X8632::Traits::Cond::CmppsCond Condition)
-    : InstX8632(Func, InstX8632::Cmpps, 2, Dest), Condition(Condition) {
-  addSource(Dest);
-  addSource(Source);
-}
-
-InstX8632Cmpxchg::InstX8632Cmpxchg(Cfg *Func, Operand *DestOrAddr,
-                                   Variable *Eax, Variable *Desired,
-                                   bool Locked)
-    : InstX8632Lockable(Func, InstX8632::Cmpxchg, 3,
-                        llvm::dyn_cast<Variable>(DestOrAddr), Locked) {
-  assert(Eax->getRegNum() == RegX8632::Reg_eax);
-  addSource(DestOrAddr);
-  addSource(Eax);
-  addSource(Desired);
-}
-
-InstX8632Cmpxchg8b::InstX8632Cmpxchg8b(Cfg *Func, OperandX8632Mem *Addr,
-                                       Variable *Edx, Variable *Eax,
-                                       Variable *Ecx, Variable *Ebx,
-                                       bool Locked)
-    : InstX8632Lockable(Func, InstX8632::Cmpxchg, 5, nullptr, Locked) {
-  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);
-  addSource(Ecx);
-  addSource(Ebx);
-}
-
-InstX8632Cvt::InstX8632Cvt(Cfg *Func, Variable *Dest, Operand *Source,
-                           CvtVariant Variant)
-    : InstX8632(Func, InstX8632::Cvt, 1, Dest), Variant(Variant) {
-  addSource(Source);
-}
-
-InstX8632Icmp::InstX8632Icmp(Cfg *Func, Operand *Src0, Operand *Src1)
-    : InstX8632(Func, InstX8632::Icmp, 2, nullptr) {
-  addSource(Src0);
-  addSource(Src1);
-}
-
-InstX8632Ucomiss::InstX8632Ucomiss(Cfg *Func, Operand *Src0, Operand *Src1)
-    : InstX8632(Func, InstX8632::Ucomiss, 2, nullptr) {
-  addSource(Src0);
-  addSource(Src1);
-}
-
-InstX8632UD2::InstX8632UD2(Cfg *Func)
-    : InstX8632(Func, InstX8632::UD2, 0, nullptr) {}
-
-InstX8632Test::InstX8632Test(Cfg *Func, Operand *Src1, Operand *Src2)
-    : InstX8632(Func, InstX8632::Test, 2, nullptr) {
-  addSource(Src1);
-  addSource(Src2);
-}
-
-InstX8632Mfence::InstX8632Mfence(Cfg *Func)
-    : InstX8632(Func, InstX8632::Mfence, 0, nullptr) {
-  HasSideEffects = true;
-}
-
-InstX8632Store::InstX8632Store(Cfg *Func, Operand *Value, OperandX8632 *Mem)
-    : InstX8632(Func, InstX8632::Store, 2, nullptr) {
-  addSource(Value);
-  addSource(Mem);
-}
-
-InstX8632StoreP::InstX8632StoreP(Cfg *Func, Variable *Value,
-                                 OperandX8632Mem *Mem)
-    : InstX8632(Func, InstX8632::StoreP, 2, nullptr) {
-  addSource(Value);
-  addSource(Mem);
-}
-
-InstX8632StoreQ::InstX8632StoreQ(Cfg *Func, Variable *Value,
-                                 OperandX8632Mem *Mem)
-    : InstX8632(Func, InstX8632::StoreQ, 2, nullptr) {
-  addSource(Value);
-  addSource(Mem);
-}
-
-InstX8632Nop::InstX8632Nop(Cfg *Func, InstX8632Nop::NopVariant Variant)
-    : InstX8632(Func, InstX8632::Nop, 0, nullptr), Variant(Variant) {}
-
-InstX8632Fld::InstX8632Fld(Cfg *Func, Operand *Src)
-    : InstX8632(Func, InstX8632::Fld, 1, nullptr) {
-  addSource(Src);
-}
-
-InstX8632Fstp::InstX8632Fstp(Cfg *Func, Variable *Dest)
-    : InstX8632(Func, InstX8632::Fstp, 0, Dest) {}
-
-InstX8632Pop::InstX8632Pop(Cfg *Func, Variable *Dest)
-    : InstX8632(Func, InstX8632::Pop, 0, Dest) {
-  // A pop instruction affects the stack pointer and so it should not
-  // be allowed to be automatically dead-code eliminated.  (The
-  // corresponding push instruction doesn't need this treatment
-  // because it has no dest variable and therefore won't be dead-code
-  // eliminated.)  This is needed for late-stage liveness analysis
-  // (e.g. asm-verbose mode).
-  HasSideEffects = true;
-}
-
-InstX8632Push::InstX8632Push(Cfg *Func, Variable *Source)
-    : InstX8632(Func, InstX8632::Push, 1, nullptr) {
-  addSource(Source);
-}
-
-InstX8632Ret::InstX8632Ret(Cfg *Func, Variable *Source)
-    : InstX8632(Func, InstX8632::Ret, Source ? 1 : 0, nullptr) {
-  if (Source)
-    addSource(Source);
-}
-
-InstX8632Setcc::InstX8632Setcc(Cfg *Func, Variable *Dest,
-                               X8632::Traits::Cond::BrCond Cond)
-    : InstX8632(Func, InstX8632::Setcc, 0, Dest), Condition(Cond) {}
-
-InstX8632Xadd::InstX8632Xadd(Cfg *Func, Operand *Dest, Variable *Source,
-                             bool Locked)
-    : InstX8632Lockable(Func, InstX8632::Xadd, 2,
-                        llvm::dyn_cast<Variable>(Dest), Locked) {
-  addSource(Dest);
-  addSource(Source);
-}
-
-InstX8632Xchg::InstX8632Xchg(Cfg *Func, Operand *Dest, Variable *Source)
-    : InstX8632(Func, InstX8632::Xchg, 2, llvm::dyn_cast<Variable>(Dest)) {
-  addSource(Dest);
-  addSource(Source);
-}
-
-// ======================== Dump routines ======================== //
-
-void InstX8632::dump(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrDump();
-  Str << "[X8632] ";
-  Inst::dump(Func);
-}
-
-void InstX8632FakeRMW::dump(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrDump();
-  Type Ty = getData()->getType();
-  Str << "rmw " << InstArithmetic::getOpName(getOp()) << " " << Ty << " *";
-  getAddr()->dump(Func);
-  Str << ", ";
-  getData()->dump(Func);
-  Str << ", beacon=";
-  getBeacon()->dump(Func);
-}
-
-void InstX8632Label::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrEmit();
-  Str << getName(Func) << ":";
-}
-
-void InstX8632Label::emitIAS(const Cfg *Func) const {
-  X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>();
-  Asm->BindLocalLabel(Number);
-}
-
-void InstX8632Label::dump(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrDump();
-  Str << getName(Func) << ":";
-}
-
-void InstX8632Br::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrEmit();
-  Str << "\t";
-
-  if (Condition == X8632::Traits::Cond::Br_None) {
-    Str << "jmp";
-  } else {
-    Str << InstX8632BrAttributes[Condition].EmitString;
-  }
-
-  if (Label) {
-    Str << "\t" << Label->getName(Func);
-  } else {
-    if (Condition == X8632::Traits::Cond::Br_None) {
-      Str << "\t" << getTargetFalse()->getAsmName();
-    } else {
-      Str << "\t" << getTargetTrue()->getAsmName();
-      if (getTargetFalse()) {
-        Str << "\n\tjmp\t" << getTargetFalse()->getAsmName();
-      }
-    }
-  }
-}
-
-void InstX8632Br::emitIAS(const Cfg *Func) const {
-  X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>();
-  if (Label) {
-    X8632::Label *L = Asm->GetOrCreateLocalLabel(Label->getNumber());
-    // In all these cases, local Labels should only be used for Near.
-    const bool Near = true;
-    if (Condition == X8632::Traits::Cond::Br_None) {
-      Asm->jmp(L, Near);
-    } else {
-      Asm->j(Condition, L, Near);
-    }
-  } else {
-    // Pessimistically assume it's far. This only affects Labels that
-    // are not Bound.
-    const bool Near = false;
-    if (Condition == X8632::Traits::Cond::Br_None) {
-      X8632::Label *L =
-          Asm->GetOrCreateCfgNodeLabel(getTargetFalse()->getIndex());
-      assert(!getTargetTrue());
-      Asm->jmp(L, Near);
-    } else {
-      X8632::Label *L =
-          Asm->GetOrCreateCfgNodeLabel(getTargetTrue()->getIndex());
-      Asm->j(Condition, L, Near);
-      if (getTargetFalse()) {
-        X8632::Label *L2 =
-            Asm->GetOrCreateCfgNodeLabel(getTargetFalse()->getIndex());
-        Asm->jmp(L2, Near);
-      }
-    }
-  }
-}
-
-void InstX8632Br::dump(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrDump();
-  Str << "br ";
-
-  if (Condition == X8632::Traits::Cond::Br_None) {
-    Str << "label %"
-        << (Label ? Label->getName(Func) : getTargetFalse()->getName());
-    return;
-  }
-
-  Str << InstX8632BrAttributes[Condition].DisplayString;
-  if (Label) {
-    Str << ", label %" << Label->getName(Func);
-  } else {
-    Str << ", label %" << getTargetTrue()->getName();
-    if (getTargetFalse()) {
-      Str << ", label %" << getTargetFalse()->getName();
-    }
-  }
-}
-
-void InstX8632Jmp::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrEmit();
-  assert(getSrcSize() == 1);
-  Str << "\tjmp\t*";
-  getJmpTarget()->emit(Func);
-}
-
-void InstX8632Jmp::emitIAS(const Cfg *Func) const {
-  // Note: Adapted (mostly copied) from InstX8632Call::emitIAS().
-  X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>();
-  Operand *Target = getJmpTarget();
-  if (const auto Var = llvm::dyn_cast<Variable>(Target)) {
-    if (Var->hasReg()) {
-      Asm->jmp(RegX8632::getEncodedGPR(Var->getRegNum()));
-    } else {
-      // The jmp instruction with a memory operand should be possible
-      // to encode, but it isn't a valid sandboxed instruction, and
-      // there shouldn't be a register allocation issue to jump
-      // through a scratch register, so we don't really need to bother
-      // implementing it.
-      llvm::report_fatal_error("Assembler can't jmp to memory operand");
-    }
-  } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Target)) {
-    (void)Mem;
-    assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
-    llvm::report_fatal_error("Assembler can't jmp to memory operand");
-  } else if (const auto CR = llvm::dyn_cast<ConstantRelocatable>(Target)) {
-    assert(CR->getOffset() == 0 && "We only support jumping to a function");
-    Asm->jmp(CR);
-  } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Target)) {
-    // NaCl trampoline calls refer to an address within the sandbox directly.
-    // This is usually only needed for non-IRT builds and otherwise not
-    // very portable or stable. Usually this is only done for "calls"
-    // and not jumps.
-    // TODO(jvoung): Support this when there is a lowering that
-    // actually triggers this case.
-    (void)Imm;
-    llvm::report_fatal_error("Unexpected jmp to absolute address");
-  } else {
-    llvm::report_fatal_error("Unexpected operand type");
-  }
-}
-
-void InstX8632Jmp::dump(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrDump();
-  Str << "jmp ";
-  getJmpTarget()->dump(Func);
-}
-
-void InstX8632Call::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrEmit();
-  assert(getSrcSize() == 1);
-  Str << "\tcall\t";
-  if (const auto CI = llvm::dyn_cast<ConstantInteger32>(getCallTarget())) {
-    // Emit without a leading '$'.
-    Str << CI->getValue();
-  } else if (const auto CallTarget =
-                 llvm::dyn_cast<ConstantRelocatable>(getCallTarget())) {
-    CallTarget->emitWithoutPrefix(Func->getTarget());
-  } else {
-    Str << "*";
-    getCallTarget()->emit(Func);
-  }
-  Func->getTarget()->resetStackAdjustment();
-}
-
-void InstX8632Call::emitIAS(const Cfg *Func) const {
-  X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>();
-  Operand *Target = getCallTarget();
-  if (const auto Var = llvm::dyn_cast<Variable>(Target)) {
-    if (Var->hasReg()) {
-      Asm->call(RegX8632::getEncodedGPR(Var->getRegNum()));
-    } else {
-      Asm->call(static_cast<TargetX8632 *>(Func->getTarget())
-                    ->stackVarToAsmOperand(Var));
-    }
-  } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Target)) {
-    assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
-    Asm->call(Mem->toAsmAddress(Asm));
-  } else if (const auto CR = llvm::dyn_cast<ConstantRelocatable>(Target)) {
-    assert(CR->getOffset() == 0 && "We only support calling a function");
-    Asm->call(CR);
-  } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Target)) {
-    Asm->call(X8632::Immediate(Imm->getValue()));
-  } else {
-    llvm_unreachable("Unexpected operand type");
-  }
-  Func->getTarget()->resetStackAdjustment();
-}
-
-void InstX8632Call::dump(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrDump();
-  if (getDest()) {
-    dumpDest(Func);
-    Str << " = ";
-  }
-  Str << "call ";
-  getCallTarget()->dump(Func);
-}
-
-// The ShiftHack parameter is used to emit "cl" instead of "ecx" for
-// shift instructions, in order to be syntactically valid.  The
-// Opcode parameter needs to be char* and not IceString because of
-// template issues.
-void InstX8632::emitTwoAddress(const char *Opcode, const Inst *Inst,
-                               const Cfg *Func, bool ShiftHack) {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrEmit();
-  assert(Inst->getSrcSize() == 2);
-  Operand *Dest = Inst->getDest();
-  if (Dest == nullptr)
-    Dest = Inst->getSrc(0);
-  assert(Dest == Inst->getSrc(0));
-  Operand *Src1 = Inst->getSrc(1);
-  Str << "\t" << Opcode << InstX8632::getWidthString(Dest->getType()) << "\t";
-  const auto ShiftReg = llvm::dyn_cast<Variable>(Src1);
-  if (ShiftHack && ShiftReg && ShiftReg->getRegNum() == RegX8632::Reg_ecx)
-    Str << "%cl";
-  else
-    Src1->emit(Func);
-  Str << ", ";
-  Dest->emit(Func);
-}
-
-void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Op,
-                    const X8632::AssemblerX8632::GPREmitterOneOp &Emitter) {
-  X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>();
-  if (const auto Var = llvm::dyn_cast<Variable>(Op)) {
-    if (Var->hasReg()) {
-      // We cheat a little and use GPRRegister even for byte operations.
-      RegX8632::GPRRegister VarReg =
-          RegX8632::getEncodedByteRegOrGPR(Ty, Var->getRegNum());
-      (Asm->*(Emitter.Reg))(Ty, VarReg);
-    } else {
-      X8632::Traits::Address StackAddr(
-          static_cast<TargetX8632 *>(Func->getTarget())
-              ->stackVarToAsmOperand(Var));
-      (Asm->*(Emitter.Addr))(Ty, StackAddr);
-    }
-  } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Op)) {
-    Mem->emitSegmentOverride(Asm);
-    (Asm->*(Emitter.Addr))(Ty, Mem->toAsmAddress(Asm));
-  } else {
-    llvm_unreachable("Unexpected operand type");
-  }
-}
-
-template <bool VarCanBeByte, bool SrcCanBeByte>
-void emitIASRegOpTyGPR(const Cfg *Func, Type Ty, const Variable *Var,
-                       const Operand *Src,
-                       const X8632::AssemblerX8632::GPREmitterRegOp &Emitter) {
-  X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>();
-  assert(Var->hasReg());
-  // We cheat a little and use GPRRegister even for byte operations.
-  RegX8632::GPRRegister VarReg =
-      VarCanBeByte ? RegX8632::getEncodedByteRegOrGPR(Ty, Var->getRegNum())
-                   : RegX8632::getEncodedGPR(Var->getRegNum());
-  if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) {
-    if (SrcVar->hasReg()) {
-      RegX8632::GPRRegister SrcReg =
-          SrcCanBeByte
-              ? RegX8632::getEncodedByteRegOrGPR(Ty, SrcVar->getRegNum())
-              : RegX8632::getEncodedGPR(SrcVar->getRegNum());
-      (Asm->*(Emitter.GPRGPR))(Ty, VarReg, SrcReg);
-    } else {
-      X8632::Traits::Address SrcStackAddr =
-          static_cast<TargetX8632 *>(Func->getTarget())
-              ->stackVarToAsmOperand(SrcVar);
-      (Asm->*(Emitter.GPRAddr))(Ty, VarReg, SrcStackAddr);
-    }
-  } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) {
-    Mem->emitSegmentOverride(Asm);
-    (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Mem->toAsmAddress(Asm));
-  } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) {
-    (Asm->*(Emitter.GPRImm))(Ty, VarReg, X8632::Immediate(Imm->getValue()));
-  } else if (const auto Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) {
-    AssemblerFixup *Fixup = Asm->createFixup(llvm::ELF::R_386_32, Reloc);
-    (Asm->*(Emitter.GPRImm))(Ty, VarReg,
-                             X8632::Immediate(Reloc->getOffset(), Fixup));
-  } else if (const auto Split = llvm::dyn_cast<VariableSplit>(Src)) {
-    (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Split->toAsmAddress(Func));
-  } else {
-    llvm_unreachable("Unexpected operand type");
-  }
-}
-
-void emitIASAddrOpTyGPR(
-    const Cfg *Func, Type Ty, const X8632::Traits::Address &Addr,
-    const Operand *Src,
-    const X8632::AssemblerX8632::GPREmitterAddrOp &Emitter) {
-  X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>();
-  // Src can only be Reg or Immediate.
-  if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) {
-    assert(SrcVar->hasReg());
-    RegX8632::GPRRegister SrcReg =
-        RegX8632::getEncodedByteRegOrGPR(Ty, SrcVar->getRegNum());
-    (Asm->*(Emitter.AddrGPR))(Ty, Addr, SrcReg);
-  } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) {
-    (Asm->*(Emitter.AddrImm))(Ty, Addr, X8632::Immediate(Imm->getValue()));
-  } else if (const auto Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) {
-    AssemblerFixup *Fixup = Asm->createFixup(llvm::ELF::R_386_32, Reloc);
-    (Asm->*(Emitter.AddrImm))(Ty, Addr,
-                              X8632::Immediate(Reloc->getOffset(), Fixup));
-  } else {
-    llvm_unreachable("Unexpected operand type");
-  }
-}
-
-void emitIASAsAddrOpTyGPR(
-    const Cfg *Func, Type Ty, const Operand *Op0, const Operand *Op1,
-    const X8632::AssemblerX8632::GPREmitterAddrOp &Emitter) {
-  if (const auto Op0Var = llvm::dyn_cast<Variable>(Op0)) {
-    assert(!Op0Var->hasReg());
-    X8632::Traits::Address StackAddr(
-        static_cast<TargetX8632 *>(Func->getTarget())
-            ->stackVarToAsmOperand(Op0Var));
-    emitIASAddrOpTyGPR(Func, Ty, StackAddr, Op1, Emitter);
-  } else if (const auto Op0Mem = llvm::dyn_cast<OperandX8632Mem>(Op0)) {
-    X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>();
-    Op0Mem->emitSegmentOverride(Asm);
-    emitIASAddrOpTyGPR(Func, Ty, Op0Mem->toAsmAddress(Asm), Op1, Emitter);
-  } else if (const auto Split = llvm::dyn_cast<VariableSplit>(Op0)) {
-    emitIASAddrOpTyGPR(Func, Ty, Split->toAsmAddress(Func), Op1, Emitter);
-  } else {
-    llvm_unreachable("Unexpected operand type");
-  }
-}
-
-void InstX8632::emitIASGPRShift(
-    const Cfg *Func, Type Ty, const Variable *Var, const Operand *Src,
-    const X8632::AssemblerX8632::GPREmitterShiftOp &Emitter) {
-  X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>();
-  // Technically, the Dest Var can be mem as well, but we only use Reg.
-  // We can extend this to check Dest if we decide to use that form.
-  assert(Var->hasReg());
-  // We cheat a little and use GPRRegister even for byte operations.
-  RegX8632::GPRRegister VarReg =
-      RegX8632::getEncodedByteRegOrGPR(Ty, Var->getRegNum());
-  // Src must be reg == ECX or an Imm8.
-  // This is asserted by the assembler.
-  if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) {
-    assert(SrcVar->hasReg());
-    RegX8632::GPRRegister SrcReg =
-        RegX8632::getEncodedByteRegOrGPR(Ty, SrcVar->getRegNum());
-    (Asm->*(Emitter.GPRGPR))(Ty, VarReg, SrcReg);
-  } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) {
-    (Asm->*(Emitter.GPRImm))(Ty, VarReg, X8632::Immediate(Imm->getValue()));
-  } else {
-    llvm_unreachable("Unexpected operand type");
-  }
-}
-
-void emitIASGPRShiftDouble(
-    const Cfg *Func, const Variable *Dest, const Operand *Src1Op,
-    const Operand *Src2Op,
-    const X8632::AssemblerX8632::GPREmitterShiftD &Emitter) {
-  X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>();
-  // Dest can be reg or mem, but we only use the reg variant.
-  assert(Dest->hasReg());
-  RegX8632::GPRRegister DestReg = RegX8632::getEncodedGPR(Dest->getRegNum());
-  // SrcVar1 must be reg.
-  const auto SrcVar1 = llvm::cast<Variable>(Src1Op);
-  assert(SrcVar1->hasReg());
-  RegX8632::GPRRegister SrcReg = RegX8632::getEncodedGPR(SrcVar1->getRegNum());
-  Type Ty = SrcVar1->getType();
-  // Src2 can be the implicit CL register or an immediate.
-  if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src2Op)) {
-    (Asm->*(Emitter.GPRGPRImm))(Ty, DestReg, SrcReg,
-                                X8632::Immediate(Imm->getValue()));
-  } else {
-    assert(llvm::cast<Variable>(Src2Op)->getRegNum() == RegX8632::Reg_ecx);
-    (Asm->*(Emitter.GPRGPR))(Ty, DestReg, SrcReg);
-  }
-}
-
-void emitIASXmmShift(const Cfg *Func, Type Ty, const Variable *Var,
-                     const Operand *Src,
-                     const X8632::AssemblerX8632::XmmEmitterShiftOp &Emitter) {
-  X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>();
-  assert(Var->hasReg());
-  RegX8632::XmmRegister VarReg = RegX8632::getEncodedXmm(Var->getRegNum());
-  if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) {
-    if (SrcVar->hasReg()) {
-      RegX8632::XmmRegister SrcReg =
-          RegX8632::getEncodedXmm(SrcVar->getRegNum());
-      (Asm->*(Emitter.XmmXmm))(Ty, VarReg, SrcReg);
-    } else {
-      X8632::Traits::Address SrcStackAddr =
-          static_cast<TargetX8632 *>(Func->getTarget())
-              ->stackVarToAsmOperand(SrcVar);
-      (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcStackAddr);
-    }
-  } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) {
-    assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
-    (Asm->*(Emitter.XmmAddr))(Ty, VarReg, Mem->toAsmAddress(Asm));
-  } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) {
-    (Asm->*(Emitter.XmmImm))(Ty, VarReg, X8632::Immediate(Imm->getValue()));
-  } else {
-    llvm_unreachable("Unexpected operand type");
-  }
-}
-
-void emitIASRegOpTyXMM(const Cfg *Func, Type Ty, const Variable *Var,
-                       const Operand *Src,
-                       const X8632::AssemblerX8632::XmmEmitterRegOp &Emitter) {
-  X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>();
-  assert(Var->hasReg());
-  RegX8632::XmmRegister VarReg = RegX8632::getEncodedXmm(Var->getRegNum());
-  if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) {
-    if (SrcVar->hasReg()) {
-      RegX8632::XmmRegister SrcReg =
-          RegX8632::getEncodedXmm(SrcVar->getRegNum());
-      (Asm->*(Emitter.XmmXmm))(Ty, VarReg, SrcReg);
-    } else {
-      X8632::Traits::Address SrcStackAddr =
-          static_cast<TargetX8632 *>(Func->getTarget())
-              ->stackVarToAsmOperand(SrcVar);
-      (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcStackAddr);
-    }
-  } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) {
-    assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
-    (Asm->*(Emitter.XmmAddr))(Ty, VarReg, Mem->toAsmAddress(Asm));
-  } else if (const auto Imm = llvm::dyn_cast<Constant>(Src)) {
-    (Asm->*(Emitter.XmmAddr))(Ty, VarReg,
-                              X8632::Traits::Address::ofConstPool(Asm, Imm));
-  } else {
-    llvm_unreachable("Unexpected operand type");
-  }
-}
-
-template <typename DReg_t, typename SReg_t, DReg_t (*destEnc)(int32_t),
-          SReg_t (*srcEnc)(int32_t)>
-void emitIASCastRegOp(
-    const Cfg *Func, Type DispatchTy, const Variable *Dest, const Operand *Src,
-    const X8632::AssemblerX8632::CastEmitterRegOp<DReg_t, SReg_t> Emitter) {
-  X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>();
-  assert(Dest->hasReg());
-  DReg_t DestReg = destEnc(Dest->getRegNum());
-  if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) {
-    if (SrcVar->hasReg()) {
-      SReg_t SrcReg = srcEnc(SrcVar->getRegNum());
-      (Asm->*(Emitter.RegReg))(DispatchTy, DestReg, SrcReg);
-    } else {
-      X8632::Traits::Address SrcStackAddr =
-          static_cast<TargetX8632 *>(Func->getTarget())
-              ->stackVarToAsmOperand(SrcVar);
-      (Asm->*(Emitter.RegAddr))(DispatchTy, DestReg, SrcStackAddr);
-    }
-  } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) {
-    Mem->emitSegmentOverride(Asm);
-    (Asm->*(Emitter.RegAddr))(DispatchTy, DestReg, Mem->toAsmAddress(Asm));
-  } else {
-    llvm_unreachable("Unexpected operand type");
-  }
-}
-
-template <typename DReg_t, typename SReg_t, DReg_t (*destEnc)(int32_t),
-          SReg_t (*srcEnc)(int32_t)>
-void emitIASThreeOpImmOps(
-    const Cfg *Func, Type DispatchTy, const Variable *Dest, const Operand *Src0,
-    const Operand *Src1,
-    const X8632::AssemblerX8632::ThreeOpImmEmitter<DReg_t, SReg_t> Emitter) {
-  X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>();
-  // This only handles Dest being a register, and Src1 being an immediate.
-  assert(Dest->hasReg());
-  DReg_t DestReg = destEnc(Dest->getRegNum());
-  X8632::Immediate Imm(llvm::cast<ConstantInteger32>(Src1)->getValue());
-  if (const auto SrcVar = llvm::dyn_cast<Variable>(Src0)) {
-    if (SrcVar->hasReg()) {
-      SReg_t SrcReg = srcEnc(SrcVar->getRegNum());
-      (Asm->*(Emitter.RegRegImm))(DispatchTy, DestReg, SrcReg, Imm);
-    } else {
-      X8632::Traits::Address SrcStackAddr =
-          static_cast<TargetX8632 *>(Func->getTarget())
-              ->stackVarToAsmOperand(SrcVar);
-      (Asm->*(Emitter.RegAddrImm))(DispatchTy, DestReg, SrcStackAddr, Imm);
-    }
-  } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src0)) {
-    Mem->emitSegmentOverride(Asm);
-    (Asm->*(Emitter.RegAddrImm))(DispatchTy, DestReg, Mem->toAsmAddress(Asm),
-                                 Imm);
-  } else {
-    llvm_unreachable("Unexpected operand type");
-  }
-}
-
-void emitIASMovlikeXMM(const Cfg *Func, const Variable *Dest,
-                       const Operand *Src,
-                       const X8632::AssemblerX8632::XmmEmitterMovOps Emitter) {
-  X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>();
-  if (Dest->hasReg()) {
-    RegX8632::XmmRegister DestReg = RegX8632::getEncodedXmm(Dest->getRegNum());
-    if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) {
-      if (SrcVar->hasReg()) {
-        (Asm->*(Emitter.XmmXmm))(DestReg,
-                                 RegX8632::getEncodedXmm(SrcVar->getRegNum()));
-      } else {
-        X8632::Traits::Address StackAddr(
-            static_cast<TargetX8632 *>(Func->getTarget())
-                ->stackVarToAsmOperand(SrcVar));
-        (Asm->*(Emitter.XmmAddr))(DestReg, StackAddr);
-      }
-    } else if (const auto SrcMem = llvm::dyn_cast<OperandX8632Mem>(Src)) {
-      assert(SrcMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
-      (Asm->*(Emitter.XmmAddr))(DestReg, SrcMem->toAsmAddress(Asm));
-    } else {
-      llvm_unreachable("Unexpected operand type");
-    }
-  } else {
-    X8632::Traits::Address StackAddr(
-        static_cast<TargetX8632 *>(Func->getTarget())
-            ->stackVarToAsmOperand(Dest));
-    // Src must be a register in this case.
-    const auto SrcVar = llvm::cast<Variable>(Src);
-    assert(SrcVar->hasReg());
-    (Asm->*(Emitter.AddrXmm))(StackAddr,
-                              RegX8632::getEncodedXmm(SrcVar->getRegNum()));
-  }
-}
-
-// In-place ops
-template <> const char *InstX8632Bswap::Opcode = "bswap";
-template <> const char *InstX8632Neg::Opcode = "neg";
-// Unary ops
-template <> const char *InstX8632Bsf::Opcode = "bsf";
-template <> const char *InstX8632Bsr::Opcode = "bsr";
-template <> const char *InstX8632Lea::Opcode = "lea";
-template <> const char *InstX8632Movd::Opcode = "movd";
-template <> const char *InstX8632Movsx::Opcode = "movs";
-template <> const char *InstX8632Movzx::Opcode = "movz";
-template <> const char *InstX8632Sqrtss::Opcode = "sqrtss";
-template <> const char *InstX8632Cbwdq::Opcode = "cbw/cwd/cdq";
-// Mov-like ops
-template <> const char *InstX8632Mov::Opcode = "mov";
-template <> const char *InstX8632Movp::Opcode = "movups";
-template <> const char *InstX8632Movq::Opcode = "movq";
-// Binary ops
-template <> const char *InstX8632Add::Opcode = "add";
-template <> const char *InstX8632AddRMW::Opcode = "add";
-template <> const char *InstX8632Addps::Opcode = "addps";
-template <> const char *InstX8632Adc::Opcode = "adc";
-template <> const char *InstX8632AdcRMW::Opcode = "adc";
-template <> const char *InstX8632Addss::Opcode = "addss";
-template <> const char *InstX8632Padd::Opcode = "padd";
-template <> const char *InstX8632Sub::Opcode = "sub";
-template <> const char *InstX8632SubRMW::Opcode = "sub";
-template <> const char *InstX8632Subps::Opcode = "subps";
-template <> const char *InstX8632Subss::Opcode = "subss";
-template <> const char *InstX8632Sbb::Opcode = "sbb";
-template <> const char *InstX8632SbbRMW::Opcode = "sbb";
-template <> const char *InstX8632Psub::Opcode = "psub";
-template <> const char *InstX8632And::Opcode = "and";
-template <> const char *InstX8632AndRMW::Opcode = "and";
-template <> const char *InstX8632Pand::Opcode = "pand";
-template <> const char *InstX8632Pandn::Opcode = "pandn";
-template <> const char *InstX8632Or::Opcode = "or";
-template <> const char *InstX8632OrRMW::Opcode = "or";
-template <> const char *InstX8632Por::Opcode = "por";
-template <> const char *InstX8632Xor::Opcode = "xor";
-template <> const char *InstX8632XorRMW::Opcode = "xor";
-template <> const char *InstX8632Pxor::Opcode = "pxor";
-template <> const char *InstX8632Imul::Opcode = "imul";
-template <> const char *InstX8632Mulps::Opcode = "mulps";
-template <> const char *InstX8632Mulss::Opcode = "mulss";
-template <> const char *InstX8632Pmull::Opcode = "pmull";
-template <> const char *InstX8632Pmuludq::Opcode = "pmuludq";
-template <> const char *InstX8632Div::Opcode = "div";
-template <> const char *InstX8632Divps::Opcode = "divps";
-template <> const char *InstX8632Idiv::Opcode = "idiv";
-template <> const char *InstX8632Divss::Opcode = "divss";
-template <> const char *InstX8632Rol::Opcode = "rol";
-template <> const char *InstX8632Shl::Opcode = "shl";
-template <> const char *InstX8632Psll::Opcode = "psll";
-template <> const char *InstX8632Shr::Opcode = "shr";
-template <> const char *InstX8632Sar::Opcode = "sar";
-template <> const char *InstX8632Psra::Opcode = "psra";
-template <> const char *InstX8632Psrl::Opcode = "psrl";
-template <> const char *InstX8632Pcmpeq::Opcode = "pcmpeq";
-template <> const char *InstX8632Pcmpgt::Opcode = "pcmpgt";
-template <> const char *InstX8632MovssRegs::Opcode = "movss";
-// Ternary ops
-template <> const char *InstX8632Insertps::Opcode = "insertps";
-template <> const char *InstX8632Shufps::Opcode = "shufps";
-template <> const char *InstX8632Pinsr::Opcode = "pinsr";
-template <> const char *InstX8632Blendvps::Opcode = "blendvps";
-template <> const char *InstX8632Pblendvb::Opcode = "pblendvb";
-// Three address ops
-template <> const char *InstX8632Pextr::Opcode = "pextr";
-template <> const char *InstX8632Pshufd::Opcode = "pshufd";
-
-// Inplace GPR ops
-template <>
-const X8632::AssemblerX8632::GPREmitterOneOp InstX8632Bswap::Emitter = {
-    &X8632::AssemblerX8632::bswap, nullptr /* only a reg form exists */
-};
-template <>
-const X8632::AssemblerX8632::GPREmitterOneOp InstX8632Neg::Emitter = {
-    &X8632::AssemblerX8632::neg, &X8632::AssemblerX8632::neg};
-
-// Unary GPR ops
-template <>
-const X8632::AssemblerX8632::GPREmitterRegOp InstX8632Bsf::Emitter = {
-    &X8632::AssemblerX8632::bsf, &X8632::AssemblerX8632::bsf, nullptr};
-template <>
-const X8632::AssemblerX8632::GPREmitterRegOp InstX8632Bsr::Emitter = {
-    &X8632::AssemblerX8632::bsr, &X8632::AssemblerX8632::bsr, nullptr};
-template <>
-const X8632::AssemblerX8632::GPREmitterRegOp InstX8632Lea::Emitter = {
-    /* reg/reg and reg/imm are illegal */ nullptr, &X8632::AssemblerX8632::lea,
-    nullptr};
-template <>
-const X8632::AssemblerX8632::GPREmitterRegOp InstX8632Movsx::Emitter = {
-    &X8632::AssemblerX8632::movsx, &X8632::AssemblerX8632::movsx, nullptr};
-template <>
-const X8632::AssemblerX8632::GPREmitterRegOp InstX8632Movzx::Emitter = {
-    &X8632::AssemblerX8632::movzx, &X8632::AssemblerX8632::movzx, nullptr};
-
-// Unary XMM ops
-template <>
-const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Sqrtss::Emitter = {
-    &X8632::AssemblerX8632::sqrtss, &X8632::AssemblerX8632::sqrtss};
-
-// Binary GPR ops
-template <>
-const X8632::AssemblerX8632::GPREmitterRegOp InstX8632Add::Emitter = {
-    &X8632::AssemblerX8632::add, &X8632::AssemblerX8632::add,
-    &X8632::AssemblerX8632::add};
-template <>
-const X8632::AssemblerX8632::GPREmitterAddrOp InstX8632AddRMW::Emitter = {
-    &X8632::AssemblerX8632::add, &X8632::AssemblerX8632::add};
-template <>
-const X8632::AssemblerX8632::GPREmitterRegOp InstX8632Adc::Emitter = {
-    &X8632::AssemblerX8632::adc, &X8632::AssemblerX8632::adc,
-    &X8632::AssemblerX8632::adc};
-template <>
-const X8632::AssemblerX8632::GPREmitterAddrOp InstX8632AdcRMW::Emitter = {
-    &X8632::AssemblerX8632::adc, &X8632::AssemblerX8632::adc};
-template <>
-const X8632::AssemblerX8632::GPREmitterRegOp InstX8632And::Emitter = {
-    &X8632::AssemblerX8632::And, &X8632::AssemblerX8632::And,
-    &X8632::AssemblerX8632::And};
-template <>
-const X8632::AssemblerX8632::GPREmitterAddrOp InstX8632AndRMW::Emitter = {
-    &X8632::AssemblerX8632::And, &X8632::AssemblerX8632::And};
-template <>
-const X8632::AssemblerX8632::GPREmitterRegOp InstX8632Or::Emitter = {
-    &X8632::AssemblerX8632::Or, &X8632::AssemblerX8632::Or,
-    &X8632::AssemblerX8632::Or};
-template <>
-const X8632::AssemblerX8632::GPREmitterAddrOp InstX8632OrRMW::Emitter = {
-    &X8632::AssemblerX8632::Or, &X8632::AssemblerX8632::Or};
-template <>
-const X8632::AssemblerX8632::GPREmitterRegOp InstX8632Sbb::Emitter = {
-    &X8632::AssemblerX8632::sbb, &X8632::AssemblerX8632::sbb,
-    &X8632::AssemblerX8632::sbb};
-template <>
-const X8632::AssemblerX8632::GPREmitterAddrOp InstX8632SbbRMW::Emitter = {
-    &X8632::AssemblerX8632::sbb, &X8632::AssemblerX8632::sbb};
-template <>
-const X8632::AssemblerX8632::GPREmitterRegOp InstX8632Sub::Emitter = {
-    &X8632::AssemblerX8632::sub, &X8632::AssemblerX8632::sub,
-    &X8632::AssemblerX8632::sub};
-template <>
-const X8632::AssemblerX8632::GPREmitterAddrOp InstX8632SubRMW::Emitter = {
-    &X8632::AssemblerX8632::sub, &X8632::AssemblerX8632::sub};
-template <>
-const X8632::AssemblerX8632::GPREmitterRegOp InstX8632Xor::Emitter = {
-    &X8632::AssemblerX8632::Xor, &X8632::AssemblerX8632::Xor,
-    &X8632::AssemblerX8632::Xor};
-template <>
-const X8632::AssemblerX8632::GPREmitterAddrOp InstX8632XorRMW::Emitter = {
-    &X8632::AssemblerX8632::Xor, &X8632::AssemblerX8632::Xor};
-
-// Binary Shift GPR ops
-template <>
-const X8632::AssemblerX8632::GPREmitterShiftOp InstX8632Rol::Emitter = {
-    &X8632::AssemblerX8632::rol, &X8632::AssemblerX8632::rol};
-template <>
-const X8632::AssemblerX8632::GPREmitterShiftOp InstX8632Sar::Emitter = {
-    &X8632::AssemblerX8632::sar, &X8632::AssemblerX8632::sar};
-template <>
-const X8632::AssemblerX8632::GPREmitterShiftOp InstX8632Shl::Emitter = {
-    &X8632::AssemblerX8632::shl, &X8632::AssemblerX8632::shl};
-template <>
-const X8632::AssemblerX8632::GPREmitterShiftOp InstX8632Shr::Emitter = {
-    &X8632::AssemblerX8632::shr, &X8632::AssemblerX8632::shr};
-
-// Binary XMM ops
-template <>
-const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Addss::Emitter = {
-    &X8632::AssemblerX8632::addss, &X8632::AssemblerX8632::addss};
-template <>
-const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Addps::Emitter = {
-    &X8632::AssemblerX8632::addps, &X8632::AssemblerX8632::addps};
-template <>
-const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Divss::Emitter = {
-    &X8632::AssemblerX8632::divss, &X8632::AssemblerX8632::divss};
-template <>
-const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Divps::Emitter = {
-    &X8632::AssemblerX8632::divps, &X8632::AssemblerX8632::divps};
-template <>
-const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Mulss::Emitter = {
-    &X8632::AssemblerX8632::mulss, &X8632::AssemblerX8632::mulss};
-template <>
-const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Mulps::Emitter = {
-    &X8632::AssemblerX8632::mulps, &X8632::AssemblerX8632::mulps};
-template <>
-const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Padd::Emitter = {
-    &X8632::AssemblerX8632::padd, &X8632::AssemblerX8632::padd};
-template <>
-const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Pand::Emitter = {
-    &X8632::AssemblerX8632::pand, &X8632::AssemblerX8632::pand};
-template <>
-const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Pandn::Emitter = {
-    &X8632::AssemblerX8632::pandn, &X8632::AssemblerX8632::pandn};
-template <>
-const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Pcmpeq::Emitter = {
-    &X8632::AssemblerX8632::pcmpeq, &X8632::AssemblerX8632::pcmpeq};
-template <>
-const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Pcmpgt::Emitter = {
-    &X8632::AssemblerX8632::pcmpgt, &X8632::AssemblerX8632::pcmpgt};
-template <>
-const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Pmull::Emitter = {
-    &X8632::AssemblerX8632::pmull, &X8632::AssemblerX8632::pmull};
-template <>
-const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Pmuludq::Emitter = {
-    &X8632::AssemblerX8632::pmuludq, &X8632::AssemblerX8632::pmuludq};
-template <>
-const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Por::Emitter = {
-    &X8632::AssemblerX8632::por, &X8632::AssemblerX8632::por};
-template <>
-const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Psub::Emitter = {
-    &X8632::AssemblerX8632::psub, &X8632::AssemblerX8632::psub};
-template <>
-const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Pxor::Emitter = {
-    &X8632::AssemblerX8632::pxor, &X8632::AssemblerX8632::pxor};
-template <>
-const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Subss::Emitter = {
-    &X8632::AssemblerX8632::subss, &X8632::AssemblerX8632::subss};
-template <>
-const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Subps::Emitter = {
-    &X8632::AssemblerX8632::subps, &X8632::AssemblerX8632::subps};
-
-// Binary XMM Shift ops
-template <>
-const X8632::AssemblerX8632::XmmEmitterShiftOp InstX8632Psll::Emitter = {
-    &X8632::AssemblerX8632::psll, &X8632::AssemblerX8632::psll,
-    &X8632::AssemblerX8632::psll};
-template <>
-const X8632::AssemblerX8632::XmmEmitterShiftOp InstX8632Psra::Emitter = {
-    &X8632::AssemblerX8632::psra, &X8632::AssemblerX8632::psra,
-    &X8632::AssemblerX8632::psra};
-template <>
-const X8632::AssemblerX8632::XmmEmitterShiftOp InstX8632Psrl::Emitter = {
-    &X8632::AssemblerX8632::psrl, &X8632::AssemblerX8632::psrl,
-    &X8632::AssemblerX8632::psrl};
-
-template <> void InstX8632Sqrtss::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrEmit();
-  assert(getSrcSize() == 1);
-  Type Ty = getSrc(0)->getType();
-  assert(isScalarFloatingType(Ty));
-  Str << "\tsqrt" << TypeX8632Attributes[Ty].SdSsString << "\t";
-  getSrc(0)->emit(Func);
-  Str << ", ";
-  getDest()->emit(Func);
-}
-
-template <> void InstX8632Addss::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  char buf[30];
-  snprintf(buf, llvm::array_lengthof(buf), "add%s",
-           TypeX8632Attributes[getDest()->getType()].SdSsString);
-  emitTwoAddress(buf, this, Func);
-}
-
-template <> void InstX8632Padd::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  char buf[30];
-  snprintf(buf, llvm::array_lengthof(buf), "padd%s",
-           TypeX8632Attributes[getDest()->getType()].PackString);
-  emitTwoAddress(buf, this, Func);
-}
-
-template <> void InstX8632Pmull::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  char buf[30];
-  bool TypesAreValid = getDest()->getType() == IceType_v4i32 ||
-                       getDest()->getType() == IceType_v8i16;
-  bool InstructionSetIsValid =
-      getDest()->getType() == IceType_v8i16 ||
-      static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >=
-          X8632::Traits::SSE4_1;
-  (void)TypesAreValid;
-  (void)InstructionSetIsValid;
-  assert(TypesAreValid);
-  assert(InstructionSetIsValid);
-  snprintf(buf, llvm::array_lengthof(buf), "pmull%s",
-           TypeX8632Attributes[getDest()->getType()].PackString);
-  emitTwoAddress(buf, this, Func);
-}
-
-template <> void InstX8632Pmull::emitIAS(const Cfg *Func) const {
-  Type Ty = getDest()->getType();
-  bool TypesAreValid = Ty == IceType_v4i32 || Ty == IceType_v8i16;
-  bool InstructionSetIsValid =
-      Ty == IceType_v8i16 ||
-      static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >=
-          X8632::Traits::SSE4_1;
-  (void)TypesAreValid;
-  (void)InstructionSetIsValid;
-  assert(TypesAreValid);
-  assert(InstructionSetIsValid);
-  assert(getSrcSize() == 2);
-  Type ElementTy = typeElementType(Ty);
-  emitIASRegOpTyXMM(Func, ElementTy, getDest(), getSrc(1), Emitter);
-}
-
-template <> void InstX8632Subss::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  char buf[30];
-  snprintf(buf, llvm::array_lengthof(buf), "sub%s",
-           TypeX8632Attributes[getDest()->getType()].SdSsString);
-  emitTwoAddress(buf, this, Func);
-}
-
-template <> void InstX8632Psub::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  char buf[30];
-  snprintf(buf, llvm::array_lengthof(buf), "psub%s",
-           TypeX8632Attributes[getDest()->getType()].PackString);
-  emitTwoAddress(buf, this, Func);
-}
-
-template <> void InstX8632Mulss::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  char buf[30];
-  snprintf(buf, llvm::array_lengthof(buf), "mul%s",
-           TypeX8632Attributes[getDest()->getType()].SdSsString);
-  emitTwoAddress(buf, this, Func);
-}
-
-template <> void InstX8632Pmuludq::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  assert(getSrc(0)->getType() == IceType_v4i32 &&
-         getSrc(1)->getType() == IceType_v4i32);
-  emitTwoAddress(Opcode, this, Func);
-}
-
-template <> void InstX8632Divss::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  char buf[30];
-  snprintf(buf, llvm::array_lengthof(buf), "div%s",
-           TypeX8632Attributes[getDest()->getType()].SdSsString);
-  emitTwoAddress(buf, this, Func);
-}
-
-template <> void InstX8632Div::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrEmit();
-  assert(getSrcSize() == 3);
-  Operand *Src1 = getSrc(1);
-  Str << "\t" << Opcode << getWidthString(Src1->getType()) << "\t";
-  Src1->emit(Func);
-}
-
-template <> void InstX8632Div::emitIAS(const Cfg *Func) const {
-  assert(getSrcSize() == 3);
-  const Operand *Src = getSrc(1);
-  Type Ty = Src->getType();
-  const static X8632::AssemblerX8632::GPREmitterOneOp Emitter = {
-      &X8632::AssemblerX8632::div, &X8632::AssemblerX8632::div};
-  emitIASOpTyGPR(Func, Ty, Src, Emitter);
-}
-
-template <> void InstX8632Idiv::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrEmit();
-  assert(getSrcSize() == 3);
-  Operand *Src1 = getSrc(1);
-  Str << "\t" << Opcode << getWidthString(Src1->getType()) << "\t";
-  Src1->emit(Func);
-}
-
-template <> void InstX8632Idiv::emitIAS(const Cfg *Func) const {
-  assert(getSrcSize() == 3);
-  const Operand *Src = getSrc(1);
-  Type Ty = Src->getType();
-  const static X8632::AssemblerX8632::GPREmitterOneOp Emitter = {
-      &X8632::AssemblerX8632::idiv, &X8632::AssemblerX8632::idiv};
-  emitIASOpTyGPR(Func, Ty, Src, Emitter);
-}
-
-namespace {
-
-// pblendvb and blendvps take xmm0 as a final implicit argument.
-void emitVariableBlendInst(const char *Opcode, const Inst *Inst,
-                           const Cfg *Func) {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrEmit();
-  assert(Inst->getSrcSize() == 3);
-  assert(llvm::cast<Variable>(Inst->getSrc(2))->getRegNum() ==
-         RegX8632::Reg_xmm0);
-  Str << "\t" << Opcode << "\t";
-  Inst->getSrc(1)->emit(Func);
-  Str << ", ";
-  Inst->getDest()->emit(Func);
-}
-
-void emitIASVariableBlendInst(
-    const Inst *Inst, const Cfg *Func,
-    const X8632::AssemblerX8632::XmmEmitterRegOp &Emitter) {
-  assert(Inst->getSrcSize() == 3);
-  assert(llvm::cast<Variable>(Inst->getSrc(2))->getRegNum() ==
-         RegX8632::Reg_xmm0);
-  const Variable *Dest = Inst->getDest();
-  const Operand *Src = Inst->getSrc(1);
-  emitIASRegOpTyXMM(Func, Dest->getType(), Dest, Src, Emitter);
-}
-
-} // end anonymous namespace
-
-template <> void InstX8632Blendvps::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >=
-         X8632::Traits::SSE4_1);
-  emitVariableBlendInst(Opcode, this, Func);
-}
-
-template <> void InstX8632Blendvps::emitIAS(const Cfg *Func) const {
-  assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >=
-         X8632::Traits::SSE4_1);
-  static const X8632::AssemblerX8632::XmmEmitterRegOp Emitter = {
-      &X8632::AssemblerX8632::blendvps, &X8632::AssemblerX8632::blendvps};
-  emitIASVariableBlendInst(this, Func, Emitter);
-}
-
-template <> void InstX8632Pblendvb::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >=
-         X8632::Traits::SSE4_1);
-  emitVariableBlendInst(Opcode, this, Func);
-}
-
-template <> void InstX8632Pblendvb::emitIAS(const Cfg *Func) const {
-  assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >=
-         X8632::Traits::SSE4_1);
-  static const X8632::AssemblerX8632::XmmEmitterRegOp Emitter = {
-      &X8632::AssemblerX8632::pblendvb, &X8632::AssemblerX8632::pblendvb};
-  emitIASVariableBlendInst(this, Func, Emitter);
-}
-
-template <> void InstX8632Imul::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrEmit();
-  assert(getSrcSize() == 2);
-  Variable *Dest = getDest();
-  if (isByteSizedArithType(Dest->getType())) {
-    // The 8-bit version of imul only allows the form "imul r/m8".
-    const auto Src0Var = llvm::dyn_cast<Variable>(getSrc(0));
-    (void)Src0Var;
-    assert(Src0Var && Src0Var->getRegNum() == RegX8632::Reg_eax);
-    Str << "\timulb\t";
-    getSrc(1)->emit(Func);
-  } else if (llvm::isa<Constant>(getSrc(1))) {
-    Str << "\timul" << getWidthString(Dest->getType()) << "\t";
-    getSrc(1)->emit(Func);
-    Str << ", ";
-    getSrc(0)->emit(Func);
-    Str << ", ";
-    Dest->emit(Func);
-  } else {
-    emitTwoAddress("imul", this, Func);
-  }
-}
-
-template <> void InstX8632Imul::emitIAS(const Cfg *Func) const {
-  assert(getSrcSize() == 2);
-  const Variable *Var = getDest();
-  Type Ty = Var->getType();
-  const Operand *Src = getSrc(1);
-  if (isByteSizedArithType(Ty)) {
-    // The 8-bit version of imul only allows the form "imul r/m8".
-    const auto Src0Var = llvm::dyn_cast<Variable>(getSrc(0));
-    (void)Src0Var;
-    assert(Src0Var && Src0Var->getRegNum() == RegX8632::Reg_eax);
-    const X8632::AssemblerX8632::GPREmitterOneOp Emitter = {
-        &X8632::AssemblerX8632::imul, &X8632::AssemblerX8632::imul};
-    emitIASOpTyGPR(Func, Ty, getSrc(1), Emitter);
-  } else {
-    // We only use imul as a two-address instruction even though
-    // there is a 3 operand version when one of the operands is a constant.
-    assert(Var == getSrc(0));
-    const X8632::AssemblerX8632::GPREmitterRegOp Emitter = {
-        &X8632::AssemblerX8632::imul, &X8632::AssemblerX8632::imul,
-        &X8632::AssemblerX8632::imul};
-    emitIASRegOpTyGPR(Func, Ty, Var, Src, Emitter);
-  }
-}
-
-template <> void InstX8632Insertps::emitIAS(const Cfg *Func) const {
-  assert(getSrcSize() == 3);
-  assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >=
-         X8632::Traits::SSE4_1);
-  const Variable *Dest = getDest();
-  assert(Dest == getSrc(0));
-  Type Ty = Dest->getType();
-  static const X8632::AssemblerX8632::ThreeOpImmEmitter<
-      RegX8632::XmmRegister, RegX8632::XmmRegister> Emitter = {
-      &X8632::AssemblerX8632::insertps, &X8632::AssemblerX8632::insertps};
-  emitIASThreeOpImmOps<RegX8632::XmmRegister, RegX8632::XmmRegister,
-                       RegX8632::getEncodedXmm, RegX8632::getEncodedXmm>(
-      Func, Ty, Dest, getSrc(1), getSrc(2), Emitter);
-}
-
-template <> void InstX8632Cbwdq::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrEmit();
-  assert(getSrcSize() == 1);
-  Operand *Src0 = getSrc(0);
-  assert(llvm::isa<Variable>(Src0));
-  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() == RegX8632::Reg_eax);
-    Str << "\tcbtw";
-    break;
-  case IceType_i16:
-    assert(getDest()->getRegNum() == RegX8632::Reg_edx);
-    Str << "\tcwtd";
-    break;
-  case IceType_i32:
-    assert(getDest()->getRegNum() == RegX8632::Reg_edx);
-    Str << "\tcltd";
-    break;
-  }
-}
-
-template <> void InstX8632Cbwdq::emitIAS(const Cfg *Func) const {
-  X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>();
-  assert(getSrcSize() == 1);
-  Operand *Src0 = getSrc(0);
-  assert(llvm::isa<Variable>(Src0));
-  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() == RegX8632::Reg_eax);
-    Asm->cbw();
-    break;
-  case IceType_i16:
-    assert(getDest()->getRegNum() == RegX8632::Reg_edx);
-    Asm->cwd();
-    break;
-  case IceType_i32:
-    assert(getDest()->getRegNum() == RegX8632::Reg_edx);
-    Asm->cdq();
-    break;
-  }
-}
-
-void InstX8632Mul::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrEmit();
-  assert(getSrcSize() == 2);
-  assert(llvm::isa<Variable>(getSrc(0)));
-  assert(llvm::cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax);
-  assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx?
-  Str << "\tmul" << getWidthString(getDest()->getType()) << "\t";
-  getSrc(1)->emit(Func);
-}
-
-void InstX8632Mul::emitIAS(const Cfg *Func) const {
-  assert(getSrcSize() == 2);
-  assert(llvm::isa<Variable>(getSrc(0)));
-  assert(llvm::cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax);
-  assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx?
-  const Operand *Src = getSrc(1);
-  Type Ty = Src->getType();
-  const static X8632::AssemblerX8632::GPREmitterOneOp Emitter = {
-      &X8632::AssemblerX8632::mul, &X8632::AssemblerX8632::mul};
-  emitIASOpTyGPR(Func, Ty, Src, Emitter);
-}
-
-void InstX8632Mul::dump(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrDump();
-  dumpDest(Func);
-  Str << " = mul." << getDest()->getType() << " ";
-  dumpSources(Func);
-}
-
-void InstX8632Shld::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrEmit();
-  Variable *Dest = getDest();
-  assert(getSrcSize() == 3);
-  assert(Dest == getSrc(0));
-  Str << "\tshld" << getWidthString(Dest->getType()) << "\t";
-  if (const auto ShiftReg = llvm::dyn_cast<Variable>(getSrc(2))) {
-    (void)ShiftReg;
-    assert(ShiftReg->getRegNum() == RegX8632::Reg_ecx);
-    Str << "%cl";
-  } else {
-    getSrc(2)->emit(Func);
-  }
-  Str << ", ";
-  getSrc(1)->emit(Func);
-  Str << ", ";
-  Dest->emit(Func);
-}
-
-void InstX8632Shld::emitIAS(const Cfg *Func) const {
-  assert(getSrcSize() == 3);
-  assert(getDest() == getSrc(0));
-  const Variable *Dest = getDest();
-  const Operand *Src1 = getSrc(1);
-  const Operand *Src2 = getSrc(2);
-  static const X8632::AssemblerX8632::GPREmitterShiftD Emitter = {
-      &X8632::AssemblerX8632::shld, &X8632::AssemblerX8632::shld};
-  emitIASGPRShiftDouble(Func, Dest, Src1, Src2, Emitter);
-}
-
-void InstX8632Shld::dump(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrDump();
-  dumpDest(Func);
-  Str << " = shld." << getDest()->getType() << " ";
-  dumpSources(Func);
-}
-
-void InstX8632Shrd::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrEmit();
-  Variable *Dest = getDest();
-  assert(getSrcSize() == 3);
-  assert(Dest == getSrc(0));
-  Str << "\tshrd" << getWidthString(Dest->getType()) << "\t";
-  if (const auto ShiftReg = llvm::dyn_cast<Variable>(getSrc(2))) {
-    (void)ShiftReg;
-    assert(ShiftReg->getRegNum() == RegX8632::Reg_ecx);
-    Str << "%cl";
-  } else {
-    getSrc(2)->emit(Func);
-  }
-  Str << ", ";
-  getSrc(1)->emit(Func);
-  Str << ", ";
-  Dest->emit(Func);
-}
-
-void InstX8632Shrd::emitIAS(const Cfg *Func) const {
-  assert(getSrcSize() == 3);
-  assert(getDest() == getSrc(0));
-  const Variable *Dest = getDest();
-  const Operand *Src1 = getSrc(1);
-  const Operand *Src2 = getSrc(2);
-  static const X8632::AssemblerX8632::GPREmitterShiftD Emitter = {
-      &X8632::AssemblerX8632::shrd, &X8632::AssemblerX8632::shrd};
-  emitIASGPRShiftDouble(Func, Dest, Src1, Src2, Emitter);
-}
-
-void InstX8632Shrd::dump(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrDump();
-  dumpDest(Func);
-  Str << " = shrd." << getDest()->getType() << " ";
-  dumpSources(Func);
-}
-
-void InstX8632Cmov::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrEmit();
-  Variable *Dest = getDest();
-  Str << "\t";
-  assert(Condition != X8632::Traits::Cond::Br_None);
-  assert(getDest()->hasReg());
-  Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString
-      << getWidthString(Dest->getType()) << "\t";
-  getSrc(1)->emit(Func);
-  Str << ", ";
-  Dest->emit(Func);
-}
-
-void InstX8632Cmov::emitIAS(const Cfg *Func) const {
-  assert(Condition != X8632::Traits::Cond::Br_None);
-  assert(getDest()->hasReg());
-  assert(getSrcSize() == 2);
-  Operand *Src = getSrc(1);
-  Type SrcTy = Src->getType();
-  assert(SrcTy == IceType_i16 || SrcTy == IceType_i32);
-  X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>();
-  if (const auto *SrcVar = llvm::dyn_cast<Variable>(Src)) {
-    if (SrcVar->hasReg()) {
-      Asm->cmov(SrcTy, Condition,
-                RegX8632::getEncodedGPR(getDest()->getRegNum()),
-                RegX8632::getEncodedGPR(SrcVar->getRegNum()));
-    } else {
-      Asm->cmov(SrcTy, Condition,
-                RegX8632::getEncodedGPR(getDest()->getRegNum()),
-                static_cast<TargetX8632 *>(Func->getTarget())
-                    ->stackVarToAsmOperand(SrcVar));
-    }
-  } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) {
-    assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
-    Asm->cmov(SrcTy, Condition, RegX8632::getEncodedGPR(getDest()->getRegNum()),
-              Mem->toAsmAddress(Asm));
-  } else {
-    llvm_unreachable("Unexpected operand type");
-  }
-}
-
-void InstX8632Cmov::dump(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrDump();
-  Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << ".";
-  Str << getDest()->getType() << " ";
-  dumpDest(Func);
-  Str << ", ";
-  dumpSources(Func);
-}
-
-void InstX8632Cmpps::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrEmit();
-  assert(getSrcSize() == 2);
-  assert(Condition < X8632::Traits::Cond::Cmpps_Invalid);
-  Str << "\t";
-  Str << "cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps"
-      << "\t";
-  getSrc(1)->emit(Func);
-  Str << ", ";
-  getDest()->emit(Func);
-}
-
-void InstX8632Cmpps::emitIAS(const Cfg *Func) const {
-  X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>();
-  assert(getSrcSize() == 2);
-  assert(Condition < X8632::Traits::Cond::Cmpps_Invalid);
-  // Assuming there isn't any load folding for cmpps, and vector constants
-  // are not allowed in PNaCl.
-  assert(llvm::isa<Variable>(getSrc(1)));
-  const auto SrcVar = llvm::cast<Variable>(getSrc(1));
-  if (SrcVar->hasReg()) {
-    Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()),
-               RegX8632::getEncodedXmm(SrcVar->getRegNum()), Condition);
-  } else {
-    X8632::Traits::Address SrcStackAddr =
-        static_cast<TargetX8632 *>(Func->getTarget())
-            ->stackVarToAsmOperand(SrcVar);
-    Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()), SrcStackAddr,
-               Condition);
-  }
-}
-
-void InstX8632Cmpps::dump(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrDump();
-  assert(Condition < X8632::Traits::Cond::Cmpps_Invalid);
-  dumpDest(Func);
-  Str << " = cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps"
-      << "\t";
-  dumpSources(Func);
-}
-
-void InstX8632Cmpxchg::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrEmit();
-  assert(getSrcSize() == 3);
-  if (Locked) {
-    Str << "\tlock";
-  }
-  Str << "\tcmpxchg" << getWidthString(getSrc(0)->getType()) << "\t";
-  getSrc(2)->emit(Func);
-  Str << ", ";
-  getSrc(0)->emit(Func);
-}
-
-void InstX8632Cmpxchg::emitIAS(const Cfg *Func) const {
-  assert(getSrcSize() == 3);
-  X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>();
-  Type Ty = getSrc(0)->getType();
-  const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0));
-  assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
-  const X8632::Traits::Address Addr = Mem->toAsmAddress(Asm);
-  const auto VarReg = llvm::cast<Variable>(getSrc(2));
-  assert(VarReg->hasReg());
-  const RegX8632::GPRRegister Reg =
-      RegX8632::getEncodedGPR(VarReg->getRegNum());
-  Asm->cmpxchg(Ty, Addr, Reg, Locked);
-}
-
-void InstX8632Cmpxchg::dump(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrDump();
-  if (Locked) {
-    Str << "lock ";
-  }
-  Str << "cmpxchg." << getSrc(0)->getType() << " ";
-  dumpSources(Func);
-}
-
-void InstX8632Cmpxchg8b::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrEmit();
-  assert(getSrcSize() == 5);
-  if (Locked) {
-    Str << "\tlock";
-  }
-  Str << "\tcmpxchg8b\t";
-  getSrc(0)->emit(Func);
-}
-
-void InstX8632Cmpxchg8b::emitIAS(const Cfg *Func) const {
-  assert(getSrcSize() == 5);
-  X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>();
-  const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0));
-  assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
-  const X8632::Traits::Address Addr = Mem->toAsmAddress(Asm);
-  Asm->cmpxchg8b(Addr, Locked);
-}
-
-void InstX8632Cmpxchg8b::dump(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrDump();
-  if (Locked) {
-    Str << "lock ";
-  }
-  Str << "cmpxchg8b ";
-  dumpSources(Func);
-}
-
-void InstX8632Cvt::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrEmit();
-  assert(getSrcSize() == 1);
-  Str << "\tcvt";
-  if (isTruncating())
-    Str << "t";
-  Str << TypeX8632Attributes[getSrc(0)->getType()].CvtString << "2"
-      << TypeX8632Attributes[getDest()->getType()].CvtString << "\t";
-  getSrc(0)->emit(Func);
-  Str << ", ";
-  getDest()->emit(Func);
-}
-
-void InstX8632Cvt::emitIAS(const Cfg *Func) const {
-  assert(getSrcSize() == 1);
-  const Variable *Dest = getDest();
-  const Operand *Src = getSrc(0);
-  Type DestTy = Dest->getType();
-  Type SrcTy = Src->getType();
-  switch (Variant) {
-  case Si2ss: {
-    assert(isScalarIntegerType(SrcTy));
-    assert(typeWidthInBytes(SrcTy) <= 4);
-    assert(isScalarFloatingType(DestTy));
-    static const X8632::AssemblerX8632::CastEmitterRegOp<
-        RegX8632::XmmRegister, RegX8632::GPRRegister> Emitter = {
-        &X8632::AssemblerX8632::cvtsi2ss, &X8632::AssemblerX8632::cvtsi2ss};
-    emitIASCastRegOp<RegX8632::XmmRegister, RegX8632::GPRRegister,
-                     RegX8632::getEncodedXmm, RegX8632::getEncodedGPR>(
-        Func, DestTy, Dest, Src, Emitter);
-    return;
-  }
-  case Tss2si: {
-    assert(isScalarFloatingType(SrcTy));
-    assert(isScalarIntegerType(DestTy));
-    assert(typeWidthInBytes(DestTy) <= 4);
-    static const X8632::AssemblerX8632::CastEmitterRegOp<
-        RegX8632::GPRRegister, RegX8632::XmmRegister> Emitter = {
-        &X8632::AssemblerX8632::cvttss2si, &X8632::AssemblerX8632::cvttss2si};
-    emitIASCastRegOp<RegX8632::GPRRegister, RegX8632::XmmRegister,
-                     RegX8632::getEncodedGPR, RegX8632::getEncodedXmm>(
-        Func, SrcTy, Dest, Src, Emitter);
-    return;
-  }
-  case Float2float: {
-    assert(isScalarFloatingType(SrcTy));
-    assert(isScalarFloatingType(DestTy));
-    assert(DestTy != SrcTy);
-    static const X8632::AssemblerX8632::XmmEmitterRegOp Emitter = {
-        &X8632::AssemblerX8632::cvtfloat2float,
-        &X8632::AssemblerX8632::cvtfloat2float};
-    emitIASRegOpTyXMM(Func, SrcTy, Dest, Src, Emitter);
-    return;
-  }
-  case Dq2ps: {
-    assert(isVectorIntegerType(SrcTy));
-    assert(isVectorFloatingType(DestTy));
-    static const X8632::AssemblerX8632::XmmEmitterRegOp Emitter = {
-        &X8632::AssemblerX8632::cvtdq2ps, &X8632::AssemblerX8632::cvtdq2ps};
-    emitIASRegOpTyXMM(Func, DestTy, Dest, Src, Emitter);
-    return;
-  }
-  case Tps2dq: {
-    assert(isVectorFloatingType(SrcTy));
-    assert(isVectorIntegerType(DestTy));
-    static const X8632::AssemblerX8632::XmmEmitterRegOp Emitter = {
-        &X8632::AssemblerX8632::cvttps2dq, &X8632::AssemblerX8632::cvttps2dq};
-    emitIASRegOpTyXMM(Func, DestTy, Dest, Src, Emitter);
-    return;
-  }
-  }
-}
-
-void InstX8632Cvt::dump(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrDump();
-  dumpDest(Func);
-  Str << " = cvt";
-  if (isTruncating())
-    Str << "t";
-  Str << TypeX8632Attributes[getSrc(0)->getType()].CvtString << "2"
-      << TypeX8632Attributes[getDest()->getType()].CvtString << " ";
-  dumpSources(Func);
-}
-
-void InstX8632Icmp::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrEmit();
-  assert(getSrcSize() == 2);
-  Str << "\tcmp" << getWidthString(getSrc(0)->getType()) << "\t";
-  getSrc(1)->emit(Func);
-  Str << ", ";
-  getSrc(0)->emit(Func);
-}
-
-void InstX8632Icmp::emitIAS(const Cfg *Func) const {
-  assert(getSrcSize() == 2);
-  const Operand *Src0 = getSrc(0);
-  const Operand *Src1 = getSrc(1);
-  Type Ty = Src0->getType();
-  static const X8632::AssemblerX8632::GPREmitterRegOp RegEmitter = {
-      &X8632::AssemblerX8632::cmp, &X8632::AssemblerX8632::cmp,
-      &X8632::AssemblerX8632::cmp};
-  static const X8632::AssemblerX8632::GPREmitterAddrOp AddrEmitter = {
-      &X8632::AssemblerX8632::cmp, &X8632::AssemblerX8632::cmp};
-  if (const auto SrcVar0 = llvm::dyn_cast<Variable>(Src0)) {
-    if (SrcVar0->hasReg()) {
-      emitIASRegOpTyGPR(Func, Ty, SrcVar0, Src1, RegEmitter);
-      return;
-    }
-  }
-  emitIASAsAddrOpTyGPR(Func, Ty, Src0, Src1, AddrEmitter);
-}
-
-void InstX8632Icmp::dump(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrDump();
-  Str << "cmp." << getSrc(0)->getType() << " ";
-  dumpSources(Func);
-}
-
-void InstX8632Ucomiss::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrEmit();
-  assert(getSrcSize() == 2);
-  Str << "\tucomi" << TypeX8632Attributes[getSrc(0)->getType()].SdSsString
-      << "\t";
-  getSrc(1)->emit(Func);
-  Str << ", ";
-  getSrc(0)->emit(Func);
-}
-
-void InstX8632Ucomiss::emitIAS(const Cfg *Func) const {
-  assert(getSrcSize() == 2);
-  // Currently src0 is always a variable by convention, to avoid having
-  // two memory operands.
-  assert(llvm::isa<Variable>(getSrc(0)));
-  const auto Src0Var = llvm::cast<Variable>(getSrc(0));
-  Type Ty = Src0Var->getType();
-  const static X8632::AssemblerX8632::XmmEmitterRegOp Emitter = {
-      &X8632::AssemblerX8632::ucomiss, &X8632::AssemblerX8632::ucomiss};
-  emitIASRegOpTyXMM(Func, Ty, Src0Var, getSrc(1), Emitter);
-}
-
-void InstX8632Ucomiss::dump(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrDump();
-  Str << "ucomiss." << getSrc(0)->getType() << " ";
-  dumpSources(Func);
-}
-
-void InstX8632UD2::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrEmit();
-  assert(getSrcSize() == 0);
-  Str << "\tud2";
-}
-
-void InstX8632UD2::emitIAS(const Cfg *Func) const {
-  X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>();
-  Asm->ud2();
-}
-
-void InstX8632UD2::dump(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrDump();
-  Str << "ud2";
-}
-
-void InstX8632Test::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrEmit();
-  assert(getSrcSize() == 2);
-  Str << "\ttest" << getWidthString(getSrc(0)->getType()) << "\t";
-  getSrc(1)->emit(Func);
-  Str << ", ";
-  getSrc(0)->emit(Func);
-}
-
-void InstX8632Test::emitIAS(const Cfg *Func) const {
-  assert(getSrcSize() == 2);
-  const Operand *Src0 = getSrc(0);
-  const Operand *Src1 = getSrc(1);
-  Type Ty = Src0->getType();
-  // The Reg/Addr form of test is not encodeable.
-  static const X8632::AssemblerX8632::GPREmitterRegOp RegEmitter = {
-      &X8632::AssemblerX8632::test, nullptr, &X8632::AssemblerX8632::test};
-  static const X8632::AssemblerX8632::GPREmitterAddrOp AddrEmitter = {
-      &X8632::AssemblerX8632::test, &X8632::AssemblerX8632::test};
-  if (const auto SrcVar0 = llvm::dyn_cast<Variable>(Src0)) {
-    if (SrcVar0->hasReg()) {
-      emitIASRegOpTyGPR(Func, Ty, SrcVar0, Src1, RegEmitter);
-      return;
-    }
-  }
-  llvm_unreachable("Nothing actually generates this so it's untested");
-  emitIASAsAddrOpTyGPR(Func, Ty, Src0, Src1, AddrEmitter);
-}
-
-void InstX8632Test::dump(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrDump();
-  Str << "test." << getSrc(0)->getType() << " ";
-  dumpSources(Func);
-}
-
-void InstX8632Mfence::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrEmit();
-  assert(getSrcSize() == 0);
-  Str << "\tmfence";
-}
-
-void InstX8632Mfence::emitIAS(const Cfg *Func) const {
-  X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>();
-  Asm->mfence();
-}
-
-void InstX8632Mfence::dump(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrDump();
-  Str << "mfence";
-}
-
-void InstX8632Store::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrEmit();
-  assert(getSrcSize() == 2);
-  Type Ty = getSrc(0)->getType();
-  Str << "\tmov" << getWidthString(Ty) << TypeX8632Attributes[Ty].SdSsString
-      << "\t";
-  getSrc(0)->emit(Func);
-  Str << ", ";
-  getSrc(1)->emit(Func);
-}
-
-void InstX8632Store::emitIAS(const Cfg *Func) const {
-  assert(getSrcSize() == 2);
-  const Operand *Dest = getSrc(1);
-  const Operand *Src = getSrc(0);
-  Type DestTy = Dest->getType();
-  if (isScalarFloatingType(DestTy)) {
-    // Src must be a register, since Dest is a Mem operand of some kind.
-    const auto SrcVar = llvm::cast<Variable>(Src);
-    assert(SrcVar->hasReg());
-    RegX8632::XmmRegister SrcReg = RegX8632::getEncodedXmm(SrcVar->getRegNum());
-    X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>();
-    if (const auto DestVar = llvm::dyn_cast<Variable>(Dest)) {
-      assert(!DestVar->hasReg());
-      X8632::Traits::Address StackAddr(
-          static_cast<TargetX8632 *>(Func->getTarget())
-              ->stackVarToAsmOperand(DestVar));
-      Asm->movss(DestTy, StackAddr, SrcReg);
-    } else {
-      const auto DestMem = llvm::cast<OperandX8632Mem>(Dest);
-      assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
-      Asm->movss(DestTy, DestMem->toAsmAddress(Asm), SrcReg);
-    }
-    return;
-  } else {
-    assert(isScalarIntegerType(DestTy));
-    static const X8632::AssemblerX8632::GPREmitterAddrOp GPRAddrEmitter = {
-        &X8632::AssemblerX8632::mov, &X8632::AssemblerX8632::mov};
-    emitIASAsAddrOpTyGPR(Func, DestTy, Dest, Src, GPRAddrEmitter);
-  }
-}
-
-void InstX8632Store::dump(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrDump();
-  Str << "mov." << getSrc(0)->getType() << " ";
-  getSrc(1)->dump(Func);
-  Str << ", ";
-  getSrc(0)->dump(Func);
-}
-
-void InstX8632StoreP::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrEmit();
-  assert(getSrcSize() == 2);
-  Str << "\tmovups\t";
-  getSrc(0)->emit(Func);
-  Str << ", ";
-  getSrc(1)->emit(Func);
-}
-
-void InstX8632StoreP::emitIAS(const Cfg *Func) const {
-  X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>();
-  assert(getSrcSize() == 2);
-  const auto SrcVar = llvm::cast<Variable>(getSrc(0));
-  const auto DestMem = llvm::cast<OperandX8632Mem>(getSrc(1));
-  assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
-  assert(SrcVar->hasReg());
-  Asm->movups(DestMem->toAsmAddress(Asm),
-              RegX8632::getEncodedXmm(SrcVar->getRegNum()));
-}
-
-void InstX8632StoreP::dump(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrDump();
-  Str << "storep." << getSrc(0)->getType() << " ";
-  getSrc(1)->dump(Func);
-  Str << ", ";
-  getSrc(0)->dump(Func);
-}
-
-void InstX8632StoreQ::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrEmit();
-  assert(getSrcSize() == 2);
-  assert(getSrc(1)->getType() == IceType_i64 ||
-         getSrc(1)->getType() == IceType_f64);
-  Str << "\tmovq\t";
-  getSrc(0)->emit(Func);
-  Str << ", ";
-  getSrc(1)->emit(Func);
-}
-
-void InstX8632StoreQ::emitIAS(const Cfg *Func) const {
-  X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>();
-  assert(getSrcSize() == 2);
-  const auto SrcVar = llvm::cast<Variable>(getSrc(0));
-  const auto DestMem = llvm::cast<OperandX8632Mem>(getSrc(1));
-  assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
-  assert(SrcVar->hasReg());
-  Asm->movq(DestMem->toAsmAddress(Asm),
-            RegX8632::getEncodedXmm(SrcVar->getRegNum()));
-}
-
-void InstX8632StoreQ::dump(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrDump();
-  Str << "storeq." << getSrc(0)->getType() << " ";
-  getSrc(1)->dump(Func);
-  Str << ", ";
-  getSrc(0)->dump(Func);
-}
-
-template <> void InstX8632Lea::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrEmit();
-  assert(getSrcSize() == 1);
-  assert(getDest()->hasReg());
-  Str << "\tleal\t";
-  Operand *Src0 = getSrc(0);
-  if (const auto Src0Var = llvm::dyn_cast<Variable>(Src0)) {
-    Type Ty = Src0Var->getType();
-    // lea on x86-32 doesn't accept mem128 operands, so cast VSrc0 to an
-    // acceptable type.
-    Src0Var->asType(isVectorType(Ty) ? IceType_i32 : Ty)->emit(Func);
-  } else {
-    Src0->emit(Func);
-  }
-  Str << ", ";
-  getDest()->emit(Func);
-}
-
-template <> void InstX8632Mov::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrEmit();
-  assert(getSrcSize() == 1);
-  Operand *Src = getSrc(0);
-  Type SrcTy = Src->getType();
-  Type DestTy = getDest()->getType();
-  Str << "\tmov" << (!isScalarFloatingType(DestTy)
-                         ? getWidthString(SrcTy)
-                         : TypeX8632Attributes[DestTy].SdSsString) << "\t";
-  // For an integer truncation operation, src is wider than dest.
-  // Ideally, we use a mov instruction whose data width matches the
-  // narrower dest.  This is a problem if e.g. src is a register like
-  // esi or si where there is no 8-bit version of the register.  To be
-  // safe, we instead widen the dest to match src.  This works even
-  // for stack-allocated dest variables because typeWidthOnStack()
-  // pads to a 4-byte boundary even if only a lower portion is used.
-  // TODO: This assert disallows usages such as copying a floating point
-  // value between a vector and a scalar (which movss is used for).
-  // Clean this up.
-  assert(Func->getTarget()->typeWidthInBytesOnStack(DestTy) ==
-         Func->getTarget()->typeWidthInBytesOnStack(SrcTy));
-  Src->emit(Func);
-  Str << ", ";
-  getDest()->asType(SrcTy)->emit(Func);
-}
-
-template <> void InstX8632Mov::emitIAS(const Cfg *Func) const {
-  assert(getSrcSize() == 1);
-  const Variable *Dest = getDest();
-  const Operand *Src = getSrc(0);
-  Type DestTy = Dest->getType();
-  Type SrcTy = Src->getType();
-  // Mov can be used for GPRs or XMM registers. Also, the type does not
-  // necessarily match (Mov can be used for bitcasts). However, when
-  // the type does not match, one of the operands must be a register.
-  // Thus, the strategy is to find out if Src or Dest are a register,
-  // then use that register's type to decide on which emitter set to use.
-  // The emitter set will include reg-reg movs, but that case should
-  // be unused when the types don't match.
-  static const X8632::AssemblerX8632::XmmEmitterRegOp XmmRegEmitter = {
-      &X8632::AssemblerX8632::movss, &X8632::AssemblerX8632::movss};
-  static const X8632::AssemblerX8632::GPREmitterRegOp GPRRegEmitter = {
-      &X8632::AssemblerX8632::mov, &X8632::AssemblerX8632::mov,
-      &X8632::AssemblerX8632::mov};
-  static const X8632::AssemblerX8632::GPREmitterAddrOp GPRAddrEmitter = {
-      &X8632::AssemblerX8632::mov, &X8632::AssemblerX8632::mov};
-  // For an integer truncation operation, src is wider than dest.
-  // Ideally, we use a mov instruction whose data width matches the
-  // narrower dest.  This is a problem if e.g. src is a register like
-  // esi or si where there is no 8-bit version of the register.  To be
-  // safe, we instead widen the dest to match src.  This works even
-  // for stack-allocated dest variables because typeWidthOnStack()
-  // pads to a 4-byte boundary even if only a lower portion is used.
-  // TODO: This assert disallows usages such as copying a floating point
-  // value between a vector and a scalar (which movss is used for).
-  // Clean this up.
-  assert(Func->getTarget()->typeWidthInBytesOnStack(getDest()->getType()) ==
-         Func->getTarget()->typeWidthInBytesOnStack(Src->getType()));
-  if (Dest->hasReg()) {
-    if (isScalarFloatingType(DestTy)) {
-      emitIASRegOpTyXMM(Func, DestTy, Dest, Src, XmmRegEmitter);
-      return;
-    } else {
-      assert(isScalarIntegerType(DestTy));
-      // Widen DestTy for truncation (see above note). We should only do this
-      // when both Src and Dest are integer types.
-      if (isScalarIntegerType(SrcTy)) {
-        DestTy = SrcTy;
-      }
-      emitIASRegOpTyGPR(Func, DestTy, Dest, Src, GPRRegEmitter);
-      return;
-    }
-  } else {
-    // Dest must be Stack and Src *could* be a register. Use Src's type
-    // to decide on the emitters.
-    X8632::Traits::Address StackAddr(
-        static_cast<TargetX8632 *>(Func->getTarget())
-            ->stackVarToAsmOperand(Dest));
-    if (isScalarFloatingType(SrcTy)) {
-      // Src must be a register.
-      const auto SrcVar = llvm::cast<Variable>(Src);
-      assert(SrcVar->hasReg());
-      X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>();
-      Asm->movss(SrcTy, StackAddr,
-                 RegX8632::getEncodedXmm(SrcVar->getRegNum()));
-      return;
-    } else {
-      // Src can be a register or immediate.
-      assert(isScalarIntegerType(SrcTy));
-      emitIASAddrOpTyGPR(Func, SrcTy, StackAddr, Src, GPRAddrEmitter);
-      return;
-    }
-    return;
-  }
-}
-
-template <> void InstX8632Movd::emitIAS(const Cfg *Func) const {
-  X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>();
-  assert(getSrcSize() == 1);
-  const Variable *Dest = getDest();
-  const auto SrcVar = llvm::cast<Variable>(getSrc(0));
-  // For insert/extract element (one of Src/Dest is an Xmm vector and
-  // the other is an int type).
-  if (SrcVar->getType() == IceType_i32) {
-    assert(isVectorType(Dest->getType()));
-    assert(Dest->hasReg());
-    RegX8632::XmmRegister DestReg = RegX8632::getEncodedXmm(Dest->getRegNum());
-    if (SrcVar->hasReg()) {
-      Asm->movd(DestReg, RegX8632::getEncodedGPR(SrcVar->getRegNum()));
-    } else {
-      X8632::Traits::Address StackAddr(
-          static_cast<TargetX8632 *>(Func->getTarget())
-              ->stackVarToAsmOperand(SrcVar));
-      Asm->movd(DestReg, StackAddr);
-    }
-  } else {
-    assert(isVectorType(SrcVar->getType()));
-    assert(SrcVar->hasReg());
-    assert(Dest->getType() == IceType_i32);
-    RegX8632::XmmRegister SrcReg = RegX8632::getEncodedXmm(SrcVar->getRegNum());
-    if (Dest->hasReg()) {
-      Asm->movd(RegX8632::getEncodedGPR(Dest->getRegNum()), SrcReg);
-    } else {
-      X8632::Traits::Address StackAddr(
-          static_cast<TargetX8632 *>(Func->getTarget())
-              ->stackVarToAsmOperand(Dest));
-      Asm->movd(StackAddr, SrcReg);
-    }
-  }
-}
-
-template <> void InstX8632Movp::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  // TODO(wala,stichnot): movups works with all vector operands, but
-  // there exist other instructions (movaps, movdqa, movdqu) that may
-  // perform better, depending on the data type and alignment of the
-  // operands.
-  Ostream &Str = Func->getContext()->getStrEmit();
-  assert(getSrcSize() == 1);
-  Str << "\tmovups\t";
-  getSrc(0)->emit(Func);
-  Str << ", ";
-  getDest()->emit(Func);
-}
-
-template <> void InstX8632Movp::emitIAS(const Cfg *Func) const {
-  assert(getSrcSize() == 1);
-  assert(isVectorType(getDest()->getType()));
-  const Variable *Dest = getDest();
-  const Operand *Src = getSrc(0);
-  const static X8632::AssemblerX8632::XmmEmitterMovOps Emitter = {
-      &X8632::AssemblerX8632::movups, &X8632::AssemblerX8632::movups,
-      &X8632::AssemblerX8632::movups};
-  emitIASMovlikeXMM(Func, Dest, Src, Emitter);
-}
-
-template <> void InstX8632Movq::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrEmit();
-  assert(getSrcSize() == 1);
-  assert(getDest()->getType() == IceType_i64 ||
-         getDest()->getType() == IceType_f64);
-  Str << "\tmovq\t";
-  getSrc(0)->emit(Func);
-  Str << ", ";
-  getDest()->emit(Func);
-}
-
-template <> void InstX8632Movq::emitIAS(const Cfg *Func) const {
-  assert(getSrcSize() == 1);
-  assert(getDest()->getType() == IceType_i64 ||
-         getDest()->getType() == IceType_f64);
-  const Variable *Dest = getDest();
-  const Operand *Src = getSrc(0);
-  const static X8632::AssemblerX8632::XmmEmitterMovOps Emitter = {
-      &X8632::AssemblerX8632::movq, &X8632::AssemblerX8632::movq,
-      &X8632::AssemblerX8632::movq};
-  emitIASMovlikeXMM(Func, Dest, Src, Emitter);
-}
-
-template <> void InstX8632MovssRegs::emitIAS(const Cfg *Func) const {
-  // This is Binop variant is only intended to be used for reg-reg moves
-  // where part of the Dest register is untouched.
-  assert(getSrcSize() == 2);
-  const Variable *Dest = getDest();
-  assert(Dest == getSrc(0));
-  const auto SrcVar = llvm::cast<Variable>(getSrc(1));
-  assert(Dest->hasReg() && SrcVar->hasReg());
-  X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>();
-  Asm->movss(IceType_f32, RegX8632::getEncodedXmm(Dest->getRegNum()),
-             RegX8632::getEncodedXmm(SrcVar->getRegNum()));
-}
-
-template <> void InstX8632Movsx::emitIAS(const Cfg *Func) const {
-  assert(getSrcSize() == 1);
-  const Variable *Dest = getDest();
-  const Operand *Src = getSrc(0);
-  // Dest must be a > 8-bit register, but Src can be 8-bit. In practice
-  // we just use the full register for Dest to avoid having an
-  // OperandSizeOverride prefix. It also allows us to only dispatch on SrcTy.
-  Type SrcTy = Src->getType();
-  assert(typeWidthInBytes(Dest->getType()) > 1);
-  assert(typeWidthInBytes(Dest->getType()) > typeWidthInBytes(SrcTy));
-  emitIASRegOpTyGPR<false, true>(Func, SrcTy, Dest, Src, Emitter);
-}
-
-template <> void InstX8632Movzx::emitIAS(const Cfg *Func) const {
-  assert(getSrcSize() == 1);
-  const Variable *Dest = getDest();
-  const Operand *Src = getSrc(0);
-  Type SrcTy = Src->getType();
-  assert(typeWidthInBytes(Dest->getType()) > 1);
-  assert(typeWidthInBytes(Dest->getType()) > typeWidthInBytes(SrcTy));
-  emitIASRegOpTyGPR<false, true>(Func, SrcTy, Dest, Src, Emitter);
-}
-
-void InstX8632Nop::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrEmit();
-  // TODO: Emit the right code for each variant.
-  Str << "\tnop\t# variant = " << Variant;
-}
-
-void InstX8632Nop::emitIAS(const Cfg *Func) const {
-  X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>();
-  // TODO: Emit the right code for the variant.
-  Asm->nop();
-}
-
-void InstX8632Nop::dump(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrDump();
-  Str << "nop (variant = " << Variant << ")";
-}
-
-void InstX8632Fld::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrEmit();
-  assert(getSrcSize() == 1);
-  Type Ty = getSrc(0)->getType();
-  SizeT Width = typeWidthInBytes(Ty);
-  const auto Var = llvm::dyn_cast<Variable>(getSrc(0));
-  if (Var && Var->hasReg()) {
-    // This is a physical xmm register, so we need to spill it to a
-    // temporary stack slot.
-    Str << "\tsubl\t$" << Width << ", %esp"
-        << "\n";
-    Str << "\tmov" << TypeX8632Attributes[Ty].SdSsString << "\t";
-    Var->emit(Func);
-    Str << ", (%esp)\n";
-    Str << "\tfld" << getFldString(Ty) << "\t"
-        << "(%esp)\n";
-    Str << "\taddl\t$" << Width << ", %esp";
-    return;
-  }
-  Str << "\tfld" << getFldString(Ty) << "\t";
-  getSrc(0)->emit(Func);
-}
-
-void InstX8632Fld::emitIAS(const Cfg *Func) const {
-  X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>();
-  assert(getSrcSize() == 1);
-  const Operand *Src = getSrc(0);
-  Type Ty = Src->getType();
-  if (const auto Var = llvm::dyn_cast<Variable>(Src)) {
-    if (Var->hasReg()) {
-      // This is a physical xmm register, so we need to spill it to a
-      // temporary stack slot.
-      X8632::Immediate Width(typeWidthInBytes(Ty));
-      Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, Width);
-      X8632::Traits::Address StackSlot =
-          X8632::Traits::Address(RegX8632::Encoded_Reg_esp, 0);
-      Asm->movss(Ty, StackSlot, RegX8632::getEncodedXmm(Var->getRegNum()));
-      Asm->fld(Ty, StackSlot);
-      Asm->add(IceType_i32, RegX8632::Encoded_Reg_esp, Width);
-    } else {
-      X8632::Traits::Address StackAddr(
-          static_cast<TargetX8632 *>(Func->getTarget())
-              ->stackVarToAsmOperand(Var));
-      Asm->fld(Ty, StackAddr);
-    }
-  } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) {
-    assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
-    Asm->fld(Ty, Mem->toAsmAddress(Asm));
-  } else if (const auto Imm = llvm::dyn_cast<Constant>(Src)) {
-    Asm->fld(Ty, X8632::Traits::Address::ofConstPool(Asm, Imm));
-  } else {
-    llvm_unreachable("Unexpected operand type");
-  }
-}
-
-void InstX8632Fld::dump(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrDump();
-  Str << "fld." << getSrc(0)->getType() << " ";
-  dumpSources(Func);
-}
-
-void InstX8632Fstp::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrEmit();
-  assert(getSrcSize() == 0);
-  // TODO(jvoung,stichnot): Utilize this by setting Dest to nullptr to
-  // "partially" delete the fstp if the Dest is unused.
-  // Even if Dest is unused, the fstp should be kept for the SideEffects
-  // of popping the stack.
-  if (!getDest()) {
-    Str << "\tfstp\tst(0)";
-    return;
-  }
-  Type Ty = getDest()->getType();
-  size_t Width = typeWidthInBytes(Ty);
-  if (!getDest()->hasReg()) {
-    Str << "\tfstp" << getFldString(Ty) << "\t";
-    getDest()->emit(Func);
-    return;
-  }
-  // Dest is a physical (xmm) register, so st(0) needs to go through
-  // memory.  Hack this by creating a temporary stack slot, spilling
-  // st(0) there, loading it into the xmm register, and deallocating
-  // the stack slot.
-  Str << "\tsubl\t$" << Width << ", %esp\n";
-  Str << "\tfstp" << getFldString(Ty) << "\t"
-      << "(%esp)\n";
-  Str << "\tmov" << TypeX8632Attributes[Ty].SdSsString << "\t"
-      << "(%esp), ";
-  getDest()->emit(Func);
-  Str << "\n";
-  Str << "\taddl\t$" << Width << ", %esp";
-}
-
-void InstX8632Fstp::emitIAS(const Cfg *Func) const {
-  X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>();
-  assert(getSrcSize() == 0);
-  const Variable *Dest = getDest();
-  // TODO(jvoung,stichnot): Utilize this by setting Dest to nullptr to
-  // "partially" delete the fstp if the Dest is unused.
-  // Even if Dest is unused, the fstp should be kept for the SideEffects
-  // of popping the stack.
-  if (!Dest) {
-    Asm->fstp(RegX8632::getEncodedSTReg(0));
-    return;
-  }
-  Type Ty = Dest->getType();
-  if (!Dest->hasReg()) {
-    X8632::Traits::Address StackAddr(
-        static_cast<TargetX8632 *>(Func->getTarget())
-            ->stackVarToAsmOperand(Dest));
-    Asm->fstp(Ty, StackAddr);
-  } else {
-    // Dest is a physical (xmm) register, so st(0) needs to go through
-    // memory.  Hack this by creating a temporary stack slot, spilling
-    // st(0) there, loading it into the xmm register, and deallocating
-    // the stack slot.
-    X8632::Immediate Width(typeWidthInBytes(Ty));
-    Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, Width);
-    X8632::Traits::Address StackSlot =
-        X8632::Traits::Address(RegX8632::Encoded_Reg_esp, 0);
-    Asm->fstp(Ty, StackSlot);
-    Asm->movss(Ty, RegX8632::getEncodedXmm(Dest->getRegNum()), StackSlot);
-    Asm->add(IceType_i32, RegX8632::Encoded_Reg_esp, Width);
-  }
-}
-
-void InstX8632Fstp::dump(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrDump();
-  dumpDest(Func);
-  Str << " = fstp." << getDest()->getType() << ", st(0)";
-}
-
-template <> void InstX8632Pcmpeq::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  char buf[30];
-  snprintf(buf, llvm::array_lengthof(buf), "pcmpeq%s",
-           TypeX8632Attributes[getDest()->getType()].PackString);
-  emitTwoAddress(buf, this, Func);
-}
-
-template <> void InstX8632Pcmpgt::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  char buf[30];
-  snprintf(buf, llvm::array_lengthof(buf), "pcmpgt%s",
-           TypeX8632Attributes[getDest()->getType()].PackString);
-  emitTwoAddress(buf, this, Func);
-}
-
-template <> void InstX8632Pextr::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrEmit();
-  assert(getSrcSize() == 2);
-  // pextrb and pextrd are SSE4.1 instructions.
-  assert(getSrc(0)->getType() == IceType_v8i16 ||
-         getSrc(0)->getType() == IceType_v8i1 ||
-         static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >=
-             X8632::Traits::SSE4_1);
-  Str << "\t" << Opcode << TypeX8632Attributes[getSrc(0)->getType()].PackString
-      << "\t";
-  getSrc(1)->emit(Func);
-  Str << ", ";
-  getSrc(0)->emit(Func);
-  Str << ", ";
-  Variable *Dest = getDest();
-  // pextrw must take a register dest. There is an SSE4.1 version that takes
-  // a memory dest, but we aren't using it. For uniformity, just restrict
-  // them all to have a register dest for now.
-  assert(Dest->hasReg());
-  Dest->asType(IceType_i32)->emit(Func);
-}
-
-template <> void InstX8632Pextr::emitIAS(const Cfg *Func) const {
-  assert(getSrcSize() == 2);
-  // pextrb and pextrd are SSE4.1 instructions.
-  const Variable *Dest = getDest();
-  Type DispatchTy = Dest->getType();
-  assert(DispatchTy == IceType_i16 ||
-         static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >=
-             X8632::Traits::SSE4_1);
-  // pextrw must take a register dest. There is an SSE4.1 version that takes
-  // a memory dest, but we aren't using it. For uniformity, just restrict
-  // them all to have a register dest for now.
-  assert(Dest->hasReg());
-  // pextrw's Src(0) must be a register (both SSE4.1 and SSE2).
-  assert(llvm::cast<Variable>(getSrc(0))->hasReg());
-  static const X8632::AssemblerX8632::ThreeOpImmEmitter<
-      RegX8632::GPRRegister, RegX8632::XmmRegister> Emitter = {
-      &X8632::AssemblerX8632::pextr, nullptr};
-  emitIASThreeOpImmOps<RegX8632::GPRRegister, RegX8632::XmmRegister,
-                       RegX8632::getEncodedGPR, RegX8632::getEncodedXmm>(
-      Func, DispatchTy, Dest, getSrc(0), getSrc(1), Emitter);
-}
-
-template <> void InstX8632Pinsr::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrEmit();
-  assert(getSrcSize() == 3);
-  // pinsrb and pinsrd are SSE4.1 instructions.
-  assert(getDest()->getType() == IceType_v8i16 ||
-         getDest()->getType() == IceType_v8i1 ||
-         static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >=
-             X8632::Traits::SSE4_1);
-  Str << "\t" << Opcode << TypeX8632Attributes[getDest()->getType()].PackString
-      << "\t";
-  getSrc(2)->emit(Func);
-  Str << ", ";
-  Operand *Src1 = getSrc(1);
-  if (const auto Src1Var = llvm::dyn_cast<Variable>(Src1)) {
-    // If src1 is a register, it should always be r32.
-    if (Src1Var->hasReg()) {
-      Src1Var->asType(IceType_i32)->emit(Func);
-    } else {
-      Src1Var->emit(Func);
-    }
-  } else {
-    Src1->emit(Func);
-  }
-  Str << ", ";
-  getDest()->emit(Func);
-}
-
-template <> void InstX8632Pinsr::emitIAS(const Cfg *Func) const {
-  assert(getSrcSize() == 3);
-  assert(getDest() == getSrc(0));
-  // pinsrb and pinsrd are SSE4.1 instructions.
-  const Operand *Src0 = getSrc(1);
-  Type DispatchTy = Src0->getType();
-  assert(DispatchTy == IceType_i16 ||
-         static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >=
-             X8632::Traits::SSE4_1);
-  // If src1 is a register, it should always be r32 (this should fall out
-  // from the encodings for ByteRegs overlapping the encodings for r32),
-  // but we have to trust the regalloc to not choose "ah", where it
-  // doesn't overlap.
-  static const X8632::AssemblerX8632::ThreeOpImmEmitter<
-      RegX8632::XmmRegister, RegX8632::GPRRegister> Emitter = {
-      &X8632::AssemblerX8632::pinsr, &X8632::AssemblerX8632::pinsr};
-  emitIASThreeOpImmOps<RegX8632::XmmRegister, RegX8632::GPRRegister,
-                       RegX8632::getEncodedXmm, RegX8632::getEncodedGPR>(
-      Func, DispatchTy, getDest(), Src0, getSrc(2), Emitter);
-}
-
-template <> void InstX8632Pshufd::emitIAS(const Cfg *Func) const {
-  assert(getSrcSize() == 2);
-  const Variable *Dest = getDest();
-  Type Ty = Dest->getType();
-  static const X8632::AssemblerX8632::ThreeOpImmEmitter<
-      RegX8632::XmmRegister, RegX8632::XmmRegister> Emitter = {
-      &X8632::AssemblerX8632::pshufd, &X8632::AssemblerX8632::pshufd};
-  emitIASThreeOpImmOps<RegX8632::XmmRegister, RegX8632::XmmRegister,
-                       RegX8632::getEncodedXmm, RegX8632::getEncodedXmm>(
-      Func, Ty, Dest, getSrc(0), getSrc(1), Emitter);
-}
-
-template <> void InstX8632Shufps::emitIAS(const Cfg *Func) const {
-  assert(getSrcSize() == 3);
-  const Variable *Dest = getDest();
-  assert(Dest == getSrc(0));
-  Type Ty = Dest->getType();
-  static const X8632::AssemblerX8632::ThreeOpImmEmitter<
-      RegX8632::XmmRegister, RegX8632::XmmRegister> Emitter = {
-      &X8632::AssemblerX8632::shufps, &X8632::AssemblerX8632::shufps};
-  emitIASThreeOpImmOps<RegX8632::XmmRegister, RegX8632::XmmRegister,
-                       RegX8632::getEncodedXmm, RegX8632::getEncodedXmm>(
-      Func, Ty, Dest, getSrc(1), getSrc(2), Emitter);
-}
-
-void InstX8632Pop::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrEmit();
-  assert(getSrcSize() == 0);
-  Str << "\tpop\t";
-  getDest()->emit(Func);
-}
-
-void InstX8632Pop::emitIAS(const Cfg *Func) const {
-  assert(getSrcSize() == 0);
-  X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>();
-  if (getDest()->hasReg()) {
-    Asm->popl(RegX8632::getEncodedGPR(getDest()->getRegNum()));
-  } else {
-    Asm->popl(static_cast<TargetX8632 *>(Func->getTarget())
-                  ->stackVarToAsmOperand(getDest()));
-  }
-}
-
-void InstX8632Pop::dump(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrDump();
-  dumpDest(Func);
-  Str << " = pop." << getDest()->getType() << " ";
-}
-
-void InstX8632AdjustStack::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrEmit();
-  Str << "\tsubl\t$" << Amount << ", %esp";
-  Func->getTarget()->updateStackAdjustment(Amount);
-}
-
-void InstX8632AdjustStack::emitIAS(const Cfg *Func) const {
-  X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>();
-  Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, X8632::Immediate(Amount));
-  Func->getTarget()->updateStackAdjustment(Amount);
-}
-
-void InstX8632AdjustStack::dump(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrDump();
-  Str << "esp = sub.i32 esp, " << Amount;
-}
-
-void InstX8632Push::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrEmit();
-  assert(getSrcSize() == 1);
-  // Push is currently only used for saving GPRs.
-  const auto Var = llvm::cast<Variable>(getSrc(0));
-  assert(Var->hasReg());
-  Str << "\tpush\t";
-  Var->emit(Func);
-}
-
-void InstX8632Push::emitIAS(const Cfg *Func) const {
-  assert(getSrcSize() == 1);
-  // Push is currently only used for saving GPRs.
-  const auto Var = llvm::cast<Variable>(getSrc(0));
-  assert(Var->hasReg());
-  X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>();
-  Asm->pushl(RegX8632::getEncodedGPR(Var->getRegNum()));
-}
-
-void InstX8632Push::dump(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrDump();
-  Str << "push." << getSrc(0)->getType() << " ";
-  dumpSources(Func);
-}
-
-template <> void InstX8632Psll::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  assert(getDest()->getType() == IceType_v8i16 ||
-         getDest()->getType() == IceType_v8i1 ||
-         getDest()->getType() == IceType_v4i32 ||
-         getDest()->getType() == IceType_v4i1);
-  char buf[30];
-  snprintf(buf, llvm::array_lengthof(buf), "psll%s",
-           TypeX8632Attributes[getDest()->getType()].PackString);
-  emitTwoAddress(buf, this, Func);
-}
-
-template <> void InstX8632Psra::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  assert(getDest()->getType() == IceType_v8i16 ||
-         getDest()->getType() == IceType_v8i1 ||
-         getDest()->getType() == IceType_v4i32 ||
-         getDest()->getType() == IceType_v4i1);
-  char buf[30];
-  snprintf(buf, llvm::array_lengthof(buf), "psra%s",
-           TypeX8632Attributes[getDest()->getType()].PackString);
-  emitTwoAddress(buf, this, Func);
-}
-
-template <> void InstX8632Psrl::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  char buf[30];
-  snprintf(buf, llvm::array_lengthof(buf), "psrl%s",
-           TypeX8632Attributes[getDest()->getType()].PackString);
-  emitTwoAddress(buf, this, Func);
-}
-
-void InstX8632Ret::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrEmit();
-  Str << "\tret";
-}
-
-void InstX8632Ret::emitIAS(const Cfg *Func) const {
-  X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>();
-  Asm->ret();
-}
-
-void InstX8632Ret::dump(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrDump();
-  Type Ty = (getSrcSize() == 0 ? IceType_void : getSrc(0)->getType());
-  Str << "ret." << Ty << " ";
-  dumpSources(Func);
-}
-
-void InstX8632Setcc::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrEmit();
-  Str << "\tset" << InstX8632BrAttributes[Condition].DisplayString << "\t";
-  Dest->emit(Func);
-}
-
-void InstX8632Setcc::emitIAS(const Cfg *Func) const {
-  assert(Condition != X8632::Traits::Cond::Br_None);
-  assert(getDest()->getType() == IceType_i1);
-  assert(getSrcSize() == 0);
-  X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>();
-  if (getDest()->hasReg())
-    Asm->setcc(Condition, RegX8632::getEncodedByteReg(getDest()->getRegNum()));
-  else
-    Asm->setcc(Condition, static_cast<TargetX8632 *>(Func->getTarget())
-                              ->stackVarToAsmOperand(getDest()));
-  return;
-}
-
-void InstX8632Setcc::dump(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrDump();
-  Str << "setcc." << InstX8632BrAttributes[Condition].DisplayString << " ";
-  dumpDest(Func);
-}
-
-void InstX8632Xadd::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrEmit();
-  if (Locked) {
-    Str << "\tlock";
-  }
-  Str << "\txadd" << getWidthString(getSrc(0)->getType()) << "\t";
-  getSrc(1)->emit(Func);
-  Str << ", ";
-  getSrc(0)->emit(Func);
-}
-
-void InstX8632Xadd::emitIAS(const Cfg *Func) const {
-  assert(getSrcSize() == 2);
-  X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>();
-  Type Ty = getSrc(0)->getType();
-  const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0));
-  assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
-  const X8632::Traits::Address Addr = Mem->toAsmAddress(Asm);
-  const auto VarReg = llvm::cast<Variable>(getSrc(1));
-  assert(VarReg->hasReg());
-  const RegX8632::GPRRegister Reg =
-      RegX8632::getEncodedGPR(VarReg->getRegNum());
-  Asm->xadd(Ty, Addr, Reg, Locked);
-}
-
-void InstX8632Xadd::dump(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrDump();
-  if (Locked) {
-    Str << "lock ";
-  }
-  Type Ty = getSrc(0)->getType();
-  Str << "xadd." << Ty << " ";
-  dumpSources(Func);
-}
-
-void InstX8632Xchg::emit(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrEmit();
-  Str << "\txchg" << getWidthString(getSrc(0)->getType()) << "\t";
-  getSrc(1)->emit(Func);
-  Str << ", ";
-  getSrc(0)->emit(Func);
-}
-
-void InstX8632Xchg::emitIAS(const Cfg *Func) const {
-  assert(getSrcSize() == 2);
-  X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>();
-  Type Ty = getSrc(0)->getType();
-  const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0));
-  assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
-  const X8632::Traits::Address Addr = Mem->toAsmAddress(Asm);
-  const auto VarReg = llvm::cast<Variable>(getSrc(1));
-  assert(VarReg->hasReg());
-  const RegX8632::GPRRegister Reg =
-      RegX8632::getEncodedGPR(VarReg->getRegNum());
-  Asm->xchg(Ty, Addr, Reg);
-}
-
-void InstX8632Xchg::dump(const Cfg *Func) const {
-  if (!BuildDefs::dump())
-    return;
-  Ostream &Str = Func->getContext()->getStrDump();
-  Type Ty = getSrc(0)->getType();
-  Str << "xchg." << Ty << " ";
-  dumpSources(Func);
-}
-
-void OperandX8632Mem::emit(const Cfg *Func) const {
+void MachineTraits<TargetX8632>::X86OperandMem::emit(const Cfg *Func) const {
   if (!BuildDefs::dump())
     return;
   Ostream &Str = Func->getContext()->getStrEmit();
   if (SegmentReg != DefaultSegment) {
     assert(SegmentReg >= 0 && SegmentReg < SegReg_NUM);
-    Str << "%" << InstX8632SegmentRegNames[SegmentReg] << ":";
+    Str << "%" << X8632::Traits::InstSegmentRegNames[SegmentReg] << ":";
   }
   // Emit as Offset(Base,Index,1<<Shift).
   // Offset is emitted without the leading '$'.
@@ -2943,12 +134,13 @@
   }
 }
 
-void OperandX8632Mem::dump(const Cfg *Func, Ostream &Str) const {
+void MachineTraits<TargetX8632>::X86OperandMem::dump(const Cfg *Func,
+                                                     Ostream &Str) const {
   if (!BuildDefs::dump())
     return;
   if (SegmentReg != DefaultSegment) {
     assert(SegmentReg >= 0 && SegmentReg < SegReg_NUM);
-    Str << InstX8632SegmentRegNames[SegmentReg] << ":";
+    Str << X8632::Traits::InstSegmentRegNames[SegmentReg] << ":";
   }
   bool Dumped = false;
   Str << "[";
@@ -2994,14 +186,17 @@
   Str << "]";
 }
 
-void OperandX8632Mem::emitSegmentOverride(X8632::AssemblerX8632 *Asm) const {
+void MachineTraits<TargetX8632>::X86OperandMem::emitSegmentOverride(
+    MachineTraits<TargetX8632>::Assembler *Asm) const {
   if (SegmentReg != DefaultSegment) {
     assert(SegmentReg >= 0 && SegmentReg < SegReg_NUM);
-    Asm->emitSegmentOverride(InstX8632SegmentPrefixes[SegmentReg]);
+    Asm->emitSegmentOverride(X8632::Traits::InstSegmentPrefixes[SegmentReg]);
   }
 }
 
-X8632::Traits::Address OperandX8632Mem::toAsmAddress(Assembler *Asm) const {
+MachineTraits<TargetX8632>::Address
+MachineTraits<TargetX8632>::X86OperandMem::toAsmAddress(
+    MachineTraits<TargetX8632>::Assembler *Asm) const {
   int32_t Disp = 0;
   AssemblerFixup *Fixup = nullptr;
   // Determine the offset (is it relocatable?)
@@ -3037,22 +232,23 @@
   }
 }
 
-X8632::Traits::Address VariableSplit::toAsmAddress(const Cfg *Func) const {
+MachineTraits<TargetX8632>::Address
+MachineTraits<TargetX8632>::VariableSplit::toAsmAddress(const Cfg *Func) const {
   assert(!Var->hasReg());
-  const TargetLowering *Target = Func->getTarget();
+  const ::Ice::TargetLowering *Target = Func->getTarget();
   int32_t Offset =
       Var->getStackOffset() + Target->getStackAdjustment() + getOffset();
   return X8632::Traits::Address(
       RegX8632::getEncodedGPR(Target->getFrameOrStackReg()), Offset);
 }
 
-void VariableSplit::emit(const Cfg *Func) const {
+void MachineTraits<TargetX8632>::VariableSplit::emit(const Cfg *Func) const {
   if (!BuildDefs::dump())
     return;
   Ostream &Str = Func->getContext()->getStrEmit();
   assert(!Var->hasReg());
   // The following is copied/adapted from TargetX8632::emitVariable().
-  const TargetLowering *Target = Func->getTarget();
+  const ::Ice::TargetLowering *Target = Func->getTarget();
   const Type Ty = IceType_i32;
   int32_t Offset =
       Var->getStackOffset() + Target->getStackAdjustment() + getOffset();
@@ -3061,7 +257,8 @@
   Str << "(%" << Target->getRegName(Target->getFrameOrStackReg(), Ty) << ")";
 }
 
-void VariableSplit::dump(const Cfg *Func, Ostream &Str) const {
+void MachineTraits<TargetX8632>::VariableSplit::dump(const Cfg *Func,
+                                                     Ostream &Str) const {
   if (!BuildDefs::dump())
     return;
   switch (Part) {
@@ -3080,4 +277,7 @@
   Str << ")";
 }
 
+} // namespace X86Internal
 } // end of namespace Ice
+
+X86INSTS_DEFINE_STATIC_DATA(TargetX8632);
diff --git a/src/IceInstX8632.h b/src/IceInstX8632.h
index 03a5205..44939dd 100644
--- a/src/IceInstX8632.h
+++ b/src/IceInstX8632.h
@@ -8,1784 +8,30 @@
 //===----------------------------------------------------------------------===//
 ///
 /// \file
-/// This file declares the InstX8632 and OperandX8632 classes and
-/// their subclasses.  This represents the machine instructions and
-/// operands used for x86-32 code selection.
+/// This file used to house all the X8632 instructions. Subzero has been
+/// modified to use templates for X86 instructions, so all those definitions are
+/// are in IceInstX86Base.h
+///
+/// When interacting with the X8632 target (which should only happen in the
+/// X8632 TargetLowering) clients have should use the Ice::X8632::Traits::Insts
+/// traits, which hides all the template verboseness behind a type alias.
+///
+/// For example, to create an X8632 MOV Instruction, clients should do
+///
+/// ::Ice::X8632::Traits::Insts::Mov::create
+///
+/// In the future, this file might be used to declare X8632 specific
+/// instructions (e.g., FLD, and FSTP.)
 ///
 //===----------------------------------------------------------------------===//
 
 #ifndef SUBZERO_SRC_ICEINSTX8632_H
 #define SUBZERO_SRC_ICEINSTX8632_H
 
-#include "IceAssemblerX8632.h"
-#include "IceConditionCodesX8632.h"
 #include "IceDefs.h"
 #include "IceInst.h"
-#include "IceInstX8632.def"
+#include "IceInstX86Base.h"
 #include "IceOperand.h"
 #include "IceTargetLoweringX8632Traits.h"
 
-namespace Ice {
-
-class TargetX8632;
-
-/// OperandX8632 extends the Operand hierarchy.  Its subclasses are
-/// OperandX8632Mem and VariableSplit.
-class OperandX8632 : public Operand {
-  OperandX8632() = delete;
-  OperandX8632(const OperandX8632 &) = delete;
-  OperandX8632 &operator=(const OperandX8632 &) = delete;
-
-public:
-  enum OperandKindX8632 { k__Start = Operand::kTarget, kMem, kSplit };
-  using Operand::dump;
-  void dump(const Cfg *, Ostream &Str) const override {
-    if (BuildDefs::dump())
-      Str << "<OperandX8632>";
-  }
-
-protected:
-  OperandX8632(OperandKindX8632 Kind, Type Ty)
-      : Operand(static_cast<OperandKind>(Kind), Ty) {}
-};
-
-/// OperandX8632Mem represents the m32 addressing mode, with optional
-/// base and index registers, a constant offset, and a fixed shift
-/// value for the index register.
-class OperandX8632Mem : public OperandX8632 {
-  OperandX8632Mem() = delete;
-  OperandX8632Mem(const OperandX8632Mem &) = delete;
-  OperandX8632Mem &operator=(const OperandX8632Mem &) = delete;
-
-public:
-  enum SegmentRegisters {
-    DefaultSegment = -1,
-#define X(val, name, prefix) val,
-    SEG_REGX8632_TABLE
-#undef X
-        SegReg_NUM
-  };
-  static OperandX8632Mem *create(Cfg *Func, Type Ty, Variable *Base,
-                                 Constant *Offset, Variable *Index = nullptr,
-                                 uint16_t Shift = 0,
-                                 SegmentRegisters SegmentReg = DefaultSegment) {
-    return new (Func->allocate<OperandX8632Mem>())
-        OperandX8632Mem(Func, Ty, Base, Offset, Index, Shift, SegmentReg);
-  }
-  Variable *getBase() const { return Base; }
-  Constant *getOffset() const { return Offset; }
-  Variable *getIndex() const { return Index; }
-  uint16_t getShift() const { return Shift; }
-  SegmentRegisters getSegmentRegister() const { return SegmentReg; }
-  void emitSegmentOverride(X8632::AssemblerX8632 *Asm) const;
-  X8632::Traits::Address toAsmAddress(Assembler *Asm) const;
-  void emit(const Cfg *Func) const override;
-  using OperandX8632::dump;
-  void dump(const Cfg *Func, Ostream &Str) const override;
-
-  static bool classof(const Operand *Operand) {
-    return Operand->getKind() == static_cast<OperandKind>(kMem);
-  }
-
-  void setRandomized(bool R) { Randomized = R; }
-
-  bool getRandomized() const { return Randomized; }
-
-private:
-  OperandX8632Mem(Cfg *Func, Type Ty, Variable *Base, Constant *Offset,
-                  Variable *Index, uint16_t Shift, SegmentRegisters SegmentReg);
-
-  Variable *Base;
-  Constant *Offset;
-  Variable *Index;
-  uint16_t Shift;
-  SegmentRegisters SegmentReg : 16;
-  /// A flag to show if this memory operand is a randomized one.
-  /// Randomized memory operands are generated in
-  /// TargetX8632::randomizeOrPoolImmediate()
-  bool Randomized;
-};
-
-/// VariableSplit is a way to treat an f64 memory location as a pair
-/// of i32 locations (Low and High).  This is needed for some cases
-/// of the Bitcast instruction.  Since it's not possible for integer
-/// registers to access the XMM registers and vice versa, the
-/// lowering forces the f64 to be spilled to the stack and then
-/// accesses through the VariableSplit.
-class VariableSplit : public OperandX8632 {
-  VariableSplit() = delete;
-  VariableSplit(const VariableSplit &) = delete;
-  VariableSplit &operator=(const VariableSplit &) = delete;
-
-public:
-  enum Portion { Low, High };
-  static VariableSplit *create(Cfg *Func, Variable *Var, Portion Part) {
-    return new (Func->allocate<VariableSplit>()) VariableSplit(Func, Var, Part);
-  }
-  int32_t getOffset() const { return Part == High ? 4 : 0; }
-
-  X8632::Traits::Address toAsmAddress(const Cfg *Func) const;
-  void emit(const Cfg *Func) const override;
-  using OperandX8632::dump;
-  void dump(const Cfg *Func, Ostream &Str) const override;
-
-  static bool classof(const Operand *Operand) {
-    return Operand->getKind() == static_cast<OperandKind>(kSplit);
-  }
-
-private:
-  VariableSplit(Cfg *Func, Variable *Var, Portion Part)
-      : OperandX8632(kSplit, IceType_i32), Var(Var), Part(Part) {
-    assert(Var->getType() == IceType_f64);
-    Vars = Func->allocateArrayOf<Variable *>(1);
-    Vars[0] = Var;
-    NumVars = 1;
-  }
-
-  Variable *Var;
-  Portion Part;
-};
-
-/// SpillVariable decorates a Variable by linking it to another
-/// Variable.  When stack frame offsets are computed, the SpillVariable
-/// is given a distinct stack slot only if its linked Variable has a
-/// register.  If the linked Variable has a stack slot, then the
-/// Variable and SpillVariable share that slot.
-class SpillVariable : public Variable {
-  SpillVariable() = delete;
-  SpillVariable(const SpillVariable &) = delete;
-  SpillVariable &operator=(const SpillVariable &) = delete;
-
-public:
-  static SpillVariable *create(Cfg *Func, Type Ty, SizeT Index) {
-    return new (Func->allocate<SpillVariable>()) SpillVariable(Ty, Index);
-  }
-  const static OperandKind SpillVariableKind =
-      static_cast<OperandKind>(kVariable_Target);
-  static bool classof(const Operand *Operand) {
-    return Operand->getKind() == SpillVariableKind;
-  }
-  void setLinkedTo(Variable *Var) { LinkedTo = Var; }
-  Variable *getLinkedTo() const { return LinkedTo; }
-  // Inherit dump() and emit() from Variable.
-private:
-  SpillVariable(Type Ty, SizeT Index)
-      : Variable(SpillVariableKind, Ty, Index), LinkedTo(nullptr) {}
-  Variable *LinkedTo;
-};
-
-class InstX8632 : public InstTarget {
-  InstX8632() = delete;
-  InstX8632(const InstX8632 &) = delete;
-  InstX8632 &operator=(const InstX8632 &) = delete;
-
-public:
-  enum InstKindX8632 {
-    k__Start = Inst::Target,
-    Adc,
-    AdcRMW,
-    Add,
-    AddRMW,
-    Addps,
-    Addss,
-    Adjuststack,
-    And,
-    AndRMW,
-    Blendvps,
-    Br,
-    Bsf,
-    Bsr,
-    Bswap,
-    Call,
-    Cbwdq,
-    Cmov,
-    Cmpps,
-    Cmpxchg,
-    Cmpxchg8b,
-    Cvt,
-    Div,
-    Divps,
-    Divss,
-    FakeRMW,
-    Fld,
-    Fstp,
-    Icmp,
-    Idiv,
-    Imul,
-    Insertps,
-    Jmp,
-    Label,
-    Lea,
-    Load,
-    Mfence,
-    Mov,
-    Movd,
-    Movp,
-    Movq,
-    MovssRegs,
-    Movsx,
-    Movzx,
-    Mul,
-    Mulps,
-    Mulss,
-    Neg,
-    Nop,
-    Or,
-    OrRMW,
-    Padd,
-    Pand,
-    Pandn,
-    Pblendvb,
-    Pcmpeq,
-    Pcmpgt,
-    Pextr,
-    Pinsr,
-    Pmull,
-    Pmuludq,
-    Pop,
-    Por,
-    Pshufd,
-    Psll,
-    Psra,
-    Psrl,
-    Psub,
-    Push,
-    Pxor,
-    Ret,
-    Rol,
-    Sar,
-    Sbb,
-    SbbRMW,
-    Setcc,
-    Shl,
-    Shld,
-    Shr,
-    Shrd,
-    Shufps,
-    Sqrtss,
-    Store,
-    StoreP,
-    StoreQ,
-    Sub,
-    SubRMW,
-    Subps,
-    Subss,
-    Test,
-    Ucomiss,
-    UD2,
-    Xadd,
-    Xchg,
-    Xor,
-    XorRMW
-  };
-
-  static const char *getWidthString(Type Ty);
-  static const char *getFldString(Type Ty);
-  static X8632::Traits::Cond::BrCond
-  getOppositeCondition(X8632::Traits::Cond::BrCond Cond);
-  void dump(const Cfg *Func) const override;
-
-  /// Shared emit routines for common forms of instructions.
-  /// See the definition of emitTwoAddress() for a description of
-  /// ShiftHack.
-  static void emitTwoAddress(const char *Opcode, const Inst *Inst,
-                             const Cfg *Func, bool ShiftHack = false);
-
-  static void
-  emitIASGPRShift(const Cfg *Func, Type Ty, const Variable *Var,
-                  const Operand *Src,
-                  const X8632::AssemblerX8632::GPREmitterShiftOp &Emitter);
-
-protected:
-  InstX8632(Cfg *Func, InstKindX8632 Kind, SizeT Maxsrcs, Variable *Dest)
-      : InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {}
-
-  static bool isClassof(const Inst *Inst, InstKindX8632 MyKind) {
-    return Inst->getKind() == static_cast<InstKind>(MyKind);
-  }
-  /// Most instructions that operate on vector arguments require vector
-  /// memory operands to be fully aligned (16-byte alignment for PNaCl
-  /// vector types).  The stack frame layout and call ABI ensure proper
-  /// alignment for stack operands, but memory operands (originating
-  /// from load/store bitcode instructions) only have element-size
-  /// alignment guarantees.  This function validates that none of the
-  /// operands is a memory operand of vector type, calling
-  /// report_fatal_error() if one is found.  This function should be
-  /// called during emission, and maybe also in the ctor (as long as
-  /// that fits the lowering style).
-  void validateVectorAddrMode() const {
-    if (getDest())
-      validateVectorAddrModeOpnd(getDest());
-    for (SizeT i = 0; i < getSrcSize(); ++i) {
-      validateVectorAddrModeOpnd(getSrc(i));
-    }
-  }
-
-private:
-  static void validateVectorAddrModeOpnd(const Operand *Opnd) {
-    if (llvm::isa<OperandX8632Mem>(Opnd) && isVectorType(Opnd->getType())) {
-      llvm::report_fatal_error("Possible misaligned vector memory operation");
-    }
-  }
-};
-
-/// InstX8632FakeRMW represents a non-atomic read-modify-write operation on a
-/// memory location.  An InstX8632FakeRMW is a "fake" instruction in that it
-/// still needs to be lowered to some actual RMW instruction.
-///
-/// If A is some memory address, D is some data value to apply, and OP is an
-/// arithmetic operator, the instruction operates as: (*A) = (*A) OP D
-class InstX8632FakeRMW : public InstX8632 {
-  InstX8632FakeRMW() = delete;
-  InstX8632FakeRMW(const InstX8632FakeRMW &) = delete;
-  InstX8632FakeRMW &operator=(const InstX8632FakeRMW &) = delete;
-
-public:
-  static InstX8632FakeRMW *create(Cfg *Func, Operand *Data, Operand *Addr,
-                                  Variable *Beacon, InstArithmetic::OpKind Op,
-                                  uint32_t Align = 1) {
-    // TODO(stichnot): Stop ignoring alignment specification.
-    (void)Align;
-    return new (Func->allocate<InstX8632FakeRMW>())
-        InstX8632FakeRMW(Func, Data, Addr, Op, Beacon);
-  }
-  Operand *getAddr() const { return getSrc(1); }
-  Operand *getData() const { return getSrc(0); }
-  InstArithmetic::OpKind getOp() const { return Op; }
-  Variable *getBeacon() const { return llvm::cast<Variable>(getSrc(2)); }
-  void dump(const Cfg *Func) const override;
-  static bool classof(const Inst *Inst) { return isClassof(Inst, FakeRMW); }
-
-private:
-  InstArithmetic::OpKind Op;
-  InstX8632FakeRMW(Cfg *Func, Operand *Data, Operand *Addr,
-                   InstArithmetic::OpKind Op, Variable *Beacon);
-};
-
-/// InstX8632Label represents an intra-block label that is the target
-/// of an intra-block branch.  The offset between the label and the
-/// branch must be fit into one byte (considered "near").  These are
-/// used for lowering i1 calculations, Select instructions, and 64-bit
-/// compares on a 32-bit architecture, without basic block splitting.
-/// Basic block splitting is not so desirable for several reasons, one
-/// of which is the impact on decisions based on whether a variable's
-/// live range spans multiple basic blocks.
-///
-/// Intra-block control flow must be used with caution.  Consider the
-/// sequence for "c = (a >= b ? x : y)".
-///     cmp a, b
-///     br lt, L1
-///     mov c, x
-///     jmp L2
-///   L1:
-///     mov c, y
-///   L2:
-///
-/// Labels L1 and L2 are intra-block labels.  Without knowledge of the
-/// intra-block control flow, liveness analysis will determine the "mov
-/// c, x" instruction to be dead.  One way to prevent this is to insert
-/// a "FakeUse(c)" instruction anywhere between the two "mov c, ..."
-/// instructions, e.g.:
-///
-///     cmp a, b
-///     br lt, L1
-///     mov c, x
-///     jmp L2
-///     FakeUse(c)
-///   L1:
-///     mov c, y
-///   L2:
-///
-/// The down-side is that "mov c, x" can never be dead-code eliminated
-/// even if there are no uses of c.  As unlikely as this situation is,
-/// it may be prevented by running dead code elimination before
-/// lowering.
-class InstX8632Label : public InstX8632 {
-  InstX8632Label() = delete;
-  InstX8632Label(const InstX8632Label &) = delete;
-  InstX8632Label &operator=(const InstX8632Label &) = delete;
-
-public:
-  static InstX8632Label *create(Cfg *Func, TargetX8632 *Target) {
-    return new (Func->allocate<InstX8632Label>()) InstX8632Label(Func, Target);
-  }
-  uint32_t getEmitInstCount() const override { return 0; }
-  IceString getName(const Cfg *Func) const;
-  SizeT getNumber() const { return Number; }
-  void emit(const Cfg *Func) const override;
-  void emitIAS(const Cfg *Func) const override;
-  void dump(const Cfg *Func) const override;
-
-private:
-  InstX8632Label(Cfg *Func, TargetX8632 *Target);
-
-  SizeT Number; /// used for unique label generation.
-};
-
-/// Conditional and unconditional branch instruction.
-class InstX8632Br : public InstX8632 {
-  InstX8632Br() = delete;
-  InstX8632Br(const InstX8632Br &) = delete;
-  InstX8632Br &operator=(const InstX8632Br &) = delete;
-
-public:
-  /// Create a conditional branch to a node.
-  static InstX8632Br *create(Cfg *Func, CfgNode *TargetTrue,
-                             CfgNode *TargetFalse,
-                             X8632::Traits::Cond::BrCond Condition) {
-    assert(Condition != X8632::Traits::Cond::Br_None);
-    const InstX8632Label *NoLabel = nullptr;
-    return new (Func->allocate<InstX8632Br>())
-        InstX8632Br(Func, TargetTrue, TargetFalse, NoLabel, Condition);
-  }
-  /// Create an unconditional branch to a node.
-  static InstX8632Br *create(Cfg *Func, CfgNode *Target) {
-    const CfgNode *NoCondTarget = nullptr;
-    const InstX8632Label *NoLabel = nullptr;
-    return new (Func->allocate<InstX8632Br>()) InstX8632Br(
-        Func, NoCondTarget, Target, NoLabel, X8632::Traits::Cond::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,
-                             X8632::Traits::Cond::BrCond Condition) {
-    assert(Condition != X8632::Traits::Cond::Br_None);
-    const CfgNode *NoUncondTarget = nullptr;
-    const InstX8632Label *NoLabel = nullptr;
-    return new (Func->allocate<InstX8632Br>())
-        InstX8632Br(Func, Target, NoUncondTarget, NoLabel, Condition);
-  }
-  /// 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,
-                             X8632::Traits::Cond::BrCond Condition) {
-    const CfgNode *NoCondTarget = nullptr;
-    const CfgNode *NoUncondTarget = nullptr;
-    return new (Func->allocate<InstX8632Br>())
-        InstX8632Br(Func, NoCondTarget, NoUncondTarget, Label, Condition);
-  }
-  const CfgNode *getTargetTrue() const { return TargetTrue; }
-  const CfgNode *getTargetFalse() const { return TargetFalse; }
-  bool optimizeBranch(const CfgNode *NextNode);
-  uint32_t getEmitInstCount() const override {
-    uint32_t Sum = 0;
-    if (Label)
-      ++Sum;
-    if (getTargetTrue())
-      ++Sum;
-    if (getTargetFalse())
-      ++Sum;
-    return Sum;
-  }
-  bool isUnconditionalBranch() const override {
-    return !Label && Condition == X8632::Traits::Cond::Br_None;
-  }
-  bool repointEdge(CfgNode *OldNode, CfgNode *NewNode) override;
-  void emit(const Cfg *Func) const override;
-  void emitIAS(const Cfg *Func) const override;
-  void dump(const Cfg *Func) const override;
-  static bool classof(const Inst *Inst) { return isClassof(Inst, Br); }
-
-private:
-  InstX8632Br(Cfg *Func, const CfgNode *TargetTrue, const CfgNode *TargetFalse,
-              const InstX8632Label *Label,
-              X8632::Traits::Cond::BrCond Condition);
-
-  X8632::Traits::Cond::BrCond Condition;
-  const CfgNode *TargetTrue;
-  const CfgNode *TargetFalse;
-  const InstX8632Label *Label; /// Intra-block branch target
-};
-
-/// Jump to a target outside this function, such as tailcall, nacljump,
-/// naclret, unreachable.  This is different from a Branch instruction
-/// in that there is no intra-function control flow to represent.
-class InstX8632Jmp : public InstX8632 {
-  InstX8632Jmp() = delete;
-  InstX8632Jmp(const InstX8632Jmp &) = delete;
-  InstX8632Jmp &operator=(const InstX8632Jmp &) = delete;
-
-public:
-  static InstX8632Jmp *create(Cfg *Func, Operand *Target) {
-    return new (Func->allocate<InstX8632Jmp>()) InstX8632Jmp(Func, Target);
-  }
-  Operand *getJmpTarget() const { return getSrc(0); }
-  void emit(const Cfg *Func) const override;
-  void emitIAS(const Cfg *Func) const override;
-  void dump(const Cfg *Func) const override;
-  static bool classof(const Inst *Inst) { return isClassof(Inst, Jmp); }
-
-private:
-  InstX8632Jmp(Cfg *Func, Operand *Target);
-};
-
-/// AdjustStack instruction - subtracts esp by the given amount and
-/// updates the stack offset during code emission.
-class InstX8632AdjustStack : public InstX8632 {
-  InstX8632AdjustStack() = delete;
-  InstX8632AdjustStack(const InstX8632AdjustStack &) = delete;
-  InstX8632AdjustStack &operator=(const InstX8632AdjustStack &) = delete;
-
-public:
-  static InstX8632AdjustStack *create(Cfg *Func, SizeT Amount, Variable *Esp) {
-    return new (Func->allocate<InstX8632AdjustStack>())
-        InstX8632AdjustStack(Func, Amount, Esp);
-  }
-  void emit(const Cfg *Func) const override;
-  void emitIAS(const Cfg *Func) const override;
-  void dump(const Cfg *Func) const override;
-  static bool classof(const Inst *Inst) { return isClassof(Inst, Adjuststack); }
-
-private:
-  InstX8632AdjustStack(Cfg *Func, SizeT Amount, Variable *Esp);
-  SizeT Amount;
-};
-
-/// Call instruction.  Arguments should have already been pushed.
-class InstX8632Call : public InstX8632 {
-  InstX8632Call() = delete;
-  InstX8632Call(const InstX8632Call &) = delete;
-  InstX8632Call &operator=(const InstX8632Call &) = delete;
-
-public:
-  static InstX8632Call *create(Cfg *Func, Variable *Dest, Operand *CallTarget) {
-    return new (Func->allocate<InstX8632Call>())
-        InstX8632Call(Func, Dest, CallTarget);
-  }
-  Operand *getCallTarget() const { return getSrc(0); }
-  void emit(const Cfg *Func) const override;
-  void emitIAS(const Cfg *Func) const override;
-  void dump(const Cfg *Func) const override;
-  static bool classof(const Inst *Inst) { return isClassof(Inst, Call); }
-
-private:
-  InstX8632Call(Cfg *Func, Variable *Dest, Operand *CallTarget);
-};
-
-/// Emit a one-operand (GPR) instruction.
-void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Var,
-                    const X8632::AssemblerX8632::GPREmitterOneOp &Emitter);
-void emitIASAsAddrOpTyGPR(
-    const Cfg *Func, Type Ty, const Operand *Op0, const Operand *Op1,
-    const X8632::AssemblerX8632::GPREmitterAddrOp &Emitter);
-
-/// Instructions of the form x := op(x).
-template <InstX8632::InstKindX8632 K>
-class InstX8632InplaceopGPR : public InstX8632 {
-  InstX8632InplaceopGPR() = delete;
-  InstX8632InplaceopGPR(const InstX8632InplaceopGPR &) = delete;
-  InstX8632InplaceopGPR &operator=(const InstX8632InplaceopGPR &) = delete;
-
-public:
-  static InstX8632InplaceopGPR *create(Cfg *Func, Operand *SrcDest) {
-    return new (Func->allocate<InstX8632InplaceopGPR>())
-        InstX8632InplaceopGPR(Func, SrcDest);
-  }
-  void emit(const Cfg *Func) const override {
-    if (!BuildDefs::dump())
-      return;
-    Ostream &Str = Func->getContext()->getStrEmit();
-    assert(getSrcSize() == 1);
-    Str << "\t" << Opcode << "\t";
-    getSrc(0)->emit(Func);
-  }
-  void emitIAS(const Cfg *Func) const override {
-    assert(getSrcSize() == 1);
-    const Variable *Var = getDest();
-    Type Ty = Var->getType();
-    emitIASOpTyGPR(Func, Ty, Var, Emitter);
-  }
-  void dump(const Cfg *Func) const override {
-    if (!BuildDefs::dump())
-      return;
-    Ostream &Str = Func->getContext()->getStrDump();
-    dumpDest(Func);
-    Str << " = " << Opcode << "." << getDest()->getType() << " ";
-    dumpSources(Func);
-  }
-  static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
-
-private:
-  InstX8632InplaceopGPR(Cfg *Func, Operand *SrcDest)
-      : InstX8632(Func, K, 1, llvm::dyn_cast<Variable>(SrcDest)) {
-    addSource(SrcDest);
-  }
-
-  static const char *Opcode;
-  static const X8632::AssemblerX8632::GPREmitterOneOp Emitter;
-};
-
-/// Emit a two-operand (GPR) instruction, where the dest operand is a
-/// Variable that's guaranteed to be a register.
-template <bool VarCanBeByte = true, bool SrcCanBeByte = true>
-void emitIASRegOpTyGPR(const Cfg *Func, Type Ty, const Variable *Dst,
-                       const Operand *Src,
-                       const X8632::AssemblerX8632::GPREmitterRegOp &Emitter);
-
-/// Instructions of the form x := op(y).
-template <InstX8632::InstKindX8632 K>
-class InstX8632UnaryopGPR : public InstX8632 {
-  InstX8632UnaryopGPR() = delete;
-  InstX8632UnaryopGPR(const InstX8632UnaryopGPR &) = delete;
-  InstX8632UnaryopGPR &operator=(const InstX8632UnaryopGPR &) = delete;
-
-public:
-  static InstX8632UnaryopGPR *create(Cfg *Func, Variable *Dest, Operand *Src) {
-    return new (Func->allocate<InstX8632UnaryopGPR>())
-        InstX8632UnaryopGPR(Func, Dest, Src);
-  }
-  void emit(const Cfg *Func) const override {
-    if (!BuildDefs::dump())
-      return;
-    Ostream &Str = Func->getContext()->getStrEmit();
-    assert(getSrcSize() == 1);
-    Type SrcTy = getSrc(0)->getType();
-    Type DestTy = getDest()->getType();
-    Str << "\t" << Opcode << getWidthString(SrcTy);
-    // Movsx and movzx need both the source and dest type width letter
-    // to define the operation.  The other unary operations have the
-    // same source and dest type and as a result need only one letter.
-    if (SrcTy != DestTy)
-      Str << getWidthString(DestTy);
-    Str << "\t";
-    getSrc(0)->emit(Func);
-    Str << ", ";
-    getDest()->emit(Func);
-  }
-  void emitIAS(const Cfg *Func) const override {
-    assert(getSrcSize() == 1);
-    const Variable *Var = getDest();
-    Type Ty = Var->getType();
-    const Operand *Src = getSrc(0);
-    emitIASRegOpTyGPR(Func, Ty, Var, Src, Emitter);
-  }
-  void dump(const Cfg *Func) const override {
-    if (!BuildDefs::dump())
-      return;
-    Ostream &Str = Func->getContext()->getStrDump();
-    dumpDest(Func);
-    Str << " = " << Opcode << "." << getSrc(0)->getType() << " ";
-    dumpSources(Func);
-  }
-  static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
-
-private:
-  InstX8632UnaryopGPR(Cfg *Func, Variable *Dest, Operand *Src)
-      : InstX8632(Func, K, 1, Dest) {
-    addSource(Src);
-  }
-
-  static const char *Opcode;
-  static const X8632::AssemblerX8632::GPREmitterRegOp Emitter;
-};
-
-void emitIASRegOpTyXMM(const Cfg *Func, Type Ty, const Variable *Var,
-                       const Operand *Src,
-                       const X8632::AssemblerX8632::XmmEmitterRegOp &Emitter);
-
-template <InstX8632::InstKindX8632 K>
-class InstX8632UnaryopXmm : public InstX8632 {
-  InstX8632UnaryopXmm() = delete;
-  InstX8632UnaryopXmm(const InstX8632UnaryopXmm &) = delete;
-  InstX8632UnaryopXmm &operator=(const InstX8632UnaryopXmm &) = delete;
-
-public:
-  static InstX8632UnaryopXmm *create(Cfg *Func, Variable *Dest, Operand *Src) {
-    return new (Func->allocate<InstX8632UnaryopXmm>())
-        InstX8632UnaryopXmm(Func, Dest, Src);
-  }
-  void emit(const Cfg *Func) const override {
-    if (!BuildDefs::dump())
-      return;
-    Ostream &Str = Func->getContext()->getStrEmit();
-    assert(getSrcSize() == 1);
-    Str << "\t" << Opcode << "\t";
-    getSrc(0)->emit(Func);
-    Str << ", ";
-    getDest()->emit(Func);
-  }
-  void emitIAS(const Cfg *Func) const override {
-    Type Ty = getDest()->getType();
-    assert(getSrcSize() == 1);
-    emitIASRegOpTyXMM(Func, Ty, getDest(), getSrc(0), Emitter);
-  }
-  void dump(const Cfg *Func) const override {
-    if (!BuildDefs::dump())
-      return;
-    Ostream &Str = Func->getContext()->getStrDump();
-    dumpDest(Func);
-    Str << " = " << Opcode << "." << getDest()->getType() << " ";
-    dumpSources(Func);
-  }
-  static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
-
-private:
-  InstX8632UnaryopXmm(Cfg *Func, Variable *Dest, Operand *Src)
-      : InstX8632(Func, K, 1, Dest) {
-    addSource(Src);
-  }
-
-  static const char *Opcode;
-  static const X8632::AssemblerX8632::XmmEmitterRegOp Emitter;
-};
-
-template <InstX8632::InstKindX8632 K>
-class InstX8632BinopGPRShift : public InstX8632 {
-  InstX8632BinopGPRShift() = delete;
-  InstX8632BinopGPRShift(const InstX8632BinopGPRShift &) = delete;
-  InstX8632BinopGPRShift &operator=(const InstX8632BinopGPRShift &) = delete;
-
-public:
-  /// Create a binary-op GPR shift instruction.
-  static InstX8632BinopGPRShift *create(Cfg *Func, Variable *Dest,
-                                        Operand *Source) {
-    return new (Func->allocate<InstX8632BinopGPRShift>())
-        InstX8632BinopGPRShift(Func, Dest, Source);
-  }
-  void emit(const Cfg *Func) const override {
-    if (!BuildDefs::dump())
-      return;
-    const bool ShiftHack = true;
-    emitTwoAddress(Opcode, this, Func, ShiftHack);
-  }
-  void emitIAS(const Cfg *Func) const override {
-    Type Ty = getDest()->getType();
-    assert(getSrcSize() == 2);
-    emitIASGPRShift(Func, Ty, getDest(), getSrc(1), Emitter);
-  }
-  void dump(const Cfg *Func) const override {
-    if (!BuildDefs::dump())
-      return;
-    Ostream &Str = Func->getContext()->getStrDump();
-    dumpDest(Func);
-    Str << " = " << Opcode << "." << getDest()->getType() << " ";
-    dumpSources(Func);
-  }
-  static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
-
-private:
-  InstX8632BinopGPRShift(Cfg *Func, Variable *Dest, Operand *Source)
-      : InstX8632(Func, K, 2, Dest) {
-    addSource(Dest);
-    addSource(Source);
-  }
-
-  static const char *Opcode;
-  static const X8632::AssemblerX8632::GPREmitterShiftOp Emitter;
-};
-
-template <InstX8632::InstKindX8632 K>
-class InstX8632BinopGPR : public InstX8632 {
-  InstX8632BinopGPR() = delete;
-  InstX8632BinopGPR(const InstX8632BinopGPR &) = delete;
-  InstX8632BinopGPR &operator=(const InstX8632BinopGPR &) = delete;
-
-public:
-  /// Create an ordinary binary-op instruction like add or sub.
-  static InstX8632BinopGPR *create(Cfg *Func, Variable *Dest, Operand *Source) {
-    return new (Func->allocate<InstX8632BinopGPR>())
-        InstX8632BinopGPR(Func, Dest, Source);
-  }
-  void emit(const Cfg *Func) const override {
-    if (!BuildDefs::dump())
-      return;
-    const bool ShiftHack = false;
-    emitTwoAddress(Opcode, this, Func, ShiftHack);
-  }
-  void emitIAS(const Cfg *Func) const override {
-    Type Ty = getDest()->getType();
-    assert(getSrcSize() == 2);
-    emitIASRegOpTyGPR(Func, Ty, getDest(), getSrc(1), Emitter);
-  }
-  void dump(const Cfg *Func) const override {
-    if (!BuildDefs::dump())
-      return;
-    Ostream &Str = Func->getContext()->getStrDump();
-    dumpDest(Func);
-    Str << " = " << Opcode << "." << getDest()->getType() << " ";
-    dumpSources(Func);
-  }
-  static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
-
-private:
-  InstX8632BinopGPR(Cfg *Func, Variable *Dest, Operand *Source)
-      : InstX8632(Func, K, 2, Dest) {
-    addSource(Dest);
-    addSource(Source);
-  }
-
-  static const char *Opcode;
-  static const X8632::AssemblerX8632::GPREmitterRegOp Emitter;
-};
-
-template <InstX8632::InstKindX8632 K>
-class InstX8632BinopRMW : public InstX8632 {
-  InstX8632BinopRMW() = delete;
-  InstX8632BinopRMW(const InstX8632BinopRMW &) = delete;
-  InstX8632BinopRMW &operator=(const InstX8632BinopRMW &) = delete;
-
-public:
-  /// Create an ordinary binary-op instruction like add or sub.
-  static InstX8632BinopRMW *create(Cfg *Func, OperandX8632Mem *DestSrc0,
-                                   Operand *Src1) {
-    return new (Func->allocate<InstX8632BinopRMW>())
-        InstX8632BinopRMW(Func, DestSrc0, Src1);
-  }
-  void emit(const Cfg *Func) const override {
-    if (!BuildDefs::dump())
-      return;
-    const bool ShiftHack = false;
-    emitTwoAddress(Opcode, this, Func, ShiftHack);
-  }
-  void emitIAS(const Cfg *Func) const override {
-    Type Ty = getSrc(0)->getType();
-    assert(getSrcSize() == 2);
-    emitIASAsAddrOpTyGPR(Func, Ty, getSrc(0), getSrc(1), Emitter);
-  }
-  void dump(const Cfg *Func) const override {
-    if (!BuildDefs::dump())
-      return;
-    Ostream &Str = Func->getContext()->getStrDump();
-    Str << Opcode << "." << getSrc(0)->getType() << " ";
-    dumpSources(Func);
-  }
-  static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
-
-private:
-  InstX8632BinopRMW(Cfg *Func, OperandX8632Mem *DestSrc0, Operand *Src1)
-      : InstX8632(Func, K, 2, nullptr) {
-    addSource(DestSrc0);
-    addSource(Src1);
-  }
-  static const char *Opcode;
-  static const X8632::AssemblerX8632::GPREmitterAddrOp Emitter;
-};
-
-template <InstX8632::InstKindX8632 K, bool NeedsElementType>
-class InstX8632BinopXmm : public InstX8632 {
-  InstX8632BinopXmm() = delete;
-  InstX8632BinopXmm(const InstX8632BinopXmm &) = delete;
-  InstX8632BinopXmm &operator=(const InstX8632BinopXmm &) = delete;
-
-public:
-  /// Create an XMM binary-op instruction like addss or addps.
-  static InstX8632BinopXmm *create(Cfg *Func, Variable *Dest, Operand *Source) {
-    return new (Func->allocate<InstX8632BinopXmm>())
-        InstX8632BinopXmm(Func, Dest, Source);
-  }
-  void emit(const Cfg *Func) const override {
-    if (!BuildDefs::dump())
-      return;
-    validateVectorAddrMode();
-    const bool ShiftHack = false;
-    emitTwoAddress(Opcode, this, Func, ShiftHack);
-  }
-  void emitIAS(const Cfg *Func) const override {
-    validateVectorAddrMode();
-    Type Ty = getDest()->getType();
-    if (NeedsElementType)
-      Ty = typeElementType(Ty);
-    assert(getSrcSize() == 2);
-    emitIASRegOpTyXMM(Func, Ty, getDest(), getSrc(1), Emitter);
-  }
-  void dump(const Cfg *Func) const override {
-    if (!BuildDefs::dump())
-      return;
-    Ostream &Str = Func->getContext()->getStrDump();
-    dumpDest(Func);
-    Str << " = " << Opcode << "." << getDest()->getType() << " ";
-    dumpSources(Func);
-  }
-  static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
-
-private:
-  InstX8632BinopXmm(Cfg *Func, Variable *Dest, Operand *Source)
-      : InstX8632(Func, K, 2, Dest) {
-    addSource(Dest);
-    addSource(Source);
-  }
-
-  static const char *Opcode;
-  static const X8632::AssemblerX8632::XmmEmitterRegOp Emitter;
-};
-
-void emitIASXmmShift(const Cfg *Func, Type Ty, const Variable *Var,
-                     const Operand *Src,
-                     const X8632::AssemblerX8632::XmmEmitterShiftOp &Emitter);
-
-template <InstX8632::InstKindX8632 K, bool AllowAllTypes = false>
-class InstX8632BinopXmmShift : public InstX8632 {
-  InstX8632BinopXmmShift() = delete;
-  InstX8632BinopXmmShift(const InstX8632BinopXmmShift &) = delete;
-  InstX8632BinopXmmShift &operator=(const InstX8632BinopXmmShift &) = delete;
-
-public:
-  /// Create an XMM binary-op shift operation.
-  static InstX8632BinopXmmShift *create(Cfg *Func, Variable *Dest,
-                                        Operand *Source) {
-    return new (Func->allocate<InstX8632BinopXmmShift>())
-        InstX8632BinopXmmShift(Func, Dest, Source);
-  }
-  void emit(const Cfg *Func) const override {
-    if (!BuildDefs::dump())
-      return;
-    validateVectorAddrMode();
-    const bool ShiftHack = false;
-    emitTwoAddress(Opcode, this, Func, ShiftHack);
-  }
-  void emitIAS(const Cfg *Func) const override {
-    validateVectorAddrMode();
-    Type Ty = getDest()->getType();
-    assert(AllowAllTypes || isVectorType(Ty));
-    Type ElementTy = typeElementType(Ty);
-    assert(getSrcSize() == 2);
-    emitIASXmmShift(Func, ElementTy, getDest(), getSrc(1), Emitter);
-  }
-  void dump(const Cfg *Func) const override {
-    if (!BuildDefs::dump())
-      return;
-    Ostream &Str = Func->getContext()->getStrDump();
-    dumpDest(Func);
-    Str << " = " << Opcode << "." << getDest()->getType() << " ";
-    dumpSources(Func);
-  }
-  static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
-
-private:
-  InstX8632BinopXmmShift(Cfg *Func, Variable *Dest, Operand *Source)
-      : InstX8632(Func, K, 2, Dest) {
-    addSource(Dest);
-    addSource(Source);
-  }
-
-  static const char *Opcode;
-  static const X8632::AssemblerX8632::XmmEmitterShiftOp Emitter;
-};
-
-template <InstX8632::InstKindX8632 K> class InstX8632Ternop : public InstX8632 {
-  InstX8632Ternop() = delete;
-  InstX8632Ternop(const InstX8632Ternop &) = delete;
-  InstX8632Ternop &operator=(const InstX8632Ternop &) = delete;
-
-public:
-  /// Create a ternary-op instruction like div or idiv.
-  static InstX8632Ternop *create(Cfg *Func, Variable *Dest, Operand *Source1,
-                                 Operand *Source2) {
-    return new (Func->allocate<InstX8632Ternop>())
-        InstX8632Ternop(Func, Dest, Source1, Source2);
-  }
-  void emit(const Cfg *Func) const override {
-    if (!BuildDefs::dump())
-      return;
-    Ostream &Str = Func->getContext()->getStrEmit();
-    assert(getSrcSize() == 3);
-    Str << "\t" << Opcode << "\t";
-    getSrc(2)->emit(Func);
-    Str << ", ";
-    getSrc(1)->emit(Func);
-    Str << ", ";
-    getDest()->emit(Func);
-  }
-  void emitIAS(const Cfg *Func) const override;
-  void dump(const Cfg *Func) const override {
-    if (!BuildDefs::dump())
-      return;
-    Ostream &Str = Func->getContext()->getStrDump();
-    dumpDest(Func);
-    Str << " = " << Opcode << "." << getDest()->getType() << " ";
-    dumpSources(Func);
-  }
-  static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
-
-private:
-  InstX8632Ternop(Cfg *Func, Variable *Dest, Operand *Source1, Operand *Source2)
-      : InstX8632(Func, K, 3, Dest) {
-    addSource(Dest);
-    addSource(Source1);
-    addSource(Source2);
-  }
-
-  static const char *Opcode;
-};
-
-/// Instructions of the form x := y op z
-template <InstX8632::InstKindX8632 K>
-class InstX8632ThreeAddressop : public InstX8632 {
-  InstX8632ThreeAddressop() = delete;
-  InstX8632ThreeAddressop(const InstX8632ThreeAddressop &) = delete;
-  InstX8632ThreeAddressop &operator=(const InstX8632ThreeAddressop &) = delete;
-
-public:
-  static InstX8632ThreeAddressop *create(Cfg *Func, Variable *Dest,
-                                         Operand *Source0, Operand *Source1) {
-    return new (Func->allocate<InstX8632ThreeAddressop>())
-        InstX8632ThreeAddressop(Func, Dest, Source0, Source1);
-  }
-  void emit(const Cfg *Func) const override {
-    if (!BuildDefs::dump())
-      return;
-    Ostream &Str = Func->getContext()->getStrEmit();
-    assert(getSrcSize() == 2);
-    Str << "\t" << Opcode << "\t";
-    getSrc(1)->emit(Func);
-    Str << ", ";
-    getSrc(0)->emit(Func);
-    Str << ", ";
-    getDest()->emit(Func);
-  }
-  void emitIAS(const Cfg *Func) const override;
-  void dump(const Cfg *Func) const override {
-    if (!BuildDefs::dump())
-      return;
-    Ostream &Str = Func->getContext()->getStrDump();
-    dumpDest(Func);
-    Str << " = " << Opcode << "." << getDest()->getType() << " ";
-    dumpSources(Func);
-  }
-  static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
-
-private:
-  InstX8632ThreeAddressop(Cfg *Func, Variable *Dest, Operand *Source0,
-                          Operand *Source1)
-      : InstX8632(Func, K, 2, Dest) {
-    addSource(Source0);
-    addSource(Source1);
-  }
-
-  static const char *Opcode;
-};
-
-/// Base class for assignment instructions
-template <InstX8632::InstKindX8632 K>
-class InstX8632Movlike : public InstX8632 {
-  InstX8632Movlike() = delete;
-  InstX8632Movlike(const InstX8632Movlike &) = delete;
-  InstX8632Movlike &operator=(const InstX8632Movlike &) = delete;
-
-public:
-  static InstX8632Movlike *create(Cfg *Func, Variable *Dest, Operand *Source) {
-    return new (Func->allocate<InstX8632Movlike>())
-        InstX8632Movlike(Func, Dest, Source);
-  }
-  bool isRedundantAssign() const override {
-    return checkForRedundantAssign(getDest(), getSrc(0));
-  }
-  bool isSimpleAssign() const override { return true; }
-  void emit(const Cfg *Func) const override;
-  void emitIAS(const Cfg *Func) const override;
-  void dump(const Cfg *Func) const override {
-    if (!BuildDefs::dump())
-      return;
-    Ostream &Str = Func->getContext()->getStrDump();
-    Str << Opcode << "." << getDest()->getType() << " ";
-    dumpDest(Func);
-    Str << ", ";
-    dumpSources(Func);
-  }
-  static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
-
-private:
-  InstX8632Movlike(Cfg *Func, Variable *Dest, Operand *Source)
-      : InstX8632(Func, K, 1, Dest) {
-    addSource(Source);
-  }
-
-  static const char *Opcode;
-};
-
-typedef InstX8632InplaceopGPR<InstX8632::Bswap> InstX8632Bswap;
-typedef InstX8632InplaceopGPR<InstX8632::Neg> InstX8632Neg;
-typedef InstX8632UnaryopGPR<InstX8632::Bsf> InstX8632Bsf;
-typedef InstX8632UnaryopGPR<InstX8632::Bsr> InstX8632Bsr;
-typedef InstX8632UnaryopGPR<InstX8632::Lea> InstX8632Lea;
-/// Cbwdq instruction - wrapper for cbw, cwd, and cdq
-typedef InstX8632UnaryopGPR<InstX8632::Cbwdq> InstX8632Cbwdq;
-typedef InstX8632UnaryopGPR<InstX8632::Movsx> InstX8632Movsx;
-typedef InstX8632UnaryopGPR<InstX8632::Movzx> InstX8632Movzx;
-typedef InstX8632UnaryopXmm<InstX8632::Movd> InstX8632Movd;
-typedef InstX8632UnaryopXmm<InstX8632::Sqrtss> InstX8632Sqrtss;
-/// Move/assignment instruction - wrapper for mov/movss/movsd.
-typedef InstX8632Movlike<InstX8632::Mov> InstX8632Mov;
-/// Move packed - copy 128 bit values between XMM registers, or mem128
-/// and XMM registers.
-typedef InstX8632Movlike<InstX8632::Movp> InstX8632Movp;
-/// Movq - copy between XMM registers, or mem64 and XMM registers.
-typedef InstX8632Movlike<InstX8632::Movq> InstX8632Movq;
-typedef InstX8632BinopGPR<InstX8632::Add> InstX8632Add;
-typedef InstX8632BinopRMW<InstX8632::AddRMW> InstX8632AddRMW;
-typedef InstX8632BinopXmm<InstX8632::Addps, true> InstX8632Addps;
-typedef InstX8632BinopGPR<InstX8632::Adc> InstX8632Adc;
-typedef InstX8632BinopRMW<InstX8632::AdcRMW> InstX8632AdcRMW;
-typedef InstX8632BinopXmm<InstX8632::Addss, false> InstX8632Addss;
-typedef InstX8632BinopXmm<InstX8632::Padd, true> InstX8632Padd;
-typedef InstX8632BinopGPR<InstX8632::Sub> InstX8632Sub;
-typedef InstX8632BinopRMW<InstX8632::SubRMW> InstX8632SubRMW;
-typedef InstX8632BinopXmm<InstX8632::Subps, true> InstX8632Subps;
-typedef InstX8632BinopXmm<InstX8632::Subss, false> InstX8632Subss;
-typedef InstX8632BinopGPR<InstX8632::Sbb> InstX8632Sbb;
-typedef InstX8632BinopRMW<InstX8632::SbbRMW> InstX8632SbbRMW;
-typedef InstX8632BinopXmm<InstX8632::Psub, true> InstX8632Psub;
-typedef InstX8632BinopGPR<InstX8632::And> InstX8632And;
-typedef InstX8632BinopRMW<InstX8632::AndRMW> InstX8632AndRMW;
-typedef InstX8632BinopXmm<InstX8632::Pand, false> InstX8632Pand;
-typedef InstX8632BinopXmm<InstX8632::Pandn, false> InstX8632Pandn;
-typedef InstX8632BinopGPR<InstX8632::Or> InstX8632Or;
-typedef InstX8632BinopRMW<InstX8632::OrRMW> InstX8632OrRMW;
-typedef InstX8632BinopXmm<InstX8632::Por, false> InstX8632Por;
-typedef InstX8632BinopGPR<InstX8632::Xor> InstX8632Xor;
-typedef InstX8632BinopRMW<InstX8632::XorRMW> InstX8632XorRMW;
-typedef InstX8632BinopXmm<InstX8632::Pxor, false> InstX8632Pxor;
-typedef InstX8632BinopGPR<InstX8632::Imul> InstX8632Imul;
-typedef InstX8632BinopXmm<InstX8632::Mulps, true> InstX8632Mulps;
-typedef InstX8632BinopXmm<InstX8632::Mulss, false> InstX8632Mulss;
-typedef InstX8632BinopXmm<InstX8632::Pmull, true> InstX8632Pmull;
-typedef InstX8632BinopXmm<InstX8632::Pmuludq, false> InstX8632Pmuludq;
-typedef InstX8632BinopXmm<InstX8632::Divps, true> InstX8632Divps;
-typedef InstX8632BinopXmm<InstX8632::Divss, false> InstX8632Divss;
-typedef InstX8632BinopGPRShift<InstX8632::Rol> InstX8632Rol;
-typedef InstX8632BinopGPRShift<InstX8632::Shl> InstX8632Shl;
-typedef InstX8632BinopXmmShift<InstX8632::Psll> InstX8632Psll;
-typedef InstX8632BinopXmmShift<InstX8632::Psrl, true> InstX8632Psrl;
-typedef InstX8632BinopGPRShift<InstX8632::Shr> InstX8632Shr;
-typedef InstX8632BinopGPRShift<InstX8632::Sar> InstX8632Sar;
-typedef InstX8632BinopXmmShift<InstX8632::Psra> InstX8632Psra;
-typedef InstX8632BinopXmm<InstX8632::Pcmpeq, true> InstX8632Pcmpeq;
-typedef InstX8632BinopXmm<InstX8632::Pcmpgt, true> InstX8632Pcmpgt;
-/// movss is only a binary operation when the source and dest
-/// operands are both registers (the high bits of dest are left untouched).
-/// In other cases, it behaves like a copy (mov-like) operation (and the
-/// high bits of dest are cleared).
-/// InstX8632Movss will assert that both its source and dest operands are
-/// registers, so the lowering code should use _mov instead of _movss
-/// in cases where a copy operation is intended.
-typedef InstX8632BinopXmm<InstX8632::MovssRegs, false> InstX8632MovssRegs;
-typedef InstX8632Ternop<InstX8632::Idiv> InstX8632Idiv;
-typedef InstX8632Ternop<InstX8632::Div> InstX8632Div;
-typedef InstX8632Ternop<InstX8632::Insertps> InstX8632Insertps;
-typedef InstX8632Ternop<InstX8632::Pinsr> InstX8632Pinsr;
-typedef InstX8632Ternop<InstX8632::Shufps> InstX8632Shufps;
-typedef InstX8632Ternop<InstX8632::Blendvps> InstX8632Blendvps;
-typedef InstX8632Ternop<InstX8632::Pblendvb> InstX8632Pblendvb;
-typedef InstX8632ThreeAddressop<InstX8632::Pextr> InstX8632Pextr;
-typedef InstX8632ThreeAddressop<InstX8632::Pshufd> InstX8632Pshufd;
-
-/// Base class for a lockable x86-32 instruction (emits a locked prefix).
-class InstX8632Lockable : public InstX8632 {
-  InstX8632Lockable() = delete;
-  InstX8632Lockable(const InstX8632Lockable &) = delete;
-  InstX8632Lockable &operator=(const InstX8632Lockable &) = delete;
-
-protected:
-  bool Locked;
-
-  InstX8632Lockable(Cfg *Func, InstKindX8632 Kind, SizeT Maxsrcs,
-                    Variable *Dest, bool Locked)
-      : InstX8632(Func, Kind, Maxsrcs, Dest), Locked(Locked) {
-    // Assume that such instructions are used for Atomics and be careful
-    // with optimizations.
-    HasSideEffects = Locked;
-  }
-};
-
-/// Mul instruction - unsigned multiply.
-class InstX8632Mul : public InstX8632 {
-  InstX8632Mul() = delete;
-  InstX8632Mul(const InstX8632Mul &) = delete;
-  InstX8632Mul &operator=(const InstX8632Mul &) = delete;
-
-public:
-  static InstX8632Mul *create(Cfg *Func, Variable *Dest, Variable *Source1,
-                              Operand *Source2) {
-    return new (Func->allocate<InstX8632Mul>())
-        InstX8632Mul(Func, Dest, Source1, Source2);
-  }
-  void emit(const Cfg *Func) const override;
-  void emitIAS(const Cfg *Func) const override;
-  void dump(const Cfg *Func) const override;
-  static bool classof(const Inst *Inst) { return isClassof(Inst, Mul); }
-
-private:
-  InstX8632Mul(Cfg *Func, Variable *Dest, Variable *Source1, Operand *Source2);
-};
-
-/// Shld instruction - shift across a pair of operands.
-class InstX8632Shld : public InstX8632 {
-  InstX8632Shld() = delete;
-  InstX8632Shld(const InstX8632Shld &) = delete;
-  InstX8632Shld &operator=(const InstX8632Shld &) = delete;
-
-public:
-  static InstX8632Shld *create(Cfg *Func, Variable *Dest, Variable *Source1,
-                               Variable *Source2) {
-    return new (Func->allocate<InstX8632Shld>())
-        InstX8632Shld(Func, Dest, Source1, Source2);
-  }
-  void emit(const Cfg *Func) const override;
-  void emitIAS(const Cfg *Func) const override;
-  void dump(const Cfg *Func) const override;
-  static bool classof(const Inst *Inst) { return isClassof(Inst, Shld); }
-
-private:
-  InstX8632Shld(Cfg *Func, Variable *Dest, Variable *Source1,
-                Variable *Source2);
-};
-
-/// Shrd instruction - shift across a pair of operands.
-class InstX8632Shrd : public InstX8632 {
-  InstX8632Shrd() = delete;
-  InstX8632Shrd(const InstX8632Shrd &) = delete;
-  InstX8632Shrd &operator=(const InstX8632Shrd &) = delete;
-
-public:
-  static InstX8632Shrd *create(Cfg *Func, Variable *Dest, Variable *Source1,
-                               Variable *Source2) {
-    return new (Func->allocate<InstX8632Shrd>())
-        InstX8632Shrd(Func, Dest, Source1, Source2);
-  }
-  void emit(const Cfg *Func) const override;
-  void emitIAS(const Cfg *Func) const override;
-  void dump(const Cfg *Func) const override;
-  static bool classof(const Inst *Inst) { return isClassof(Inst, Shrd); }
-
-private:
-  InstX8632Shrd(Cfg *Func, Variable *Dest, Variable *Source1,
-                Variable *Source2);
-};
-
-/// Conditional move instruction.
-class InstX8632Cmov : public InstX8632 {
-  InstX8632Cmov() = delete;
-  InstX8632Cmov(const InstX8632Cmov &) = delete;
-  InstX8632Cmov &operator=(const InstX8632Cmov &) = delete;
-
-public:
-  static InstX8632Cmov *create(Cfg *Func, Variable *Dest, Operand *Source,
-                               X8632::Traits::Cond::BrCond Cond) {
-    return new (Func->allocate<InstX8632Cmov>())
-        InstX8632Cmov(Func, Dest, Source, Cond);
-  }
-  void emit(const Cfg *Func) const override;
-  void emitIAS(const Cfg *Func) const override;
-  void dump(const Cfg *Func) const override;
-  static bool classof(const Inst *Inst) { return isClassof(Inst, Cmov); }
-
-private:
-  InstX8632Cmov(Cfg *Func, Variable *Dest, Operand *Source,
-                X8632::Traits::Cond::BrCond Cond);
-
-  X8632::Traits::Cond::BrCond Condition;
-};
-
-/// Cmpps instruction - compare packed singled-precision floating point
-/// values
-class InstX8632Cmpps : public InstX8632 {
-  InstX8632Cmpps() = delete;
-  InstX8632Cmpps(const InstX8632Cmpps &) = delete;
-  InstX8632Cmpps &operator=(const InstX8632Cmpps &) = delete;
-
-public:
-  static InstX8632Cmpps *create(Cfg *Func, Variable *Dest, Operand *Source,
-                                X8632::Traits::Cond::CmppsCond Condition) {
-    return new (Func->allocate<InstX8632Cmpps>())
-        InstX8632Cmpps(Func, Dest, Source, Condition);
-  }
-  void emit(const Cfg *Func) const override;
-  void emitIAS(const Cfg *Func) const override;
-  void dump(const Cfg *Func) const override;
-  static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpps); }
-
-private:
-  InstX8632Cmpps(Cfg *Func, Variable *Dest, Operand *Source,
-                 X8632::Traits::Cond::CmppsCond Cond);
-
-  X8632::Traits::Cond::CmppsCond Condition;
-};
-
-/// Cmpxchg instruction - cmpxchg <dest>, <desired> will compare if <dest>
-/// equals eax. If so, the ZF is set and <desired> is stored in <dest>.
-/// If not, ZF is cleared and <dest> is copied to eax (or subregister).
-/// <dest> can be a register or memory, while <desired> must be a register.
-/// It is the user's responsiblity to mark eax with a FakeDef.
-class InstX8632Cmpxchg : public InstX8632Lockable {
-  InstX8632Cmpxchg() = delete;
-  InstX8632Cmpxchg(const InstX8632Cmpxchg &) = delete;
-  InstX8632Cmpxchg &operator=(const InstX8632Cmpxchg &) = delete;
-
-public:
-  static InstX8632Cmpxchg *create(Cfg *Func, Operand *DestOrAddr, Variable *Eax,
-                                  Variable *Desired, bool Locked) {
-    return new (Func->allocate<InstX8632Cmpxchg>())
-        InstX8632Cmpxchg(Func, DestOrAddr, Eax, Desired, Locked);
-  }
-  void emit(const Cfg *Func) const override;
-  void emitIAS(const Cfg *Func) const override;
-  void dump(const Cfg *Func) const override;
-  static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpxchg); }
-
-private:
-  InstX8632Cmpxchg(Cfg *Func, Operand *DestOrAddr, Variable *Eax,
-                   Variable *Desired, bool Locked);
-};
-
-/// Cmpxchg8b instruction - cmpxchg8b <m64> will compare if <m64>
-/// equals edx:eax. If so, the ZF is set and ecx:ebx is stored in <m64>.
-/// If not, ZF is cleared and <m64> is copied to edx:eax.
-/// The caller is responsible for inserting FakeDefs to mark edx
-/// and eax as modified.
-/// <m64> must be a memory operand.
-class InstX8632Cmpxchg8b : public InstX8632Lockable {
-  InstX8632Cmpxchg8b() = delete;
-  InstX8632Cmpxchg8b(const InstX8632Cmpxchg8b &) = delete;
-  InstX8632Cmpxchg8b &operator=(const InstX8632Cmpxchg8b &) = delete;
-
-public:
-  static InstX8632Cmpxchg8b *create(Cfg *Func, OperandX8632Mem *Dest,
-                                    Variable *Edx, Variable *Eax, Variable *Ecx,
-                                    Variable *Ebx, bool Locked) {
-    return new (Func->allocate<InstX8632Cmpxchg8b>())
-        InstX8632Cmpxchg8b(Func, Dest, Edx, Eax, Ecx, Ebx, Locked);
-  }
-  void emit(const Cfg *Func) const override;
-  void emitIAS(const Cfg *Func) const override;
-  void dump(const Cfg *Func) const override;
-  static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpxchg8b); }
-
-private:
-  InstX8632Cmpxchg8b(Cfg *Func, OperandX8632Mem *Dest, Variable *Edx,
-                     Variable *Eax, Variable *Ecx, Variable *Ebx, bool Locked);
-};
-
-/// Cvt instruction - wrapper for cvtsX2sY where X and Y are in {s,d,i}
-/// as appropriate.  s=float, d=double, i=int.  X and Y are determined
-/// from dest/src types.  Sign and zero extension on the integer
-/// operand needs to be done separately.
-class InstX8632Cvt : public InstX8632 {
-  InstX8632Cvt() = delete;
-  InstX8632Cvt(const InstX8632Cvt &) = delete;
-  InstX8632Cvt &operator=(const InstX8632Cvt &) = delete;
-
-public:
-  enum CvtVariant { Si2ss, Tss2si, Float2float, Dq2ps, Tps2dq };
-  static InstX8632Cvt *create(Cfg *Func, Variable *Dest, Operand *Source,
-                              CvtVariant Variant) {
-    return new (Func->allocate<InstX8632Cvt>())
-        InstX8632Cvt(Func, Dest, Source, Variant);
-  }
-  void emit(const Cfg *Func) const override;
-  void emitIAS(const Cfg *Func) const override;
-  void dump(const Cfg *Func) const override;
-  static bool classof(const Inst *Inst) { return isClassof(Inst, Cvt); }
-  bool isTruncating() const { return Variant == Tss2si || Variant == Tps2dq; }
-
-private:
-  CvtVariant Variant;
-  InstX8632Cvt(Cfg *Func, Variable *Dest, Operand *Source, CvtVariant Variant);
-};
-
-/// cmp - Integer compare instruction.
-class InstX8632Icmp : public InstX8632 {
-  InstX8632Icmp() = delete;
-  InstX8632Icmp(const InstX8632Icmp &) = delete;
-  InstX8632Icmp &operator=(const InstX8632Icmp &) = delete;
-
-public:
-  static InstX8632Icmp *create(Cfg *Func, Operand *Src1, Operand *Src2) {
-    return new (Func->allocate<InstX8632Icmp>())
-        InstX8632Icmp(Func, Src1, Src2);
-  }
-  void emit(const Cfg *Func) const override;
-  void emitIAS(const Cfg *Func) const override;
-  void dump(const Cfg *Func) const override;
-  static bool classof(const Inst *Inst) { return isClassof(Inst, Icmp); }
-
-private:
-  InstX8632Icmp(Cfg *Func, Operand *Src1, Operand *Src2);
-};
-
-/// ucomiss/ucomisd - floating-point compare instruction.
-class InstX8632Ucomiss : public InstX8632 {
-  InstX8632Ucomiss() = delete;
-  InstX8632Ucomiss(const InstX8632Ucomiss &) = delete;
-  InstX8632Ucomiss &operator=(const InstX8632Ucomiss &) = delete;
-
-public:
-  static InstX8632Ucomiss *create(Cfg *Func, Operand *Src1, Operand *Src2) {
-    return new (Func->allocate<InstX8632Ucomiss>())
-        InstX8632Ucomiss(Func, Src1, Src2);
-  }
-  void emit(const Cfg *Func) const override;
-  void emitIAS(const Cfg *Func) const override;
-  void dump(const Cfg *Func) const override;
-  static bool classof(const Inst *Inst) { return isClassof(Inst, Ucomiss); }
-
-private:
-  InstX8632Ucomiss(Cfg *Func, Operand *Src1, Operand *Src2);
-};
-
-/// UD2 instruction.
-class InstX8632UD2 : public InstX8632 {
-  InstX8632UD2() = delete;
-  InstX8632UD2(const InstX8632UD2 &) = delete;
-  InstX8632UD2 &operator=(const InstX8632UD2 &) = delete;
-
-public:
-  static InstX8632UD2 *create(Cfg *Func) {
-    return new (Func->allocate<InstX8632UD2>()) InstX8632UD2(Func);
-  }
-  void emit(const Cfg *Func) const override;
-  void emitIAS(const Cfg *Func) const override;
-  void dump(const Cfg *Func) const override;
-  static bool classof(const Inst *Inst) { return isClassof(Inst, UD2); }
-
-private:
-  explicit InstX8632UD2(Cfg *Func);
-};
-
-/// Test instruction.
-class InstX8632Test : public InstX8632 {
-  InstX8632Test() = delete;
-  InstX8632Test(const InstX8632Test &) = delete;
-  InstX8632Test &operator=(const InstX8632Test &) = delete;
-
-public:
-  static InstX8632Test *create(Cfg *Func, Operand *Source1, Operand *Source2) {
-    return new (Func->allocate<InstX8632Test>())
-        InstX8632Test(Func, Source1, Source2);
-  }
-  void emit(const Cfg *Func) const override;
-  void emitIAS(const Cfg *Func) const override;
-  void dump(const Cfg *Func) const override;
-  static bool classof(const Inst *Inst) { return isClassof(Inst, Test); }
-
-private:
-  InstX8632Test(Cfg *Func, Operand *Source1, Operand *Source2);
-};
-
-/// Mfence instruction.
-class InstX8632Mfence : public InstX8632 {
-  InstX8632Mfence() = delete;
-  InstX8632Mfence(const InstX8632Mfence &) = delete;
-  InstX8632Mfence &operator=(const InstX8632Mfence &) = delete;
-
-public:
-  static InstX8632Mfence *create(Cfg *Func) {
-    return new (Func->allocate<InstX8632Mfence>()) InstX8632Mfence(Func);
-  }
-  void emit(const Cfg *Func) const override;
-  void emitIAS(const Cfg *Func) const override;
-  void dump(const Cfg *Func) const override;
-  static bool classof(const Inst *Inst) { return isClassof(Inst, Mfence); }
-
-private:
-  explicit InstX8632Mfence(Cfg *Func);
-};
-
-/// This is essentially a "mov" instruction with an OperandX8632Mem
-/// operand instead of Variable as the destination.  It's important
-/// for liveness that there is no Dest operand.
-class InstX8632Store : public InstX8632 {
-  InstX8632Store() = delete;
-  InstX8632Store(const InstX8632Store &) = delete;
-  InstX8632Store &operator=(const InstX8632Store &) = delete;
-
-public:
-  static InstX8632Store *create(Cfg *Func, Operand *Value, OperandX8632 *Mem) {
-    return new (Func->allocate<InstX8632Store>())
-        InstX8632Store(Func, Value, Mem);
-  }
-  void emit(const Cfg *Func) const override;
-  void emitIAS(const Cfg *Func) const override;
-  void dump(const Cfg *Func) const override;
-  static bool classof(const Inst *Inst) { return isClassof(Inst, Store); }
-
-private:
-  InstX8632Store(Cfg *Func, Operand *Value, OperandX8632 *Mem);
-};
-
-/// This is essentially a vector "mov" instruction with an OperandX8632Mem
-/// operand instead of Variable as the destination.  It's important
-/// for liveness that there is no Dest operand. The source must be an
-/// Xmm register, since Dest is mem.
-class InstX8632StoreP : public InstX8632 {
-  InstX8632StoreP() = delete;
-  InstX8632StoreP(const InstX8632StoreP &) = delete;
-  InstX8632StoreP &operator=(const InstX8632StoreP &) = delete;
-
-public:
-  static InstX8632StoreP *create(Cfg *Func, Variable *Value,
-                                 OperandX8632Mem *Mem) {
-    return new (Func->allocate<InstX8632StoreP>())
-        InstX8632StoreP(Func, Value, Mem);
-  }
-  void emit(const Cfg *Func) const override;
-  void emitIAS(const Cfg *Func) const override;
-  void dump(const Cfg *Func) const override;
-  static bool classof(const Inst *Inst) { return isClassof(Inst, StoreP); }
-
-private:
-  InstX8632StoreP(Cfg *Func, Variable *Value, OperandX8632Mem *Mem);
-};
-
-class InstX8632StoreQ : public InstX8632 {
-  InstX8632StoreQ() = delete;
-  InstX8632StoreQ(const InstX8632StoreQ &) = delete;
-  InstX8632StoreQ &operator=(const InstX8632StoreQ &) = delete;
-
-public:
-  static InstX8632StoreQ *create(Cfg *Func, Variable *Value,
-                                 OperandX8632Mem *Mem) {
-    return new (Func->allocate<InstX8632StoreQ>())
-        InstX8632StoreQ(Func, Value, Mem);
-  }
-  void emit(const Cfg *Func) const override;
-  void emitIAS(const Cfg *Func) const override;
-  void dump(const Cfg *Func) const override;
-  static bool classof(const Inst *Inst) { return isClassof(Inst, StoreQ); }
-
-private:
-  InstX8632StoreQ(Cfg *Func, Variable *Value, OperandX8632Mem *Mem);
-};
-
-/// Nop instructions of varying length
-class InstX8632Nop : public InstX8632 {
-  InstX8632Nop() = delete;
-  InstX8632Nop(const InstX8632Nop &) = delete;
-  InstX8632Nop &operator=(const InstX8632Nop &) = delete;
-
-public:
-  // TODO: Replace with enum.
-  typedef unsigned NopVariant;
-
-  static InstX8632Nop *create(Cfg *Func, NopVariant Variant) {
-    return new (Func->allocate<InstX8632Nop>()) InstX8632Nop(Func, Variant);
-  }
-  void emit(const Cfg *Func) const override;
-  void emitIAS(const Cfg *Func) const override;
-  void dump(const Cfg *Func) const override;
-  static bool classof(const Inst *Inst) { return isClassof(Inst, Nop); }
-
-private:
-  InstX8632Nop(Cfg *Func, SizeT Length);
-
-  NopVariant Variant;
-};
-
-/// Fld - load a value onto the x87 FP stack.
-class InstX8632Fld : public InstX8632 {
-  InstX8632Fld() = delete;
-  InstX8632Fld(const InstX8632Fld &) = delete;
-  InstX8632Fld &operator=(const InstX8632Fld &) = delete;
-
-public:
-  static InstX8632Fld *create(Cfg *Func, Operand *Src) {
-    return new (Func->allocate<InstX8632Fld>()) InstX8632Fld(Func, Src);
-  }
-  void emit(const Cfg *Func) const override;
-  void emitIAS(const Cfg *Func) const override;
-  void dump(const Cfg *Func) const override;
-  static bool classof(const Inst *Inst) { return isClassof(Inst, Fld); }
-
-private:
-  InstX8632Fld(Cfg *Func, Operand *Src);
-};
-
-/// Fstp - store x87 st(0) into memory and pop st(0).
-class InstX8632Fstp : public InstX8632 {
-  InstX8632Fstp() = delete;
-  InstX8632Fstp(const InstX8632Fstp &) = delete;
-  InstX8632Fstp &operator=(const InstX8632Fstp &) = delete;
-
-public:
-  static InstX8632Fstp *create(Cfg *Func, Variable *Dest) {
-    return new (Func->allocate<InstX8632Fstp>()) InstX8632Fstp(Func, Dest);
-  }
-  void emit(const Cfg *Func) const override;
-  void emitIAS(const Cfg *Func) const override;
-  void dump(const Cfg *Func) const override;
-  static bool classof(const Inst *Inst) { return isClassof(Inst, Fstp); }
-
-private:
-  InstX8632Fstp(Cfg *Func, Variable *Dest);
-};
-
-class InstX8632Pop : public InstX8632 {
-  InstX8632Pop() = delete;
-  InstX8632Pop(const InstX8632Pop &) = delete;
-  InstX8632Pop &operator=(const InstX8632Pop &) = delete;
-
-public:
-  static InstX8632Pop *create(Cfg *Func, Variable *Dest) {
-    return new (Func->allocate<InstX8632Pop>()) InstX8632Pop(Func, Dest);
-  }
-  void emit(const Cfg *Func) const override;
-  void emitIAS(const Cfg *Func) const override;
-  void dump(const Cfg *Func) const override;
-  static bool classof(const Inst *Inst) { return isClassof(Inst, Pop); }
-
-private:
-  InstX8632Pop(Cfg *Func, Variable *Dest);
-};
-
-class InstX8632Push : public InstX8632 {
-  InstX8632Push() = delete;
-  InstX8632Push(const InstX8632Push &) = delete;
-  InstX8632Push &operator=(const InstX8632Push &) = delete;
-
-public:
-  static InstX8632Push *create(Cfg *Func, Variable *Source) {
-    return new (Func->allocate<InstX8632Push>()) InstX8632Push(Func, Source);
-  }
-  void emit(const Cfg *Func) const override;
-  void emitIAS(const Cfg *Func) const override;
-  void dump(const Cfg *Func) const override;
-  static bool classof(const Inst *Inst) { return isClassof(Inst, Push); }
-
-private:
-  InstX8632Push(Cfg *Func, Variable *Source);
-};
-
-/// Ret instruction.  Currently only supports the "ret" version that
-/// does not pop arguments.  This instruction takes a Source operand
-/// (for non-void returning functions) for liveness analysis, though
-/// a FakeUse before the ret would do just as well.
-class InstX8632Ret : public InstX8632 {
-  InstX8632Ret() = delete;
-  InstX8632Ret(const InstX8632Ret &) = delete;
-  InstX8632Ret &operator=(const InstX8632Ret &) = delete;
-
-public:
-  static InstX8632Ret *create(Cfg *Func, Variable *Source = nullptr) {
-    return new (Func->allocate<InstX8632Ret>()) InstX8632Ret(Func, Source);
-  }
-  void emit(const Cfg *Func) const override;
-  void emitIAS(const Cfg *Func) const override;
-  void dump(const Cfg *Func) const override;
-  static bool classof(const Inst *Inst) { return isClassof(Inst, Ret); }
-
-private:
-  InstX8632Ret(Cfg *Func, Variable *Source);
-};
-
-/// Conditional set-byte instruction.
-class InstX8632Setcc : public InstX8632 {
-  InstX8632Setcc() = delete;
-  InstX8632Setcc(const InstX8632Cmov &) = delete;
-  InstX8632Setcc &operator=(const InstX8632Setcc &) = delete;
-
-public:
-  static InstX8632Setcc *create(Cfg *Func, Variable *Dest,
-                                X8632::Traits::Cond::BrCond Cond) {
-    return new (Func->allocate<InstX8632Setcc>())
-        InstX8632Setcc(Func, Dest, Cond);
-  }
-  void emit(const Cfg *Func) const override;
-  void emitIAS(const Cfg *Func) const override;
-  void dump(const Cfg *Func) const override;
-  static bool classof(const Inst *Inst) { return isClassof(Inst, Setcc); }
-
-private:
-  InstX8632Setcc(Cfg *Func, Variable *Dest, X8632::Traits::Cond::BrCond Cond);
-
-  const X8632::Traits::Cond::BrCond Condition;
-};
-
-/// Exchanging Add instruction.  Exchanges the first operand (destination
-/// operand) with the second operand (source operand), then loads the sum
-/// of the two values into the destination operand. The destination may be
-/// a register or memory, while the source must be a register.
-///
-/// Both the dest and source are updated. The caller should then insert a
-/// FakeDef to reflect the second udpate.
-class InstX8632Xadd : public InstX8632Lockable {
-  InstX8632Xadd() = delete;
-  InstX8632Xadd(const InstX8632Xadd &) = delete;
-  InstX8632Xadd &operator=(const InstX8632Xadd &) = delete;
-
-public:
-  static InstX8632Xadd *create(Cfg *Func, Operand *Dest, Variable *Source,
-                               bool Locked) {
-    return new (Func->allocate<InstX8632Xadd>())
-        InstX8632Xadd(Func, Dest, Source, Locked);
-  }
-  void emit(const Cfg *Func) const override;
-  void emitIAS(const Cfg *Func) const override;
-  void dump(const Cfg *Func) const override;
-  static bool classof(const Inst *Inst) { return isClassof(Inst, Xadd); }
-
-private:
-  InstX8632Xadd(Cfg *Func, Operand *Dest, Variable *Source, bool Locked);
-};
-
-/// Exchange instruction.  Exchanges the first operand (destination
-/// operand) with the second operand (source operand). At least one of
-/// the operands must be a register (and the other can be reg or mem).
-/// Both the Dest and Source are updated. If there is a memory operand,
-/// then the instruction is automatically "locked" without the need for
-/// a lock prefix.
-class InstX8632Xchg : public InstX8632 {
-  InstX8632Xchg() = delete;
-  InstX8632Xchg(const InstX8632Xchg &) = delete;
-  InstX8632Xchg &operator=(const InstX8632Xchg &) = delete;
-
-public:
-  static InstX8632Xchg *create(Cfg *Func, Operand *Dest, Variable *Source) {
-    return new (Func->allocate<InstX8632Xchg>())
-        InstX8632Xchg(Func, Dest, Source);
-  }
-  void emit(const Cfg *Func) const override;
-  void emitIAS(const Cfg *Func) const override;
-  void dump(const Cfg *Func) const override;
-  static bool classof(const Inst *Inst) { return isClassof(Inst, Xchg); }
-
-private:
-  InstX8632Xchg(Cfg *Func, Operand *Dest, Variable *Source);
-};
-
-/// Declare partial template specializations of emit() methods that
-/// already have default implementations.  Without this, there is the
-/// possibility of ODR violations and link errors.
-template <> void InstX8632Addss::emit(const Cfg *Func) const;
-template <> void InstX8632Blendvps::emit(const Cfg *Func) const;
-template <> void InstX8632Cbwdq::emit(const Cfg *Func) const;
-template <> void InstX8632Div::emit(const Cfg *Func) const;
-template <> void InstX8632Divss::emit(const Cfg *Func) const;
-template <> void InstX8632Idiv::emit(const Cfg *Func) const;
-template <> void InstX8632Imul::emit(const Cfg *Func) const;
-template <> void InstX8632Lea::emit(const Cfg *Func) const;
-template <> void InstX8632Mulss::emit(const Cfg *Func) const;
-template <> void InstX8632Padd::emit(const Cfg *Func) const;
-template <> void InstX8632Pblendvb::emit(const Cfg *Func) const;
-template <> void InstX8632Pcmpeq::emit(const Cfg *Func) const;
-template <> void InstX8632Pcmpgt::emit(const Cfg *Func) const;
-template <> void InstX8632Pextr::emit(const Cfg *Func) const;
-template <> void InstX8632Pinsr::emit(const Cfg *Func) const;
-template <> void InstX8632Pmull::emit(const Cfg *Func) const;
-template <> void InstX8632Pmuludq::emit(const Cfg *Func) const;
-template <> void InstX8632Psll::emit(const Cfg *Func) const;
-template <> void InstX8632Psra::emit(const Cfg *Func) const;
-template <> void InstX8632Psrl::emit(const Cfg *Func) const;
-template <> void InstX8632Psub::emit(const Cfg *Func) const;
-template <> void InstX8632Sqrtss::emit(const Cfg *Func) const;
-template <> void InstX8632Subss::emit(const Cfg *Func) const;
-
-template <> void InstX8632Blendvps::emitIAS(const Cfg *Func) const;
-template <> void InstX8632Cbwdq::emitIAS(const Cfg *Func) const;
-template <> void InstX8632Div::emitIAS(const Cfg *Func) const;
-template <> void InstX8632Idiv::emitIAS(const Cfg *Func) const;
-template <> void InstX8632Imul::emitIAS(const Cfg *Func) const;
-template <> void InstX8632Insertps::emitIAS(const Cfg *Func) const;
-template <> void InstX8632Movd::emitIAS(const Cfg *Func) const;
-template <> void InstX8632MovssRegs::emitIAS(const Cfg *Func) const;
-template <> void InstX8632Pblendvb::emitIAS(const Cfg *Func) const;
-template <> void InstX8632Pextr::emitIAS(const Cfg *Func) const;
-template <> void InstX8632Pinsr::emitIAS(const Cfg *Func) const;
-template <> void InstX8632Movsx::emitIAS(const Cfg *Func) const;
-template <> void InstX8632Movzx::emitIAS(const Cfg *Func) const;
-template <> void InstX8632Pmull::emitIAS(const Cfg *Func) const;
-template <> void InstX8632Pshufd::emitIAS(const Cfg *Func) const;
-template <> void InstX8632Shufps::emitIAS(const Cfg *Func) const;
-
-} // end of namespace Ice
-
 #endif // SUBZERO_SRC_ICEINSTX8632_H
diff --git a/src/IceInstX86Base.h b/src/IceInstX86Base.h
new file mode 100644
index 0000000..7275e44
--- /dev/null
+++ b/src/IceInstX86Base.h
@@ -0,0 +1,3148 @@
+//===- subzero/src/IceInstX86Base.h - Generic x86 instructions -*- C++ -*--===//
+//
+//                        The Subzero Code Generator
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file defines the InstX86Base template class, as well as the generic X86
+/// Instruction class hierarchy. Only X86 instructions common across all/most
+/// X86 targets should be defined here, with target-specific instructions
+/// declared in the target's traits.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef SUBZERO_SRC_ICEINSTX86BASE_H
+#define SUBZERO_SRC_ICEINSTX86BASE_H
+
+#include "IceDefs.h"
+#include "IceInst.h"
+#include "IceOperand.h"
+
+namespace Ice {
+
+namespace X86Internal {
+
+template <class Machine> struct MachineTraits;
+
+template <class Machine> class InstX86Base : public InstTarget {
+  InstX86Base<Machine>() = delete;
+  InstX86Base<Machine>(const InstX86Base &) = delete;
+  InstX86Base &operator=(const InstX86Base &) = delete;
+
+public:
+  using Traits = MachineTraits<Machine>;
+
+  enum InstKindX86 {
+    k__Start = Inst::Target,
+    Adc,
+    AdcRMW,
+    Add,
+    AddRMW,
+    Addps,
+    Addss,
+    Adjuststack,
+    And,
+    AndRMW,
+    Blendvps,
+    Br,
+    Bsf,
+    Bsr,
+    Bswap,
+    Call,
+    Cbwdq,
+    Cmov,
+    Cmpps,
+    Cmpxchg,
+    Cmpxchg8b,
+    Cvt,
+    Div,
+    Divps,
+    Divss,
+    FakeRMW,
+    Fld,
+    Fstp,
+    Icmp,
+    Idiv,
+    Imul,
+    Insertps,
+    Jmp,
+    Label,
+    Lea,
+    Load,
+    Mfence,
+    Mov,
+    Movd,
+    Movp,
+    Movq,
+    MovssRegs,
+    Movsx,
+    Movzx,
+    Mul,
+    Mulps,
+    Mulss,
+    Neg,
+    Nop,
+    Or,
+    OrRMW,
+    Padd,
+    Pand,
+    Pandn,
+    Pblendvb,
+    Pcmpeq,
+    Pcmpgt,
+    Pextr,
+    Pinsr,
+    Pmull,
+    Pmuludq,
+    Pop,
+    Por,
+    Pshufd,
+    Psll,
+    Psra,
+    Psrl,
+    Psub,
+    Push,
+    Pxor,
+    Ret,
+    Rol,
+    Sar,
+    Sbb,
+    SbbRMW,
+    Setcc,
+    Shl,
+    Shld,
+    Shr,
+    Shrd,
+    Shufps,
+    Sqrtss,
+    Store,
+    StoreP,
+    StoreQ,
+    Sub,
+    SubRMW,
+    Subps,
+    Subss,
+    Test,
+    Ucomiss,
+    UD2,
+    Xadd,
+    Xchg,
+    Xor,
+    XorRMW
+  };
+
+  static const char *getWidthString(Type Ty);
+  static const char *getFldString(Type Ty);
+  static typename Traits::Cond::BrCond
+  getOppositeCondition(typename Traits::Cond::BrCond Cond);
+  void dump(const Cfg *Func) const override;
+
+  // Shared emit routines for common forms of instructions.
+  // See the definition of emitTwoAddress() for a description of
+  // ShiftHack.
+  static void emitTwoAddress(const char *Opcode, const Inst *Inst,
+                             const Cfg *Func, bool ShiftHack = false);
+
+  static void
+  emitIASGPRShift(const Cfg *Func, Type Ty, const Variable *Var,
+                  const Operand *Src,
+                  const typename Traits::Assembler::GPREmitterShiftOp &Emitter);
+
+protected:
+  InstX86Base<Machine>(Cfg *Func, InstKindX86 Kind, SizeT Maxsrcs,
+                       Variable *Dest)
+      : InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {}
+
+  static bool isClassof(const Inst *Inst, InstKindX86 MyKind) {
+    return Inst->getKind() == static_cast<InstKind>(MyKind);
+  }
+  // Most instructions that operate on vector arguments require vector
+  // memory operands to be fully aligned (16-byte alignment for PNaCl
+  // vector types).  The stack frame layout and call ABI ensure proper
+  // alignment for stack operands, but memory operands (originating
+  // from load/store bitcode instructions) only have element-size
+  // alignment guarantees.  This function validates that none of the
+  // operands is a memory operand of vector type, calling
+  // report_fatal_error() if one is found.  This function should be
+  // called during emission, and maybe also in the ctor (as long as
+  // that fits the lowering style).
+  void validateVectorAddrMode() const {
+    if (this->getDest())
+      this->validateVectorAddrModeOpnd(this->getDest());
+    for (SizeT i = 0; i < this->getSrcSize(); ++i) {
+      this->validateVectorAddrModeOpnd(this->getSrc(i));
+    }
+  }
+
+private:
+  static void validateVectorAddrModeOpnd(const Operand *Opnd) {
+    if (llvm::isa<typename InstX86Base<Machine>::Traits::X86OperandMem>(Opnd) &&
+        isVectorType(Opnd->getType())) {
+      llvm::report_fatal_error("Possible misaligned vector memory operation");
+    }
+  }
+};
+
+/// InstX86FakeRMW represents a non-atomic read-modify-write operation on a
+/// memory location.  An InstX86FakeRMW is a "fake" instruction in that it
+/// still needs to be lowered to some actual RMW instruction.
+///
+/// If A is some memory address, D is some data value to apply, and OP is an
+/// arithmetic operator, the instruction operates as: (*A) = (*A) OP D
+template <class Machine>
+class InstX86FakeRMW final : public InstX86Base<Machine> {
+  InstX86FakeRMW() = delete;
+  InstX86FakeRMW(const InstX86FakeRMW &) = delete;
+  InstX86FakeRMW &operator=(const InstX86FakeRMW &) = delete;
+
+public:
+  static InstX86FakeRMW *create(Cfg *Func, Operand *Data, Operand *Addr,
+                                Variable *Beacon, InstArithmetic::OpKind Op,
+                                uint32_t Align = 1) {
+    // TODO(stichnot): Stop ignoring alignment specification.
+    (void)Align;
+    return new (Func->allocate<InstX86FakeRMW>())
+        InstX86FakeRMW(Func, Data, Addr, Op, Beacon);
+  }
+  Operand *getAddr() const { return this->getSrc(1); }
+  Operand *getData() const { return this->getSrc(0); }
+  InstArithmetic::OpKind getOp() const { return Op; }
+  Variable *getBeacon() const { return llvm::cast<Variable>(this->getSrc(2)); }
+  void dump(const Cfg *Func) const override;
+  static bool classof(const Inst *Inst) {
+    return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::FakeRMW);
+  }
+
+private:
+  InstArithmetic::OpKind Op;
+  InstX86FakeRMW(Cfg *Func, Operand *Data, Operand *Addr,
+                 InstArithmetic::OpKind Op, Variable *Beacon);
+};
+
+/// InstX86Label represents an intra-block label that is the target
+/// of an intra-block branch.  The offset between the label and the
+/// branch must be fit into one byte (considered "near").  These are
+/// used for lowering i1 calculations, Select instructions, and 64-bit
+/// compares on a 32-bit architecture, without basic block splitting.
+/// Basic block splitting is not so desirable for several reasons, one
+/// of which is the impact on decisions based on whether a variable's
+/// live range spans multiple basic blocks.
+///
+/// Intra-block control flow must be used with caution.  Consider the
+/// sequence for "c = (a >= b ? x : y)".
+///     cmp a, b
+///     br lt, L1
+///     mov c, x
+///     jmp L2
+///   L1:
+///     mov c, y
+///   L2:
+///
+/// Labels L1 and L2 are intra-block labels.  Without knowledge of the
+/// intra-block control flow, liveness analysis will determine the "mov
+/// c, x" instruction to be dead.  One way to prevent this is to insert
+/// a "FakeUse(c)" instruction anywhere between the two "mov c, ..."
+/// instructions, e.g.:
+///
+///     cmp a, b
+///     br lt, L1
+///     mov c, x
+///     jmp L2
+///     FakeUse(c)
+///   L1:
+///     mov c, y
+///   L2:
+///
+/// The down-side is that "mov c, x" can never be dead-code eliminated
+/// even if there are no uses of c.  As unlikely as this situation is,
+/// it may be prevented by running dead code elimination before
+/// lowering.
+template <class Machine>
+class InstX86Label final : public InstX86Base<Machine> {
+  InstX86Label() = delete;
+  InstX86Label(const InstX86Label &) = delete;
+  InstX86Label &operator=(const InstX86Label &) = delete;
+
+public:
+  static InstX86Label *
+  create(Cfg *Func,
+         typename InstX86Base<Machine>::Traits::TargetLowering *Target) {
+    return new (Func->allocate<InstX86Label>()) InstX86Label(Func, Target);
+  }
+  uint32_t getEmitInstCount() const override { return 0; }
+  IceString getName(const Cfg *Func) const;
+  SizeT getNumber() const { return Number; }
+  void emit(const Cfg *Func) const override;
+  void emitIAS(const Cfg *Func) const override;
+  void dump(const Cfg *Func) const override;
+
+private:
+  InstX86Label(Cfg *Func,
+               typename InstX86Base<Machine>::Traits::TargetLowering *Target);
+
+  SizeT Number; // used for unique label generation.
+};
+
+/// Conditional and unconditional branch instruction.
+template <class Machine> class InstX86Br final : public InstX86Base<Machine> {
+  InstX86Br() = delete;
+  InstX86Br(const InstX86Br &) = delete;
+  InstX86Br &operator=(const InstX86Br &) = delete;
+
+public:
+  /// Create a conditional branch to a node.
+  static InstX86Br *
+  create(Cfg *Func, CfgNode *TargetTrue, CfgNode *TargetFalse,
+         typename InstX86Base<Machine>::Traits::Cond::BrCond Condition) {
+    assert(Condition != InstX86Base<Machine>::Traits::Cond::Br_None);
+    const InstX86Label<Machine> *NoLabel = nullptr;
+    return new (Func->allocate<InstX86Br>())
+        InstX86Br(Func, TargetTrue, TargetFalse, NoLabel, Condition);
+  }
+  /// Create an unconditional branch to a node.
+  static InstX86Br *create(Cfg *Func, CfgNode *Target) {
+    const CfgNode *NoCondTarget = nullptr;
+    const InstX86Label<Machine> *NoLabel = nullptr;
+    return new (Func->allocate<InstX86Br>())
+        InstX86Br(Func, NoCondTarget, Target, NoLabel,
+                  InstX86Base<Machine>::Traits::Cond::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 InstX86Br *
+  create(Cfg *Func, CfgNode *Target,
+         typename InstX86Base<Machine>::Traits::Cond::BrCond Condition) {
+    assert(Condition != InstX86Base<Machine>::Traits::Cond::Br_None);
+    const CfgNode *NoUncondTarget = nullptr;
+    const InstX86Label<Machine> *NoLabel = nullptr;
+    return new (Func->allocate<InstX86Br>())
+        InstX86Br(Func, Target, NoUncondTarget, NoLabel, Condition);
+  }
+  /// Create a conditional intra-block branch (or unconditional, if
+  /// Condition==Br_None) to a label in the current block.
+  static InstX86Br *
+  create(Cfg *Func, InstX86Label<Machine> *Label,
+         typename InstX86Base<Machine>::Traits::Cond::BrCond Condition) {
+    const CfgNode *NoCondTarget = nullptr;
+    const CfgNode *NoUncondTarget = nullptr;
+    return new (Func->allocate<InstX86Br>())
+        InstX86Br(Func, NoCondTarget, NoUncondTarget, Label, Condition);
+  }
+  const CfgNode *getTargetTrue() const { return TargetTrue; }
+  const CfgNode *getTargetFalse() const { return TargetFalse; }
+  bool optimizeBranch(const CfgNode *NextNode);
+  uint32_t getEmitInstCount() const override {
+    uint32_t Sum = 0;
+    if (Label)
+      ++Sum;
+    if (getTargetTrue())
+      ++Sum;
+    if (getTargetFalse())
+      ++Sum;
+    return Sum;
+  }
+  bool isUnconditionalBranch() const override {
+    return !Label && Condition == InstX86Base<Machine>::Traits::Cond::Br_None;
+  }
+  bool repointEdge(CfgNode *OldNode, CfgNode *NewNode) override;
+  void emit(const Cfg *Func) const override;
+  void emitIAS(const Cfg *Func) const override;
+  void dump(const Cfg *Func) const override;
+  static bool classof(const Inst *Inst) {
+    return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Br);
+  }
+
+private:
+  InstX86Br(Cfg *Func, const CfgNode *TargetTrue, const CfgNode *TargetFalse,
+            const InstX86Label<Machine> *Label,
+            typename InstX86Base<Machine>::Traits::Cond::BrCond Condition);
+
+  typename InstX86Base<Machine>::Traits::Cond::BrCond Condition;
+  const CfgNode *TargetTrue;
+  const CfgNode *TargetFalse;
+  const InstX86Label<Machine> *Label; // Intra-block branch target
+};
+
+/// Jump to a target outside this function, such as tailcall, nacljump,
+/// naclret, unreachable.  This is different from a Branch instruction
+/// in that there is no intra-function control flow to represent.
+template <class Machine> class InstX86Jmp final : public InstX86Base<Machine> {
+  InstX86Jmp() = delete;
+  InstX86Jmp(const InstX86Jmp &) = delete;
+  InstX86Jmp &operator=(const InstX86Jmp &) = delete;
+
+public:
+  static InstX86Jmp *create(Cfg *Func, Operand *Target) {
+    return new (Func->allocate<InstX86Jmp>()) InstX86Jmp(Func, Target);
+  }
+  Operand *getJmpTarget() const { return this->getSrc(0); }
+  void emit(const Cfg *Func) const override;
+  void emitIAS(const Cfg *Func) const override;
+  void dump(const Cfg *Func) const override;
+  static bool classof(const Inst *Inst) {
+    return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Jmp);
+  }
+
+private:
+  InstX86Jmp(Cfg *Func, Operand *Target);
+};
+
+/// AdjustStack instruction - subtracts esp by the given amount and
+/// updates the stack offset during code emission.
+template <class Machine>
+class InstX86AdjustStack final : public InstX86Base<Machine> {
+  InstX86AdjustStack() = delete;
+  InstX86AdjustStack(const InstX86AdjustStack &) = delete;
+  InstX86AdjustStack &operator=(const InstX86AdjustStack &) = delete;
+
+public:
+  static InstX86AdjustStack *create(Cfg *Func, SizeT Amount, Variable *Esp) {
+    return new (Func->allocate<InstX86AdjustStack>())
+        InstX86AdjustStack(Func, Amount, Esp);
+  }
+  void emit(const Cfg *Func) const override;
+  void emitIAS(const Cfg *Func) const override;
+  void dump(const Cfg *Func) const override;
+  static bool classof(const Inst *Inst) {
+    return InstX86Base<Machine>::isClassof(Inst,
+                                           InstX86Base<Machine>::Adjuststack);
+  }
+
+private:
+  InstX86AdjustStack(Cfg *Func, SizeT Amount, Variable *Esp);
+  SizeT Amount;
+};
+
+/// Call instruction.  Arguments should have already been pushed.
+template <class Machine> class InstX86Call final : public InstX86Base<Machine> {
+  InstX86Call() = delete;
+  InstX86Call(const InstX86Call &) = delete;
+  InstX86Call &operator=(const InstX86Call &) = delete;
+
+public:
+  static InstX86Call *create(Cfg *Func, Variable *Dest, Operand *CallTarget) {
+    return new (Func->allocate<InstX86Call>())
+        InstX86Call(Func, Dest, CallTarget);
+  }
+  Operand *getCallTarget() const { return this->getSrc(0); }
+  void emit(const Cfg *Func) const override;
+  void emitIAS(const Cfg *Func) const override;
+  void dump(const Cfg *Func) const override;
+  static bool classof(const Inst *Inst) {
+    return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Call);
+  }
+
+private:
+  InstX86Call(Cfg *Func, Variable *Dest, Operand *CallTarget);
+};
+
+/// Emit a one-operand (GPR) instruction.
+template <class Machine>
+void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Var,
+                    const typename InstX86Base<
+                        Machine>::Traits::Assembler::GPREmitterOneOp &Emitter);
+
+template <class Machine>
+void emitIASAsAddrOpTyGPR(
+    const Cfg *Func, Type Ty, const Operand *Op0, const Operand *Op1,
+    const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterAddrOp
+        &Emitter);
+
+/// Instructions of the form x := op(x).
+template <class Machine, typename InstX86Base<Machine>::InstKindX86 K>
+class InstX86BaseInplaceopGPR : public InstX86Base<Machine> {
+  InstX86BaseInplaceopGPR() = delete;
+  InstX86BaseInplaceopGPR(const InstX86BaseInplaceopGPR &) = delete;
+  InstX86BaseInplaceopGPR &operator=(const InstX86BaseInplaceopGPR &) = delete;
+
+public:
+  using Base = InstX86BaseInplaceopGPR<Machine, K>;
+
+  void emit(const Cfg *Func) const override {
+    if (!BuildDefs::dump())
+      return;
+    Ostream &Str = Func->getContext()->getStrEmit();
+    assert(this->getSrcSize() == 1);
+    Str << "\t" << Opcode << "\t";
+    this->getSrc(0)->emit(Func);
+  }
+  void emitIAS(const Cfg *Func) const override {
+    assert(this->getSrcSize() == 1);
+    const Variable *Var = this->getDest();
+    Type Ty = Var->getType();
+    emitIASOpTyGPR<Machine>(Func, Ty, Var, Emitter);
+  }
+  void dump(const Cfg *Func) const override {
+    if (!BuildDefs::dump())
+      return;
+    Ostream &Str = Func->getContext()->getStrDump();
+    this->dumpDest(Func);
+    Str << " = " << Opcode << "." << this->getDest()->getType() << " ";
+    this->dumpSources(Func);
+  }
+  static bool classof(const Inst *Inst) {
+    return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::K);
+  }
+
+protected:
+  InstX86BaseInplaceopGPR(Cfg *Func, Operand *SrcDest)
+      : InstX86Base<Machine>(Func, K, 1, llvm::dyn_cast<Variable>(SrcDest)) {
+    this->addSource(SrcDest);
+  }
+
+private:
+  static const char *Opcode;
+  static const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterOneOp
+      Emitter;
+};
+
+/// Emit a two-operand (GPR) instruction, where the dest operand is a
+/// Variable that's guaranteed to be a register.
+template <class Machine, bool VarCanBeByte = true, bool SrcCanBeByte = true>
+void emitIASRegOpTyGPR(
+    const Cfg *Func, Type Ty, const Variable *Dst, const Operand *Src,
+    const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterRegOp
+        &Emitter);
+
+/// Instructions of the form x := op(y).
+template <class Machine, typename InstX86Base<Machine>::InstKindX86 K>
+class InstX86BaseUnaryopGPR : public InstX86Base<Machine> {
+  InstX86BaseUnaryopGPR() = delete;
+  InstX86BaseUnaryopGPR(const InstX86BaseUnaryopGPR &) = delete;
+  InstX86BaseUnaryopGPR &operator=(const InstX86BaseUnaryopGPR &) = delete;
+
+public:
+  using Base = InstX86BaseUnaryopGPR<Machine, K>;
+
+  void emit(const Cfg *Func) const override {
+    if (!BuildDefs::dump())
+      return;
+    Ostream &Str = Func->getContext()->getStrEmit();
+    assert(this->getSrcSize() == 1);
+    Type SrcTy = this->getSrc(0)->getType();
+    Type DestTy = this->getDest()->getType();
+    Str << "\t" << Opcode << this->getWidthString(SrcTy);
+    // Movsx and movzx need both the source and dest type width letter
+    // to define the operation.  The other unary operations have the
+    // same source and dest type and as a result need only one letter.
+    if (SrcTy != DestTy)
+      Str << this->getWidthString(DestTy);
+    Str << "\t";
+    this->getSrc(0)->emit(Func);
+    Str << ", ";
+    this->getDest()->emit(Func);
+  }
+  void emitIAS(const Cfg *Func) const override {
+    assert(this->getSrcSize() == 1);
+    const Variable *Var = this->getDest();
+    Type Ty = Var->getType();
+    const Operand *Src = this->getSrc(0);
+    emitIASRegOpTyGPR<Machine>(Func, Ty, Var, Src, Emitter);
+  }
+  void dump(const Cfg *Func) const override {
+    if (!BuildDefs::dump())
+      return;
+    Ostream &Str = Func->getContext()->getStrDump();
+    this->dumpDest(Func);
+    Str << " = " << Opcode << "." << this->getSrc(0)->getType() << " ";
+    this->dumpSources(Func);
+  }
+  static bool classof(const Inst *Inst) {
+    return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::K);
+  }
+
+protected:
+  InstX86BaseUnaryopGPR(Cfg *Func, Variable *Dest, Operand *Src)
+      : InstX86Base<Machine>(Func, K, 1, Dest) {
+    this->addSource(Src);
+  }
+
+  static const char *Opcode;
+  static const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterRegOp
+      Emitter;
+};
+
+template <class Machine>
+void emitIASRegOpTyXMM(
+    const Cfg *Func, Type Ty, const Variable *Var, const Operand *Src,
+    const typename InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp
+        &Emitter);
+
+template <class Machine, typename InstX86Base<Machine>::InstKindX86 K>
+class InstX86BaseUnaryopXmm : public InstX86Base<Machine> {
+  InstX86BaseUnaryopXmm() = delete;
+  InstX86BaseUnaryopXmm(const InstX86BaseUnaryopXmm &) = delete;
+  InstX86BaseUnaryopXmm &operator=(const InstX86BaseUnaryopXmm &) = delete;
+
+public:
+  using Base = InstX86BaseUnaryopXmm<Machine, K>;
+
+  void emit(const Cfg *Func) const override {
+    if (!BuildDefs::dump())
+      return;
+    Ostream &Str = Func->getContext()->getStrEmit();
+    assert(this->getSrcSize() == 1);
+    Str << "\t" << Opcode << "\t";
+    this->getSrc(0)->emit(Func);
+    Str << ", ";
+    this->getDest()->emit(Func);
+  }
+  void emitIAS(const Cfg *Func) const override {
+    Type Ty = this->getDest()->getType();
+    assert(this->getSrcSize() == 1);
+    emitIASRegOpTyXMM<Machine>(Func, Ty, this->getDest(), this->getSrc(0),
+                               Emitter);
+  }
+  void dump(const Cfg *Func) const override {
+    if (!BuildDefs::dump())
+      return;
+    Ostream &Str = Func->getContext()->getStrDump();
+    this->dumpDest(Func);
+    Str << " = " << Opcode << "." << this->getDest()->getType() << " ";
+    this->dumpSources(Func);
+  }
+  static bool classof(const Inst *Inst) {
+    return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::K);
+  }
+
+protected:
+  InstX86BaseUnaryopXmm(Cfg *Func, Variable *Dest, Operand *Src)
+      : InstX86Base<Machine>(Func, K, 1, Dest) {
+    this->addSource(Src);
+  }
+
+  static const char *Opcode;
+  static const typename InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp
+      Emitter;
+};
+
+template <class Machine, typename InstX86Base<Machine>::InstKindX86 K>
+class InstX86BaseBinopGPRShift : public InstX86Base<Machine> {
+  InstX86BaseBinopGPRShift() = delete;
+  InstX86BaseBinopGPRShift(const InstX86BaseBinopGPRShift &) = delete;
+  InstX86BaseBinopGPRShift &
+  operator=(const InstX86BaseBinopGPRShift &) = delete;
+
+public:
+  using Base = InstX86BaseBinopGPRShift<Machine, K>;
+
+  void emit(const Cfg *Func) const override {
+    if (!BuildDefs::dump())
+      return;
+    const bool ShiftHack = true;
+    this->emitTwoAddress(Opcode, this, Func, ShiftHack);
+  }
+  void emitIAS(const Cfg *Func) const override {
+    Type Ty = this->getDest()->getType();
+    assert(this->getSrcSize() == 2);
+    this->emitIASGPRShift(Func, Ty, this->getDest(), this->getSrc(1), Emitter);
+  }
+  void dump(const Cfg *Func) const override {
+    if (!BuildDefs::dump())
+      return;
+    Ostream &Str = Func->getContext()->getStrDump();
+    this->dumpDest(Func);
+    Str << " = " << Opcode << "." << this->getDest()->getType() << " ";
+    this->dumpSources(Func);
+  }
+  static bool classof(const Inst *Inst) {
+    return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::K);
+  }
+
+protected:
+  InstX86BaseBinopGPRShift(Cfg *Func, Variable *Dest, Operand *Source)
+      : InstX86Base<Machine>(Func, K, 2, Dest) {
+    this->addSource(Dest);
+    this->addSource(Source);
+  }
+
+  static const char *Opcode;
+  static const typename InstX86Base<
+      Machine>::Traits::Assembler::GPREmitterShiftOp Emitter;
+};
+
+template <class Machine, typename InstX86Base<Machine>::InstKindX86 K>
+class InstX86BaseBinopGPR : public InstX86Base<Machine> {
+  InstX86BaseBinopGPR() = delete;
+  InstX86BaseBinopGPR(const InstX86BaseBinopGPR &) = delete;
+  InstX86BaseBinopGPR &operator=(const InstX86BaseBinopGPR &) = delete;
+
+public:
+  using Base = InstX86BaseBinopGPR<Machine, K>;
+
+  void emit(const Cfg *Func) const override {
+    if (!BuildDefs::dump())
+      return;
+    const bool ShiftHack = false;
+    this->emitTwoAddress(Opcode, this, Func, ShiftHack);
+  }
+  void emitIAS(const Cfg *Func) const override {
+    Type Ty = this->getDest()->getType();
+    assert(this->getSrcSize() == 2);
+    emitIASRegOpTyGPR<Machine>(Func, Ty, this->getDest(), this->getSrc(1),
+                               Emitter);
+  }
+  void dump(const Cfg *Func) const override {
+    if (!BuildDefs::dump())
+      return;
+    Ostream &Str = Func->getContext()->getStrDump();
+    this->dumpDest(Func);
+    Str << " = " << Opcode << "." << this->getDest()->getType() << " ";
+    this->dumpSources(Func);
+  }
+  static bool classof(const Inst *Inst) {
+    return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::K);
+  }
+
+protected:
+  InstX86BaseBinopGPR(Cfg *Func, Variable *Dest, Operand *Source)
+      : InstX86Base<Machine>(Func, K, 2, Dest) {
+    this->addSource(Dest);
+    this->addSource(Source);
+  }
+
+  static const char *Opcode;
+  static const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterRegOp
+      Emitter;
+};
+
+template <class Machine, typename InstX86Base<Machine>::InstKindX86 K>
+class InstX86BaseBinopRMW : public InstX86Base<Machine> {
+  InstX86BaseBinopRMW() = delete;
+  InstX86BaseBinopRMW(const InstX86BaseBinopRMW &) = delete;
+  InstX86BaseBinopRMW &operator=(const InstX86BaseBinopRMW &) = delete;
+
+public:
+  using Base = InstX86BaseBinopRMW<Machine, K>;
+
+  void emit(const Cfg *Func) const override {
+    if (!BuildDefs::dump())
+      return;
+    const bool ShiftHack = false;
+    this->emitTwoAddress(Opcode, this, Func, ShiftHack);
+  }
+  void emitIAS(const Cfg *Func) const override {
+    Type Ty = this->getSrc(0)->getType();
+    assert(this->getSrcSize() == 2);
+    emitIASAsAddrOpTyGPR<Machine>(Func, Ty, this->getSrc(0), this->getSrc(1),
+                                  Emitter);
+  }
+  void dump(const Cfg *Func) const override {
+    if (!BuildDefs::dump())
+      return;
+    Ostream &Str = Func->getContext()->getStrDump();
+    Str << Opcode << "." << this->getSrc(0)->getType() << " ";
+    this->dumpSources(Func);
+  }
+  static bool classof(const Inst *Inst) {
+    return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::K);
+  }
+
+protected:
+  InstX86BaseBinopRMW(
+      Cfg *Func, typename InstX86Base<Machine>::Traits::X86OperandMem *DestSrc0,
+      Operand *Src1)
+      : InstX86Base<Machine>(Func, K, 2, nullptr) {
+    this->addSource(DestSrc0);
+    this->addSource(Src1);
+  }
+
+  static const char *Opcode;
+  static const typename InstX86Base<
+      Machine>::Traits::Assembler::GPREmitterAddrOp Emitter;
+};
+
+template <class Machine, typename InstX86Base<Machine>::InstKindX86 K,
+          bool NeedsElementType>
+class InstX86BaseBinopXmm : public InstX86Base<Machine> {
+  InstX86BaseBinopXmm() = delete;
+  InstX86BaseBinopXmm(const InstX86BaseBinopXmm &) = delete;
+  InstX86BaseBinopXmm &operator=(const InstX86BaseBinopXmm &) = delete;
+
+public:
+  using Base = InstX86BaseBinopXmm<Machine, K, NeedsElementType>;
+
+  void emit(const Cfg *Func) const override {
+    if (!BuildDefs::dump())
+      return;
+    this->validateVectorAddrMode();
+    const bool ShiftHack = false;
+    this->emitTwoAddress(Opcode, this, Func, ShiftHack);
+  }
+  void emitIAS(const Cfg *Func) const override {
+    this->validateVectorAddrMode();
+    Type Ty = this->getDest()->getType();
+    if (NeedsElementType)
+      Ty = typeElementType(Ty);
+    assert(this->getSrcSize() == 2);
+    emitIASRegOpTyXMM<Machine>(Func, Ty, this->getDest(), this->getSrc(1),
+                               Emitter);
+  }
+  void dump(const Cfg *Func) const override {
+    if (!BuildDefs::dump())
+      return;
+    Ostream &Str = Func->getContext()->getStrDump();
+    this->dumpDest(Func);
+    Str << " = " << Opcode << "." << this->getDest()->getType() << " ";
+    this->dumpSources(Func);
+  }
+  static bool classof(const Inst *Inst) {
+    return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::K);
+  }
+
+protected:
+  InstX86BaseBinopXmm(Cfg *Func, Variable *Dest, Operand *Source)
+      : InstX86Base<Machine>(Func, K, 2, Dest) {
+    this->addSource(Dest);
+    this->addSource(Source);
+  }
+
+  static const char *Opcode;
+  static const typename InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp
+      Emitter;
+};
+
+template <class Machine>
+void emitIASXmmShift(
+    const Cfg *Func, Type Ty, const Variable *Var, const Operand *Src,
+    const typename InstX86Base<Machine>::Traits::Assembler::XmmEmitterShiftOp
+        &Emitter);
+
+template <class Machine, typename InstX86Base<Machine>::InstKindX86 K,
+          bool AllowAllTypes = false>
+class InstX86BaseBinopXmmShift : public InstX86Base<Machine> {
+  InstX86BaseBinopXmmShift() = delete;
+  InstX86BaseBinopXmmShift(const InstX86BaseBinopXmmShift &) = delete;
+  InstX86BaseBinopXmmShift &
+  operator=(const InstX86BaseBinopXmmShift &) = delete;
+
+public:
+  using Base = InstX86BaseBinopXmmShift<Machine, K, AllowAllTypes>;
+
+  void emit(const Cfg *Func) const override {
+    if (!BuildDefs::dump())
+      return;
+    this->validateVectorAddrMode();
+    const bool ShiftHack = false;
+    this->emitTwoAddress(Opcode, this, Func, ShiftHack);
+  }
+  void emitIAS(const Cfg *Func) const override {
+    this->validateVectorAddrMode();
+    Type Ty = this->getDest()->getType();
+    assert(AllowAllTypes || isVectorType(Ty));
+    Type ElementTy = typeElementType(Ty);
+    assert(this->getSrcSize() == 2);
+    emitIASXmmShift<Machine>(Func, ElementTy, this->getDest(), this->getSrc(1),
+                             Emitter);
+  }
+  void dump(const Cfg *Func) const override {
+    if (!BuildDefs::dump())
+      return;
+    Ostream &Str = Func->getContext()->getStrDump();
+    this->dumpDest(Func);
+    Str << " = " << Opcode << "." << this->getDest()->getType() << " ";
+    this->dumpSources(Func);
+  }
+  static bool classof(const Inst *Inst) {
+    return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::K);
+  }
+
+protected:
+  InstX86BaseBinopXmmShift(Cfg *Func, Variable *Dest, Operand *Source)
+      : InstX86Base<Machine>(Func, K, 2, Dest) {
+    this->addSource(Dest);
+    this->addSource(Source);
+  }
+
+  static const char *Opcode;
+  static const typename InstX86Base<
+      Machine>::Traits::Assembler::XmmEmitterShiftOp Emitter;
+};
+
+template <class Machine, typename InstX86Base<Machine>::InstKindX86 K>
+class InstX86BaseTernop : public InstX86Base<Machine> {
+  InstX86BaseTernop() = delete;
+  InstX86BaseTernop(const InstX86BaseTernop &) = delete;
+  InstX86BaseTernop &operator=(const InstX86BaseTernop &) = delete;
+
+public:
+  using Base = InstX86BaseTernop<Machine, K>;
+
+  void emit(const Cfg *Func) const override {
+    if (!BuildDefs::dump())
+      return;
+    Ostream &Str = Func->getContext()->getStrEmit();
+    assert(this->getSrcSize() == 3);
+    Str << "\t" << Opcode << "\t";
+    this->getSrc(2)->emit(Func);
+    Str << ", ";
+    this->getSrc(1)->emit(Func);
+    Str << ", ";
+    this->getDest()->emit(Func);
+  }
+  void dump(const Cfg *Func) const override {
+    if (!BuildDefs::dump())
+      return;
+    Ostream &Str = Func->getContext()->getStrDump();
+    this->dumpDest(Func);
+    Str << " = " << Opcode << "." << this->getDest()->getType() << " ";
+    this->dumpSources(Func);
+  }
+  static bool classof(const Inst *Inst) {
+    return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::K);
+  }
+
+protected:
+  InstX86BaseTernop(Cfg *Func, Variable *Dest, Operand *Source1,
+                    Operand *Source2)
+      : InstX86Base<Machine>(Func, K, 3, Dest) {
+    this->addSource(Dest);
+    this->addSource(Source1);
+    this->addSource(Source2);
+  }
+
+  static const char *Opcode;
+};
+
+// Instructions of the form x := y op z
+template <class Machine, typename InstX86Base<Machine>::InstKindX86 K>
+class InstX86BaseThreeAddressop : public InstX86Base<Machine> {
+  InstX86BaseThreeAddressop() = delete;
+  InstX86BaseThreeAddressop(const InstX86BaseThreeAddressop &) = delete;
+  InstX86BaseThreeAddressop &
+  operator=(const InstX86BaseThreeAddressop &) = delete;
+
+public:
+  using Base = InstX86BaseThreeAddressop<Machine, K>;
+
+  void emit(const Cfg *Func) const override {
+    if (!BuildDefs::dump())
+      return;
+    Ostream &Str = Func->getContext()->getStrEmit();
+    assert(this->getSrcSize() == 2);
+    Str << "\t" << Opcode << "\t";
+    this->getSrc(1)->emit(Func);
+    Str << ", ";
+    this->getSrc(0)->emit(Func);
+    Str << ", ";
+    this->getDest()->emit(Func);
+  }
+  void dump(const Cfg *Func) const override {
+    if (!BuildDefs::dump())
+      return;
+    Ostream &Str = Func->getContext()->getStrDump();
+    this->dumpDest(Func);
+    Str << " = " << Opcode << "." << this->getDest()->getType() << " ";
+    this->dumpSources(Func);
+  }
+  static bool classof(const Inst *Inst) {
+    return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::K);
+  }
+
+protected:
+  InstX86BaseThreeAddressop(Cfg *Func, Variable *Dest, Operand *Source0,
+                            Operand *Source1)
+      : InstX86Base<Machine>(Func, K, 2, Dest) {
+    this->addSource(Source0);
+    this->addSource(Source1);
+  }
+
+  static const char *Opcode;
+};
+
+/// Base class for assignment instructions
+template <class Machine, typename InstX86Base<Machine>::InstKindX86 K>
+class InstX86BaseMovlike : public InstX86Base<Machine> {
+  InstX86BaseMovlike() = delete;
+  InstX86BaseMovlike(const InstX86BaseMovlike &) = delete;
+  InstX86BaseMovlike &operator=(const InstX86BaseMovlike &) = delete;
+
+public:
+  using Base = InstX86BaseMovlike<Machine, K>;
+
+  bool isRedundantAssign() const override {
+    return checkForRedundantAssign(this->getDest(), this->getSrc(0));
+  }
+  bool isSimpleAssign() const override { return true; }
+  void dump(const Cfg *Func) const override {
+    if (!BuildDefs::dump())
+      return;
+    Ostream &Str = Func->getContext()->getStrDump();
+    Str << Opcode << "." << this->getDest()->getType() << " ";
+    this->dumpDest(Func);
+    Str << ", ";
+    this->dumpSources(Func);
+  }
+  static bool classof(const Inst *Inst) {
+    return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::K);
+  }
+
+protected:
+  InstX86BaseMovlike(Cfg *Func, Variable *Dest, Operand *Source)
+      : InstX86Base<Machine>(Func, K, 1, Dest) {
+    this->addSource(Source);
+  }
+
+  static const char *Opcode;
+};
+
+template <class Machine>
+class InstX86Bswap
+    : public InstX86BaseInplaceopGPR<Machine, InstX86Base<Machine>::Bswap> {
+public:
+  static InstX86Bswap *create(Cfg *Func, Operand *SrcDest) {
+    return new (Func->allocate<InstX86Bswap>()) InstX86Bswap(Func, SrcDest);
+  }
+
+private:
+  InstX86Bswap(Cfg *Func, Operand *SrcDest)
+      : InstX86BaseInplaceopGPR<Machine, InstX86Base<Machine>::Bswap>(Func,
+                                                                      SrcDest) {
+  }
+};
+
+template <class Machine>
+class InstX86Neg
+    : public InstX86BaseInplaceopGPR<Machine, InstX86Base<Machine>::Neg> {
+public:
+  static InstX86Neg *create(Cfg *Func, Operand *SrcDest) {
+    return new (Func->allocate<InstX86Neg>()) InstX86Neg(Func, SrcDest);
+  }
+
+private:
+  InstX86Neg(Cfg *Func, Operand *SrcDest)
+      : InstX86BaseInplaceopGPR<Machine, InstX86Base<Machine>::Neg>(Func,
+                                                                    SrcDest) {}
+};
+
+template <class Machine>
+class InstX86Bsf
+    : public InstX86BaseUnaryopGPR<Machine, InstX86Base<Machine>::Bsf> {
+public:
+  static InstX86Bsf *create(Cfg *Func, Variable *Dest, Operand *Src) {
+    return new (Func->allocate<InstX86Bsf>()) InstX86Bsf(Func, Dest, Src);
+  }
+
+private:
+  InstX86Bsf(Cfg *Func, Variable *Dest, Operand *Src)
+      : InstX86BaseUnaryopGPR<Machine, InstX86Base<Machine>::Bsf>(Func, Dest,
+                                                                  Src) {}
+};
+
+template <class Machine>
+class InstX86Bsr
+    : public InstX86BaseUnaryopGPR<Machine, InstX86Base<Machine>::Bsr> {
+public:
+  static InstX86Bsr *create(Cfg *Func, Variable *Dest, Operand *Src) {
+    return new (Func->allocate<InstX86Bsr>()) InstX86Bsr(Func, Dest, Src);
+  }
+
+private:
+  InstX86Bsr(Cfg *Func, Variable *Dest, Operand *Src)
+      : InstX86BaseUnaryopGPR<Machine, InstX86Base<Machine>::Bsr>(Func, Dest,
+                                                                  Src) {}
+};
+
+template <class Machine>
+class InstX86Lea
+    : public InstX86BaseUnaryopGPR<Machine, InstX86Base<Machine>::Lea> {
+public:
+  static InstX86Lea *create(Cfg *Func, Variable *Dest, Operand *Src) {
+    return new (Func->allocate<InstX86Lea>()) InstX86Lea(Func, Dest, Src);
+  }
+
+  void emit(const Cfg *Func) const override;
+
+private:
+  InstX86Lea(Cfg *Func, Variable *Dest, Operand *Src)
+      : InstX86BaseUnaryopGPR<Machine, InstX86Base<Machine>::Lea>(Func, Dest,
+                                                                  Src) {}
+};
+
+// Cbwdq instruction - wrapper for cbw, cwd, and cdq
+template <class Machine>
+class InstX86Cbwdq
+    : public InstX86BaseUnaryopGPR<Machine, InstX86Base<Machine>::Cbwdq> {
+public:
+  static InstX86Cbwdq *create(Cfg *Func, Variable *Dest, Operand *Src) {
+    return new (Func->allocate<InstX86Cbwdq>()) InstX86Cbwdq(Func, Dest, Src);
+  }
+
+  void emit(const Cfg *Func) const override;
+  void emitIAS(const Cfg *Func) const override;
+
+private:
+  InstX86Cbwdq(Cfg *Func, Variable *Dest, Operand *Src)
+      : InstX86BaseUnaryopGPR<Machine, InstX86Base<Machine>::Cbwdq>(Func, Dest,
+                                                                    Src) {}
+};
+
+template <class Machine>
+class InstX86Movsx
+    : public InstX86BaseUnaryopGPR<Machine, InstX86Base<Machine>::Movsx> {
+public:
+  static InstX86Movsx *create(Cfg *Func, Variable *Dest, Operand *Src) {
+    return new (Func->allocate<InstX86Movsx>()) InstX86Movsx(Func, Dest, Src);
+  }
+
+  void emitIAS(const Cfg *Func) const override;
+
+private:
+  InstX86Movsx(Cfg *Func, Variable *Dest, Operand *Src)
+      : InstX86BaseUnaryopGPR<Machine, InstX86Base<Machine>::Movsx>(Func, Dest,
+                                                                    Src) {}
+};
+
+template <class Machine>
+class InstX86Movzx
+    : public InstX86BaseUnaryopGPR<Machine, InstX86Base<Machine>::Movzx> {
+public:
+  static InstX86Movzx *create(Cfg *Func, Variable *Dest, Operand *Src) {
+    return new (Func->allocate<InstX86Movzx>()) InstX86Movzx(Func, Dest, Src);
+  }
+
+  void emitIAS(const Cfg *Func) const override;
+
+private:
+  InstX86Movzx(Cfg *Func, Variable *Dest, Operand *Src)
+      : InstX86BaseUnaryopGPR<Machine, InstX86Base<Machine>::Movzx>(Func, Dest,
+                                                                    Src) {}
+};
+
+template <class Machine>
+class InstX86Movd
+    : public InstX86BaseUnaryopXmm<Machine, InstX86Base<Machine>::Movd> {
+public:
+  static InstX86Movd *create(Cfg *Func, Variable *Dest, Operand *Src) {
+    return new (Func->allocate<InstX86Movd>()) InstX86Movd(Func, Dest, Src);
+  }
+
+  void emitIAS(const Cfg *Func) const override;
+
+private:
+  InstX86Movd(Cfg *Func, Variable *Dest, Operand *Src)
+      : InstX86BaseUnaryopXmm<Machine, InstX86Base<Machine>::Movd>(Func, Dest,
+                                                                   Src) {}
+};
+
+template <class Machine>
+class InstX86Sqrtss
+    : public InstX86BaseUnaryopXmm<Machine, InstX86Base<Machine>::Sqrtss> {
+public:
+  static InstX86Sqrtss *create(Cfg *Func, Variable *Dest, Operand *Src) {
+    return new (Func->allocate<InstX86Sqrtss>()) InstX86Sqrtss(Func, Dest, Src);
+  }
+
+  virtual void emit(const Cfg *Func) const override;
+
+private:
+  InstX86Sqrtss(Cfg *Func, Variable *Dest, Operand *Src)
+      : InstX86BaseUnaryopXmm<Machine, InstX86Base<Machine>::Sqrtss>(Func, Dest,
+                                                                     Src) {}
+};
+
+/// Move/assignment instruction - wrapper for mov/movss/movsd.
+template <class Machine>
+class InstX86Mov
+    : public InstX86BaseMovlike<Machine, InstX86Base<Machine>::Mov> {
+public:
+  static InstX86Mov *create(Cfg *Func, Variable *Dest, Operand *Source) {
+    return new (Func->allocate<InstX86Mov>()) InstX86Mov(Func, Dest, Source);
+  }
+
+  void emit(const Cfg *Func) const override;
+  void emitIAS(const Cfg *Func) const override;
+
+private:
+  InstX86Mov(Cfg *Func, Variable *Dest, Operand *Source)
+      : InstX86BaseMovlike<Machine, InstX86Base<Machine>::Mov>(Func, Dest,
+                                                               Source) {}
+};
+
+/// Move packed - copy 128 bit values between XMM registers, or mem128
+/// and XMM registers.
+template <class Machine>
+class InstX86Movp
+    : public InstX86BaseMovlike<Machine, InstX86Base<Machine>::Movp> {
+public:
+  static InstX86Movp *create(Cfg *Func, Variable *Dest, Operand *Source) {
+    return new (Func->allocate<InstX86Movp>()) InstX86Movp(Func, Dest, Source);
+  }
+
+  void emit(const Cfg *Func) const override;
+  void emitIAS(const Cfg *Func) const override;
+
+private:
+  InstX86Movp(Cfg *Func, Variable *Dest, Operand *Source)
+      : InstX86BaseMovlike<Machine, InstX86Base<Machine>::Movp>(Func, Dest,
+                                                                Source) {}
+};
+
+/// Movq - copy between XMM registers, or mem64 and XMM registers.
+template <class Machine>
+class InstX86Movq
+    : public InstX86BaseMovlike<Machine, InstX86Base<Machine>::Movq> {
+public:
+  static InstX86Movq *create(Cfg *Func, Variable *Dest, Operand *Source) {
+    return new (Func->allocate<InstX86Movq>()) InstX86Movq(Func, Dest, Source);
+  }
+
+  void emit(const Cfg *Func) const override;
+  void emitIAS(const Cfg *Func) const override;
+
+private:
+  InstX86Movq(Cfg *Func, Variable *Dest, Operand *Source)
+      : InstX86BaseMovlike<Machine, InstX86Base<Machine>::Movq>(Func, Dest,
+                                                                Source) {}
+};
+
+template <class Machine>
+class InstX86Add
+    : public InstX86BaseBinopGPR<Machine, InstX86Base<Machine>::Add> {
+public:
+  static InstX86Add *create(Cfg *Func, Variable *Dest, Operand *Source) {
+    return new (Func->allocate<InstX86Add>()) InstX86Add(Func, Dest, Source);
+  }
+
+private:
+  InstX86Add(Cfg *Func, Variable *Dest, Operand *Source)
+      : InstX86BaseBinopGPR<Machine, InstX86Base<Machine>::Add>(Func, Dest,
+                                                                Source) {}
+};
+
+template <class Machine>
+class InstX86AddRMW
+    : public InstX86BaseBinopRMW<Machine, InstX86Base<Machine>::AddRMW> {
+public:
+  static InstX86AddRMW *
+  create(Cfg *Func,
+         typename InstX86Base<Machine>::Traits::X86OperandMem *DestSrc0,
+         Operand *Src1) {
+    return new (Func->allocate<InstX86AddRMW>())
+        InstX86AddRMW(Func, DestSrc0, Src1);
+  }
+
+private:
+  InstX86AddRMW(Cfg *Func,
+                typename InstX86Base<Machine>::Traits::X86OperandMem *DestSrc0,
+                Operand *Src1)
+      : InstX86BaseBinopRMW<Machine, InstX86Base<Machine>::AddRMW>(
+            Func, DestSrc0, Src1) {}
+};
+
+template <class Machine>
+class InstX86Addps
+    : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Addps, true> {
+public:
+  static InstX86Addps *create(Cfg *Func, Variable *Dest, Operand *Source) {
+    return new (Func->allocate<InstX86Addps>())
+        InstX86Addps(Func, Dest, Source);
+  }
+
+private:
+  InstX86Addps(Cfg *Func, Variable *Dest, Operand *Source)
+      : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Addps, true>(
+            Func, Dest, Source) {}
+};
+
+template <class Machine>
+class InstX86Adc
+    : public InstX86BaseBinopGPR<Machine, InstX86Base<Machine>::Adc> {
+public:
+  static InstX86Adc *create(Cfg *Func, Variable *Dest, Operand *Source) {
+    return new (Func->allocate<InstX86Adc>()) InstX86Adc(Func, Dest, Source);
+  }
+
+private:
+  InstX86Adc(Cfg *Func, Variable *Dest, Operand *Source)
+      : InstX86BaseBinopGPR<Machine, InstX86Base<Machine>::Adc>(Func, Dest,
+                                                                Source) {}
+};
+
+template <class Machine>
+class InstX86AdcRMW
+    : public InstX86BaseBinopRMW<Machine, InstX86Base<Machine>::AdcRMW> {
+public:
+  static InstX86AdcRMW *
+  create(Cfg *Func,
+         typename InstX86Base<Machine>::Traits::X86OperandMem *DestSrc0,
+         Operand *Src1) {
+    return new (Func->allocate<InstX86AdcRMW>())
+        InstX86AdcRMW(Func, DestSrc0, Src1);
+  }
+
+private:
+  InstX86AdcRMW(Cfg *Func,
+                typename InstX86Base<Machine>::Traits::X86OperandMem *DestSrc0,
+                Operand *Src1)
+      : InstX86BaseBinopRMW<Machine, InstX86Base<Machine>::AdcRMW>(
+            Func, DestSrc0, Src1) {}
+};
+
+template <class Machine>
+class InstX86Addss
+    : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Addss, false> {
+public:
+  static InstX86Addss *create(Cfg *Func, Variable *Dest, Operand *Source) {
+    return new (Func->allocate<InstX86Addss>())
+        InstX86Addss(Func, Dest, Source);
+  }
+
+  void emit(const Cfg *Func) const override;
+
+private:
+  InstX86Addss(Cfg *Func, Variable *Dest, Operand *Source)
+      : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Addss, false>(
+            Func, Dest, Source) {}
+};
+
+template <class Machine>
+class InstX86Padd
+    : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Padd, true> {
+public:
+  static InstX86Padd *create(Cfg *Func, Variable *Dest, Operand *Source) {
+    return new (Func->allocate<InstX86Padd>()) InstX86Padd(Func, Dest, Source);
+  }
+
+  void emit(const Cfg *Func) const override;
+
+private:
+  InstX86Padd(Cfg *Func, Variable *Dest, Operand *Source)
+      : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Padd, true>(
+            Func, Dest, Source) {}
+};
+
+template <class Machine>
+class InstX86Sub
+    : public InstX86BaseBinopGPR<Machine, InstX86Base<Machine>::Sub> {
+public:
+  static InstX86Sub *create(Cfg *Func, Variable *Dest, Operand *Source) {
+    return new (Func->allocate<InstX86Sub>()) InstX86Sub(Func, Dest, Source);
+  }
+
+private:
+  InstX86Sub(Cfg *Func, Variable *Dest, Operand *Source)
+      : InstX86BaseBinopGPR<Machine, InstX86Base<Machine>::Sub>(Func, Dest,
+                                                                Source) {}
+};
+
+template <class Machine>
+class InstX86SubRMW
+    : public InstX86BaseBinopRMW<Machine, InstX86Base<Machine>::SubRMW> {
+public:
+  static InstX86SubRMW *
+  create(Cfg *Func,
+         typename InstX86Base<Machine>::Traits::X86OperandMem *DestSrc0,
+         Operand *Src1) {
+    return new (Func->allocate<InstX86SubRMW>())
+        InstX86SubRMW(Func, DestSrc0, Src1);
+  }
+
+private:
+  InstX86SubRMW(Cfg *Func,
+                typename InstX86Base<Machine>::Traits::X86OperandMem *DestSrc0,
+                Operand *Src1)
+      : InstX86BaseBinopRMW<Machine, InstX86Base<Machine>::SubRMW>(
+            Func, DestSrc0, Src1) {}
+};
+
+template <class Machine>
+class InstX86Subps
+    : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Subps, true> {
+public:
+  static InstX86Subps *create(Cfg *Func, Variable *Dest, Operand *Source) {
+    return new (Func->allocate<InstX86Subps>())
+        InstX86Subps(Func, Dest, Source);
+  }
+
+private:
+  InstX86Subps(Cfg *Func, Variable *Dest, Operand *Source)
+      : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Subps, true>(
+            Func, Dest, Source) {}
+};
+
+template <class Machine>
+class InstX86Subss
+    : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Subss, false> {
+public:
+  static InstX86Subss *create(Cfg *Func, Variable *Dest, Operand *Source) {
+    return new (Func->allocate<InstX86Subss>())
+        InstX86Subss(Func, Dest, Source);
+  }
+
+  void emit(const Cfg *Func) const override;
+
+private:
+  InstX86Subss(Cfg *Func, Variable *Dest, Operand *Source)
+      : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Subss, false>(
+            Func, Dest, Source) {}
+};
+
+template <class Machine>
+class InstX86Sbb
+    : public InstX86BaseBinopGPR<Machine, InstX86Base<Machine>::Sbb> {
+public:
+  static InstX86Sbb *create(Cfg *Func, Variable *Dest, Operand *Source) {
+    return new (Func->allocate<InstX86Sbb>()) InstX86Sbb(Func, Dest, Source);
+  }
+
+private:
+  InstX86Sbb(Cfg *Func, Variable *Dest, Operand *Source)
+      : InstX86BaseBinopGPR<Machine, InstX86Base<Machine>::Sbb>(Func, Dest,
+                                                                Source) {}
+};
+
+template <class Machine>
+class InstX86SbbRMW
+    : public InstX86BaseBinopRMW<Machine, InstX86Base<Machine>::SbbRMW> {
+public:
+  static InstX86SbbRMW *
+  create(Cfg *Func,
+         typename InstX86Base<Machine>::Traits::X86OperandMem *DestSrc0,
+         Operand *Src1) {
+    return new (Func->allocate<InstX86SbbRMW>())
+        InstX86SbbRMW(Func, DestSrc0, Src1);
+  }
+
+private:
+  InstX86SbbRMW(Cfg *Func,
+                typename InstX86Base<Machine>::Traits::X86OperandMem *DestSrc0,
+                Operand *Src1)
+      : InstX86BaseBinopRMW<Machine, InstX86Base<Machine>::SbbRMW>(
+            Func, DestSrc0, Src1) {}
+};
+
+template <class Machine>
+class InstX86Psub
+    : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Psub, true> {
+public:
+  static InstX86Psub *create(Cfg *Func, Variable *Dest, Operand *Source) {
+    return new (Func->allocate<InstX86Psub>()) InstX86Psub(Func, Dest, Source);
+  }
+
+  void emit(const Cfg *Func) const override;
+
+private:
+  InstX86Psub(Cfg *Func, Variable *Dest, Operand *Source)
+      : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Psub, true>(
+            Func, Dest, Source) {}
+};
+
+template <class Machine>
+class InstX86And
+    : public InstX86BaseBinopGPR<Machine, InstX86Base<Machine>::And> {
+public:
+  static InstX86And *create(Cfg *Func, Variable *Dest, Operand *Source) {
+    return new (Func->allocate<InstX86And>()) InstX86And(Func, Dest, Source);
+  }
+
+private:
+  InstX86And(Cfg *Func, Variable *Dest, Operand *Source)
+      : InstX86BaseBinopGPR<Machine, InstX86Base<Machine>::And>(Func, Dest,
+                                                                Source) {}
+};
+
+template <class Machine>
+class InstX86AndRMW
+    : public InstX86BaseBinopRMW<Machine, InstX86Base<Machine>::AndRMW> {
+public:
+  static InstX86AndRMW *
+  create(Cfg *Func,
+         typename InstX86Base<Machine>::Traits::X86OperandMem *DestSrc0,
+         Operand *Src1) {
+    return new (Func->allocate<InstX86AndRMW>())
+        InstX86AndRMW(Func, DestSrc0, Src1);
+  }
+
+private:
+  InstX86AndRMW(Cfg *Func,
+                typename InstX86Base<Machine>::Traits::X86OperandMem *DestSrc0,
+                Operand *Src1)
+      : InstX86BaseBinopRMW<Machine, InstX86Base<Machine>::AndRMW>(
+            Func, DestSrc0, Src1) {}
+};
+
+template <class Machine>
+class InstX86Pand
+    : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pand, false> {
+public:
+  static InstX86Pand *create(Cfg *Func, Variable *Dest, Operand *Source) {
+    return new (Func->allocate<InstX86Pand>()) InstX86Pand(Func, Dest, Source);
+  }
+
+private:
+  InstX86Pand(Cfg *Func, Variable *Dest, Operand *Source)
+      : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pand, false>(
+            Func, Dest, Source) {}
+};
+
+template <class Machine>
+class InstX86Pandn
+    : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pandn, false> {
+public:
+  static InstX86Pandn *create(Cfg *Func, Variable *Dest, Operand *Source) {
+    return new (Func->allocate<InstX86Pandn>())
+        InstX86Pandn(Func, Dest, Source);
+  }
+
+private:
+  InstX86Pandn(Cfg *Func, Variable *Dest, Operand *Source)
+      : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pandn, false>(
+            Func, Dest, Source) {}
+};
+
+template <class Machine>
+class InstX86Or
+    : public InstX86BaseBinopGPR<Machine, InstX86Base<Machine>::Or> {
+public:
+  static InstX86Or *create(Cfg *Func, Variable *Dest, Operand *Source) {
+    return new (Func->allocate<InstX86Or>()) InstX86Or(Func, Dest, Source);
+  }
+
+private:
+  InstX86Or(Cfg *Func, Variable *Dest, Operand *Source)
+      : InstX86BaseBinopGPR<Machine, InstX86Base<Machine>::Or>(Func, Dest,
+                                                               Source) {}
+};
+
+template <class Machine>
+class InstX86OrRMW
+    : public InstX86BaseBinopRMW<Machine, InstX86Base<Machine>::OrRMW> {
+public:
+  static InstX86OrRMW *
+  create(Cfg *Func,
+         typename InstX86Base<Machine>::Traits::X86OperandMem *DestSrc0,
+         Operand *Src1) {
+    return new (Func->allocate<InstX86OrRMW>())
+        InstX86OrRMW(Func, DestSrc0, Src1);
+  }
+
+private:
+  InstX86OrRMW(Cfg *Func,
+               typename InstX86Base<Machine>::Traits::X86OperandMem *DestSrc0,
+               Operand *Src1)
+      : InstX86BaseBinopRMW<Machine, InstX86Base<Machine>::OrRMW>(
+            Func, DestSrc0, Src1) {}
+};
+
+template <class Machine>
+class InstX86Por
+    : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Por, false> {
+public:
+  static InstX86Por *create(Cfg *Func, Variable *Dest, Operand *Source) {
+    return new (Func->allocate<InstX86Por>()) InstX86Por(Func, Dest, Source);
+  }
+
+private:
+  InstX86Por(Cfg *Func, Variable *Dest, Operand *Source)
+      : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Por, false>(
+            Func, Dest, Source) {}
+};
+
+template <class Machine>
+class InstX86Xor
+    : public InstX86BaseBinopGPR<Machine, InstX86Base<Machine>::Xor> {
+public:
+  static InstX86Xor *create(Cfg *Func, Variable *Dest, Operand *Source) {
+    return new (Func->allocate<InstX86Xor>()) InstX86Xor(Func, Dest, Source);
+  }
+
+private:
+  InstX86Xor(Cfg *Func, Variable *Dest, Operand *Source)
+      : InstX86BaseBinopGPR<Machine, InstX86Base<Machine>::Xor>(Func, Dest,
+                                                                Source) {}
+};
+
+template <class Machine>
+class InstX86XorRMW
+    : public InstX86BaseBinopRMW<Machine, InstX86Base<Machine>::XorRMW> {
+public:
+  static InstX86XorRMW *
+  create(Cfg *Func,
+         typename InstX86Base<Machine>::Traits::X86OperandMem *DestSrc0,
+         Operand *Src1) {
+    return new (Func->allocate<InstX86XorRMW>())
+        InstX86XorRMW(Func, DestSrc0, Src1);
+  }
+
+private:
+  InstX86XorRMW(Cfg *Func,
+                typename InstX86Base<Machine>::Traits::X86OperandMem *DestSrc0,
+                Operand *Src1)
+      : InstX86BaseBinopRMW<Machine, InstX86Base<Machine>::XorRMW>(
+            Func, DestSrc0, Src1) {}
+};
+
+template <class Machine>
+class InstX86Pxor
+    : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pxor, false> {
+public:
+  static InstX86Pxor *create(Cfg *Func, Variable *Dest, Operand *Source) {
+    return new (Func->allocate<InstX86Pxor>()) InstX86Pxor(Func, Dest, Source);
+  }
+
+private:
+  InstX86Pxor(Cfg *Func, Variable *Dest, Operand *Source)
+      : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pxor, false>(
+            Func, Dest, Source) {}
+};
+
+template <class Machine>
+class InstX86Imul
+    : public InstX86BaseBinopGPR<Machine, InstX86Base<Machine>::Imul> {
+public:
+  static InstX86Imul *create(Cfg *Func, Variable *Dest, Operand *Source) {
+    return new (Func->allocate<InstX86Imul>()) InstX86Imul(Func, Dest, Source);
+  }
+
+  void emit(const Cfg *Func) const override;
+  void emitIAS(const Cfg *Func) const override;
+
+private:
+  InstX86Imul(Cfg *Func, Variable *Dest, Operand *Source)
+      : InstX86BaseBinopGPR<Machine, InstX86Base<Machine>::Imul>(Func, Dest,
+                                                                 Source) {}
+};
+
+template <class Machine>
+class InstX86Mulps
+    : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Mulps, true> {
+public:
+  static InstX86Mulps *create(Cfg *Func, Variable *Dest, Operand *Source) {
+    return new (Func->allocate<InstX86Mulps>())
+        InstX86Mulps(Func, Dest, Source);
+  }
+
+private:
+  InstX86Mulps(Cfg *Func, Variable *Dest, Operand *Source)
+      : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Mulps, true>(
+            Func, Dest, Source) {}
+};
+
+template <class Machine>
+class InstX86Mulss
+    : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Mulss, false> {
+public:
+  static InstX86Mulss *create(Cfg *Func, Variable *Dest, Operand *Source) {
+    return new (Func->allocate<InstX86Mulss>())
+        InstX86Mulss(Func, Dest, Source);
+  }
+
+  void emit(const Cfg *Func) const override;
+
+private:
+  InstX86Mulss(Cfg *Func, Variable *Dest, Operand *Source)
+      : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Mulss, false>(
+            Func, Dest, Source) {}
+};
+
+template <class Machine>
+class InstX86Pmull
+    : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pmull, true> {
+public:
+  static InstX86Pmull *create(Cfg *Func, Variable *Dest, Operand *Source) {
+    return new (Func->allocate<InstX86Pmull>())
+        InstX86Pmull(Func, Dest, Source);
+  }
+
+  void emit(const Cfg *Func) const override;
+  void emitIAS(const Cfg *Func) const override;
+
+private:
+  InstX86Pmull(Cfg *Func, Variable *Dest, Operand *Source)
+      : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pmull, true>(
+            Func, Dest, Source) {}
+};
+
+template <class Machine>
+class InstX86Pmuludq
+    : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pmuludq,
+                                 false> {
+public:
+  static InstX86Pmuludq *create(Cfg *Func, Variable *Dest, Operand *Source) {
+    return new (Func->allocate<InstX86Pmuludq>())
+        InstX86Pmuludq(Func, Dest, Source);
+  }
+
+  void emit(const Cfg *Func) const override;
+
+private:
+  InstX86Pmuludq(Cfg *Func, Variable *Dest, Operand *Source)
+      : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pmuludq, false>(
+            Func, Dest, Source) {}
+};
+
+template <class Machine>
+class InstX86Divps
+    : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Divps, true> {
+public:
+  static InstX86Divps *create(Cfg *Func, Variable *Dest, Operand *Source) {
+    return new (Func->allocate<InstX86Divps>())
+        InstX86Divps(Func, Dest, Source);
+  }
+
+private:
+  InstX86Divps(Cfg *Func, Variable *Dest, Operand *Source)
+      : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Divps, true>(
+            Func, Dest, Source) {}
+};
+
+template <class Machine>
+class InstX86Divss
+    : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Divss, false> {
+public:
+  static InstX86Divss *create(Cfg *Func, Variable *Dest, Operand *Source) {
+    return new (Func->allocate<InstX86Divss>())
+        InstX86Divss(Func, Dest, Source);
+  }
+
+  void emit(const Cfg *Func) const override;
+
+private:
+  InstX86Divss(Cfg *Func, Variable *Dest, Operand *Source)
+      : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Divss, false>(
+            Func, Dest, Source) {}
+};
+
+template <class Machine>
+class InstX86Rol
+    : public InstX86BaseBinopGPRShift<Machine, InstX86Base<Machine>::Rol> {
+public:
+  static InstX86Rol *create(Cfg *Func, Variable *Dest, Operand *Source) {
+    return new (Func->allocate<InstX86Rol>()) InstX86Rol(Func, Dest, Source);
+  }
+
+private:
+  InstX86Rol(Cfg *Func, Variable *Dest, Operand *Source)
+      : InstX86BaseBinopGPRShift<Machine, InstX86Base<Machine>::Rol>(Func, Dest,
+                                                                     Source) {}
+};
+
+template <class Machine>
+class InstX86Shl
+    : public InstX86BaseBinopGPRShift<Machine, InstX86Base<Machine>::Shl> {
+public:
+  static InstX86Shl *create(Cfg *Func, Variable *Dest, Operand *Source) {
+    return new (Func->allocate<InstX86Shl>()) InstX86Shl(Func, Dest, Source);
+  }
+
+private:
+  InstX86Shl(Cfg *Func, Variable *Dest, Operand *Source)
+      : InstX86BaseBinopGPRShift<Machine, InstX86Base<Machine>::Shl>(Func, Dest,
+                                                                     Source) {}
+};
+
+template <class Machine>
+class InstX86Psll
+    : public InstX86BaseBinopXmmShift<Machine, InstX86Base<Machine>::Psll> {
+public:
+  static InstX86Psll *create(Cfg *Func, Variable *Dest, Operand *Source) {
+    return new (Func->allocate<InstX86Psll>()) InstX86Psll(Func, Dest, Source);
+  }
+
+  void emit(const Cfg *Func) const override;
+
+private:
+  InstX86Psll(Cfg *Func, Variable *Dest, Operand *Source)
+      : InstX86BaseBinopXmmShift<Machine, InstX86Base<Machine>::Psll>(
+            Func, Dest, Source) {}
+};
+
+template <class Machine>
+class InstX86Psrl
+    : public InstX86BaseBinopXmmShift<Machine, InstX86Base<Machine>::Psrl,
+                                      true> {
+public:
+  static InstX86Psrl *create(Cfg *Func, Variable *Dest, Operand *Source) {
+    return new (Func->allocate<InstX86Psrl>()) InstX86Psrl(Func, Dest, Source);
+  }
+
+  void emit(const Cfg *Func) const override;
+
+private:
+  InstX86Psrl(Cfg *Func, Variable *Dest, Operand *Source)
+      : InstX86BaseBinopXmmShift<Machine, InstX86Base<Machine>::Psrl, true>(
+            Func, Dest, Source) {}
+};
+
+template <class Machine>
+class InstX86Shr
+    : public InstX86BaseBinopGPRShift<Machine, InstX86Base<Machine>::Shr> {
+public:
+  static InstX86Shr *create(Cfg *Func, Variable *Dest, Operand *Source) {
+    return new (Func->allocate<InstX86Shr>()) InstX86Shr(Func, Dest, Source);
+  }
+
+private:
+  InstX86Shr(Cfg *Func, Variable *Dest, Operand *Source)
+      : InstX86BaseBinopGPRShift<Machine, InstX86Base<Machine>::Shr>(Func, Dest,
+                                                                     Source) {}
+};
+
+template <class Machine>
+class InstX86Sar
+    : public InstX86BaseBinopGPRShift<Machine, InstX86Base<Machine>::Sar> {
+public:
+  static InstX86Sar *create(Cfg *Func, Variable *Dest, Operand *Source) {
+    return new (Func->allocate<InstX86Sar>()) InstX86Sar(Func, Dest, Source);
+  }
+
+private:
+  InstX86Sar(Cfg *Func, Variable *Dest, Operand *Source)
+      : InstX86BaseBinopGPRShift<Machine, InstX86Base<Machine>::Sar>(Func, Dest,
+                                                                     Source) {}
+};
+
+template <class Machine>
+class InstX86Psra
+    : public InstX86BaseBinopXmmShift<Machine, InstX86Base<Machine>::Psra> {
+public:
+  static InstX86Psra *create(Cfg *Func, Variable *Dest, Operand *Source) {
+    return new (Func->allocate<InstX86Psra>()) InstX86Psra(Func, Dest, Source);
+  }
+
+  void emit(const Cfg *Func) const override;
+
+private:
+  InstX86Psra(Cfg *Func, Variable *Dest, Operand *Source)
+      : InstX86BaseBinopXmmShift<Machine, InstX86Base<Machine>::Psra>(
+            Func, Dest, Source) {}
+};
+
+template <class Machine>
+class InstX86Pcmpeq
+    : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pcmpeq, true> {
+public:
+  static InstX86Pcmpeq *create(Cfg *Func, Variable *Dest, Operand *Source) {
+    return new (Func->allocate<InstX86Pcmpeq>())
+        InstX86Pcmpeq(Func, Dest, Source);
+  }
+
+  void emit(const Cfg *Func) const override;
+
+private:
+  InstX86Pcmpeq(Cfg *Func, Variable *Dest, Operand *Source)
+      : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pcmpeq, true>(
+            Func, Dest, Source) {}
+};
+
+template <class Machine>
+class InstX86Pcmpgt
+    : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pcmpgt, true> {
+public:
+  static InstX86Pcmpgt *create(Cfg *Func, Variable *Dest, Operand *Source) {
+    return new (Func->allocate<InstX86Pcmpgt>())
+        InstX86Pcmpgt(Func, Dest, Source);
+  }
+
+  void emit(const Cfg *Func) const override;
+
+private:
+  InstX86Pcmpgt(Cfg *Func, Variable *Dest, Operand *Source)
+      : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pcmpgt, true>(
+            Func, Dest, Source) {}
+};
+
+/// movss is only a binary operation when the source and dest
+/// operands are both registers (the high bits of dest are left untouched).
+/// In other cases, it behaves like a copy (mov-like) operation (and the
+/// high bits of dest are cleared).
+/// InstX86Movss will assert that both its source and dest operands are
+/// registers, so the lowering code should use _mov instead of _movss
+/// in cases where a copy operation is intended.
+template <class Machine>
+class InstX86MovssRegs
+    : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::MovssRegs,
+                                 false> {
+public:
+  static InstX86MovssRegs *create(Cfg *Func, Variable *Dest, Operand *Source) {
+    return new (Func->allocate<InstX86MovssRegs>())
+        InstX86MovssRegs(Func, Dest, Source);
+  }
+
+  void emitIAS(const Cfg *Func) const override;
+
+private:
+  InstX86MovssRegs(Cfg *Func, Variable *Dest, Operand *Source)
+      : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::MovssRegs, false>(
+            Func, Dest, Source) {}
+};
+
+template <class Machine>
+class InstX86Idiv
+    : public InstX86BaseTernop<Machine, InstX86Base<Machine>::Idiv> {
+public:
+  static InstX86Idiv *create(Cfg *Func, Variable *Dest, Operand *Source1,
+                             Operand *Source2) {
+    return new (Func->allocate<InstX86Idiv>())
+        InstX86Idiv(Func, Dest, Source1, Source2);
+  }
+
+  void emit(const Cfg *Func) const override;
+  void emitIAS(const Cfg *Func) const override;
+
+private:
+  InstX86Idiv(Cfg *Func, Variable *Dest, Operand *Source1, Operand *Source2)
+      : InstX86BaseTernop<Machine, InstX86Base<Machine>::Idiv>(
+            Func, Dest, Source1, Source2) {}
+};
+
+template <class Machine>
+class InstX86Div
+    : public InstX86BaseTernop<Machine, InstX86Base<Machine>::Div> {
+public:
+  static InstX86Div *create(Cfg *Func, Variable *Dest, Operand *Source1,
+                            Operand *Source2) {
+    return new (Func->allocate<InstX86Div>())
+        InstX86Div(Func, Dest, Source1, Source2);
+  }
+
+  void emit(const Cfg *Func) const override;
+  void emitIAS(const Cfg *Func) const override;
+
+private:
+  InstX86Div(Cfg *Func, Variable *Dest, Operand *Source1, Operand *Source2)
+      : InstX86BaseTernop<Machine, InstX86Base<Machine>::Div>(
+            Func, Dest, Source1, Source2) {}
+};
+
+template <class Machine>
+class InstX86Insertps
+    : public InstX86BaseTernop<Machine, InstX86Base<Machine>::Insertps> {
+public:
+  static InstX86Insertps *create(Cfg *Func, Variable *Dest, Operand *Source1,
+                                 Operand *Source2) {
+    return new (Func->allocate<InstX86Insertps>())
+        InstX86Insertps(Func, Dest, Source1, Source2);
+  }
+
+  void emitIAS(const Cfg *Func) const override;
+
+private:
+  InstX86Insertps(Cfg *Func, Variable *Dest, Operand *Source1, Operand *Source2)
+      : InstX86BaseTernop<Machine, InstX86Base<Machine>::Insertps>(
+            Func, Dest, Source1, Source2) {}
+};
+
+template <class Machine>
+class InstX86Pinsr
+    : public InstX86BaseTernop<Machine, InstX86Base<Machine>::Pinsr> {
+public:
+  static InstX86Pinsr *create(Cfg *Func, Variable *Dest, Operand *Source1,
+                              Operand *Source2) {
+    return new (Func->allocate<InstX86Pinsr>())
+        InstX86Pinsr(Func, Dest, Source1, Source2);
+  }
+
+  void emit(const Cfg *Func) const override;
+  void emitIAS(const Cfg *Func) const override;
+
+private:
+  InstX86Pinsr(Cfg *Func, Variable *Dest, Operand *Source1, Operand *Source2)
+      : InstX86BaseTernop<Machine, InstX86Base<Machine>::Pinsr>(
+            Func, Dest, Source1, Source2) {}
+};
+
+template <class Machine>
+class InstX86Shufps
+    : public InstX86BaseTernop<Machine, InstX86Base<Machine>::Shufps> {
+public:
+  static InstX86Shufps *create(Cfg *Func, Variable *Dest, Operand *Source1,
+                               Operand *Source2) {
+    return new (Func->allocate<InstX86Shufps>())
+        InstX86Shufps(Func, Dest, Source1, Source2);
+  }
+
+  void emitIAS(const Cfg *Func) const override;
+
+private:
+  InstX86Shufps(Cfg *Func, Variable *Dest, Operand *Source1, Operand *Source2)
+      : InstX86BaseTernop<Machine, InstX86Base<Machine>::Shufps>(
+            Func, Dest, Source1, Source2) {}
+};
+
+template <class Machine>
+class InstX86Blendvps
+    : public InstX86BaseTernop<Machine, InstX86Base<Machine>::Blendvps> {
+public:
+  static InstX86Blendvps *create(Cfg *Func, Variable *Dest, Operand *Source1,
+                                 Operand *Source2) {
+    return new (Func->allocate<InstX86Blendvps>())
+        InstX86Blendvps(Func, Dest, Source1, Source2);
+  }
+
+  void emit(const Cfg *Func) const override;
+  void emitIAS(const Cfg *Fund) const override;
+
+private:
+  InstX86Blendvps(Cfg *Func, Variable *Dest, Operand *Source1, Operand *Source2)
+      : InstX86BaseTernop<Machine, InstX86Base<Machine>::Blendvps>(
+            Func, Dest, Source1, Source2) {}
+};
+
+template <class Machine>
+class InstX86Pblendvb
+    : public InstX86BaseTernop<Machine, InstX86Base<Machine>::Pblendvb> {
+public:
+  static InstX86Pblendvb *create(Cfg *Func, Variable *Dest, Operand *Source1,
+                                 Operand *Source2) {
+    return new (Func->allocate<InstX86Pblendvb>())
+        InstX86Pblendvb(Func, Dest, Source1, Source2);
+  }
+
+  void emit(const Cfg *Func) const override;
+  void emitIAS(const Cfg *Func) const override;
+
+private:
+  InstX86Pblendvb(Cfg *Func, Variable *Dest, Operand *Source1, Operand *Source2)
+      : InstX86BaseTernop<Machine, InstX86Base<Machine>::Pblendvb>(
+            Func, Dest, Source1, Source2) {}
+};
+
+template <class Machine>
+class InstX86Pextr
+    : public InstX86BaseThreeAddressop<Machine, InstX86Base<Machine>::Pextr> {
+public:
+  static InstX86Pextr *create(Cfg *Func, Variable *Dest, Operand *Source0,
+                              Operand *Source1) {
+    return new (Func->allocate<InstX86Pextr>())
+        InstX86Pextr(Func, Dest, Source0, Source1);
+  }
+
+  void emit(const Cfg *Func) const override;
+  void emitIAS(const Cfg *Func) const override;
+
+private:
+  InstX86Pextr(Cfg *Func, Variable *Dest, Operand *Source0, Operand *Source1)
+      : InstX86BaseThreeAddressop<Machine, InstX86Base<Machine>::Pextr>(
+            Func, Dest, Source0, Source1) {}
+};
+
+template <class Machine>
+class InstX86Pshufd
+    : public InstX86BaseThreeAddressop<Machine, InstX86Base<Machine>::Pshufd> {
+public:
+  static InstX86Pshufd *create(Cfg *Func, Variable *Dest, Operand *Source0,
+                               Operand *Source1) {
+    return new (Func->allocate<InstX86Pshufd>())
+        InstX86Pshufd(Func, Dest, Source0, Source1);
+  }
+
+  void emitIAS(const Cfg *Func) const override;
+
+private:
+  InstX86Pshufd(Cfg *Func, Variable *Dest, Operand *Source0, Operand *Source1)
+      : InstX86BaseThreeAddressop<Machine, InstX86Base<Machine>::Pshufd>(
+            Func, Dest, Source0, Source1) {}
+};
+
+/// Base class for a lockable x86-32 instruction (emits a locked prefix).
+template <class Machine>
+class InstX86BaseLockable : public InstX86Base<Machine> {
+  InstX86BaseLockable() = delete;
+  InstX86BaseLockable(const InstX86BaseLockable &) = delete;
+  InstX86BaseLockable &operator=(const InstX86BaseLockable &) = delete;
+
+protected:
+  bool Locked;
+
+  InstX86BaseLockable(Cfg *Func,
+                      typename InstX86Base<Machine>::InstKindX86 Kind,
+                      SizeT Maxsrcs, Variable *Dest, bool Locked)
+      : InstX86Base<Machine>(Func, Kind, Maxsrcs, Dest), Locked(Locked) {
+    // Assume that such instructions are used for Atomics and be careful
+    // with optimizations.
+    this->HasSideEffects = Locked;
+  }
+};
+
+/// Mul instruction - unsigned multiply.
+template <class Machine> class InstX86Mul final : public InstX86Base<Machine> {
+  InstX86Mul() = delete;
+  InstX86Mul(const InstX86Mul &) = delete;
+  InstX86Mul &operator=(const InstX86Mul &) = delete;
+
+public:
+  static InstX86Mul *create(Cfg *Func, Variable *Dest, Variable *Source1,
+                            Operand *Source2) {
+    return new (Func->allocate<InstX86Mul>())
+        InstX86Mul(Func, Dest, Source1, Source2);
+  }
+  void emit(const Cfg *Func) const override;
+  void emitIAS(const Cfg *Func) const override;
+  void dump(const Cfg *Func) const override;
+  static bool classof(const Inst *Inst) {
+    return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Mul);
+  }
+
+private:
+  InstX86Mul(Cfg *Func, Variable *Dest, Variable *Source1, Operand *Source2);
+};
+
+/// Shld instruction - shift across a pair of operands.
+template <class Machine> class InstX86Shld final : public InstX86Base<Machine> {
+  InstX86Shld() = delete;
+  InstX86Shld(const InstX86Shld &) = delete;
+  InstX86Shld &operator=(const InstX86Shld &) = delete;
+
+public:
+  static InstX86Shld *create(Cfg *Func, Variable *Dest, Variable *Source1,
+                             Variable *Source2) {
+    return new (Func->allocate<InstX86Shld>())
+        InstX86Shld(Func, Dest, Source1, Source2);
+  }
+  void emit(const Cfg *Func) const override;
+  void emitIAS(const Cfg *Func) const override;
+  void dump(const Cfg *Func) const override;
+  static bool classof(const Inst *Inst) {
+    return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Shld);
+  }
+
+private:
+  InstX86Shld(Cfg *Func, Variable *Dest, Variable *Source1, Variable *Source2);
+};
+
+/// Shrd instruction - shift across a pair of operands.
+template <class Machine> class InstX86Shrd final : public InstX86Base<Machine> {
+  InstX86Shrd() = delete;
+  InstX86Shrd(const InstX86Shrd &) = delete;
+  InstX86Shrd &operator=(const InstX86Shrd &) = delete;
+
+public:
+  static InstX86Shrd *create(Cfg *Func, Variable *Dest, Variable *Source1,
+                             Variable *Source2) {
+    return new (Func->allocate<InstX86Shrd>())
+        InstX86Shrd(Func, Dest, Source1, Source2);
+  }
+  void emit(const Cfg *Func) const override;
+  void emitIAS(const Cfg *Func) const override;
+  void dump(const Cfg *Func) const override;
+  static bool classof(const Inst *Inst) {
+    return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Shrd);
+  }
+
+private:
+  InstX86Shrd(Cfg *Func, Variable *Dest, Variable *Source1, Variable *Source2);
+};
+
+/// Conditional move instruction.
+template <class Machine> class InstX86Cmov final : public InstX86Base<Machine> {
+  InstX86Cmov() = delete;
+  InstX86Cmov(const InstX86Cmov &) = delete;
+  InstX86Cmov &operator=(const InstX86Cmov &) = delete;
+
+public:
+  static InstX86Cmov *
+  create(Cfg *Func, Variable *Dest, Operand *Source,
+         typename InstX86Base<Machine>::Traits::Cond::BrCond Cond) {
+    return new (Func->allocate<InstX86Cmov>())
+        InstX86Cmov(Func, Dest, Source, Cond);
+  }
+  void emit(const Cfg *Func) const override;
+  void emitIAS(const Cfg *Func) const override;
+  void dump(const Cfg *Func) const override;
+  static bool classof(const Inst *Inst) {
+    return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Cmov);
+  }
+
+private:
+  InstX86Cmov(Cfg *Func, Variable *Dest, Operand *Source,
+              typename InstX86Base<Machine>::Traits::Cond::BrCond Cond);
+
+  typename InstX86Base<Machine>::Traits::Cond::BrCond Condition;
+};
+
+/// Cmpps instruction - compare packed singled-precision floating point
+/// values
+template <class Machine>
+class InstX86Cmpps final : public InstX86Base<Machine> {
+  InstX86Cmpps() = delete;
+  InstX86Cmpps(const InstX86Cmpps &) = delete;
+  InstX86Cmpps &operator=(const InstX86Cmpps &) = delete;
+
+public:
+  static InstX86Cmpps *
+  create(Cfg *Func, Variable *Dest, Operand *Source,
+         typename InstX86Base<Machine>::Traits::Cond::CmppsCond Condition) {
+    return new (Func->allocate<InstX86Cmpps>())
+        InstX86Cmpps(Func, Dest, Source, Condition);
+  }
+  void emit(const Cfg *Func) const override;
+  void emitIAS(const Cfg *Func) const override;
+  void dump(const Cfg *Func) const override;
+  static bool classof(const Inst *Inst) {
+    return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Cmpps);
+  }
+
+private:
+  InstX86Cmpps(Cfg *Func, Variable *Dest, Operand *Source,
+               typename InstX86Base<Machine>::Traits::Cond::CmppsCond Cond);
+
+  typename InstX86Base<Machine>::Traits::Cond::CmppsCond Condition;
+};
+
+/// Cmpxchg instruction - cmpxchg <dest>, <desired> will compare if <dest>
+/// equals eax. If so, the ZF is set and <desired> is stored in <dest>.
+/// If not, ZF is cleared and <dest> is copied to eax (or subregister).
+/// <dest> can be a register or memory, while <desired> must be a register.
+/// It is the user's responsiblity to mark eax with a FakeDef.
+template <class Machine>
+class InstX86Cmpxchg final : public InstX86BaseLockable<Machine> {
+  InstX86Cmpxchg() = delete;
+  InstX86Cmpxchg(const InstX86Cmpxchg &) = delete;
+  InstX86Cmpxchg &operator=(const InstX86Cmpxchg &) = delete;
+
+public:
+  static InstX86Cmpxchg *create(Cfg *Func, Operand *DestOrAddr, Variable *Eax,
+                                Variable *Desired, bool Locked) {
+    return new (Func->allocate<InstX86Cmpxchg>())
+        InstX86Cmpxchg(Func, DestOrAddr, Eax, Desired, Locked);
+  }
+  void emit(const Cfg *Func) const override;
+  void emitIAS(const Cfg *Func) const override;
+  void dump(const Cfg *Func) const override;
+  static bool classof(const Inst *Inst) {
+    return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Cmpxchg);
+  }
+
+private:
+  InstX86Cmpxchg(Cfg *Func, Operand *DestOrAddr, Variable *Eax,
+                 Variable *Desired, bool Locked);
+};
+
+/// Cmpxchg8b instruction - cmpxchg8b <m64> will compare if <m64>
+/// equals edx:eax. If so, the ZF is set and ecx:ebx is stored in <m64>.
+/// If not, ZF is cleared and <m64> is copied to edx:eax.
+/// The caller is responsible for inserting FakeDefs to mark edx
+/// and eax as modified.
+/// <m64> must be a memory operand.
+template <class Machine>
+class InstX86Cmpxchg8b final : public InstX86BaseLockable<Machine> {
+  InstX86Cmpxchg8b() = delete;
+  InstX86Cmpxchg8b(const InstX86Cmpxchg8b &) = delete;
+  InstX86Cmpxchg8b &operator=(const InstX86Cmpxchg8b &) = delete;
+
+public:
+  static InstX86Cmpxchg8b *
+  create(Cfg *Func, typename InstX86Base<Machine>::Traits::X86OperandMem *Dest,
+         Variable *Edx, Variable *Eax, Variable *Ecx, Variable *Ebx,
+         bool Locked) {
+    return new (Func->allocate<InstX86Cmpxchg8b>())
+        InstX86Cmpxchg8b(Func, Dest, Edx, Eax, Ecx, Ebx, Locked);
+  }
+  void emit(const Cfg *Func) const override;
+  void emitIAS(const Cfg *Func) const override;
+  void dump(const Cfg *Func) const override;
+  static bool classof(const Inst *Inst) {
+    return InstX86Base<Machine>::isClassof(Inst,
+                                           InstX86Base<Machine>::Cmpxchg8b);
+  }
+
+private:
+  InstX86Cmpxchg8b(Cfg *Func,
+                   typename InstX86Base<Machine>::Traits::X86OperandMem *Dest,
+                   Variable *Edx, Variable *Eax, Variable *Ecx, Variable *Ebx,
+                   bool Locked);
+};
+
+/// Cvt instruction - wrapper for cvtsX2sY where X and Y are in {s,d,i}
+/// as appropriate.  s=float, d=double, i=int.  X and Y are determined
+/// from dest/src types.  Sign and zero extension on the integer
+/// operand needs to be done separately.
+template <class Machine> class InstX86Cvt final : public InstX86Base<Machine> {
+  InstX86Cvt() = delete;
+  InstX86Cvt(const InstX86Cvt &) = delete;
+  InstX86Cvt &operator=(const InstX86Cvt &) = delete;
+
+public:
+  enum CvtVariant { Si2ss, Tss2si, Float2float, Dq2ps, Tps2dq };
+  static InstX86Cvt *create(Cfg *Func, Variable *Dest, Operand *Source,
+                            CvtVariant Variant) {
+    return new (Func->allocate<InstX86Cvt>())
+        InstX86Cvt(Func, Dest, Source, Variant);
+  }
+  void emit(const Cfg *Func) const override;
+  void emitIAS(const Cfg *Func) const override;
+  void dump(const Cfg *Func) const override;
+  static bool classof(const Inst *Inst) {
+    return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Cvt);
+  }
+  bool isTruncating() const { return Variant == Tss2si || Variant == Tps2dq; }
+
+private:
+  CvtVariant Variant;
+  InstX86Cvt(Cfg *Func, Variable *Dest, Operand *Source, CvtVariant Variant);
+};
+
+/// cmp - Integer compare instruction.
+template <class Machine> class InstX86Icmp final : public InstX86Base<Machine> {
+  InstX86Icmp() = delete;
+  InstX86Icmp(const InstX86Icmp &) = delete;
+  InstX86Icmp &operator=(const InstX86Icmp &) = delete;
+
+public:
+  static InstX86Icmp *create(Cfg *Func, Operand *Src1, Operand *Src2) {
+    return new (Func->allocate<InstX86Icmp>()) InstX86Icmp(Func, Src1, Src2);
+  }
+  void emit(const Cfg *Func) const override;
+  void emitIAS(const Cfg *Func) const override;
+  void dump(const Cfg *Func) const override;
+  static bool classof(const Inst *Inst) {
+    return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Icmp);
+  }
+
+private:
+  InstX86Icmp(Cfg *Func, Operand *Src1, Operand *Src2);
+};
+
+/// ucomiss/ucomisd - floating-point compare instruction.
+template <class Machine>
+class InstX86Ucomiss final : public InstX86Base<Machine> {
+  InstX86Ucomiss() = delete;
+  InstX86Ucomiss(const InstX86Ucomiss &) = delete;
+  InstX86Ucomiss &operator=(const InstX86Ucomiss &) = delete;
+
+public:
+  static InstX86Ucomiss *create(Cfg *Func, Operand *Src1, Operand *Src2) {
+    return new (Func->allocate<InstX86Ucomiss>())
+        InstX86Ucomiss(Func, Src1, Src2);
+  }
+  void emit(const Cfg *Func) const override;
+  void emitIAS(const Cfg *Func) const override;
+  void dump(const Cfg *Func) const override;
+  static bool classof(const Inst *Inst) {
+    return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Ucomiss);
+  }
+
+private:
+  InstX86Ucomiss(Cfg *Func, Operand *Src1, Operand *Src2);
+};
+
+/// UD2 instruction.
+template <class Machine> class InstX86UD2 final : public InstX86Base<Machine> {
+  InstX86UD2() = delete;
+  InstX86UD2(const InstX86UD2 &) = delete;
+  InstX86UD2 &operator=(const InstX86UD2 &) = delete;
+
+public:
+  static InstX86UD2 *create(Cfg *Func) {
+    return new (Func->allocate<InstX86UD2>()) InstX86UD2(Func);
+  }
+  void emit(const Cfg *Func) const override;
+  void emitIAS(const Cfg *Func) const override;
+  void dump(const Cfg *Func) const override;
+  static bool classof(const Inst *Inst) {
+    return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::UD2);
+  }
+
+private:
+  explicit InstX86UD2(Cfg *Func);
+};
+
+/// Test instruction.
+template <class Machine> class InstX86Test final : public InstX86Base<Machine> {
+  InstX86Test() = delete;
+  InstX86Test(const InstX86Test &) = delete;
+  InstX86Test &operator=(const InstX86Test &) = delete;
+
+public:
+  static InstX86Test *create(Cfg *Func, Operand *Source1, Operand *Source2) {
+    return new (Func->allocate<InstX86Test>())
+        InstX86Test(Func, Source1, Source2);
+  }
+  void emit(const Cfg *Func) const override;
+  void emitIAS(const Cfg *Func) const override;
+  void dump(const Cfg *Func) const override;
+  static bool classof(const Inst *Inst) {
+    return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Test);
+  }
+
+private:
+  InstX86Test(Cfg *Func, Operand *Source1, Operand *Source2);
+};
+
+/// Mfence instruction.
+template <class Machine>
+class InstX86Mfence final : public InstX86Base<Machine> {
+  InstX86Mfence() = delete;
+  InstX86Mfence(const InstX86Mfence &) = delete;
+  InstX86Mfence &operator=(const InstX86Mfence &) = delete;
+
+public:
+  static InstX86Mfence *create(Cfg *Func) {
+    return new (Func->allocate<InstX86Mfence>()) InstX86Mfence(Func);
+  }
+  void emit(const Cfg *Func) const override;
+  void emitIAS(const Cfg *Func) const override;
+  void dump(const Cfg *Func) const override;
+  static bool classof(const Inst *Inst) {
+    return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Mfence);
+  }
+
+private:
+  explicit InstX86Mfence(Cfg *Func);
+};
+
+/// This is essentially a "mov" instruction with an
+/// InstX86Base<Machine>::Traits::X86OperandMem
+/// operand instead of Variable as the destination.  It's important
+/// for liveness that there is no Dest operand.
+template <class Machine>
+class InstX86Store final : public InstX86Base<Machine> {
+  InstX86Store() = delete;
+  InstX86Store(const InstX86Store &) = delete;
+  InstX86Store &operator=(const InstX86Store &) = delete;
+
+public:
+  static InstX86Store *
+  create(Cfg *Func, Operand *Value,
+         typename InstX86Base<Machine>::Traits::X86Operand *Mem) {
+    return new (Func->allocate<InstX86Store>()) InstX86Store(Func, Value, Mem);
+  }
+  void emit(const Cfg *Func) const override;
+  void emitIAS(const Cfg *Func) const override;
+  void dump(const Cfg *Func) const override;
+  static bool classof(const Inst *Inst) {
+    return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Store);
+  }
+
+private:
+  InstX86Store(Cfg *Func, Operand *Value,
+               typename InstX86Base<Machine>::Traits::X86Operand *Mem);
+};
+
+/// This is essentially a vector "mov" instruction with an typename
+/// InstX86Base<Machine>::Traits::X86OperandMem
+/// operand instead of Variable as the destination.  It's important
+/// for liveness that there is no Dest operand. The source must be an
+/// Xmm register, since Dest is mem.
+template <class Machine>
+class InstX86StoreP final : public InstX86Base<Machine> {
+  InstX86StoreP() = delete;
+  InstX86StoreP(const InstX86StoreP &) = delete;
+  InstX86StoreP &operator=(const InstX86StoreP &) = delete;
+
+public:
+  static InstX86StoreP *
+  create(Cfg *Func, Variable *Value,
+         typename InstX86Base<Machine>::Traits::X86OperandMem *Mem) {
+    return new (Func->allocate<InstX86StoreP>())
+        InstX86StoreP(Func, Value, Mem);
+  }
+  void emit(const Cfg *Func) const override;
+  void emitIAS(const Cfg *Func) const override;
+  void dump(const Cfg *Func) const override;
+  static bool classof(const Inst *Inst) {
+    return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::StoreP);
+  }
+
+private:
+  InstX86StoreP(Cfg *Func, Variable *Value,
+                typename InstX86Base<Machine>::Traits::X86OperandMem *Mem);
+};
+
+template <class Machine>
+class InstX86StoreQ final : public InstX86Base<Machine> {
+  InstX86StoreQ() = delete;
+  InstX86StoreQ(const InstX86StoreQ &) = delete;
+  InstX86StoreQ &operator=(const InstX86StoreQ &) = delete;
+
+public:
+  static InstX86StoreQ *
+  create(Cfg *Func, Variable *Value,
+         typename InstX86Base<Machine>::Traits::X86OperandMem *Mem) {
+    return new (Func->allocate<InstX86StoreQ>())
+        InstX86StoreQ(Func, Value, Mem);
+  }
+  void emit(const Cfg *Func) const override;
+  void emitIAS(const Cfg *Func) const override;
+  void dump(const Cfg *Func) const override;
+  static bool classof(const Inst *Inst) {
+    return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::StoreQ);
+  }
+
+private:
+  InstX86StoreQ(Cfg *Func, Variable *Value,
+                typename InstX86Base<Machine>::Traits::X86OperandMem *Mem);
+};
+
+/// Nop instructions of varying length
+template <class Machine> class InstX86Nop final : public InstX86Base<Machine> {
+  InstX86Nop() = delete;
+  InstX86Nop(const InstX86Nop &) = delete;
+  InstX86Nop &operator=(const InstX86Nop &) = delete;
+
+public:
+  // TODO: Replace with enum.
+  typedef unsigned NopVariant;
+
+  static InstX86Nop *create(Cfg *Func, NopVariant Variant) {
+    return new (Func->allocate<InstX86Nop>()) InstX86Nop(Func, Variant);
+  }
+  void emit(const Cfg *Func) const override;
+  void emitIAS(const Cfg *Func) const override;
+  void dump(const Cfg *Func) const override;
+  static bool classof(const Inst *Inst) {
+    return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Nop);
+  }
+
+private:
+  InstX86Nop(Cfg *Func, SizeT Length);
+
+  NopVariant Variant;
+};
+
+/// Fld - load a value onto the x87 FP stack.
+template <class Machine> class InstX86Fld final : public InstX86Base<Machine> {
+  InstX86Fld() = delete;
+  InstX86Fld(const InstX86Fld &) = delete;
+  InstX86Fld &operator=(const InstX86Fld &) = delete;
+
+public:
+  static InstX86Fld *create(Cfg *Func, Operand *Src) {
+    return new (Func->allocate<InstX86Fld>()) InstX86Fld(Func, Src);
+  }
+  void emit(const Cfg *Func) const override;
+  void emitIAS(const Cfg *Func) const override;
+  void dump(const Cfg *Func) const override;
+  static bool classof(const Inst *Inst) {
+    return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Fld);
+  }
+
+private:
+  InstX86Fld(Cfg *Func, Operand *Src);
+};
+
+/// Fstp - store x87 st(0) into memory and pop st(0).
+template <class Machine> class InstX86Fstp final : public InstX86Base<Machine> {
+  InstX86Fstp() = delete;
+  InstX86Fstp(const InstX86Fstp &) = delete;
+  InstX86Fstp &operator=(const InstX86Fstp &) = delete;
+
+public:
+  static InstX86Fstp *create(Cfg *Func, Variable *Dest) {
+    return new (Func->allocate<InstX86Fstp>()) InstX86Fstp(Func, Dest);
+  }
+  void emit(const Cfg *Func) const override;
+  void emitIAS(const Cfg *Func) const override;
+  void dump(const Cfg *Func) const override;
+  static bool classof(const Inst *Inst) {
+    return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Fstp);
+  }
+
+private:
+  InstX86Fstp(Cfg *Func, Variable *Dest);
+};
+
+template <class Machine> class InstX86Pop final : public InstX86Base<Machine> {
+  InstX86Pop() = delete;
+  InstX86Pop(const InstX86Pop &) = delete;
+  InstX86Pop &operator=(const InstX86Pop &) = delete;
+
+public:
+  static InstX86Pop *create(Cfg *Func, Variable *Dest) {
+    return new (Func->allocate<InstX86Pop>()) InstX86Pop(Func, Dest);
+  }
+  void emit(const Cfg *Func) const override;
+  void emitIAS(const Cfg *Func) const override;
+  void dump(const Cfg *Func) const override;
+  static bool classof(const Inst *Inst) {
+    return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Pop);
+  }
+
+private:
+  InstX86Pop(Cfg *Func, Variable *Dest);
+};
+
+template <class Machine> class InstX86Push final : public InstX86Base<Machine> {
+  InstX86Push() = delete;
+  InstX86Push(const InstX86Push &) = delete;
+  InstX86Push &operator=(const InstX86Push &) = delete;
+
+public:
+  static InstX86Push *create(Cfg *Func, Variable *Source) {
+    return new (Func->allocate<InstX86Push>()) InstX86Push(Func, Source);
+  }
+  void emit(const Cfg *Func) const override;
+  void emitIAS(const Cfg *Func) const override;
+  void dump(const Cfg *Func) const override;
+  static bool classof(const Inst *Inst) {
+    return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Push);
+  }
+
+private:
+  InstX86Push(Cfg *Func, Variable *Source);
+};
+
+/// Ret instruction.  Currently only supports the "ret" version that
+/// does not pop arguments.  This instruction takes a Source operand
+/// (for non-void returning functions) for liveness analysis, though
+/// a FakeUse before the ret would do just as well.
+template <class Machine> class InstX86Ret final : public InstX86Base<Machine> {
+  InstX86Ret() = delete;
+  InstX86Ret(const InstX86Ret &) = delete;
+  InstX86Ret &operator=(const InstX86Ret &) = delete;
+
+public:
+  static InstX86Ret *create(Cfg *Func, Variable *Source = nullptr) {
+    return new (Func->allocate<InstX86Ret>()) InstX86Ret(Func, Source);
+  }
+  void emit(const Cfg *Func) const override;
+  void emitIAS(const Cfg *Func) const override;
+  void dump(const Cfg *Func) const override;
+  static bool classof(const Inst *Inst) {
+    return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Ret);
+  }
+
+private:
+  InstX86Ret(Cfg *Func, Variable *Source);
+};
+
+/// Conditional set-byte instruction.
+template <class Machine>
+class InstX86Setcc final : public InstX86Base<Machine> {
+  InstX86Setcc() = delete;
+  InstX86Setcc(const InstX86Cmov<Machine> &) = delete;
+  InstX86Setcc &operator=(const InstX86Setcc &) = delete;
+
+public:
+  static InstX86Setcc *
+  create(Cfg *Func, Variable *Dest,
+         typename InstX86Base<Machine>::Traits::Cond::BrCond Cond) {
+    return new (Func->allocate<InstX86Setcc>()) InstX86Setcc(Func, Dest, Cond);
+  }
+  void emit(const Cfg *Func) const override;
+  void emitIAS(const Cfg *Func) const override;
+  void dump(const Cfg *Func) const override;
+  static bool classof(const Inst *Inst) {
+    return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Setcc);
+  }
+
+private:
+  InstX86Setcc(Cfg *Func, Variable *Dest,
+               typename InstX86Base<Machine>::Traits::Cond::BrCond Cond);
+
+  const typename InstX86Base<Machine>::Traits::Cond::BrCond Condition;
+};
+
+/// Exchanging Add instruction.  Exchanges the first operand (destination
+/// operand) with the second operand (source operand), then loads the sum
+/// of the two values into the destination operand. The destination may be
+/// a register or memory, while the source must be a register.
+///
+/// Both the dest and source are updated. The caller should then insert a
+/// FakeDef to reflect the second udpate.
+template <class Machine>
+class InstX86Xadd final : public InstX86BaseLockable<Machine> {
+  InstX86Xadd() = delete;
+  InstX86Xadd(const InstX86Xadd &) = delete;
+  InstX86Xadd &operator=(const InstX86Xadd &) = delete;
+
+public:
+  static InstX86Xadd *create(Cfg *Func, Operand *Dest, Variable *Source,
+                             bool Locked) {
+    return new (Func->allocate<InstX86Xadd>())
+        InstX86Xadd(Func, Dest, Source, Locked);
+  }
+  void emit(const Cfg *Func) const override;
+  void emitIAS(const Cfg *Func) const override;
+  void dump(const Cfg *Func) const override;
+  static bool classof(const Inst *Inst) {
+    return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Xadd);
+  }
+
+private:
+  InstX86Xadd(Cfg *Func, Operand *Dest, Variable *Source, bool Locked);
+};
+
+/// Exchange instruction.  Exchanges the first operand (destination
+/// operand) with the second operand (source operand). At least one of
+/// the operands must be a register (and the other can be reg or mem).
+/// Both the Dest and Source are updated. If there is a memory operand,
+/// then the instruction is automatically "locked" without the need for
+/// a lock prefix.
+template <class Machine> class InstX86Xchg final : public InstX86Base<Machine> {
+  InstX86Xchg() = delete;
+  InstX86Xchg(const InstX86Xchg &) = delete;
+  InstX86Xchg &operator=(const InstX86Xchg &) = delete;
+
+public:
+  static InstX86Xchg *create(Cfg *Func, Operand *Dest, Variable *Source) {
+    return new (Func->allocate<InstX86Xchg>()) InstX86Xchg(Func, Dest, Source);
+  }
+  void emit(const Cfg *Func) const override;
+  void emitIAS(const Cfg *Func) const override;
+  void dump(const Cfg *Func) const override;
+  static bool classof(const Inst *Inst) {
+    return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Xchg);
+  }
+
+private:
+  InstX86Xchg(Cfg *Func, Operand *Dest, Variable *Source);
+};
+
+/// struct Insts is a template that can be used to instantiate all the X86
+/// instructions for a target with a simple
+///
+/// using Insts = ::Ice::X86Internal::Insts<TargeT>;
+template <class Machine> struct Insts {
+  using FakeRMW = InstX86FakeRMW<Machine>;
+  using Label = InstX86Label<Machine>;
+
+  using AdjustStack = InstX86AdjustStack<Machine>;
+  using Call = InstX86Call<Machine>;
+
+  using Br = InstX86Br<Machine>;
+  using Jmp = InstX86Jmp<Machine>;
+  using Bswap = InstX86Bswap<Machine>;
+  using Neg = InstX86Neg<Machine>;
+  using Bsf = InstX86Bsf<Machine>;
+  using Bsr = InstX86Bsr<Machine>;
+  using Lea = InstX86Lea<Machine>;
+  using Cbwdq = InstX86Cbwdq<Machine>;
+  using Movsx = InstX86Movsx<Machine>;
+  using Movzx = InstX86Movzx<Machine>;
+  using Movd = InstX86Movd<Machine>;
+  using Sqrtss = InstX86Sqrtss<Machine>;
+  using Mov = InstX86Mov<Machine>;
+  using Movp = InstX86Movp<Machine>;
+  using Movq = InstX86Movq<Machine>;
+  using Add = InstX86Add<Machine>;
+  using AddRMW = InstX86AddRMW<Machine>;
+  using Addps = InstX86Addps<Machine>;
+  using Adc = InstX86Adc<Machine>;
+  using AdcRMW = InstX86AdcRMW<Machine>;
+  using Addss = InstX86Addss<Machine>;
+  using Padd = InstX86Padd<Machine>;
+  using Sub = InstX86Sub<Machine>;
+  using SubRMW = InstX86SubRMW<Machine>;
+  using Subps = InstX86Subps<Machine>;
+  using Subss = InstX86Subss<Machine>;
+  using Sbb = InstX86Sbb<Machine>;
+  using SbbRMW = InstX86SbbRMW<Machine>;
+  using Psub = InstX86Psub<Machine>;
+  using And = InstX86And<Machine>;
+  using AndRMW = InstX86AndRMW<Machine>;
+  using Pand = InstX86Pand<Machine>;
+  using Pandn = InstX86Pandn<Machine>;
+  using Or = InstX86Or<Machine>;
+  using OrRMW = InstX86OrRMW<Machine>;
+  using Por = InstX86Por<Machine>;
+  using Xor = InstX86Xor<Machine>;
+  using XorRMW = InstX86XorRMW<Machine>;
+  using Pxor = InstX86Pxor<Machine>;
+  using Imul = InstX86Imul<Machine>;
+  using Mulps = InstX86Mulps<Machine>;
+  using Mulss = InstX86Mulss<Machine>;
+  using Pmull = InstX86Pmull<Machine>;
+  using Pmuludq = InstX86Pmuludq<Machine>;
+  using Divps = InstX86Divps<Machine>;
+  using Divss = InstX86Divss<Machine>;
+  using Rol = InstX86Rol<Machine>;
+  using Shl = InstX86Shl<Machine>;
+  using Psll = InstX86Psll<Machine>;
+  using Psrl = InstX86Psrl<Machine>;
+  using Shr = InstX86Shr<Machine>;
+  using Sar = InstX86Sar<Machine>;
+  using Psra = InstX86Psra<Machine>;
+  using Pcmpeq = InstX86Pcmpeq<Machine>;
+  using Pcmpgt = InstX86Pcmpgt<Machine>;
+  using MovssRegs = InstX86MovssRegs<Machine>;
+  using Idiv = InstX86Idiv<Machine>;
+  using Div = InstX86Div<Machine>;
+  using Insertps = InstX86Insertps<Machine>;
+  using Pinsr = InstX86Pinsr<Machine>;
+  using Shufps = InstX86Shufps<Machine>;
+  using Blendvps = InstX86Blendvps<Machine>;
+  using Pblendvb = InstX86Pblendvb<Machine>;
+  using Pextr = InstX86Pextr<Machine>;
+  using Pshufd = InstX86Pshufd<Machine>;
+  using Lockable = InstX86BaseLockable<Machine>;
+  using Mul = InstX86Mul<Machine>;
+  using Shld = InstX86Shld<Machine>;
+  using Shrd = InstX86Shrd<Machine>;
+  using Cmov = InstX86Cmov<Machine>;
+  using Cmpps = InstX86Cmpps<Machine>;
+  using Cmpxchg = InstX86Cmpxchg<Machine>;
+  using Cmpxchg8b = InstX86Cmpxchg8b<Machine>;
+  using Cvt = InstX86Cvt<Machine>;
+  using Icmp = InstX86Icmp<Machine>;
+  using Ucomiss = InstX86Ucomiss<Machine>;
+  using UD2 = InstX86UD2<Machine>;
+  using Test = InstX86Test<Machine>;
+  using Mfence = InstX86Mfence<Machine>;
+  using Store = InstX86Store<Machine>;
+  using StoreP = InstX86StoreP<Machine>;
+  using StoreQ = InstX86StoreQ<Machine>;
+  using Nop = InstX86Nop<Machine>;
+  using Fld = InstX86Fld<Machine>;
+  using Fstp = InstX86Fstp<Machine>;
+  using Pop = InstX86Pop<Machine>;
+  using Push = InstX86Push<Machine>;
+  using Ret = InstX86Ret<Machine>;
+  using Setcc = InstX86Setcc<Machine>;
+  using Xadd = InstX86Xadd<Machine>;
+  using Xchg = InstX86Xchg<Machine>;
+};
+
+/// X86 Instructions have static data (particularly, opcodes and instruction
+/// emitters). Each X86 target needs to define all of these, so this macro is
+/// provided so that, if something changes, then all X86 targets will be updated
+/// automatically.
+#define X86INSTS_DEFINE_STATIC_DATA(Machine)                                   \
+  namespace Ice {                                                              \
+  namespace X86Internal {                                                      \
+  /* In-place ops */                                                           \
+  template <> const char *InstX86Bswap<Machine>::Base::Opcode = "bswap";       \
+  template <> const char *InstX86Neg<Machine>::Base::Opcode = "neg";           \
+  /* Unary ops */                                                              \
+  template <> const char *InstX86Bsf<Machine>::Base::Opcode = "bsf";           \
+  template <> const char *InstX86Bsr<Machine>::Base::Opcode = "bsr";           \
+  template <> const char *InstX86Lea<Machine>::Base::Opcode = "lea";           \
+  template <> const char *InstX86Movd<Machine>::Base::Opcode = "movd";         \
+  template <> const char *InstX86Movsx<Machine>::Base::Opcode = "movs";        \
+  template <> const char *InstX86Movzx<Machine>::Base::Opcode = "movz";        \
+  template <> const char *InstX86Sqrtss<Machine>::Base::Opcode = "sqrtss";     \
+  template <> const char *InstX86Cbwdq<Machine>::Base::Opcode = "cbw/cwd/cdq"; \
+  /* Mov-like ops */                                                           \
+  template <> const char *InstX86Mov<Machine>::Base::Opcode = "mov";           \
+  template <> const char *InstX86Movp<Machine>::Base::Opcode = "movups";       \
+  template <> const char *InstX86Movq<Machine>::Base::Opcode = "movq";         \
+  /* Binary ops */                                                             \
+  template <> const char *InstX86Add<Machine>::Base::Opcode = "add";           \
+  template <> const char *InstX86AddRMW<Machine>::Base::Opcode = "add";        \
+  template <> const char *InstX86Addps<Machine>::Base::Opcode = "addps";       \
+  template <> const char *InstX86Adc<Machine>::Base::Opcode = "adc";           \
+  template <> const char *InstX86AdcRMW<Machine>::Base::Opcode = "adc";        \
+  template <> const char *InstX86Addss<Machine>::Base::Opcode = "addss";       \
+  template <> const char *InstX86Padd<Machine>::Base::Opcode = "padd";         \
+  template <> const char *InstX86Sub<Machine>::Base::Opcode = "sub";           \
+  template <> const char *InstX86SubRMW<Machine>::Base::Opcode = "sub";        \
+  template <> const char *InstX86Subps<Machine>::Base::Opcode = "subps";       \
+  template <> const char *InstX86Subss<Machine>::Base::Opcode = "subss";       \
+  template <> const char *InstX86Sbb<Machine>::Base::Opcode = "sbb";           \
+  template <> const char *InstX86SbbRMW<Machine>::Base::Opcode = "sbb";        \
+  template <> const char *InstX86Psub<Machine>::Base::Opcode = "psub";         \
+  template <> const char *InstX86And<Machine>::Base::Opcode = "and";           \
+  template <> const char *InstX86AndRMW<Machine>::Base::Opcode = "and";        \
+  template <> const char *InstX86Pand<Machine>::Base::Opcode = "pand";         \
+  template <> const char *InstX86Pandn<Machine>::Base::Opcode = "pandn";       \
+  template <> const char *InstX86Or<Machine>::Base::Opcode = "or";             \
+  template <> const char *InstX86OrRMW<Machine>::Base::Opcode = "or";          \
+  template <> const char *InstX86Por<Machine>::Base::Opcode = "por";           \
+  template <> const char *InstX86Xor<Machine>::Base::Opcode = "xor";           \
+  template <> const char *InstX86XorRMW<Machine>::Base::Opcode = "xor";        \
+  template <> const char *InstX86Pxor<Machine>::Base::Opcode = "pxor";         \
+  template <> const char *InstX86Imul<Machine>::Base::Opcode = "imul";         \
+  template <> const char *InstX86Mulps<Machine>::Base::Opcode = "mulps";       \
+  template <> const char *InstX86Mulss<Machine>::Base::Opcode = "mulss";       \
+  template <> const char *InstX86Pmull<Machine>::Base::Opcode = "pmull";       \
+  template <> const char *InstX86Pmuludq<Machine>::Base::Opcode = "pmuludq";   \
+  template <> const char *InstX86Div<Machine>::Base::Opcode = "div";           \
+  template <> const char *InstX86Divps<Machine>::Base::Opcode = "divps";       \
+  template <> const char *InstX86Idiv<Machine>::Base::Opcode = "idiv";         \
+  template <> const char *InstX86Divss<Machine>::Base::Opcode = "divss";       \
+  template <> const char *InstX86Rol<Machine>::Base::Opcode = "rol";           \
+  template <> const char *InstX86Shl<Machine>::Base::Opcode = "shl";           \
+  template <> const char *InstX86Psll<Machine>::Base::Opcode = "psll";         \
+  template <> const char *InstX86Shr<Machine>::Base::Opcode = "shr";           \
+  template <> const char *InstX86Sar<Machine>::Base::Opcode = "sar";           \
+  template <> const char *InstX86Psra<Machine>::Base::Opcode = "psra";         \
+  template <> const char *InstX86Psrl<Machine>::Base::Opcode = "psrl";         \
+  template <> const char *InstX86Pcmpeq<Machine>::Base::Opcode = "pcmpeq";     \
+  template <> const char *InstX86Pcmpgt<Machine>::Base::Opcode = "pcmpgt";     \
+  template <> const char *InstX86MovssRegs<Machine>::Base::Opcode = "movss";   \
+  /* Ternary ops */                                                            \
+  template <> const char *InstX86Insertps<Machine>::Base::Opcode = "insertps"; \
+  template <> const char *InstX86Shufps<Machine>::Base::Opcode = "shufps";     \
+  template <> const char *InstX86Pinsr<Machine>::Base::Opcode = "pinsr";       \
+  template <> const char *InstX86Blendvps<Machine>::Base::Opcode = "blendvps"; \
+  template <> const char *InstX86Pblendvb<Machine>::Base::Opcode = "pblendvb"; \
+  /* Three address ops */                                                      \
+  template <> const char *InstX86Pextr<Machine>::Base::Opcode = "pextr";       \
+  template <> const char *InstX86Pshufd<Machine>::Base::Opcode = "pshufd";     \
+  /* Inplace GPR ops */                                                        \
+  template <>                                                                  \
+  const InstX86Base<Machine>::Traits::Assembler::GPREmitterOneOp               \
+      InstX86Bswap<Machine>::Base::Emitter = {                                 \
+          &InstX86Base<Machine>::Traits::Assembler::bswap,                     \
+          nullptr /* only a reg form exists */                                 \
+  };                                                                           \
+  template <>                                                                  \
+  const InstX86Base<Machine>::Traits::Assembler::GPREmitterOneOp               \
+      InstX86Neg<Machine>::Base::Emitter = {                                   \
+          &InstX86Base<Machine>::Traits::Assembler::neg,                       \
+          &InstX86Base<Machine>::Traits::Assembler::neg};                      \
+                                                                               \
+  /* Unary GPR ops */                                                          \
+  template <> /* uses specialized emitter. */                                  \
+  const InstX86Base<Machine>::Traits::Assembler::GPREmitterRegOp               \
+      InstX86Cbwdq<Machine>::Base::Emitter = {nullptr, nullptr, nullptr};      \
+  template <>                                                                  \
+  const InstX86Base<Machine>::Traits::Assembler::GPREmitterRegOp               \
+      InstX86Bsf<Machine>::Base::Emitter = {                                   \
+          &InstX86Base<Machine>::Traits::Assembler::bsf,                       \
+          &InstX86Base<Machine>::Traits::Assembler::bsf, nullptr};             \
+  template <>                                                                  \
+  const InstX86Base<Machine>::Traits::Assembler::GPREmitterRegOp               \
+      InstX86Bsr<Machine>::Base::Emitter = {                                   \
+          &InstX86Base<Machine>::Traits::Assembler::bsr,                       \
+          &InstX86Base<Machine>::Traits::Assembler::bsr, nullptr};             \
+  template <>                                                                  \
+  const InstX86Base<Machine>::Traits::Assembler::GPREmitterRegOp               \
+      InstX86Lea<Machine>::Base::Emitter = {                                   \
+          /* reg/reg and reg/imm are illegal */ nullptr,                       \
+          &InstX86Base<Machine>::Traits::Assembler::lea, nullptr};             \
+  template <>                                                                  \
+  const InstX86Base<Machine>::Traits::Assembler::GPREmitterRegOp               \
+      InstX86Movsx<Machine>::Base::Emitter = {                                 \
+          &InstX86Base<Machine>::Traits::Assembler::movsx,                     \
+          &InstX86Base<Machine>::Traits::Assembler::movsx, nullptr};           \
+  template <>                                                                  \
+  const InstX86Base<Machine>::Traits::Assembler::GPREmitterRegOp               \
+      InstX86Movzx<Machine>::Base::Emitter = {                                 \
+          &InstX86Base<Machine>::Traits::Assembler::movzx,                     \
+          &InstX86Base<Machine>::Traits::Assembler::movzx, nullptr};           \
+                                                                               \
+  /* Unary XMM ops */                                                          \
+  template <> /* uses specialized emitter. */                                  \
+  const InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp               \
+      InstX86Movd<Machine>::Base::Emitter = {nullptr, nullptr};                \
+  template <>                                                                  \
+  const InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp               \
+      InstX86Sqrtss<Machine>::Base::Emitter = {                                \
+          &InstX86Base<Machine>::Traits::Assembler::sqrtss,                    \
+          &InstX86Base<Machine>::Traits::Assembler::sqrtss};                   \
+                                                                               \
+  /* Binary GPR ops */                                                         \
+  template <> /* uses specialized emitter. */                                  \
+  const InstX86Base<Machine>::Traits::Assembler::GPREmitterRegOp               \
+      InstX86Imul<Machine>::Base::Emitter = {nullptr, nullptr, nullptr};       \
+  template <>                                                                  \
+  const InstX86Base<Machine>::Traits::Assembler::GPREmitterRegOp               \
+      InstX86Add<Machine>::Base::Emitter = {                                   \
+          &InstX86Base<Machine>::Traits::Assembler::add,                       \
+          &InstX86Base<Machine>::Traits::Assembler::add,                       \
+          &InstX86Base<Machine>::Traits::Assembler::add};                      \
+  template <>                                                                  \
+  const InstX86Base<Machine>::Traits::Assembler::GPREmitterAddrOp              \
+      InstX86AddRMW<Machine>::Base::Emitter = {                                \
+          &InstX86Base<Machine>::Traits::Assembler::add,                       \
+          &InstX86Base<Machine>::Traits::Assembler::add};                      \
+  template <>                                                                  \
+  const InstX86Base<Machine>::Traits::Assembler::GPREmitterRegOp               \
+      InstX86Adc<Machine>::Base::Emitter = {                                   \
+          &InstX86Base<Machine>::Traits::Assembler::adc,                       \
+          &InstX86Base<Machine>::Traits::Assembler::adc,                       \
+          &InstX86Base<Machine>::Traits::Assembler::adc};                      \
+  template <>                                                                  \
+  const InstX86Base<Machine>::Traits::Assembler::GPREmitterAddrOp              \
+      InstX86AdcRMW<Machine>::Base::Emitter = {                                \
+          &InstX86Base<Machine>::Traits::Assembler::adc,                       \
+          &InstX86Base<Machine>::Traits::Assembler::adc};                      \
+  template <>                                                                  \
+  const InstX86Base<Machine>::Traits::Assembler::GPREmitterRegOp               \
+      InstX86And<Machine>::Base::Emitter = {                                   \
+          &InstX86Base<Machine>::Traits::Assembler::And,                       \
+          &InstX86Base<Machine>::Traits::Assembler::And,                       \
+          &InstX86Base<Machine>::Traits::Assembler::And};                      \
+  template <>                                                                  \
+  const InstX86Base<Machine>::Traits::Assembler::GPREmitterAddrOp              \
+      InstX86AndRMW<Machine>::Base::Emitter = {                                \
+          &InstX86Base<Machine>::Traits::Assembler::And,                       \
+          &InstX86Base<Machine>::Traits::Assembler::And};                      \
+  template <>                                                                  \
+  const InstX86Base<Machine>::Traits::Assembler::GPREmitterRegOp               \
+      InstX86Or<Machine>::Base::Emitter = {                                    \
+          &InstX86Base<Machine>::Traits::Assembler::Or,                        \
+          &InstX86Base<Machine>::Traits::Assembler::Or,                        \
+          &InstX86Base<Machine>::Traits::Assembler::Or};                       \
+  template <>                                                                  \
+  const InstX86Base<Machine>::Traits::Assembler::GPREmitterAddrOp              \
+      InstX86OrRMW<Machine>::Base::Emitter = {                                 \
+          &InstX86Base<Machine>::Traits::Assembler::Or,                        \
+          &InstX86Base<Machine>::Traits::Assembler::Or};                       \
+  template <>                                                                  \
+  const InstX86Base<Machine>::Traits::Assembler::GPREmitterRegOp               \
+      InstX86Sbb<Machine>::Base::Emitter = {                                   \
+          &InstX86Base<Machine>::Traits::Assembler::sbb,                       \
+          &InstX86Base<Machine>::Traits::Assembler::sbb,                       \
+          &InstX86Base<Machine>::Traits::Assembler::sbb};                      \
+  template <>                                                                  \
+  const InstX86Base<Machine>::Traits::Assembler::GPREmitterAddrOp              \
+      InstX86SbbRMW<Machine>::Base::Emitter = {                                \
+          &InstX86Base<Machine>::Traits::Assembler::sbb,                       \
+          &InstX86Base<Machine>::Traits::Assembler::sbb};                      \
+  template <>                                                                  \
+  const InstX86Base<Machine>::Traits::Assembler::GPREmitterRegOp               \
+      InstX86Sub<Machine>::Base::Emitter = {                                   \
+          &InstX86Base<Machine>::Traits::Assembler::sub,                       \
+          &InstX86Base<Machine>::Traits::Assembler::sub,                       \
+          &InstX86Base<Machine>::Traits::Assembler::sub};                      \
+  template <>                                                                  \
+  const InstX86Base<Machine>::Traits::Assembler::GPREmitterAddrOp              \
+      InstX86SubRMW<Machine>::Base::Emitter = {                                \
+          &InstX86Base<Machine>::Traits::Assembler::sub,                       \
+          &InstX86Base<Machine>::Traits::Assembler::sub};                      \
+  template <>                                                                  \
+  const InstX86Base<Machine>::Traits::Assembler::GPREmitterRegOp               \
+      InstX86Xor<Machine>::Base::Emitter = {                                   \
+          &InstX86Base<Machine>::Traits::Assembler::Xor,                       \
+          &InstX86Base<Machine>::Traits::Assembler::Xor,                       \
+          &InstX86Base<Machine>::Traits::Assembler::Xor};                      \
+  template <>                                                                  \
+  const InstX86Base<Machine>::Traits::Assembler::GPREmitterAddrOp              \
+      InstX86XorRMW<Machine>::Base::Emitter = {                                \
+          &InstX86Base<Machine>::Traits::Assembler::Xor,                       \
+          &InstX86Base<Machine>::Traits::Assembler::Xor};                      \
+                                                                               \
+  /* Binary Shift GPR ops */                                                   \
+  template <>                                                                  \
+  const InstX86Base<Machine>::Traits::Assembler::GPREmitterShiftOp             \
+      InstX86Rol<Machine>::Base::Emitter = {                                   \
+          &InstX86Base<Machine>::Traits::Assembler::rol,                       \
+          &InstX86Base<Machine>::Traits::Assembler::rol};                      \
+  template <>                                                                  \
+  const InstX86Base<Machine>::Traits::Assembler::GPREmitterShiftOp             \
+      InstX86Sar<Machine>::Base::Emitter = {                                   \
+          &InstX86Base<Machine>::Traits::Assembler::sar,                       \
+          &InstX86Base<Machine>::Traits::Assembler::sar};                      \
+  template <>                                                                  \
+  const InstX86Base<Machine>::Traits::Assembler::GPREmitterShiftOp             \
+      InstX86Shl<Machine>::Base::Emitter = {                                   \
+          &InstX86Base<Machine>::Traits::Assembler::shl,                       \
+          &InstX86Base<Machine>::Traits::Assembler::shl};                      \
+  template <>                                                                  \
+  const InstX86Base<Machine>::Traits::Assembler::GPREmitterShiftOp             \
+      InstX86Shr<Machine>::Base::Emitter = {                                   \
+          &InstX86Base<Machine>::Traits::Assembler::shr,                       \
+          &InstX86Base<Machine>::Traits::Assembler::shr};                      \
+                                                                               \
+  /* Binary XMM ops */                                                         \
+  template <> /* uses specialized emitter. */                                  \
+  const InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp               \
+      InstX86MovssRegs<Machine>::Base::Emitter = {nullptr, nullptr};           \
+  template <>                                                                  \
+  const InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp               \
+      InstX86Addss<Machine>::Base::Emitter = {                                 \
+          &InstX86Base<Machine>::Traits::Assembler::addss,                     \
+          &InstX86Base<Machine>::Traits::Assembler::addss};                    \
+  template <>                                                                  \
+  const InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp               \
+      InstX86Addps<Machine>::Base::Emitter = {                                 \
+          &InstX86Base<Machine>::Traits::Assembler::addps,                     \
+          &InstX86Base<Machine>::Traits::Assembler::addps};                    \
+  template <>                                                                  \
+  const InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp               \
+      InstX86Divss<Machine>::Base::Emitter = {                                 \
+          &InstX86Base<Machine>::Traits::Assembler::divss,                     \
+          &InstX86Base<Machine>::Traits::Assembler::divss};                    \
+  template <>                                                                  \
+  const InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp               \
+      InstX86Divps<Machine>::Base::Emitter = {                                 \
+          &InstX86Base<Machine>::Traits::Assembler::divps,                     \
+          &InstX86Base<Machine>::Traits::Assembler::divps};                    \
+  template <>                                                                  \
+  const InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp               \
+      InstX86Mulss<Machine>::Base::Emitter = {                                 \
+          &InstX86Base<Machine>::Traits::Assembler::mulss,                     \
+          &InstX86Base<Machine>::Traits::Assembler::mulss};                    \
+  template <>                                                                  \
+  const InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp               \
+      InstX86Mulps<Machine>::Base::Emitter = {                                 \
+          &InstX86Base<Machine>::Traits::Assembler::mulps,                     \
+          &InstX86Base<Machine>::Traits::Assembler::mulps};                    \
+  template <>                                                                  \
+  const InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp               \
+      InstX86Padd<Machine>::Base::Emitter = {                                  \
+          &InstX86Base<Machine>::Traits::Assembler::padd,                      \
+          &InstX86Base<Machine>::Traits::Assembler::padd};                     \
+  template <>                                                                  \
+  const InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp               \
+      InstX86Pand<Machine>::Base::Emitter = {                                  \
+          &InstX86Base<Machine>::Traits::Assembler::pand,                      \
+          &InstX86Base<Machine>::Traits::Assembler::pand};                     \
+  template <>                                                                  \
+  const InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp               \
+      InstX86Pandn<Machine>::Base::Emitter = {                                 \
+          &InstX86Base<Machine>::Traits::Assembler::pandn,                     \
+          &InstX86Base<Machine>::Traits::Assembler::pandn};                    \
+  template <>                                                                  \
+  const InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp               \
+      InstX86Pcmpeq<Machine>::Base::Emitter = {                                \
+          &InstX86Base<Machine>::Traits::Assembler::pcmpeq,                    \
+          &InstX86Base<Machine>::Traits::Assembler::pcmpeq};                   \
+  template <>                                                                  \
+  const InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp               \
+      InstX86Pcmpgt<Machine>::Base::Emitter = {                                \
+          &InstX86Base<Machine>::Traits::Assembler::pcmpgt,                    \
+          &InstX86Base<Machine>::Traits::Assembler::pcmpgt};                   \
+  template <>                                                                  \
+  const InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp               \
+      InstX86Pmull<Machine>::Base::Emitter = {                                 \
+          &InstX86Base<Machine>::Traits::Assembler::pmull,                     \
+          &InstX86Base<Machine>::Traits::Assembler::pmull};                    \
+  template <>                                                                  \
+  const InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp               \
+      InstX86Pmuludq<Machine>::Base::Emitter = {                               \
+          &InstX86Base<Machine>::Traits::Assembler::pmuludq,                   \
+          &InstX86Base<Machine>::Traits::Assembler::pmuludq};                  \
+  template <>                                                                  \
+  const InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp               \
+      InstX86Por<Machine>::Base::Emitter = {                                   \
+          &InstX86Base<Machine>::Traits::Assembler::por,                       \
+          &InstX86Base<Machine>::Traits::Assembler::por};                      \
+  template <>                                                                  \
+  const InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp               \
+      InstX86Psub<Machine>::Base::Emitter = {                                  \
+          &InstX86Base<Machine>::Traits::Assembler::psub,                      \
+          &InstX86Base<Machine>::Traits::Assembler::psub};                     \
+  template <>                                                                  \
+  const InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp               \
+      InstX86Pxor<Machine>::Base::Emitter = {                                  \
+          &InstX86Base<Machine>::Traits::Assembler::pxor,                      \
+          &InstX86Base<Machine>::Traits::Assembler::pxor};                     \
+  template <>                                                                  \
+  const InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp               \
+      InstX86Subss<Machine>::Base::Emitter = {                                 \
+          &InstX86Base<Machine>::Traits::Assembler::subss,                     \
+          &InstX86Base<Machine>::Traits::Assembler::subss};                    \
+  template <>                                                                  \
+  const InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp               \
+      InstX86Subps<Machine>::Base::Emitter = {                                 \
+          &InstX86Base<Machine>::Traits::Assembler::subps,                     \
+          &InstX86Base<Machine>::Traits::Assembler::subps};                    \
+                                                                               \
+  /* Binary XMM Shift ops */                                                   \
+  template <>                                                                  \
+  const InstX86Base<Machine>::Traits::Assembler::XmmEmitterShiftOp             \
+      InstX86Psll<Machine>::Base::Emitter = {                                  \
+          &InstX86Base<Machine>::Traits::Assembler::psll,                      \
+          &InstX86Base<Machine>::Traits::Assembler::psll,                      \
+          &InstX86Base<Machine>::Traits::Assembler::psll};                     \
+  template <>                                                                  \
+  const InstX86Base<Machine>::Traits::Assembler::XmmEmitterShiftOp             \
+      InstX86Psra<Machine>::Base::Emitter = {                                  \
+          &InstX86Base<Machine>::Traits::Assembler::psra,                      \
+          &InstX86Base<Machine>::Traits::Assembler::psra,                      \
+          &InstX86Base<Machine>::Traits::Assembler::psra};                     \
+  template <>                                                                  \
+  const InstX86Base<Machine>::Traits::Assembler::XmmEmitterShiftOp             \
+      InstX86Psrl<Machine>::Base::Emitter = {                                  \
+          &InstX86Base<Machine>::Traits::Assembler::psrl,                      \
+          &InstX86Base<Machine>::Traits::Assembler::psrl,                      \
+          &InstX86Base<Machine>::Traits::Assembler::psrl};                     \
+  }                                                                            \
+  }
+
+} // end of namespace X86Internal
+} // end of namespace Ice
+
+#include "IceInstX86BaseImpl.h"
+
+#endif // SUBZERO_SRC_ICEINSTX86BASE_H
diff --git a/src/IceInstX86BaseImpl.h b/src/IceInstX86BaseImpl.h
new file mode 100644
index 0000000..2d9ee0f
--- /dev/null
+++ b/src/IceInstX86BaseImpl.h
@@ -0,0 +1,3162 @@
+//===- subzero/src/IceInstX86BaseImpl.h - Generic X86 instructions -*- C++ -*=//
+//
+//                        The Subzero Code Generator
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file implements the InstX86Base class and its descendants.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef SUBZERO_SRC_ICEINSTX86BASEIMPL_H
+#define SUBZERO_SRC_ICEINSTX86BASEIMPL_H
+
+#include "IceInstX86Base.h"
+
+#include "IceAssemblerX86Base.h"
+#include "IceCfg.h"
+#include "IceCfgNode.h"
+#include "IceDefs.h"
+#include "IceInst.h"
+#include "IceOperand.h"
+#include "IceTargetLowering.h"
+
+namespace Ice {
+
+namespace X86Internal {
+
+template <class Machine>
+const char *InstX86Base<Machine>::getWidthString(Type Ty) {
+  return Traits::TypeAttributes[Ty].WidthString;
+}
+
+template <class Machine>
+const char *InstX86Base<Machine>::getFldString(Type Ty) {
+  return Traits::TypeAttributes[Ty].FldString;
+}
+
+template <class Machine>
+typename InstX86Base<Machine>::Traits::Cond::BrCond
+InstX86Base<Machine>::getOppositeCondition(typename Traits::Cond::BrCond Cond) {
+  return Traits::InstBrAttributes[Cond].Opposite;
+}
+
+template <class Machine>
+InstX86FakeRMW<Machine>::InstX86FakeRMW(Cfg *Func, Operand *Data, Operand *Addr,
+                                        InstArithmetic::OpKind Op,
+                                        Variable *Beacon)
+    : InstX86Base<Machine>(Func, InstX86Base<Machine>::FakeRMW, 3, nullptr),
+      Op(Op) {
+  this->addSource(Data);
+  this->addSource(Addr);
+  this->addSource(Beacon);
+}
+
+template <class Machine>
+InstX86AdjustStack<Machine>::InstX86AdjustStack(Cfg *Func, SizeT Amount,
+                                                Variable *Esp)
+    : InstX86Base<Machine>(Func, InstX86Base<Machine>::Adjuststack, 1, Esp),
+      Amount(Amount) {
+  this->addSource(Esp);
+}
+
+template <class Machine>
+InstX86Mul<Machine>::InstX86Mul(Cfg *Func, Variable *Dest, Variable *Source1,
+                                Operand *Source2)
+    : InstX86Base<Machine>(Func, InstX86Base<Machine>::Mul, 2, Dest) {
+  this->addSource(Source1);
+  this->addSource(Source2);
+}
+
+template <class Machine>
+InstX86Shld<Machine>::InstX86Shld(Cfg *Func, Variable *Dest, Variable *Source1,
+                                  Variable *Source2)
+    : InstX86Base<Machine>(Func, InstX86Base<Machine>::Shld, 3, Dest) {
+  this->addSource(Dest);
+  this->addSource(Source1);
+  this->addSource(Source2);
+}
+
+template <class Machine>
+InstX86Shrd<Machine>::InstX86Shrd(Cfg *Func, Variable *Dest, Variable *Source1,
+                                  Variable *Source2)
+    : InstX86Base<Machine>(Func, InstX86Base<Machine>::Shrd, 3, Dest) {
+  this->addSource(Dest);
+  this->addSource(Source1);
+  this->addSource(Source2);
+}
+
+template <class Machine>
+InstX86Label<Machine>::InstX86Label(
+    Cfg *Func, typename InstX86Base<Machine>::Traits::TargetLowering *Target)
+    : InstX86Base<Machine>(Func, InstX86Base<Machine>::Label, 0, nullptr),
+      Number(Target->makeNextLabelNumber()) {}
+
+template <class Machine>
+IceString InstX86Label<Machine>::getName(const Cfg *Func) const {
+  return ".L" + Func->getFunctionName() + "$local$__" + std::to_string(Number);
+}
+
+template <class Machine>
+InstX86Br<Machine>::InstX86Br(
+    Cfg *Func, const CfgNode *TargetTrue, const CfgNode *TargetFalse,
+    const InstX86Label<Machine> *Label,
+    typename InstX86Base<Machine>::Traits::Cond::BrCond Condition)
+    : InstX86Base<Machine>(Func, InstX86Base<Machine>::Br, 0, nullptr),
+      Condition(Condition), TargetTrue(TargetTrue), TargetFalse(TargetFalse),
+      Label(Label) {}
+
+template <class Machine>
+bool InstX86Br<Machine>::optimizeBranch(const CfgNode *NextNode) {
+  // If there is no next block, then there can be no fallthrough to
+  // optimize.
+  if (NextNode == nullptr)
+    return false;
+  // Intra-block conditional branches can't be optimized.
+  if (Label)
+    return false;
+  // If there is no fallthrough node, such as a non-default case label
+  // for a switch instruction, then there is no opportunity to
+  // optimize.
+  if (getTargetFalse() == nullptr)
+    return false;
+
+  // Unconditional branch to the next node can be removed.
+  if (Condition == InstX86Base<Machine>::Traits::Cond::Br_None &&
+      getTargetFalse() == NextNode) {
+    assert(getTargetTrue() == nullptr);
+    this->setDeleted();
+    return true;
+  }
+  // If the fallthrough is to the next node, set fallthrough to nullptr
+  // to indicate.
+  if (getTargetFalse() == NextNode) {
+    TargetFalse = nullptr;
+    return true;
+  }
+  // If TargetTrue is the next node, and TargetFalse is not nullptr
+  // (which was already tested above), then invert the branch
+  // condition, swap the targets, and set new fallthrough to nullptr.
+  if (getTargetTrue() == NextNode) {
+    assert(Condition != InstX86Base<Machine>::Traits::Cond::Br_None);
+    Condition = this->getOppositeCondition(Condition);
+    TargetTrue = getTargetFalse();
+    TargetFalse = nullptr;
+    return true;
+  }
+  return false;
+}
+
+template <class Machine>
+bool InstX86Br<Machine>::repointEdge(CfgNode *OldNode, CfgNode *NewNode) {
+  if (TargetFalse == OldNode) {
+    TargetFalse = NewNode;
+    return true;
+  } else if (TargetTrue == OldNode) {
+    TargetTrue = NewNode;
+    return true;
+  }
+  return false;
+}
+
+template <class Machine>
+InstX86Jmp<Machine>::InstX86Jmp(Cfg *Func, Operand *Target)
+    : InstX86Base<Machine>(Func, InstX86Base<Machine>::Jmp, 1, nullptr) {
+  this->addSource(Target);
+}
+
+template <class Machine>
+InstX86Call<Machine>::InstX86Call(Cfg *Func, Variable *Dest,
+                                  Operand *CallTarget)
+    : InstX86Base<Machine>(Func, InstX86Base<Machine>::Call, 1, Dest) {
+  this->HasSideEffects = true;
+  this->addSource(CallTarget);
+}
+
+template <class Machine>
+InstX86Cmov<Machine>::InstX86Cmov(
+    Cfg *Func, Variable *Dest, Operand *Source,
+    typename InstX86Base<Machine>::Traits::Cond::BrCond Condition)
+    : InstX86Base<Machine>(Func, InstX86Base<Machine>::Cmov, 2, Dest),
+      Condition(Condition) {
+  // The final result is either the original Dest, or Source, so mark
+  // both as sources.
+  this->addSource(Dest);
+  this->addSource(Source);
+}
+
+template <class Machine>
+InstX86Cmpps<Machine>::InstX86Cmpps(
+    Cfg *Func, Variable *Dest, Operand *Source,
+    typename InstX86Base<Machine>::Traits::Cond::CmppsCond Condition)
+    : InstX86Base<Machine>(Func, InstX86Base<Machine>::Cmpps, 2, Dest),
+      Condition(Condition) {
+  this->addSource(Dest);
+  this->addSource(Source);
+}
+
+template <class Machine>
+InstX86Cmpxchg<Machine>::InstX86Cmpxchg(Cfg *Func, Operand *DestOrAddr,
+                                        Variable *Eax, Variable *Desired,
+                                        bool Locked)
+    : InstX86BaseLockable<Machine>(Func, InstX86Base<Machine>::Cmpxchg, 3,
+                                   llvm::dyn_cast<Variable>(DestOrAddr),
+                                   Locked) {
+  assert(Eax->getRegNum() ==
+         InstX86Base<Machine>::Traits::RegisterSet::Reg_eax);
+  this->addSource(DestOrAddr);
+  this->addSource(Eax);
+  this->addSource(Desired);
+}
+
+template <class Machine>
+InstX86Cmpxchg8b<Machine>::InstX86Cmpxchg8b(
+    Cfg *Func, typename InstX86Base<Machine>::Traits::X86OperandMem *Addr,
+    Variable *Edx, Variable *Eax, Variable *Ecx, Variable *Ebx, bool Locked)
+    : InstX86BaseLockable<Machine>(Func, InstX86Base<Machine>::Cmpxchg, 5,
+                                   nullptr, Locked) {
+  assert(Edx->getRegNum() ==
+         InstX86Base<Machine>::Traits::RegisterSet::Reg_edx);
+  assert(Eax->getRegNum() ==
+         InstX86Base<Machine>::Traits::RegisterSet::Reg_eax);
+  assert(Ecx->getRegNum() ==
+         InstX86Base<Machine>::Traits::RegisterSet::Reg_ecx);
+  assert(Ebx->getRegNum() ==
+         InstX86Base<Machine>::Traits::RegisterSet::Reg_ebx);
+  this->addSource(Addr);
+  this->addSource(Edx);
+  this->addSource(Eax);
+  this->addSource(Ecx);
+  this->addSource(Ebx);
+}
+
+template <class Machine>
+InstX86Cvt<Machine>::InstX86Cvt(Cfg *Func, Variable *Dest, Operand *Source,
+                                CvtVariant Variant)
+    : InstX86Base<Machine>(Func, InstX86Base<Machine>::Cvt, 1, Dest),
+      Variant(Variant) {
+  this->addSource(Source);
+}
+
+template <class Machine>
+InstX86Icmp<Machine>::InstX86Icmp(Cfg *Func, Operand *Src0, Operand *Src1)
+    : InstX86Base<Machine>(Func, InstX86Base<Machine>::Icmp, 2, nullptr) {
+  this->addSource(Src0);
+  this->addSource(Src1);
+}
+
+template <class Machine>
+InstX86Ucomiss<Machine>::InstX86Ucomiss(Cfg *Func, Operand *Src0, Operand *Src1)
+    : InstX86Base<Machine>(Func, InstX86Base<Machine>::Ucomiss, 2, nullptr) {
+  this->addSource(Src0);
+  this->addSource(Src1);
+}
+
+template <class Machine>
+InstX86UD2<Machine>::InstX86UD2(Cfg *Func)
+    : InstX86Base<Machine>(Func, InstX86Base<Machine>::UD2, 0, nullptr) {}
+
+template <class Machine>
+InstX86Test<Machine>::InstX86Test(Cfg *Func, Operand *Src1, Operand *Src2)
+    : InstX86Base<Machine>(Func, InstX86Base<Machine>::Test, 2, nullptr) {
+  this->addSource(Src1);
+  this->addSource(Src2);
+}
+
+template <class Machine>
+InstX86Mfence<Machine>::InstX86Mfence(Cfg *Func)
+    : InstX86Base<Machine>(Func, InstX86Base<Machine>::Mfence, 0, nullptr) {
+  this->HasSideEffects = true;
+}
+
+template <class Machine>
+InstX86Store<Machine>::InstX86Store(
+    Cfg *Func, Operand *Value,
+    typename InstX86Base<Machine>::Traits::X86Operand *Mem)
+    : InstX86Base<Machine>(Func, InstX86Base<Machine>::Store, 2, nullptr) {
+  this->addSource(Value);
+  this->addSource(Mem);
+}
+
+template <class Machine>
+InstX86StoreP<Machine>::InstX86StoreP(
+    Cfg *Func, Variable *Value,
+    typename InstX86Base<Machine>::Traits::X86OperandMem *Mem)
+    : InstX86Base<Machine>(Func, InstX86Base<Machine>::StoreP, 2, nullptr) {
+  this->addSource(Value);
+  this->addSource(Mem);
+}
+
+template <class Machine>
+InstX86StoreQ<Machine>::InstX86StoreQ(
+    Cfg *Func, Variable *Value,
+    typename InstX86Base<Machine>::Traits::X86OperandMem *Mem)
+    : InstX86Base<Machine>(Func, InstX86Base<Machine>::StoreQ, 2, nullptr) {
+  this->addSource(Value);
+  this->addSource(Mem);
+}
+
+template <class Machine>
+InstX86Nop<Machine>::InstX86Nop(Cfg *Func, InstX86Nop::NopVariant Variant)
+    : InstX86Base<Machine>(Func, InstX86Base<Machine>::Nop, 0, nullptr),
+      Variant(Variant) {}
+
+template <class Machine>
+InstX86Fld<Machine>::InstX86Fld(Cfg *Func, Operand *Src)
+    : InstX86Base<Machine>(Func, InstX86Base<Machine>::Fld, 1, nullptr) {
+  this->addSource(Src);
+}
+
+template <class Machine>
+InstX86Fstp<Machine>::InstX86Fstp(Cfg *Func, Variable *Dest)
+    : InstX86Base<Machine>(Func, InstX86Base<Machine>::Fstp, 0, Dest) {}
+
+template <class Machine>
+InstX86Pop<Machine>::InstX86Pop(Cfg *Func, Variable *Dest)
+    : InstX86Base<Machine>(Func, InstX86Base<Machine>::Pop, 0, Dest) {
+  // A pop instruction affects the stack pointer and so it should not
+  // be allowed to be automatically dead-code eliminated.  (The
+  // corresponding push instruction doesn't need this treatment
+  // because it has no dest variable and therefore won't be dead-code
+  // eliminated.)  This is needed for late-stage liveness analysis
+  // (e.g. asm-verbose mode).
+  this->HasSideEffects = true;
+}
+
+template <class Machine>
+InstX86Push<Machine>::InstX86Push(Cfg *Func, Variable *Source)
+    : InstX86Base<Machine>(Func, InstX86Base<Machine>::Push, 1, nullptr) {
+  this->addSource(Source);
+}
+
+template <class Machine>
+InstX86Ret<Machine>::InstX86Ret(Cfg *Func, Variable *Source)
+    : InstX86Base<Machine>(Func, InstX86Base<Machine>::Ret, Source ? 1 : 0,
+                           nullptr) {
+  if (Source)
+    this->addSource(Source);
+}
+
+template <class Machine>
+InstX86Setcc<Machine>::InstX86Setcc(
+    Cfg *Func, Variable *Dest,
+    typename InstX86Base<Machine>::Traits::Cond::BrCond Cond)
+    : InstX86Base<Machine>(Func, InstX86Base<Machine>::Setcc, 0, Dest),
+      Condition(Cond) {}
+
+template <class Machine>
+InstX86Xadd<Machine>::InstX86Xadd(Cfg *Func, Operand *Dest, Variable *Source,
+                                  bool Locked)
+    : InstX86BaseLockable<Machine>(Func, InstX86Base<Machine>::Xadd, 2,
+                                   llvm::dyn_cast<Variable>(Dest), Locked) {
+  this->addSource(Dest);
+  this->addSource(Source);
+}
+
+template <class Machine>
+InstX86Xchg<Machine>::InstX86Xchg(Cfg *Func, Operand *Dest, Variable *Source)
+    : InstX86Base<Machine>(Func, InstX86Base<Machine>::Xchg, 2,
+                           llvm::dyn_cast<Variable>(Dest)) {
+  this->addSource(Dest);
+  this->addSource(Source);
+}
+
+// ======================== Dump routines ======================== //
+
+template <class Machine>
+void InstX86Base<Machine>::dump(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrDump();
+  Str << "[" << Traits::TargetName << "] ";
+  Inst::dump(Func);
+}
+
+template <class Machine>
+void InstX86FakeRMW<Machine>::dump(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrDump();
+  Type Ty = getData()->getType();
+  Str << "rmw " << InstArithmetic::getOpName(getOp()) << " " << Ty << " *";
+  getAddr()->dump(Func);
+  Str << ", ";
+  getData()->dump(Func);
+  Str << ", beacon=";
+  getBeacon()->dump(Func);
+}
+
+template <class Machine>
+void InstX86Label<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrEmit();
+  Str << getName(Func) << ":";
+}
+
+template <class Machine>
+void InstX86Label<Machine>::emitIAS(const Cfg *Func) const {
+  typename InstX86Base<Machine>::Traits::Assembler *Asm =
+      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
+  Asm->BindLocalLabel(Number);
+}
+
+template <class Machine>
+void InstX86Label<Machine>::dump(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrDump();
+  Str << getName(Func) << ":";
+}
+
+template <class Machine> void InstX86Br<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrEmit();
+  Str << "\t";
+
+  if (Condition == InstX86Base<Machine>::Traits::Cond::Br_None) {
+    Str << "jmp";
+  } else {
+    Str << InstX86Base<Machine>::Traits::InstBrAttributes[Condition].EmitString;
+  }
+
+  if (Label) {
+    Str << "\t" << Label->getName(Func);
+  } else {
+    if (Condition == InstX86Base<Machine>::Traits::Cond::Br_None) {
+      Str << "\t" << getTargetFalse()->getAsmName();
+    } else {
+      Str << "\t" << getTargetTrue()->getAsmName();
+      if (getTargetFalse()) {
+        Str << "\n\tjmp\t" << getTargetFalse()->getAsmName();
+      }
+    }
+  }
+}
+
+template <class Machine>
+void InstX86Br<Machine>::emitIAS(const Cfg *Func) const {
+  typename InstX86Base<Machine>::Traits::Assembler *Asm =
+      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
+  if (Label) {
+    class Label *L = Asm->GetOrCreateLocalLabel(Label->getNumber());
+    // In all these cases, local Labels should only be used for Near.
+    const bool Near = true;
+    if (Condition == InstX86Base<Machine>::Traits::Cond::Br_None) {
+      Asm->jmp(L, Near);
+    } else {
+      Asm->j(Condition, L, Near);
+    }
+  } else {
+    // Pessimistically assume it's far. This only affects Labels that
+    // are not Bound.
+    const bool Near = false;
+    if (Condition == InstX86Base<Machine>::Traits::Cond::Br_None) {
+      class Label *L =
+          Asm->GetOrCreateCfgNodeLabel(getTargetFalse()->getIndex());
+      assert(!getTargetTrue());
+      Asm->jmp(L, Near);
+    } else {
+      class Label *L =
+          Asm->GetOrCreateCfgNodeLabel(getTargetTrue()->getIndex());
+      Asm->j(Condition, L, Near);
+      if (getTargetFalse()) {
+        class Label *L2 =
+            Asm->GetOrCreateCfgNodeLabel(getTargetFalse()->getIndex());
+        Asm->jmp(L2, Near);
+      }
+    }
+  }
+}
+
+template <class Machine> void InstX86Br<Machine>::dump(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrDump();
+  Str << "br ";
+
+  if (Condition == InstX86Base<Machine>::Traits::Cond::Br_None) {
+    Str << "label %"
+        << (Label ? Label->getName(Func) : getTargetFalse()->getName());
+    return;
+  }
+
+  Str << InstX86Base<Machine>::Traits::InstBrAttributes[Condition]
+             .DisplayString;
+  if (Label) {
+    Str << ", label %" << Label->getName(Func);
+  } else {
+    Str << ", label %" << getTargetTrue()->getName();
+    if (getTargetFalse()) {
+      Str << ", label %" << getTargetFalse()->getName();
+    }
+  }
+}
+
+template <class Machine> void InstX86Jmp<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrEmit();
+  assert(this->getSrcSize() == 1);
+  Str << "\tjmp\t*";
+  getJmpTarget()->emit(Func);
+}
+
+template <class Machine>
+void InstX86Jmp<Machine>::emitIAS(const Cfg *Func) const {
+  // Note: Adapted (mostly copied) from InstX86Call<Machine>::emitIAS().
+  typename InstX86Base<Machine>::Traits::Assembler *Asm =
+      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
+  Operand *Target = getJmpTarget();
+  if (const auto Var = llvm::dyn_cast<Variable>(Target)) {
+    if (Var->hasReg()) {
+      Asm->jmp(InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
+          Var->getRegNum()));
+    } else {
+      // The jmp instruction with a memory operand should be possible
+      // to encode, but it isn't a valid sandboxed instruction, and
+      // there shouldn't be a register allocation issue to jump
+      // through a scratch register, so we don't really need to bother
+      // implementing it.
+      llvm::report_fatal_error("Assembler can't jmp to memory operand");
+    }
+  } else if (const auto Mem = llvm::dyn_cast<
+                 typename InstX86Base<Machine>::Traits::X86OperandMem>(
+                 Target)) {
+    (void)Mem;
+    assert(Mem->getSegmentRegister() ==
+           InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment);
+    llvm::report_fatal_error("Assembler can't jmp to memory operand");
+  } else if (const auto CR = llvm::dyn_cast<ConstantRelocatable>(Target)) {
+    assert(CR->getOffset() == 0 && "We only support jumping to a function");
+    Asm->jmp(CR);
+  } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Target)) {
+    // NaCl trampoline calls refer to an address within the sandbox directly.
+    // This is usually only needed for non-IRT builds and otherwise not
+    // very portable or stable. Usually this is only done for "calls"
+    // and not jumps.
+    // TODO(jvoung): Support this when there is a lowering that
+    // actually triggers this case.
+    (void)Imm;
+    llvm::report_fatal_error("Unexpected jmp to absolute address");
+  } else {
+    llvm::report_fatal_error("Unexpected operand type");
+  }
+}
+
+template <class Machine> void InstX86Jmp<Machine>::dump(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrDump();
+  Str << "jmp ";
+  getJmpTarget()->dump(Func);
+}
+
+template <class Machine>
+void InstX86Call<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrEmit();
+  assert(this->getSrcSize() == 1);
+  Str << "\tcall\t";
+  if (const auto CI = llvm::dyn_cast<ConstantInteger32>(getCallTarget())) {
+    // Emit without a leading '$'.
+    Str << CI->getValue();
+  } else if (const auto CallTarget =
+                 llvm::dyn_cast<ConstantRelocatable>(getCallTarget())) {
+    CallTarget->emitWithoutPrefix(Func->getTarget());
+  } else {
+    Str << "*";
+    getCallTarget()->emit(Func);
+  }
+  Func->getTarget()->resetStackAdjustment();
+}
+
+template <class Machine>
+void InstX86Call<Machine>::emitIAS(const Cfg *Func) const {
+  typename InstX86Base<Machine>::Traits::Assembler *Asm =
+      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
+  Operand *Target = getCallTarget();
+  if (const auto Var = llvm::dyn_cast<Variable>(Target)) {
+    if (Var->hasReg()) {
+      Asm->call(InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
+          Var->getRegNum()));
+    } else {
+      Asm->call(
+          static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
+              Func->getTarget())
+              ->stackVarToAsmOperand(Var));
+    }
+  } else if (const auto Mem = llvm::dyn_cast<
+                 typename InstX86Base<Machine>::Traits::X86OperandMem>(
+                 Target)) {
+    assert(Mem->getSegmentRegister() ==
+           InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment);
+    Asm->call(Mem->toAsmAddress(Asm));
+  } else if (const auto CR = llvm::dyn_cast<ConstantRelocatable>(Target)) {
+    assert(CR->getOffset() == 0 && "We only support calling a function");
+    Asm->call(CR);
+  } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Target)) {
+    Asm->call(Immediate(Imm->getValue()));
+  } else {
+    llvm_unreachable("Unexpected operand type");
+  }
+  Func->getTarget()->resetStackAdjustment();
+}
+
+template <class Machine>
+void InstX86Call<Machine>::dump(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrDump();
+  if (this->getDest()) {
+    this->dumpDest(Func);
+    Str << " = ";
+  }
+  Str << "call ";
+  getCallTarget()->dump(Func);
+}
+
+// The ShiftHack parameter is used to emit "cl" instead of "ecx" for
+// shift instructions, in order to be syntactically valid.  The
+// this->Opcode parameter needs to be char* and not IceString because of
+// template issues.
+template <class Machine>
+void InstX86Base<Machine>::emitTwoAddress(const char *Opcode, const Inst *Inst,
+                                          const Cfg *Func, bool ShiftHack) {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrEmit();
+  assert(Inst->getSrcSize() == 2);
+  Operand *Dest = Inst->getDest();
+  if (Dest == nullptr)
+    Dest = Inst->getSrc(0);
+  assert(Dest == Inst->getSrc(0));
+  Operand *Src1 = Inst->getSrc(1);
+  Str << "\t" << Opcode << InstX86Base<Machine>::getWidthString(Dest->getType())
+      << "\t";
+  const auto ShiftReg = llvm::dyn_cast<Variable>(Src1);
+  if (ShiftHack && ShiftReg &&
+      ShiftReg->getRegNum() ==
+          InstX86Base<Machine>::Traits::RegisterSet::Reg_ecx)
+    Str << "%cl";
+  else
+    Src1->emit(Func);
+  Str << ", ";
+  Dest->emit(Func);
+}
+
+template <class Machine>
+void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Op,
+                    const typename InstX86Base<
+                        Machine>::Traits::Assembler::GPREmitterOneOp &Emitter) {
+  typename InstX86Base<Machine>::Traits::Assembler *Asm =
+      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
+  if (const auto Var = llvm::dyn_cast<Variable>(Op)) {
+    if (Var->hasReg()) {
+      // We cheat a little and use GPRRegister even for byte operations.
+      typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister VarReg =
+          InstX86Base<Machine>::Traits::RegisterSet::getEncodedByteRegOrGPR(
+              Ty, Var->getRegNum());
+      (Asm->*(Emitter.Reg))(Ty, VarReg);
+    } else {
+      typename InstX86Base<Machine>::Traits::Address StackAddr(
+          static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
+              Func->getTarget())
+              ->stackVarToAsmOperand(Var));
+      (Asm->*(Emitter.Addr))(Ty, StackAddr);
+    }
+  } else if (const auto Mem = llvm::dyn_cast<
+                 typename InstX86Base<Machine>::Traits::X86OperandMem>(Op)) {
+    Mem->emitSegmentOverride(Asm);
+    (Asm->*(Emitter.Addr))(Ty, Mem->toAsmAddress(Asm));
+  } else {
+    llvm_unreachable("Unexpected operand type");
+  }
+}
+
+template <class Machine, bool VarCanBeByte, bool SrcCanBeByte>
+void emitIASRegOpTyGPR(
+    const Cfg *Func, Type Ty, const Variable *Var, const Operand *Src,
+    const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterRegOp
+        &Emitter) {
+  typename InstX86Base<Machine>::Traits::Assembler *Asm =
+      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
+  assert(Var->hasReg());
+  // We cheat a little and use GPRRegister even for byte operations.
+  typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister VarReg =
+      VarCanBeByte
+          ? InstX86Base<Machine>::Traits::RegisterSet::getEncodedByteRegOrGPR(
+                Ty, Var->getRegNum())
+          : InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
+                Var->getRegNum());
+  if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) {
+    if (SrcVar->hasReg()) {
+      typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister SrcReg =
+          SrcCanBeByte
+              ? InstX86Base<Machine>::Traits::RegisterSet::
+                    getEncodedByteRegOrGPR(Ty, SrcVar->getRegNum())
+              : InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
+                    SrcVar->getRegNum());
+      (Asm->*(Emitter.GPRGPR))(Ty, VarReg, SrcReg);
+    } else {
+      typename InstX86Base<Machine>::Traits::Address SrcStackAddr =
+          static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
+              Func->getTarget())
+              ->stackVarToAsmOperand(SrcVar);
+      (Asm->*(Emitter.GPRAddr))(Ty, VarReg, SrcStackAddr);
+    }
+  } else if (const auto Mem = llvm::dyn_cast<
+                 typename InstX86Base<Machine>::Traits::X86OperandMem>(Src)) {
+    Mem->emitSegmentOverride(Asm);
+    (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Mem->toAsmAddress(Asm));
+  } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) {
+    (Asm->*(Emitter.GPRImm))(Ty, VarReg, Immediate(Imm->getValue()));
+  } else if (const auto Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) {
+    AssemblerFixup *Fixup = Asm->createFixup(llvm::ELF::R_386_32, Reloc);
+    (Asm->*(Emitter.GPRImm))(Ty, VarReg, Immediate(Reloc->getOffset(), Fixup));
+  } else if (const auto Split = llvm::dyn_cast<
+                 typename InstX86Base<Machine>::Traits::VariableSplit>(Src)) {
+    (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Split->toAsmAddress(Func));
+  } else {
+    llvm_unreachable("Unexpected operand type");
+  }
+}
+
+template <class Machine>
+void emitIASAddrOpTyGPR(
+    const Cfg *Func, Type Ty,
+    const typename InstX86Base<Machine>::Traits::Address &Addr,
+    const Operand *Src,
+    const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterAddrOp
+        &Emitter) {
+  typename InstX86Base<Machine>::Traits::Assembler *Asm =
+      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
+  // Src can only be Reg or Immediate.
+  if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) {
+    assert(SrcVar->hasReg());
+    typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister SrcReg =
+        InstX86Base<Machine>::Traits::RegisterSet::getEncodedByteRegOrGPR(
+            Ty, SrcVar->getRegNum());
+    (Asm->*(Emitter.AddrGPR))(Ty, Addr, SrcReg);
+  } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) {
+    (Asm->*(Emitter.AddrImm))(Ty, Addr, Immediate(Imm->getValue()));
+  } else if (const auto Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) {
+    AssemblerFixup *Fixup = Asm->createFixup(llvm::ELF::R_386_32, Reloc);
+    (Asm->*(Emitter.AddrImm))(Ty, Addr, Immediate(Reloc->getOffset(), Fixup));
+  } else {
+    llvm_unreachable("Unexpected operand type");
+  }
+}
+
+template <class Machine>
+void emitIASAsAddrOpTyGPR(
+    const Cfg *Func, Type Ty, const Operand *Op0, const Operand *Op1,
+    const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterAddrOp
+        &Emitter) {
+  if (const auto Op0Var = llvm::dyn_cast<Variable>(Op0)) {
+    assert(!Op0Var->hasReg());
+    typename InstX86Base<Machine>::Traits::Address StackAddr(
+        static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
+            Func->getTarget())
+            ->stackVarToAsmOperand(Op0Var));
+    emitIASAddrOpTyGPR<Machine>(Func, Ty, StackAddr, Op1, Emitter);
+  } else if (const auto Op0Mem = llvm::dyn_cast<
+                 typename InstX86Base<Machine>::Traits::X86OperandMem>(Op0)) {
+    typename InstX86Base<Machine>::Traits::Assembler *Asm =
+        Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
+    Op0Mem->emitSegmentOverride(Asm);
+    emitIASAddrOpTyGPR<Machine>(Func, Ty, Op0Mem->toAsmAddress(Asm), Op1,
+                                Emitter);
+  } else if (const auto Split = llvm::dyn_cast<
+                 typename InstX86Base<Machine>::Traits::VariableSplit>(Op0)) {
+    emitIASAddrOpTyGPR<Machine>(Func, Ty, Split->toAsmAddress(Func), Op1,
+                                Emitter);
+  } else {
+    llvm_unreachable("Unexpected operand type");
+  }
+}
+
+template <class Machine>
+void InstX86Base<Machine>::emitIASGPRShift(
+    const Cfg *Func, Type Ty, const Variable *Var, const Operand *Src,
+    const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterShiftOp
+        &Emitter) {
+  typename InstX86Base<Machine>::Traits::Assembler *Asm =
+      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
+  // Technically, the Dest Var can be mem as well, but we only use Reg.
+  // We can extend this to check Dest if we decide to use that form.
+  assert(Var->hasReg());
+  // We cheat a little and use GPRRegister even for byte operations.
+  typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister VarReg =
+      InstX86Base<Machine>::Traits::RegisterSet::getEncodedByteRegOrGPR(
+          Ty, Var->getRegNum());
+  // Src must be reg == ECX or an Imm8.
+  // This is asserted by the assembler.
+  if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) {
+    assert(SrcVar->hasReg());
+    typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister SrcReg =
+        InstX86Base<Machine>::Traits::RegisterSet::getEncodedByteRegOrGPR(
+            Ty, SrcVar->getRegNum());
+    (Asm->*(Emitter.GPRGPR))(Ty, VarReg, SrcReg);
+  } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) {
+    (Asm->*(Emitter.GPRImm))(Ty, VarReg, Immediate(Imm->getValue()));
+  } else {
+    llvm_unreachable("Unexpected operand type");
+  }
+}
+
+template <class Machine>
+void emitIASGPRShiftDouble(
+    const Cfg *Func, const Variable *Dest, const Operand *Src1Op,
+    const Operand *Src2Op,
+    const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterShiftD
+        &Emitter) {
+  typename InstX86Base<Machine>::Traits::Assembler *Asm =
+      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
+  // Dest can be reg or mem, but we only use the reg variant.
+  assert(Dest->hasReg());
+  typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister DestReg =
+      InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
+          Dest->getRegNum());
+  // SrcVar1 must be reg.
+  const auto SrcVar1 = llvm::cast<Variable>(Src1Op);
+  assert(SrcVar1->hasReg());
+  typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister SrcReg =
+      InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
+          SrcVar1->getRegNum());
+  Type Ty = SrcVar1->getType();
+  // Src2 can be the implicit CL register or an immediate.
+  if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src2Op)) {
+    (Asm->*(Emitter.GPRGPRImm))(Ty, DestReg, SrcReg,
+                                Immediate(Imm->getValue()));
+  } else {
+    assert(llvm::cast<Variable>(Src2Op)->getRegNum() ==
+           InstX86Base<Machine>::Traits::RegisterSet::Reg_ecx);
+    (Asm->*(Emitter.GPRGPR))(Ty, DestReg, SrcReg);
+  }
+}
+
+template <class Machine>
+void emitIASXmmShift(
+    const Cfg *Func, Type Ty, const Variable *Var, const Operand *Src,
+    const typename InstX86Base<Machine>::Traits::Assembler::XmmEmitterShiftOp
+        &Emitter) {
+  typename InstX86Base<Machine>::Traits::Assembler *Asm =
+      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
+  assert(Var->hasReg());
+  typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister VarReg =
+      InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
+          Var->getRegNum());
+  if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) {
+    if (SrcVar->hasReg()) {
+      typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister SrcReg =
+          InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
+              SrcVar->getRegNum());
+      (Asm->*(Emitter.XmmXmm))(Ty, VarReg, SrcReg);
+    } else {
+      typename InstX86Base<Machine>::Traits::Address SrcStackAddr =
+          static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
+              Func->getTarget())
+              ->stackVarToAsmOperand(SrcVar);
+      (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcStackAddr);
+    }
+  } else if (const auto Mem = llvm::dyn_cast<
+                 typename InstX86Base<Machine>::Traits::X86OperandMem>(Src)) {
+    assert(Mem->getSegmentRegister() ==
+           InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment);
+    (Asm->*(Emitter.XmmAddr))(Ty, VarReg, Mem->toAsmAddress(Asm));
+  } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) {
+    (Asm->*(Emitter.XmmImm))(Ty, VarReg, Immediate(Imm->getValue()));
+  } else {
+    llvm_unreachable("Unexpected operand type");
+  }
+}
+
+template <class Machine>
+void emitIASRegOpTyXMM(
+    const Cfg *Func, Type Ty, const Variable *Var, const Operand *Src,
+    const typename InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp
+        &Emitter) {
+  typename InstX86Base<Machine>::Traits::Assembler *Asm =
+      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
+  assert(Var->hasReg());
+  typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister VarReg =
+      InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
+          Var->getRegNum());
+  if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) {
+    if (SrcVar->hasReg()) {
+      typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister SrcReg =
+          InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
+              SrcVar->getRegNum());
+      (Asm->*(Emitter.XmmXmm))(Ty, VarReg, SrcReg);
+    } else {
+      typename InstX86Base<Machine>::Traits::Address SrcStackAddr =
+          static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
+              Func->getTarget())
+              ->stackVarToAsmOperand(SrcVar);
+      (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcStackAddr);
+    }
+  } else if (const auto Mem = llvm::dyn_cast<
+                 typename InstX86Base<Machine>::Traits::X86OperandMem>(Src)) {
+    assert(Mem->getSegmentRegister() ==
+           InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment);
+    (Asm->*(Emitter.XmmAddr))(Ty, VarReg, Mem->toAsmAddress(Asm));
+  } else if (const auto Imm = llvm::dyn_cast<Constant>(Src)) {
+    (Asm->*(Emitter.XmmAddr))(
+        Ty, VarReg,
+        InstX86Base<Machine>::Traits::Address::ofConstPool(Asm, Imm));
+  } else {
+    llvm_unreachable("Unexpected operand type");
+  }
+}
+
+template <class Machine, typename DReg_t, typename SReg_t,
+          DReg_t (*destEnc)(int32_t), SReg_t (*srcEnc)(int32_t)>
+void emitIASCastRegOp(const Cfg *Func, Type DispatchTy, const Variable *Dest,
+                      const Operand *Src,
+                      const typename InstX86Base<Machine>::Traits::Assembler::
+                          template CastEmitterRegOp<DReg_t, SReg_t> &Emitter) {
+  typename InstX86Base<Machine>::Traits::Assembler *Asm =
+      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
+  assert(Dest->hasReg());
+  DReg_t DestReg = destEnc(Dest->getRegNum());
+  if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) {
+    if (SrcVar->hasReg()) {
+      SReg_t SrcReg = srcEnc(SrcVar->getRegNum());
+      (Asm->*(Emitter.RegReg))(DispatchTy, DestReg, SrcReg);
+    } else {
+      typename InstX86Base<Machine>::Traits::Address SrcStackAddr =
+          static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
+              Func->getTarget())
+              ->stackVarToAsmOperand(SrcVar);
+      (Asm->*(Emitter.RegAddr))(DispatchTy, DestReg, SrcStackAddr);
+    }
+  } else if (const auto Mem = llvm::dyn_cast<
+                 typename InstX86Base<Machine>::Traits::X86OperandMem>(Src)) {
+    Mem->emitSegmentOverride(Asm);
+    (Asm->*(Emitter.RegAddr))(DispatchTy, DestReg, Mem->toAsmAddress(Asm));
+  } else {
+    llvm_unreachable("Unexpected operand type");
+  }
+}
+
+template <class Machine, typename DReg_t, typename SReg_t,
+          DReg_t (*destEnc)(int32_t), SReg_t (*srcEnc)(int32_t)>
+void emitIASThreeOpImmOps(
+    const Cfg *Func, Type DispatchTy, const Variable *Dest, const Operand *Src0,
+    const Operand *Src1,
+    const typename InstX86Base<Machine>::Traits::Assembler::
+        template ThreeOpImmEmitter<DReg_t, SReg_t> Emitter) {
+  typename InstX86Base<Machine>::Traits::Assembler *Asm =
+      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
+  // This only handles Dest being a register, and Src1 being an immediate.
+  assert(Dest->hasReg());
+  DReg_t DestReg = destEnc(Dest->getRegNum());
+  Immediate Imm(llvm::cast<ConstantInteger32>(Src1)->getValue());
+  if (const auto SrcVar = llvm::dyn_cast<Variable>(Src0)) {
+    if (SrcVar->hasReg()) {
+      SReg_t SrcReg = srcEnc(SrcVar->getRegNum());
+      (Asm->*(Emitter.RegRegImm))(DispatchTy, DestReg, SrcReg, Imm);
+    } else {
+      typename InstX86Base<Machine>::Traits::Address SrcStackAddr =
+          static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
+              Func->getTarget())
+              ->stackVarToAsmOperand(SrcVar);
+      (Asm->*(Emitter.RegAddrImm))(DispatchTy, DestReg, SrcStackAddr, Imm);
+    }
+  } else if (const auto Mem = llvm::dyn_cast<
+                 typename InstX86Base<Machine>::Traits::X86OperandMem>(Src0)) {
+    Mem->emitSegmentOverride(Asm);
+    (Asm->*(Emitter.RegAddrImm))(DispatchTy, DestReg, Mem->toAsmAddress(Asm),
+                                 Imm);
+  } else {
+    llvm_unreachable("Unexpected operand type");
+  }
+}
+
+template <class Machine>
+void emitIASMovlikeXMM(
+    const Cfg *Func, const Variable *Dest, const Operand *Src,
+    const typename InstX86Base<Machine>::Traits::Assembler::XmmEmitterMovOps
+        Emitter) {
+  typename InstX86Base<Machine>::Traits::Assembler *Asm =
+      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
+  if (Dest->hasReg()) {
+    typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister DestReg =
+        InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
+            Dest->getRegNum());
+    if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) {
+      if (SrcVar->hasReg()) {
+        (Asm->*(Emitter.XmmXmm))(
+            DestReg, InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
+                         SrcVar->getRegNum()));
+      } else {
+        typename InstX86Base<Machine>::Traits::Address StackAddr(
+            static_cast<typename InstX86Base<Machine>::Traits::TargetLowering
+                            *>(Func->getTarget())
+                ->stackVarToAsmOperand(SrcVar));
+        (Asm->*(Emitter.XmmAddr))(DestReg, StackAddr);
+      }
+    } else if (const auto SrcMem = llvm::dyn_cast<
+                   typename InstX86Base<Machine>::Traits::X86OperandMem>(Src)) {
+      assert(SrcMem->getSegmentRegister() ==
+             InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment);
+      (Asm->*(Emitter.XmmAddr))(DestReg, SrcMem->toAsmAddress(Asm));
+    } else {
+      llvm_unreachable("Unexpected operand type");
+    }
+  } else {
+    typename InstX86Base<Machine>::Traits::Address StackAddr(
+        static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
+            Func->getTarget())
+            ->stackVarToAsmOperand(Dest));
+    // Src must be a register in this case.
+    const auto SrcVar = llvm::cast<Variable>(Src);
+    assert(SrcVar->hasReg());
+    (Asm->*(Emitter.AddrXmm))(
+        StackAddr, InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
+                       SrcVar->getRegNum()));
+  }
+}
+
+template <class Machine>
+void InstX86Sqrtss<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrEmit();
+  assert(this->getSrcSize() == 1);
+  Type Ty = this->getSrc(0)->getType();
+  assert(isScalarFloatingType(Ty));
+  Str << "\tsqrt" << InstX86Base<Machine>::Traits::TypeAttributes[Ty].SdSsString
+      << "\t";
+  this->getSrc(0)->emit(Func);
+  Str << ", ";
+  this->getDest()->emit(Func);
+}
+
+template <class Machine>
+void InstX86Addss<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  char buf[30];
+  snprintf(
+      buf, llvm::array_lengthof(buf), "add%s",
+      InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()]
+          .SdSsString);
+  this->emitTwoAddress(buf, this, Func);
+}
+
+template <class Machine>
+void InstX86Padd<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  char buf[30];
+  snprintf(
+      buf, llvm::array_lengthof(buf), "padd%s",
+      InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()]
+          .PackString);
+  this->emitTwoAddress(buf, this, Func);
+}
+
+template <class Machine>
+void InstX86Pmull<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  char buf[30];
+  bool TypesAreValid = this->getDest()->getType() == IceType_v4i32 ||
+                       this->getDest()->getType() == IceType_v8i16;
+  bool InstructionSetIsValid =
+      this->getDest()->getType() == IceType_v8i16 ||
+      static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
+          Func->getTarget())
+              ->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1;
+  (void)TypesAreValid;
+  (void)InstructionSetIsValid;
+  assert(TypesAreValid);
+  assert(InstructionSetIsValid);
+  snprintf(
+      buf, llvm::array_lengthof(buf), "pmull%s",
+      InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()]
+          .PackString);
+  this->emitTwoAddress(buf, this, Func);
+}
+
+template <class Machine>
+void InstX86Pmull<Machine>::emitIAS(const Cfg *Func) const {
+  Type Ty = this->getDest()->getType();
+  bool TypesAreValid = Ty == IceType_v4i32 || Ty == IceType_v8i16;
+  bool InstructionSetIsValid =
+      Ty == IceType_v8i16 ||
+      static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
+          Func->getTarget())
+              ->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1;
+  (void)TypesAreValid;
+  (void)InstructionSetIsValid;
+  assert(TypesAreValid);
+  assert(InstructionSetIsValid);
+  assert(this->getSrcSize() == 2);
+  Type ElementTy = typeElementType(Ty);
+  emitIASRegOpTyXMM<Machine>(Func, ElementTy, this->getDest(), this->getSrc(1),
+                             this->Emitter);
+}
+
+template <class Machine>
+void InstX86Subss<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  char buf[30];
+  snprintf(
+      buf, llvm::array_lengthof(buf), "sub%s",
+      InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()]
+          .SdSsString);
+  this->emitTwoAddress(buf, this, Func);
+}
+
+template <class Machine>
+void InstX86Psub<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  char buf[30];
+  snprintf(
+      buf, llvm::array_lengthof(buf), "psub%s",
+      InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()]
+          .PackString);
+  this->emitTwoAddress(buf, this, Func);
+}
+
+template <class Machine>
+void InstX86Mulss<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  char buf[30];
+  snprintf(
+      buf, llvm::array_lengthof(buf), "mul%s",
+      InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()]
+          .SdSsString);
+  this->emitTwoAddress(buf, this, Func);
+}
+
+template <class Machine>
+void InstX86Pmuludq<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  assert(this->getSrc(0)->getType() == IceType_v4i32 &&
+         this->getSrc(1)->getType() == IceType_v4i32);
+  this->emitTwoAddress(this->Opcode, this, Func);
+}
+
+template <class Machine>
+void InstX86Divss<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  char buf[30];
+  snprintf(
+      buf, llvm::array_lengthof(buf), "div%s",
+      InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()]
+          .SdSsString);
+  this->emitTwoAddress(buf, this, Func);
+}
+
+template <class Machine> void InstX86Div<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrEmit();
+  assert(this->getSrcSize() == 3);
+  Operand *Src1 = this->getSrc(1);
+  Str << "\t" << this->Opcode << this->getWidthString(Src1->getType()) << "\t";
+  Src1->emit(Func);
+}
+
+template <class Machine>
+void InstX86Div<Machine>::emitIAS(const Cfg *Func) const {
+  assert(this->getSrcSize() == 3);
+  const Operand *Src = this->getSrc(1);
+  Type Ty = Src->getType();
+  static const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterOneOp
+      Emitter = {&InstX86Base<Machine>::Traits::Assembler::div,
+                 &InstX86Base<Machine>::Traits::Assembler::div};
+  emitIASOpTyGPR<Machine>(Func, Ty, Src, Emitter);
+}
+
+template <class Machine>
+void InstX86Idiv<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrEmit();
+  assert(this->getSrcSize() == 3);
+  Operand *Src1 = this->getSrc(1);
+  Str << "\t" << this->Opcode << this->getWidthString(Src1->getType()) << "\t";
+  Src1->emit(Func);
+}
+
+template <class Machine>
+void InstX86Idiv<Machine>::emitIAS(const Cfg *Func) const {
+  assert(this->getSrcSize() == 3);
+  const Operand *Src = this->getSrc(1);
+  Type Ty = Src->getType();
+  static const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterOneOp
+      Emitter = {&InstX86Base<Machine>::Traits::Assembler::idiv,
+                 &InstX86Base<Machine>::Traits::Assembler::idiv};
+  emitIASOpTyGPR<Machine>(Func, Ty, Src, Emitter);
+}
+
+// pblendvb and blendvps take xmm0 as a final implicit argument.
+template <class Machine>
+void emitVariableBlendInst(const char *Opcode, const Inst *Inst,
+                           const Cfg *Func) {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrEmit();
+  assert(Inst->getSrcSize() == 3);
+  assert(llvm::cast<Variable>(Inst->getSrc(2))->getRegNum() ==
+         InstX86Base<Machine>::Traits::RegisterSet::Reg_xmm0);
+  Str << "\t" << Opcode << "\t";
+  Inst->getSrc(1)->emit(Func);
+  Str << ", ";
+  Inst->getDest()->emit(Func);
+}
+
+template <class Machine>
+void emitIASVariableBlendInst(
+    const Inst *Inst, const Cfg *Func,
+    const typename InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp
+        &Emitter) {
+  assert(Inst->getSrcSize() == 3);
+  assert(llvm::cast<Variable>(Inst->getSrc(2))->getRegNum() ==
+         InstX86Base<Machine>::Traits::RegisterSet::Reg_xmm0);
+  const Variable *Dest = Inst->getDest();
+  const Operand *Src = Inst->getSrc(1);
+  emitIASRegOpTyXMM<Machine>(Func, Dest->getType(), Dest, Src, Emitter);
+}
+
+template <class Machine>
+void InstX86Blendvps<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  assert(static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
+             Func->getTarget())
+             ->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1);
+  emitVariableBlendInst<Machine>(this->Opcode, this, Func);
+}
+
+template <class Machine>
+void InstX86Blendvps<Machine>::emitIAS(const Cfg *Func) const {
+  assert(static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
+             Func->getTarget())
+             ->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1);
+  static const typename InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp
+      Emitter = {&InstX86Base<Machine>::Traits::Assembler::blendvps,
+                 &InstX86Base<Machine>::Traits::Assembler::blendvps};
+  emitIASVariableBlendInst<Machine>(this, Func, Emitter);
+}
+
+template <class Machine>
+void InstX86Pblendvb<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  assert(static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
+             Func->getTarget())
+             ->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1);
+  emitVariableBlendInst<Machine>(this->Opcode, this, Func);
+}
+
+template <class Machine>
+void InstX86Pblendvb<Machine>::emitIAS(const Cfg *Func) const {
+  assert(static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
+             Func->getTarget())
+             ->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1);
+  static const typename InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp
+      Emitter = {&InstX86Base<Machine>::Traits::Assembler::pblendvb,
+                 &InstX86Base<Machine>::Traits::Assembler::pblendvb};
+  emitIASVariableBlendInst<Machine>(this, Func, Emitter);
+}
+
+template <class Machine>
+void InstX86Imul<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrEmit();
+  assert(this->getSrcSize() == 2);
+  Variable *Dest = this->getDest();
+  if (isByteSizedArithType(Dest->getType())) {
+    // The 8-bit version of imul only allows the form "imul r/m8".
+    const auto Src0Var = llvm::dyn_cast<Variable>(this->getSrc(0));
+    (void)Src0Var;
+    assert(Src0Var &&
+           Src0Var->getRegNum() ==
+               InstX86Base<Machine>::Traits::RegisterSet::Reg_eax);
+    Str << "\timulb\t";
+    this->getSrc(1)->emit(Func);
+  } else if (llvm::isa<Constant>(this->getSrc(1))) {
+    Str << "\timul" << this->getWidthString(Dest->getType()) << "\t";
+    this->getSrc(1)->emit(Func);
+    Str << ", ";
+    this->getSrc(0)->emit(Func);
+    Str << ", ";
+    Dest->emit(Func);
+  } else {
+    this->emitTwoAddress("imul", this, Func);
+  }
+}
+
+template <class Machine>
+void InstX86Imul<Machine>::emitIAS(const Cfg *Func) const {
+  assert(this->getSrcSize() == 2);
+  const Variable *Var = this->getDest();
+  Type Ty = Var->getType();
+  const Operand *Src = this->getSrc(1);
+  if (isByteSizedArithType(Ty)) {
+    // The 8-bit version of imul only allows the form "imul r/m8".
+    const auto Src0Var = llvm::dyn_cast<Variable>(this->getSrc(0));
+    (void)Src0Var;
+    assert(Src0Var &&
+           Src0Var->getRegNum() ==
+               InstX86Base<Machine>::Traits::RegisterSet::Reg_eax);
+    static const typename InstX86Base<
+        Machine>::Traits::Assembler::GPREmitterOneOp Emitter = {
+        &InstX86Base<Machine>::Traits::Assembler::imul,
+        &InstX86Base<Machine>::Traits::Assembler::imul};
+    emitIASOpTyGPR<Machine>(Func, Ty, this->getSrc(1), Emitter);
+  } else {
+    // We only use imul as a two-address instruction even though
+    // there is a 3 operand version when one of the operands is a constant.
+    assert(Var == this->getSrc(0));
+    static const typename InstX86Base<
+        Machine>::Traits::Assembler::GPREmitterRegOp Emitter = {
+        &InstX86Base<Machine>::Traits::Assembler::imul,
+        &InstX86Base<Machine>::Traits::Assembler::imul,
+        &InstX86Base<Machine>::Traits::Assembler::imul};
+    emitIASRegOpTyGPR<Machine>(Func, Ty, Var, Src, Emitter);
+  }
+}
+
+template <class Machine>
+void InstX86Insertps<Machine>::emitIAS(const Cfg *Func) const {
+  assert(this->getSrcSize() == 3);
+  assert(static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
+             Func->getTarget())
+             ->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1);
+  const Variable *Dest = this->getDest();
+  assert(Dest == this->getSrc(0));
+  Type Ty = Dest->getType();
+  static const typename InstX86Base<Machine>::Traits::Assembler::
+      template ThreeOpImmEmitter<
+          typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
+          typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister>
+          Emitter = {&InstX86Base<Machine>::Traits::Assembler::insertps,
+                     &InstX86Base<Machine>::Traits::Assembler::insertps};
+  emitIASThreeOpImmOps<
+      Machine, typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
+      typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
+      InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm,
+      InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm>(
+      Func, Ty, Dest, this->getSrc(1), this->getSrc(2), Emitter);
+}
+
+template <class Machine>
+void InstX86Cbwdq<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrEmit();
+  assert(this->getSrcSize() == 1);
+  Operand *Src0 = this->getSrc(0);
+  assert(llvm::isa<Variable>(Src0));
+  assert(llvm::cast<Variable>(Src0)->getRegNum() ==
+         InstX86Base<Machine>::Traits::RegisterSet::Reg_eax);
+  switch (Src0->getType()) {
+  default:
+    llvm_unreachable("unexpected source type!");
+    break;
+  case IceType_i8:
+    assert(this->getDest()->getRegNum() ==
+           InstX86Base<Machine>::Traits::RegisterSet::Reg_eax);
+    Str << "\tcbtw";
+    break;
+  case IceType_i16:
+    assert(this->getDest()->getRegNum() ==
+           InstX86Base<Machine>::Traits::RegisterSet::Reg_edx);
+    Str << "\tcwtd";
+    break;
+  case IceType_i32:
+    assert(this->getDest()->getRegNum() ==
+           InstX86Base<Machine>::Traits::RegisterSet::Reg_edx);
+    Str << "\tcltd";
+    break;
+  }
+}
+
+template <class Machine>
+void InstX86Cbwdq<Machine>::emitIAS(const Cfg *Func) const {
+  typename InstX86Base<Machine>::Traits::Assembler *Asm =
+      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
+  assert(this->getSrcSize() == 1);
+  Operand *Src0 = this->getSrc(0);
+  assert(llvm::isa<Variable>(Src0));
+  assert(llvm::cast<Variable>(Src0)->getRegNum() ==
+         InstX86Base<Machine>::Traits::RegisterSet::Reg_eax);
+  switch (Src0->getType()) {
+  default:
+    llvm_unreachable("unexpected source type!");
+    break;
+  case IceType_i8:
+    assert(this->getDest()->getRegNum() ==
+           InstX86Base<Machine>::Traits::RegisterSet::Reg_eax);
+    Asm->cbw();
+    break;
+  case IceType_i16:
+    assert(this->getDest()->getRegNum() ==
+           InstX86Base<Machine>::Traits::RegisterSet::Reg_edx);
+    Asm->cwd();
+    break;
+  case IceType_i32:
+    assert(this->getDest()->getRegNum() ==
+           InstX86Base<Machine>::Traits::RegisterSet::Reg_edx);
+    Asm->cdq();
+    break;
+  }
+}
+
+template <class Machine> void InstX86Mul<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrEmit();
+  assert(this->getSrcSize() == 2);
+  assert(llvm::isa<Variable>(this->getSrc(0)));
+  assert(llvm::cast<Variable>(this->getSrc(0))->getRegNum() ==
+         InstX86Base<Machine>::Traits::RegisterSet::Reg_eax);
+  assert(
+      this->getDest()->getRegNum() ==
+      InstX86Base<Machine>::Traits::RegisterSet::Reg_eax); // TODO: allow edx?
+  Str << "\tmul" << this->getWidthString(this->getDest()->getType()) << "\t";
+  this->getSrc(1)->emit(Func);
+}
+
+template <class Machine>
+void InstX86Mul<Machine>::emitIAS(const Cfg *Func) const {
+  assert(this->getSrcSize() == 2);
+  assert(llvm::isa<Variable>(this->getSrc(0)));
+  assert(llvm::cast<Variable>(this->getSrc(0))->getRegNum() ==
+         InstX86Base<Machine>::Traits::RegisterSet::Reg_eax);
+  assert(
+      this->getDest()->getRegNum() ==
+      InstX86Base<Machine>::Traits::RegisterSet::Reg_eax); // TODO: allow edx?
+  const Operand *Src = this->getSrc(1);
+  Type Ty = Src->getType();
+  static const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterOneOp
+      Emitter = {&InstX86Base<Machine>::Traits::Assembler::mul,
+                 &InstX86Base<Machine>::Traits::Assembler::mul};
+  emitIASOpTyGPR<Machine>(Func, Ty, Src, Emitter);
+}
+
+template <class Machine> void InstX86Mul<Machine>::dump(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrDump();
+  this->dumpDest(Func);
+  Str << " = mul." << this->getDest()->getType() << " ";
+  this->dumpSources(Func);
+}
+
+template <class Machine>
+void InstX86Shld<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrEmit();
+  Variable *Dest = this->getDest();
+  assert(this->getSrcSize() == 3);
+  assert(Dest == this->getSrc(0));
+  Str << "\tshld" << this->getWidthString(Dest->getType()) << "\t";
+  if (const auto ShiftReg = llvm::dyn_cast<Variable>(this->getSrc(2))) {
+    (void)ShiftReg;
+    assert(ShiftReg->getRegNum() ==
+           InstX86Base<Machine>::Traits::RegisterSet::Reg_ecx);
+    Str << "%cl";
+  } else {
+    this->getSrc(2)->emit(Func);
+  }
+  Str << ", ";
+  this->getSrc(1)->emit(Func);
+  Str << ", ";
+  Dest->emit(Func);
+}
+
+template <class Machine>
+void InstX86Shld<Machine>::emitIAS(const Cfg *Func) const {
+  assert(this->getSrcSize() == 3);
+  assert(this->getDest() == this->getSrc(0));
+  const Variable *Dest = this->getDest();
+  const Operand *Src1 = this->getSrc(1);
+  const Operand *Src2 = this->getSrc(2);
+  static const typename InstX86Base<
+      Machine>::Traits::Assembler::GPREmitterShiftD Emitter = {
+      &InstX86Base<Machine>::Traits::Assembler::shld,
+      &InstX86Base<Machine>::Traits::Assembler::shld};
+  emitIASGPRShiftDouble<Machine>(Func, Dest, Src1, Src2, Emitter);
+}
+
+template <class Machine>
+void InstX86Shld<Machine>::dump(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrDump();
+  this->dumpDest(Func);
+  Str << " = shld." << this->getDest()->getType() << " ";
+  this->dumpSources(Func);
+}
+
+template <class Machine>
+void InstX86Shrd<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrEmit();
+  Variable *Dest = this->getDest();
+  assert(this->getSrcSize() == 3);
+  assert(Dest == this->getSrc(0));
+  Str << "\tshrd" << this->getWidthString(Dest->getType()) << "\t";
+  if (const auto ShiftReg = llvm::dyn_cast<Variable>(this->getSrc(2))) {
+    (void)ShiftReg;
+    assert(ShiftReg->getRegNum() ==
+           InstX86Base<Machine>::Traits::RegisterSet::Reg_ecx);
+    Str << "%cl";
+  } else {
+    this->getSrc(2)->emit(Func);
+  }
+  Str << ", ";
+  this->getSrc(1)->emit(Func);
+  Str << ", ";
+  Dest->emit(Func);
+}
+
+template <class Machine>
+void InstX86Shrd<Machine>::emitIAS(const Cfg *Func) const {
+  assert(this->getSrcSize() == 3);
+  assert(this->getDest() == this->getSrc(0));
+  const Variable *Dest = this->getDest();
+  const Operand *Src1 = this->getSrc(1);
+  const Operand *Src2 = this->getSrc(2);
+  static const typename InstX86Base<
+      Machine>::Traits::Assembler::GPREmitterShiftD Emitter = {
+      &InstX86Base<Machine>::Traits::Assembler::shrd,
+      &InstX86Base<Machine>::Traits::Assembler::shrd};
+  emitIASGPRShiftDouble<Machine>(Func, Dest, Src1, Src2, Emitter);
+}
+
+template <class Machine>
+void InstX86Shrd<Machine>::dump(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrDump();
+  this->dumpDest(Func);
+  Str << " = shrd." << this->getDest()->getType() << " ";
+  this->dumpSources(Func);
+}
+
+template <class Machine>
+void InstX86Cmov<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrEmit();
+  Variable *Dest = this->getDest();
+  Str << "\t";
+  assert(Condition != InstX86Base<Machine>::Traits::Cond::Br_None);
+  assert(this->getDest()->hasReg());
+  Str << "cmov"
+      << InstX86Base<Machine>::Traits::InstBrAttributes[Condition].DisplayString
+      << this->getWidthString(Dest->getType()) << "\t";
+  this->getSrc(1)->emit(Func);
+  Str << ", ";
+  Dest->emit(Func);
+}
+
+template <class Machine>
+void InstX86Cmov<Machine>::emitIAS(const Cfg *Func) const {
+  assert(Condition != InstX86Base<Machine>::Traits::Cond::Br_None);
+  assert(this->getDest()->hasReg());
+  assert(this->getSrcSize() == 2);
+  Operand *Src = this->getSrc(1);
+  Type SrcTy = Src->getType();
+  assert(SrcTy == IceType_i16 || SrcTy == IceType_i32);
+  typename InstX86Base<Machine>::Traits::Assembler *Asm =
+      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
+  if (const auto *SrcVar = llvm::dyn_cast<Variable>(Src)) {
+    if (SrcVar->hasReg()) {
+      Asm->cmov(SrcTy, Condition,
+                InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
+                    this->getDest()->getRegNum()),
+                InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
+                    SrcVar->getRegNum()));
+    } else {
+      Asm->cmov(
+          SrcTy, Condition,
+          InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
+              this->getDest()->getRegNum()),
+          static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
+              Func->getTarget())
+              ->stackVarToAsmOperand(SrcVar));
+    }
+  } else if (const auto Mem = llvm::dyn_cast<
+                 typename InstX86Base<Machine>::Traits::X86OperandMem>(Src)) {
+    assert(Mem->getSegmentRegister() ==
+           InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment);
+    Asm->cmov(SrcTy, Condition,
+              InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
+                  this->getDest()->getRegNum()),
+              Mem->toAsmAddress(Asm));
+  } else {
+    llvm_unreachable("Unexpected operand type");
+  }
+}
+
+template <class Machine>
+void InstX86Cmov<Machine>::dump(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrDump();
+  Str << "cmov"
+      << InstX86Base<Machine>::Traits::InstBrAttributes[Condition].DisplayString
+      << ".";
+  Str << this->getDest()->getType() << " ";
+  this->dumpDest(Func);
+  Str << ", ";
+  this->dumpSources(Func);
+}
+
+template <class Machine>
+void InstX86Cmpps<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrEmit();
+  assert(this->getSrcSize() == 2);
+  assert(Condition < InstX86Base<Machine>::Traits::Cond::Cmpps_Invalid);
+  Str << "\t";
+  Str << "cmp"
+      << InstX86Base<Machine>::Traits::InstCmppsAttributes[Condition].EmitString
+      << "ps"
+      << "\t";
+  this->getSrc(1)->emit(Func);
+  Str << ", ";
+  this->getDest()->emit(Func);
+}
+
+template <class Machine>
+void InstX86Cmpps<Machine>::emitIAS(const Cfg *Func) const {
+  typename InstX86Base<Machine>::Traits::Assembler *Asm =
+      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
+  assert(this->getSrcSize() == 2);
+  assert(Condition < InstX86Base<Machine>::Traits::Cond::Cmpps_Invalid);
+  // Assuming there isn't any load folding for cmpps, and vector constants
+  // are not allowed in PNaCl.
+  assert(llvm::isa<Variable>(this->getSrc(1)));
+  const auto SrcVar = llvm::cast<Variable>(this->getSrc(1));
+  if (SrcVar->hasReg()) {
+    Asm->cmpps(InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
+                   this->getDest()->getRegNum()),
+               InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
+                   SrcVar->getRegNum()),
+               Condition);
+  } else {
+    typename InstX86Base<Machine>::Traits::Address SrcStackAddr =
+        static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
+            Func->getTarget())
+            ->stackVarToAsmOperand(SrcVar);
+    Asm->cmpps(InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
+                   this->getDest()->getRegNum()),
+               SrcStackAddr, Condition);
+  }
+}
+
+template <class Machine>
+void InstX86Cmpps<Machine>::dump(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrDump();
+  assert(Condition < InstX86Base<Machine>::Traits::Cond::Cmpps_Invalid);
+  this->dumpDest(Func);
+  Str << " = cmp"
+      << InstX86Base<Machine>::Traits::InstCmppsAttributes[Condition].EmitString
+      << "ps"
+      << "\t";
+  this->dumpSources(Func);
+}
+
+template <class Machine>
+void InstX86Cmpxchg<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrEmit();
+  assert(this->getSrcSize() == 3);
+  if (this->Locked) {
+    Str << "\tlock";
+  }
+  Str << "\tcmpxchg" << this->getWidthString(this->getSrc(0)->getType())
+      << "\t";
+  this->getSrc(2)->emit(Func);
+  Str << ", ";
+  this->getSrc(0)->emit(Func);
+}
+
+template <class Machine>
+void InstX86Cmpxchg<Machine>::emitIAS(const Cfg *Func) const {
+  assert(this->getSrcSize() == 3);
+  typename InstX86Base<Machine>::Traits::Assembler *Asm =
+      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
+  Type Ty = this->getSrc(0)->getType();
+  const auto Mem =
+      llvm::cast<typename InstX86Base<Machine>::Traits::X86OperandMem>(
+          this->getSrc(0));
+  assert(Mem->getSegmentRegister() ==
+         InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment);
+  const typename InstX86Base<Machine>::Traits::Address Addr =
+      Mem->toAsmAddress(Asm);
+  const auto VarReg = llvm::cast<Variable>(this->getSrc(2));
+  assert(VarReg->hasReg());
+  const typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister Reg =
+      InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
+          VarReg->getRegNum());
+  Asm->cmpxchg(Ty, Addr, Reg, this->Locked);
+}
+
+template <class Machine>
+void InstX86Cmpxchg<Machine>::dump(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrDump();
+  if (this->Locked) {
+    Str << "lock ";
+  }
+  Str << "cmpxchg." << this->getSrc(0)->getType() << " ";
+  this->dumpSources(Func);
+}
+
+template <class Machine>
+void InstX86Cmpxchg8b<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrEmit();
+  assert(this->getSrcSize() == 5);
+  if (this->Locked) {
+    Str << "\tlock";
+  }
+  Str << "\tcmpxchg8b\t";
+  this->getSrc(0)->emit(Func);
+}
+
+template <class Machine>
+void InstX86Cmpxchg8b<Machine>::emitIAS(const Cfg *Func) const {
+  assert(this->getSrcSize() == 5);
+  typename InstX86Base<Machine>::Traits::Assembler *Asm =
+      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
+  const auto Mem =
+      llvm::cast<typename InstX86Base<Machine>::Traits::X86OperandMem>(
+          this->getSrc(0));
+  assert(Mem->getSegmentRegister() ==
+         InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment);
+  const typename InstX86Base<Machine>::Traits::Address Addr =
+      Mem->toAsmAddress(Asm);
+  Asm->cmpxchg8b(Addr, this->Locked);
+}
+
+template <class Machine>
+void InstX86Cmpxchg8b<Machine>::dump(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrDump();
+  if (this->Locked) {
+    Str << "lock ";
+  }
+  Str << "cmpxchg8b ";
+  this->dumpSources(Func);
+}
+
+template <class Machine> void InstX86Cvt<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrEmit();
+  assert(this->getSrcSize() == 1);
+  Str << "\tcvt";
+  if (isTruncating())
+    Str << "t";
+  Str << InstX86Base<Machine>::Traits::TypeAttributes[this->getSrc(0)
+                                                          ->getType()]
+             .CvtString << "2"
+      << InstX86Base<
+             Machine>::Traits::TypeAttributes[this->getDest()->getType()]
+             .CvtString << "\t";
+  this->getSrc(0)->emit(Func);
+  Str << ", ";
+  this->getDest()->emit(Func);
+}
+
+template <class Machine>
+void InstX86Cvt<Machine>::emitIAS(const Cfg *Func) const {
+  assert(this->getSrcSize() == 1);
+  const Variable *Dest = this->getDest();
+  const Operand *Src = this->getSrc(0);
+  Type DestTy = Dest->getType();
+  Type SrcTy = Src->getType();
+  switch (Variant) {
+  case Si2ss: {
+    assert(isScalarIntegerType(SrcTy));
+    assert(typeWidthInBytes(SrcTy) <= 4);
+    assert(isScalarFloatingType(DestTy));
+    static const typename InstX86Base<Machine>::Traits::Assembler::
+        template CastEmitterRegOp<
+            typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
+            typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister>
+            Emitter = {&InstX86Base<Machine>::Traits::Assembler::cvtsi2ss,
+                       &InstX86Base<Machine>::Traits::Assembler::cvtsi2ss};
+    emitIASCastRegOp<
+        Machine,
+        typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
+        typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister,
+        InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm,
+        InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR>(
+        Func, DestTy, Dest, Src, Emitter);
+    return;
+  }
+  case Tss2si: {
+    assert(isScalarFloatingType(SrcTy));
+    assert(isScalarIntegerType(DestTy));
+    assert(typeWidthInBytes(DestTy) <= 4);
+    static const typename InstX86Base<Machine>::Traits::Assembler::
+        template CastEmitterRegOp<
+            typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister,
+            typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister>
+            Emitter = {&InstX86Base<Machine>::Traits::Assembler::cvttss2si,
+                       &InstX86Base<Machine>::Traits::Assembler::cvttss2si};
+    emitIASCastRegOp<
+        Machine,
+        typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister,
+        typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
+        InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR,
+        InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm>(
+        Func, SrcTy, Dest, Src, Emitter);
+    return;
+  }
+  case Float2float: {
+    assert(isScalarFloatingType(SrcTy));
+    assert(isScalarFloatingType(DestTy));
+    assert(DestTy != SrcTy);
+    static const typename InstX86Base<
+        Machine>::Traits::Assembler::XmmEmitterRegOp Emitter = {
+        &InstX86Base<Machine>::Traits::Assembler::cvtfloat2float,
+        &InstX86Base<Machine>::Traits::Assembler::cvtfloat2float};
+    emitIASRegOpTyXMM<Machine>(Func, SrcTy, Dest, Src, Emitter);
+    return;
+  }
+  case Dq2ps: {
+    assert(isVectorIntegerType(SrcTy));
+    assert(isVectorFloatingType(DestTy));
+    static const typename InstX86Base<
+        Machine>::Traits::Assembler::XmmEmitterRegOp Emitter = {
+        &InstX86Base<Machine>::Traits::Assembler::cvtdq2ps,
+        &InstX86Base<Machine>::Traits::Assembler::cvtdq2ps};
+    emitIASRegOpTyXMM<Machine>(Func, DestTy, Dest, Src, Emitter);
+    return;
+  }
+  case Tps2dq: {
+    assert(isVectorFloatingType(SrcTy));
+    assert(isVectorIntegerType(DestTy));
+    static const typename InstX86Base<
+        Machine>::Traits::Assembler::XmmEmitterRegOp Emitter = {
+        &InstX86Base<Machine>::Traits::Assembler::cvttps2dq,
+        &InstX86Base<Machine>::Traits::Assembler::cvttps2dq};
+    emitIASRegOpTyXMM<Machine>(Func, DestTy, Dest, Src, Emitter);
+    return;
+  }
+  }
+}
+
+template <class Machine> void InstX86Cvt<Machine>::dump(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrDump();
+  this->dumpDest(Func);
+  Str << " = cvt";
+  if (isTruncating())
+    Str << "t";
+  Str << InstX86Base<Machine>::Traits::TypeAttributes[this->getSrc(0)
+                                                          ->getType()]
+             .CvtString << "2"
+      << InstX86Base<
+             Machine>::Traits::TypeAttributes[this->getDest()->getType()]
+             .CvtString << " ";
+  this->dumpSources(Func);
+}
+
+template <class Machine>
+void InstX86Icmp<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrEmit();
+  assert(this->getSrcSize() == 2);
+  Str << "\tcmp" << this->getWidthString(this->getSrc(0)->getType()) << "\t";
+  this->getSrc(1)->emit(Func);
+  Str << ", ";
+  this->getSrc(0)->emit(Func);
+}
+
+template <class Machine>
+void InstX86Icmp<Machine>::emitIAS(const Cfg *Func) const {
+  assert(this->getSrcSize() == 2);
+  const Operand *Src0 = this->getSrc(0);
+  const Operand *Src1 = this->getSrc(1);
+  Type Ty = Src0->getType();
+  static const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterRegOp
+      RegEmitter = {&InstX86Base<Machine>::Traits::Assembler::cmp,
+                    &InstX86Base<Machine>::Traits::Assembler::cmp,
+                    &InstX86Base<Machine>::Traits::Assembler::cmp};
+  static const typename InstX86Base<
+      Machine>::Traits::Assembler::GPREmitterAddrOp AddrEmitter = {
+      &InstX86Base<Machine>::Traits::Assembler::cmp,
+      &InstX86Base<Machine>::Traits::Assembler::cmp};
+  if (const auto SrcVar0 = llvm::dyn_cast<Variable>(Src0)) {
+    if (SrcVar0->hasReg()) {
+      emitIASRegOpTyGPR<Machine>(Func, Ty, SrcVar0, Src1, RegEmitter);
+      return;
+    }
+  }
+  emitIASAsAddrOpTyGPR<Machine>(Func, Ty, Src0, Src1, AddrEmitter);
+}
+
+template <class Machine>
+void InstX86Icmp<Machine>::dump(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrDump();
+  Str << "cmp." << this->getSrc(0)->getType() << " ";
+  this->dumpSources(Func);
+}
+
+template <class Machine>
+void InstX86Ucomiss<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrEmit();
+  assert(this->getSrcSize() == 2);
+  Str << "\tucomi"
+      << InstX86Base<Machine>::Traits::TypeAttributes[this->getSrc(0)
+                                                          ->getType()]
+             .SdSsString << "\t";
+  this->getSrc(1)->emit(Func);
+  Str << ", ";
+  this->getSrc(0)->emit(Func);
+}
+
+template <class Machine>
+void InstX86Ucomiss<Machine>::emitIAS(const Cfg *Func) const {
+  assert(this->getSrcSize() == 2);
+  // Currently src0 is always a variable by convention, to avoid having
+  // two memory operands.
+  assert(llvm::isa<Variable>(this->getSrc(0)));
+  const auto Src0Var = llvm::cast<Variable>(this->getSrc(0));
+  Type Ty = Src0Var->getType();
+  static const typename InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp
+      Emitter = {&InstX86Base<Machine>::Traits::Assembler::ucomiss,
+                 &InstX86Base<Machine>::Traits::Assembler::ucomiss};
+  emitIASRegOpTyXMM<Machine>(Func, Ty, Src0Var, this->getSrc(1), Emitter);
+}
+
+template <class Machine>
+void InstX86Ucomiss<Machine>::dump(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrDump();
+  Str << "ucomiss." << this->getSrc(0)->getType() << " ";
+  this->dumpSources(Func);
+}
+
+template <class Machine> void InstX86UD2<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrEmit();
+  assert(this->getSrcSize() == 0);
+  Str << "\tud2";
+}
+
+template <class Machine>
+void InstX86UD2<Machine>::emitIAS(const Cfg *Func) const {
+  typename InstX86Base<Machine>::Traits::Assembler *Asm =
+      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
+  Asm->ud2();
+}
+
+template <class Machine> void InstX86UD2<Machine>::dump(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrDump();
+  Str << "ud2";
+}
+
+template <class Machine>
+void InstX86Test<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrEmit();
+  assert(this->getSrcSize() == 2);
+  Str << "\ttest" << this->getWidthString(this->getSrc(0)->getType()) << "\t";
+  this->getSrc(1)->emit(Func);
+  Str << ", ";
+  this->getSrc(0)->emit(Func);
+}
+
+template <class Machine>
+void InstX86Test<Machine>::emitIAS(const Cfg *Func) const {
+  assert(this->getSrcSize() == 2);
+  const Operand *Src0 = this->getSrc(0);
+  const Operand *Src1 = this->getSrc(1);
+  Type Ty = Src0->getType();
+  // The Reg/Addr form of test is not encodeable.
+  static const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterRegOp
+      RegEmitter = {&InstX86Base<Machine>::Traits::Assembler::test, nullptr,
+                    &InstX86Base<Machine>::Traits::Assembler::test};
+  static const typename InstX86Base<
+      Machine>::Traits::Assembler::GPREmitterAddrOp AddrEmitter = {
+      &InstX86Base<Machine>::Traits::Assembler::test,
+      &InstX86Base<Machine>::Traits::Assembler::test};
+  if (const auto SrcVar0 = llvm::dyn_cast<Variable>(Src0)) {
+    if (SrcVar0->hasReg()) {
+      emitIASRegOpTyGPR<Machine>(Func, Ty, SrcVar0, Src1, RegEmitter);
+      return;
+    }
+  }
+  llvm_unreachable("Nothing actually generates this so it's untested");
+  emitIASAsAddrOpTyGPR<Machine>(Func, Ty, Src0, Src1, AddrEmitter);
+}
+
+template <class Machine>
+void InstX86Test<Machine>::dump(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrDump();
+  Str << "test." << this->getSrc(0)->getType() << " ";
+  this->dumpSources(Func);
+}
+
+template <class Machine>
+void InstX86Mfence<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrEmit();
+  assert(this->getSrcSize() == 0);
+  Str << "\tmfence";
+}
+
+template <class Machine>
+void InstX86Mfence<Machine>::emitIAS(const Cfg *Func) const {
+  typename InstX86Base<Machine>::Traits::Assembler *Asm =
+      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
+  Asm->mfence();
+}
+
+template <class Machine>
+void InstX86Mfence<Machine>::dump(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrDump();
+  Str << "mfence";
+}
+
+template <class Machine>
+void InstX86Store<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrEmit();
+  assert(this->getSrcSize() == 2);
+  Type Ty = this->getSrc(0)->getType();
+  Str << "\tmov" << this->getWidthString(Ty)
+      << InstX86Base<Machine>::Traits::TypeAttributes[Ty].SdSsString << "\t";
+  this->getSrc(0)->emit(Func);
+  Str << ", ";
+  this->getSrc(1)->emit(Func);
+}
+
+template <class Machine>
+void InstX86Store<Machine>::emitIAS(const Cfg *Func) const {
+  assert(this->getSrcSize() == 2);
+  const Operand *Dest = this->getSrc(1);
+  const Operand *Src = this->getSrc(0);
+  Type DestTy = Dest->getType();
+  if (isScalarFloatingType(DestTy)) {
+    // Src must be a register, since Dest is a Mem operand of some kind.
+    const auto SrcVar = llvm::cast<Variable>(Src);
+    assert(SrcVar->hasReg());
+    typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister SrcReg =
+        InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
+            SrcVar->getRegNum());
+    typename InstX86Base<Machine>::Traits::Assembler *Asm =
+        Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
+    if (const auto DestVar = llvm::dyn_cast<Variable>(Dest)) {
+      assert(!DestVar->hasReg());
+      typename InstX86Base<Machine>::Traits::Address StackAddr(
+          static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
+              Func->getTarget())
+              ->stackVarToAsmOperand(DestVar));
+      Asm->movss(DestTy, StackAddr, SrcReg);
+    } else {
+      const auto DestMem =
+          llvm::cast<typename InstX86Base<Machine>::Traits::X86OperandMem>(
+              Dest);
+      assert(DestMem->getSegmentRegister() ==
+             InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment);
+      Asm->movss(DestTy, DestMem->toAsmAddress(Asm), SrcReg);
+    }
+    return;
+  } else {
+    assert(isScalarIntegerType(DestTy));
+    static const typename InstX86Base<
+        Machine>::Traits::Assembler::GPREmitterAddrOp GPRAddrEmitter = {
+        &InstX86Base<Machine>::Traits::Assembler::mov,
+        &InstX86Base<Machine>::Traits::Assembler::mov};
+    emitIASAsAddrOpTyGPR<Machine>(Func, DestTy, Dest, Src, GPRAddrEmitter);
+  }
+}
+
+template <class Machine>
+void InstX86Store<Machine>::dump(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrDump();
+  Str << "mov." << this->getSrc(0)->getType() << " ";
+  this->getSrc(1)->dump(Func);
+  Str << ", ";
+  this->getSrc(0)->dump(Func);
+}
+
+template <class Machine>
+void InstX86StoreP<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrEmit();
+  assert(this->getSrcSize() == 2);
+  Str << "\tmovups\t";
+  this->getSrc(0)->emit(Func);
+  Str << ", ";
+  this->getSrc(1)->emit(Func);
+}
+
+template <class Machine>
+void InstX86StoreP<Machine>::emitIAS(const Cfg *Func) const {
+  typename InstX86Base<Machine>::Traits::Assembler *Asm =
+      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
+  assert(this->getSrcSize() == 2);
+  const auto SrcVar = llvm::cast<Variable>(this->getSrc(0));
+  const auto DestMem =
+      llvm::cast<typename InstX86Base<Machine>::Traits::X86OperandMem>(
+          this->getSrc(1));
+  assert(DestMem->getSegmentRegister() ==
+         InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment);
+  assert(SrcVar->hasReg());
+  Asm->movups(DestMem->toAsmAddress(Asm),
+              InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
+                  SrcVar->getRegNum()));
+}
+
+template <class Machine>
+void InstX86StoreP<Machine>::dump(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrDump();
+  Str << "storep." << this->getSrc(0)->getType() << " ";
+  this->getSrc(1)->dump(Func);
+  Str << ", ";
+  this->getSrc(0)->dump(Func);
+}
+
+template <class Machine>
+void InstX86StoreQ<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrEmit();
+  assert(this->getSrcSize() == 2);
+  assert(this->getSrc(1)->getType() == IceType_i64 ||
+         this->getSrc(1)->getType() == IceType_f64);
+  Str << "\tmovq\t";
+  this->getSrc(0)->emit(Func);
+  Str << ", ";
+  this->getSrc(1)->emit(Func);
+}
+
+template <class Machine>
+void InstX86StoreQ<Machine>::emitIAS(const Cfg *Func) const {
+  typename InstX86Base<Machine>::Traits::Assembler *Asm =
+      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
+  assert(this->getSrcSize() == 2);
+  const auto SrcVar = llvm::cast<Variable>(this->getSrc(0));
+  const auto DestMem =
+      llvm::cast<typename InstX86Base<Machine>::Traits::X86OperandMem>(
+          this->getSrc(1));
+  assert(DestMem->getSegmentRegister() ==
+         InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment);
+  assert(SrcVar->hasReg());
+  Asm->movq(DestMem->toAsmAddress(Asm),
+            InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
+                SrcVar->getRegNum()));
+}
+
+template <class Machine>
+void InstX86StoreQ<Machine>::dump(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrDump();
+  Str << "storeq." << this->getSrc(0)->getType() << " ";
+  this->getSrc(1)->dump(Func);
+  Str << ", ";
+  this->getSrc(0)->dump(Func);
+}
+
+template <class Machine> void InstX86Lea<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrEmit();
+  assert(this->getSrcSize() == 1);
+  assert(this->getDest()->hasReg());
+  Str << "\tleal\t";
+  Operand *Src0 = this->getSrc(0);
+  if (const auto Src0Var = llvm::dyn_cast<Variable>(Src0)) {
+    Type Ty = Src0Var->getType();
+    // lea on x86-32 doesn't accept mem128 operands, so cast VSrc0 to an
+    // acceptable type.
+    Src0Var->asType(isVectorType(Ty) ? IceType_i32 : Ty)->emit(Func);
+  } else {
+    Src0->emit(Func);
+  }
+  Str << ", ";
+  this->getDest()->emit(Func);
+}
+
+template <class Machine> void InstX86Mov<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrEmit();
+  assert(this->getSrcSize() == 1);
+  Operand *Src = this->getSrc(0);
+  Type SrcTy = Src->getType();
+  Type DestTy = this->getDest()->getType();
+  Str << "\tmov"
+      << (!isScalarFloatingType(DestTy)
+              ? this->getWidthString(SrcTy)
+              : InstX86Base<Machine>::Traits::TypeAttributes[DestTy].SdSsString)
+      << "\t";
+  // For an integer truncation operation, src is wider than dest.
+  // Ideally, we use a mov instruction whose data width matches the
+  // narrower dest.  This is a problem if e.g. src is a register like
+  // esi or si where there is no 8-bit version of the register.  To be
+  // safe, we instead widen the dest to match src.  This works even
+  // for stack-allocated dest variables because typeWidthOnStack()
+  // pads to a 4-byte boundary even if only a lower portion is used.
+  // TODO: This assert disallows usages such as copying a floating point
+  // value between a vector and a scalar (which movss is used for).
+  // Clean this up.
+  assert(Func->getTarget()->typeWidthInBytesOnStack(DestTy) ==
+         Func->getTarget()->typeWidthInBytesOnStack(SrcTy));
+  Src->emit(Func);
+  Str << ", ";
+  this->getDest()->asType(SrcTy)->emit(Func);
+}
+
+template <class Machine>
+void InstX86Mov<Machine>::emitIAS(const Cfg *Func) const {
+  assert(this->getSrcSize() == 1);
+  const Variable *Dest = this->getDest();
+  const Operand *Src = this->getSrc(0);
+  Type DestTy = Dest->getType();
+  Type SrcTy = Src->getType();
+  // Mov can be used for GPRs or XMM registers. Also, the type does not
+  // necessarily match (Mov can be used for bitcasts). However, when
+  // the type does not match, one of the operands must be a register.
+  // Thus, the strategy is to find out if Src or Dest are a register,
+  // then use that register's type to decide on which emitter set to use.
+  // The emitter set will include reg-reg movs, but that case should
+  // be unused when the types don't match.
+  static const typename InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp
+      XmmRegEmitter = {&InstX86Base<Machine>::Traits::Assembler::movss,
+                       &InstX86Base<Machine>::Traits::Assembler::movss};
+  static const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterRegOp
+      GPRRegEmitter = {&InstX86Base<Machine>::Traits::Assembler::mov,
+                       &InstX86Base<Machine>::Traits::Assembler::mov,
+                       &InstX86Base<Machine>::Traits::Assembler::mov};
+  static const typename InstX86Base<
+      Machine>::Traits::Assembler::GPREmitterAddrOp GPRAddrEmitter = {
+      &InstX86Base<Machine>::Traits::Assembler::mov,
+      &InstX86Base<Machine>::Traits::Assembler::mov};
+  // For an integer truncation operation, src is wider than dest.
+  // Ideally, we use a mov instruction whose data width matches the
+  // narrower dest.  This is a problem if e.g. src is a register like
+  // esi or si where there is no 8-bit version of the register.  To be
+  // safe, we instead widen the dest to match src.  This works even
+  // for stack-allocated dest variables because typeWidthOnStack()
+  // pads to a 4-byte boundary even if only a lower portion is used.
+  // TODO: This assert disallows usages such as copying a floating point
+  // value between a vector and a scalar (which movss is used for).
+  // Clean this up.
+  assert(
+      Func->getTarget()->typeWidthInBytesOnStack(this->getDest()->getType()) ==
+      Func->getTarget()->typeWidthInBytesOnStack(Src->getType()));
+  if (Dest->hasReg()) {
+    if (isScalarFloatingType(DestTy)) {
+      emitIASRegOpTyXMM<Machine>(Func, DestTy, Dest, Src, XmmRegEmitter);
+      return;
+    } else {
+      assert(isScalarIntegerType(DestTy));
+      // Widen DestTy for truncation (see above note). We should only do this
+      // when both Src and Dest are integer types.
+      if (isScalarIntegerType(SrcTy)) {
+        DestTy = SrcTy;
+      }
+      emitIASRegOpTyGPR<Machine>(Func, DestTy, Dest, Src, GPRRegEmitter);
+      return;
+    }
+  } else {
+    // Dest must be Stack and Src *could* be a register. Use Src's type
+    // to decide on the emitters.
+    typename InstX86Base<Machine>::Traits::Address StackAddr(
+        static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
+            Func->getTarget())
+            ->stackVarToAsmOperand(Dest));
+    if (isScalarFloatingType(SrcTy)) {
+      // Src must be a register.
+      const auto SrcVar = llvm::cast<Variable>(Src);
+      assert(SrcVar->hasReg());
+      typename InstX86Base<Machine>::Traits::Assembler *Asm =
+          Func->getAssembler<
+              typename InstX86Base<Machine>::Traits::Assembler>();
+      Asm->movss(SrcTy, StackAddr,
+                 InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
+                     SrcVar->getRegNum()));
+      return;
+    } else {
+      // Src can be a register or immediate.
+      assert(isScalarIntegerType(SrcTy));
+      emitIASAddrOpTyGPR<Machine>(Func, SrcTy, StackAddr, Src, GPRAddrEmitter);
+      return;
+    }
+    return;
+  }
+}
+
+template <class Machine>
+void InstX86Movd<Machine>::emitIAS(const Cfg *Func) const {
+  typename InstX86Base<Machine>::Traits::Assembler *Asm =
+      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
+  assert(this->getSrcSize() == 1);
+  const Variable *Dest = this->getDest();
+  const auto SrcVar = llvm::cast<Variable>(this->getSrc(0));
+  // For insert/extract element (one of Src/Dest is an Xmm vector and
+  // the other is an int type).
+  if (SrcVar->getType() == IceType_i32) {
+    assert(isVectorType(Dest->getType()));
+    assert(Dest->hasReg());
+    typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister DestReg =
+        InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
+            Dest->getRegNum());
+    if (SrcVar->hasReg()) {
+      Asm->movd(DestReg,
+                InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
+                    SrcVar->getRegNum()));
+    } else {
+      typename InstX86Base<Machine>::Traits::Address StackAddr(
+          static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
+              Func->getTarget())
+              ->stackVarToAsmOperand(SrcVar));
+      Asm->movd(DestReg, StackAddr);
+    }
+  } else {
+    assert(isVectorType(SrcVar->getType()));
+    assert(SrcVar->hasReg());
+    assert(Dest->getType() == IceType_i32);
+    typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister SrcReg =
+        InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
+            SrcVar->getRegNum());
+    if (Dest->hasReg()) {
+      Asm->movd(InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
+                    Dest->getRegNum()),
+                SrcReg);
+    } else {
+      typename InstX86Base<Machine>::Traits::Address StackAddr(
+          static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
+              Func->getTarget())
+              ->stackVarToAsmOperand(Dest));
+      Asm->movd(StackAddr, SrcReg);
+    }
+  }
+}
+
+template <class Machine>
+void InstX86Movp<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  // TODO(wala,stichnot): movups works with all vector operands, but
+  // there exist other instructions (movaps, movdqa, movdqu) that may
+  // perform better, depending on the data type and alignment of the
+  // operands.
+  Ostream &Str = Func->getContext()->getStrEmit();
+  assert(this->getSrcSize() == 1);
+  Str << "\tmovups\t";
+  this->getSrc(0)->emit(Func);
+  Str << ", ";
+  this->getDest()->emit(Func);
+}
+
+template <class Machine>
+void InstX86Movp<Machine>::emitIAS(const Cfg *Func) const {
+  assert(this->getSrcSize() == 1);
+  assert(isVectorType(this->getDest()->getType()));
+  const Variable *Dest = this->getDest();
+  const Operand *Src = this->getSrc(0);
+  static const typename InstX86Base<
+      Machine>::Traits::Assembler::XmmEmitterMovOps Emitter = {
+      &InstX86Base<Machine>::Traits::Assembler::movups,
+      &InstX86Base<Machine>::Traits::Assembler::movups,
+      &InstX86Base<Machine>::Traits::Assembler::movups};
+  emitIASMovlikeXMM<Machine>(Func, Dest, Src, Emitter);
+}
+
+template <class Machine>
+void InstX86Movq<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrEmit();
+  assert(this->getSrcSize() == 1);
+  assert(this->getDest()->getType() == IceType_i64 ||
+         this->getDest()->getType() == IceType_f64);
+  Str << "\tmovq\t";
+  this->getSrc(0)->emit(Func);
+  Str << ", ";
+  this->getDest()->emit(Func);
+}
+
+template <class Machine>
+void InstX86Movq<Machine>::emitIAS(const Cfg *Func) const {
+  assert(this->getSrcSize() == 1);
+  assert(this->getDest()->getType() == IceType_i64 ||
+         this->getDest()->getType() == IceType_f64);
+  const Variable *Dest = this->getDest();
+  const Operand *Src = this->getSrc(0);
+  static const typename InstX86Base<
+      Machine>::Traits::Assembler::XmmEmitterMovOps Emitter = {
+      &InstX86Base<Machine>::Traits::Assembler::movq,
+      &InstX86Base<Machine>::Traits::Assembler::movq,
+      &InstX86Base<Machine>::Traits::Assembler::movq};
+  emitIASMovlikeXMM<Machine>(Func, Dest, Src, Emitter);
+}
+
+template <class Machine>
+void InstX86MovssRegs<Machine>::emitIAS(const Cfg *Func) const {
+  // This is Binop variant is only intended to be used for reg-reg moves
+  // where part of the Dest register is untouched.
+  assert(this->getSrcSize() == 2);
+  const Variable *Dest = this->getDest();
+  assert(Dest == this->getSrc(0));
+  const auto SrcVar = llvm::cast<Variable>(this->getSrc(1));
+  assert(Dest->hasReg() && SrcVar->hasReg());
+  typename InstX86Base<Machine>::Traits::Assembler *Asm =
+      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
+  Asm->movss(IceType_f32,
+             InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
+                 Dest->getRegNum()),
+             InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
+                 SrcVar->getRegNum()));
+}
+
+template <class Machine>
+void InstX86Movsx<Machine>::emitIAS(const Cfg *Func) const {
+  assert(this->getSrcSize() == 1);
+  const Variable *Dest = this->getDest();
+  const Operand *Src = this->getSrc(0);
+  // Dest must be a > 8-bit register, but Src can be 8-bit. In practice
+  // we just use the full register for Dest to avoid having an
+  // OperandSizeOverride prefix. It also allows us to only dispatch on SrcTy.
+  Type SrcTy = Src->getType();
+  assert(typeWidthInBytes(Dest->getType()) > 1);
+  assert(typeWidthInBytes(Dest->getType()) > typeWidthInBytes(SrcTy));
+  emitIASRegOpTyGPR<Machine, false, true>(Func, SrcTy, Dest, Src,
+                                          this->Emitter);
+}
+
+template <class Machine>
+void InstX86Movzx<Machine>::emitIAS(const Cfg *Func) const {
+  assert(this->getSrcSize() == 1);
+  const Variable *Dest = this->getDest();
+  const Operand *Src = this->getSrc(0);
+  Type SrcTy = Src->getType();
+  assert(typeWidthInBytes(Dest->getType()) > 1);
+  assert(typeWidthInBytes(Dest->getType()) > typeWidthInBytes(SrcTy));
+  emitIASRegOpTyGPR<Machine, false, true>(Func, SrcTy, Dest, Src,
+                                          this->Emitter);
+}
+
+template <class Machine> void InstX86Nop<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrEmit();
+  // TODO: Emit the right code for each variant.
+  Str << "\tnop\t# variant = " << Variant;
+}
+
+template <class Machine>
+void InstX86Nop<Machine>::emitIAS(const Cfg *Func) const {
+  typename InstX86Base<Machine>::Traits::Assembler *Asm =
+      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
+  // TODO: Emit the right code for the variant.
+  Asm->nop();
+}
+
+template <class Machine> void InstX86Nop<Machine>::dump(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrDump();
+  Str << "nop (variant = " << Variant << ")";
+}
+
+template <class Machine> void InstX86Fld<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrEmit();
+  assert(this->getSrcSize() == 1);
+  Type Ty = this->getSrc(0)->getType();
+  SizeT Width = typeWidthInBytes(Ty);
+  const auto Var = llvm::dyn_cast<Variable>(this->getSrc(0));
+  if (Var && Var->hasReg()) {
+    // This is a physical xmm register, so we need to spill it to a
+    // temporary stack slot.
+    Str << "\tsubl\t$" << Width << ", %esp"
+        << "\n";
+    Str << "\tmov"
+        << InstX86Base<Machine>::Traits::TypeAttributes[Ty].SdSsString << "\t";
+    Var->emit(Func);
+    Str << ", (%esp)\n";
+    Str << "\tfld" << this->getFldString(Ty) << "\t"
+        << "(%esp)\n";
+    Str << "\taddl\t$" << Width << ", %esp";
+    return;
+  }
+  Str << "\tfld" << this->getFldString(Ty) << "\t";
+  this->getSrc(0)->emit(Func);
+}
+
+template <class Machine>
+void InstX86Fld<Machine>::emitIAS(const Cfg *Func) const {
+  typename InstX86Base<Machine>::Traits::Assembler *Asm =
+      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
+  assert(this->getSrcSize() == 1);
+  const Operand *Src = this->getSrc(0);
+  Type Ty = Src->getType();
+  if (const auto Var = llvm::dyn_cast<Variable>(Src)) {
+    if (Var->hasReg()) {
+      // This is a physical xmm register, so we need to spill it to a
+      // temporary stack slot.
+      Immediate Width(typeWidthInBytes(Ty));
+      Asm->sub(IceType_i32,
+               InstX86Base<Machine>::Traits::RegisterSet::Encoded_Reg_esp,
+               Width);
+      typename InstX86Base<Machine>::Traits::Address StackSlot =
+          typename InstX86Base<Machine>::Traits::Address(
+              InstX86Base<Machine>::Traits::RegisterSet::Encoded_Reg_esp, 0);
+      Asm->movss(Ty, StackSlot,
+                 InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
+                     Var->getRegNum()));
+      Asm->fld(Ty, StackSlot);
+      Asm->add(IceType_i32,
+               InstX86Base<Machine>::Traits::RegisterSet::Encoded_Reg_esp,
+               Width);
+    } else {
+      typename InstX86Base<Machine>::Traits::Address StackAddr(
+          static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
+              Func->getTarget())
+              ->stackVarToAsmOperand(Var));
+      Asm->fld(Ty, StackAddr);
+    }
+  } else if (const auto Mem = llvm::dyn_cast<
+                 typename InstX86Base<Machine>::Traits::X86OperandMem>(Src)) {
+    assert(Mem->getSegmentRegister() ==
+           InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment);
+    Asm->fld(Ty, Mem->toAsmAddress(Asm));
+  } else if (const auto Imm = llvm::dyn_cast<Constant>(Src)) {
+    Asm->fld(Ty, InstX86Base<Machine>::Traits::Address::ofConstPool(Asm, Imm));
+  } else {
+    llvm_unreachable("Unexpected operand type");
+  }
+}
+
+template <class Machine> void InstX86Fld<Machine>::dump(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrDump();
+  Str << "fld." << this->getSrc(0)->getType() << " ";
+  this->dumpSources(Func);
+}
+
+template <class Machine>
+void InstX86Fstp<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrEmit();
+  assert(this->getSrcSize() == 0);
+  // TODO(jvoung,stichnot): Utilize this by setting Dest to nullptr to
+  // "partially" delete the fstp if the Dest is unused.
+  // Even if Dest is unused, the fstp should be kept for the SideEffects
+  // of popping the stack.
+  if (!this->getDest()) {
+    Str << "\tfstp\tst(0)";
+    return;
+  }
+  Type Ty = this->getDest()->getType();
+  size_t Width = typeWidthInBytes(Ty);
+  if (!this->getDest()->hasReg()) {
+    Str << "\tfstp" << this->getFldString(Ty) << "\t";
+    this->getDest()->emit(Func);
+    return;
+  }
+  // Dest is a physical (xmm) register, so st(0) needs to go through
+  // memory.  Hack this by creating a temporary stack slot, spilling
+  // st(0) there, loading it into the xmm register, and deallocating
+  // the stack slot.
+  Str << "\tsubl\t$" << Width << ", %esp\n";
+  Str << "\tfstp" << this->getFldString(Ty) << "\t"
+      << "(%esp)\n";
+  Str << "\tmov" << InstX86Base<Machine>::Traits::TypeAttributes[Ty].SdSsString
+      << "\t"
+      << "(%esp), ";
+  this->getDest()->emit(Func);
+  Str << "\n";
+  Str << "\taddl\t$" << Width << ", %esp";
+}
+
+template <class Machine>
+void InstX86Fstp<Machine>::emitIAS(const Cfg *Func) const {
+  typename InstX86Base<Machine>::Traits::Assembler *Asm =
+      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
+  assert(this->getSrcSize() == 0);
+  const Variable *Dest = this->getDest();
+  // TODO(jvoung,stichnot): Utilize this by setting Dest to nullptr to
+  // "partially" delete the fstp if the Dest is unused.
+  // Even if Dest is unused, the fstp should be kept for the SideEffects
+  // of popping the stack.
+  if (!Dest) {
+    Asm->fstp(InstX86Base<Machine>::Traits::RegisterSet::getEncodedSTReg(0));
+    return;
+  }
+  Type Ty = Dest->getType();
+  if (!Dest->hasReg()) {
+    typename InstX86Base<Machine>::Traits::Address StackAddr(
+        static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
+            Func->getTarget())
+            ->stackVarToAsmOperand(Dest));
+    Asm->fstp(Ty, StackAddr);
+  } else {
+    // Dest is a physical (xmm) register, so st(0) needs to go through
+    // memory.  Hack this by creating a temporary stack slot, spilling
+    // st(0) there, loading it into the xmm register, and deallocating
+    // the stack slot.
+    Immediate Width(typeWidthInBytes(Ty));
+    Asm->sub(IceType_i32,
+             InstX86Base<Machine>::Traits::RegisterSet::Encoded_Reg_esp, Width);
+    typename InstX86Base<Machine>::Traits::Address StackSlot =
+        typename InstX86Base<Machine>::Traits::Address(
+            InstX86Base<Machine>::Traits::RegisterSet::Encoded_Reg_esp, 0);
+    Asm->fstp(Ty, StackSlot);
+    Asm->movss(Ty, InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
+                       Dest->getRegNum()),
+               StackSlot);
+    Asm->add(IceType_i32,
+             InstX86Base<Machine>::Traits::RegisterSet::Encoded_Reg_esp, Width);
+  }
+}
+
+template <class Machine>
+void InstX86Fstp<Machine>::dump(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrDump();
+  this->dumpDest(Func);
+  Str << " = fstp." << this->getDest()->getType() << ", st(0)";
+}
+
+template <class Machine>
+void InstX86Pcmpeq<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  char buf[30];
+  snprintf(
+      buf, llvm::array_lengthof(buf), "pcmpeq%s",
+      InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()]
+          .PackString);
+  this->emitTwoAddress(buf, this, Func);
+}
+
+template <class Machine>
+void InstX86Pcmpgt<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  char buf[30];
+  snprintf(
+      buf, llvm::array_lengthof(buf), "pcmpgt%s",
+      InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()]
+          .PackString);
+  this->emitTwoAddress(buf, this, Func);
+}
+
+template <class Machine>
+void InstX86Pextr<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrEmit();
+  assert(this->getSrcSize() == 2);
+  // pextrb and pextrd are SSE4.1 instructions.
+  assert(this->getSrc(0)->getType() == IceType_v8i16 ||
+         this->getSrc(0)->getType() == IceType_v8i1 ||
+         static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
+             Func->getTarget())
+                 ->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1);
+  Str << "\t" << this->Opcode
+      << InstX86Base<Machine>::Traits::TypeAttributes[this->getSrc(0)
+                                                          ->getType()]
+             .PackString << "\t";
+  this->getSrc(1)->emit(Func);
+  Str << ", ";
+  this->getSrc(0)->emit(Func);
+  Str << ", ";
+  Variable *Dest = this->getDest();
+  // pextrw must take a register dest. There is an SSE4.1 version that takes
+  // a memory dest, but we aren't using it. For uniformity, just restrict
+  // them all to have a register dest for now.
+  assert(Dest->hasReg());
+  Dest->asType(IceType_i32)->emit(Func);
+}
+
+template <class Machine>
+void InstX86Pextr<Machine>::emitIAS(const Cfg *Func) const {
+  assert(this->getSrcSize() == 2);
+  // pextrb and pextrd are SSE4.1 instructions.
+  const Variable *Dest = this->getDest();
+  Type DispatchTy = Dest->getType();
+  assert(DispatchTy == IceType_i16 ||
+         static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
+             Func->getTarget())
+                 ->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1);
+  // pextrw must take a register dest. There is an SSE4.1 version that takes
+  // a memory dest, but we aren't using it. For uniformity, just restrict
+  // them all to have a register dest for now.
+  assert(Dest->hasReg());
+  // pextrw's Src(0) must be a register (both SSE4.1 and SSE2).
+  assert(llvm::cast<Variable>(this->getSrc(0))->hasReg());
+  static const typename InstX86Base<Machine>::Traits::Assembler::
+      template ThreeOpImmEmitter<
+          typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister,
+          typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister>
+          Emitter = {&InstX86Base<Machine>::Traits::Assembler::pextr, nullptr};
+  emitIASThreeOpImmOps<
+      Machine, typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister,
+      typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
+      InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR,
+      InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm>(
+      Func, DispatchTy, Dest, this->getSrc(0), this->getSrc(1), Emitter);
+}
+
+template <class Machine>
+void InstX86Pinsr<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrEmit();
+  assert(this->getSrcSize() == 3);
+  // pinsrb and pinsrd are SSE4.1 instructions.
+  assert(this->getDest()->getType() == IceType_v8i16 ||
+         this->getDest()->getType() == IceType_v8i1 ||
+         static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
+             Func->getTarget())
+                 ->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1);
+  Str << "\t" << this->Opcode
+      << InstX86Base<
+             Machine>::Traits::TypeAttributes[this->getDest()->getType()]
+             .PackString << "\t";
+  this->getSrc(2)->emit(Func);
+  Str << ", ";
+  Operand *Src1 = this->getSrc(1);
+  if (const auto Src1Var = llvm::dyn_cast<Variable>(Src1)) {
+    // If src1 is a register, it should always be r32.
+    if (Src1Var->hasReg()) {
+      Src1Var->asType(IceType_i32)->emit(Func);
+    } else {
+      Src1Var->emit(Func);
+    }
+  } else {
+    Src1->emit(Func);
+  }
+  Str << ", ";
+  this->getDest()->emit(Func);
+}
+
+template <class Machine>
+void InstX86Pinsr<Machine>::emitIAS(const Cfg *Func) const {
+  assert(this->getSrcSize() == 3);
+  assert(this->getDest() == this->getSrc(0));
+  // pinsrb and pinsrd are SSE4.1 instructions.
+  const Operand *Src0 = this->getSrc(1);
+  Type DispatchTy = Src0->getType();
+  assert(DispatchTy == IceType_i16 ||
+         static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
+             Func->getTarget())
+                 ->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1);
+  // If src1 is a register, it should always be r32 (this should fall out
+  // from the encodings for ByteRegs overlapping the encodings for r32),
+  // but we have to trust the regalloc to not choose "ah", where it
+  // doesn't overlap.
+  static const typename InstX86Base<Machine>::Traits::Assembler::
+      template ThreeOpImmEmitter<
+          typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
+          typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister>
+          Emitter = {&InstX86Base<Machine>::Traits::Assembler::pinsr,
+                     &InstX86Base<Machine>::Traits::Assembler::pinsr};
+  emitIASThreeOpImmOps<
+      Machine, typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
+      typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister,
+      InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm,
+      InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR>(
+      Func, DispatchTy, this->getDest(), Src0, this->getSrc(2), Emitter);
+}
+
+template <class Machine>
+void InstX86Pshufd<Machine>::emitIAS(const Cfg *Func) const {
+  assert(this->getSrcSize() == 2);
+  const Variable *Dest = this->getDest();
+  Type Ty = Dest->getType();
+  static const typename InstX86Base<Machine>::Traits::Assembler::
+      template ThreeOpImmEmitter<
+          typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
+          typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister>
+          Emitter = {&InstX86Base<Machine>::Traits::Assembler::pshufd,
+                     &InstX86Base<Machine>::Traits::Assembler::pshufd};
+  emitIASThreeOpImmOps<
+      Machine, typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
+      typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
+      InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm,
+      InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm>(
+      Func, Ty, Dest, this->getSrc(0), this->getSrc(1), Emitter);
+}
+
+template <class Machine>
+void InstX86Shufps<Machine>::emitIAS(const Cfg *Func) const {
+  assert(this->getSrcSize() == 3);
+  const Variable *Dest = this->getDest();
+  assert(Dest == this->getSrc(0));
+  Type Ty = Dest->getType();
+  static const typename InstX86Base<Machine>::Traits::Assembler::
+      template ThreeOpImmEmitter<
+          typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
+          typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister>
+          Emitter = {&InstX86Base<Machine>::Traits::Assembler::shufps,
+                     &InstX86Base<Machine>::Traits::Assembler::shufps};
+  emitIASThreeOpImmOps<
+      Machine, typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
+      typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
+      InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm,
+      InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm>(
+      Func, Ty, Dest, this->getSrc(1), this->getSrc(2), Emitter);
+}
+
+template <class Machine> void InstX86Pop<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrEmit();
+  assert(this->getSrcSize() == 0);
+  Str << "\tpop\t";
+  this->getDest()->emit(Func);
+}
+
+template <class Machine>
+void InstX86Pop<Machine>::emitIAS(const Cfg *Func) const {
+  assert(this->getSrcSize() == 0);
+  typename InstX86Base<Machine>::Traits::Assembler *Asm =
+      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
+  if (this->getDest()->hasReg()) {
+    Asm->popl(InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
+        this->getDest()->getRegNum()));
+  } else {
+    Asm->popl(
+        static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
+            Func->getTarget())
+            ->stackVarToAsmOperand(this->getDest()));
+  }
+}
+
+template <class Machine> void InstX86Pop<Machine>::dump(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrDump();
+  this->dumpDest(Func);
+  Str << " = pop." << this->getDest()->getType() << " ";
+}
+
+template <class Machine>
+void InstX86AdjustStack<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrEmit();
+  Str << "\tsubl\t$" << Amount << ", %esp";
+  Func->getTarget()->updateStackAdjustment(Amount);
+}
+
+template <class Machine>
+void InstX86AdjustStack<Machine>::emitIAS(const Cfg *Func) const {
+  typename InstX86Base<Machine>::Traits::Assembler *Asm =
+      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
+  Asm->sub(IceType_i32,
+           InstX86Base<Machine>::Traits::RegisterSet::Encoded_Reg_esp,
+           Immediate(Amount));
+  Func->getTarget()->updateStackAdjustment(Amount);
+}
+
+template <class Machine>
+void InstX86AdjustStack<Machine>::dump(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrDump();
+  Str << "esp = sub.i32 esp, " << Amount;
+}
+
+template <class Machine>
+void InstX86Push<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrEmit();
+  assert(this->getSrcSize() == 1);
+  // Push is currently only used for saving GPRs.
+  const auto Var = llvm::cast<Variable>(this->getSrc(0));
+  assert(Var->hasReg());
+  Str << "\tpush\t";
+  Var->emit(Func);
+}
+
+template <class Machine>
+void InstX86Push<Machine>::emitIAS(const Cfg *Func) const {
+  assert(this->getSrcSize() == 1);
+  // Push is currently only used for saving GPRs.
+  const auto Var = llvm::cast<Variable>(this->getSrc(0));
+  assert(Var->hasReg());
+  typename InstX86Base<Machine>::Traits::Assembler *Asm =
+      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
+  Asm->pushl(InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
+      Var->getRegNum()));
+}
+
+template <class Machine>
+void InstX86Push<Machine>::dump(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrDump();
+  Str << "push." << this->getSrc(0)->getType() << " ";
+  this->dumpSources(Func);
+}
+
+template <class Machine>
+void InstX86Psll<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  assert(this->getDest()->getType() == IceType_v8i16 ||
+         this->getDest()->getType() == IceType_v8i1 ||
+         this->getDest()->getType() == IceType_v4i32 ||
+         this->getDest()->getType() == IceType_v4i1);
+  char buf[30];
+  snprintf(
+      buf, llvm::array_lengthof(buf), "psll%s",
+      InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()]
+          .PackString);
+  this->emitTwoAddress(buf, this, Func);
+}
+
+template <class Machine>
+void InstX86Psra<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  assert(this->getDest()->getType() == IceType_v8i16 ||
+         this->getDest()->getType() == IceType_v8i1 ||
+         this->getDest()->getType() == IceType_v4i32 ||
+         this->getDest()->getType() == IceType_v4i1);
+  char buf[30];
+  snprintf(
+      buf, llvm::array_lengthof(buf), "psra%s",
+      InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()]
+          .PackString);
+  this->emitTwoAddress(buf, this, Func);
+}
+
+template <class Machine>
+void InstX86Psrl<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  char buf[30];
+  snprintf(
+      buf, llvm::array_lengthof(buf), "psrl%s",
+      InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()]
+          .PackString);
+  this->emitTwoAddress(buf, this, Func);
+}
+
+template <class Machine> void InstX86Ret<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrEmit();
+  Str << "\tret";
+}
+
+template <class Machine>
+void InstX86Ret<Machine>::emitIAS(const Cfg *Func) const {
+  typename InstX86Base<Machine>::Traits::Assembler *Asm =
+      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
+  Asm->ret();
+}
+
+template <class Machine> void InstX86Ret<Machine>::dump(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrDump();
+  Type Ty =
+      (this->getSrcSize() == 0 ? IceType_void : this->getSrc(0)->getType());
+  Str << "ret." << Ty << " ";
+  this->dumpSources(Func);
+}
+
+template <class Machine>
+void InstX86Setcc<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrEmit();
+  Str << "\tset"
+      << InstX86Base<Machine>::Traits::InstBrAttributes[Condition].DisplayString
+      << "\t";
+  this->Dest->emit(Func);
+}
+
+template <class Machine>
+void InstX86Setcc<Machine>::emitIAS(const Cfg *Func) const {
+  assert(Condition != InstX86Base<Machine>::Traits::Cond::Br_None);
+  assert(this->getDest()->getType() == IceType_i1);
+  assert(this->getSrcSize() == 0);
+  typename InstX86Base<Machine>::Traits::Assembler *Asm =
+      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
+  if (this->getDest()->hasReg())
+    Asm->setcc(Condition,
+               InstX86Base<Machine>::Traits::RegisterSet::getEncodedByteReg(
+                   this->getDest()->getRegNum()));
+  else
+    Asm->setcc(
+        Condition,
+        static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
+            Func->getTarget())
+            ->stackVarToAsmOperand(this->getDest()));
+  return;
+}
+
+template <class Machine>
+void InstX86Setcc<Machine>::dump(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrDump();
+  Str << "setcc."
+      << InstX86Base<Machine>::Traits::InstBrAttributes[Condition].DisplayString
+      << " ";
+  this->dumpDest(Func);
+}
+
+template <class Machine>
+void InstX86Xadd<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrEmit();
+  if (this->Locked) {
+    Str << "\tlock";
+  }
+  Str << "\txadd" << this->getWidthString(this->getSrc(0)->getType()) << "\t";
+  this->getSrc(1)->emit(Func);
+  Str << ", ";
+  this->getSrc(0)->emit(Func);
+}
+
+template <class Machine>
+void InstX86Xadd<Machine>::emitIAS(const Cfg *Func) const {
+  assert(this->getSrcSize() == 2);
+  typename InstX86Base<Machine>::Traits::Assembler *Asm =
+      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
+  Type Ty = this->getSrc(0)->getType();
+  const auto Mem =
+      llvm::cast<typename InstX86Base<Machine>::Traits::X86OperandMem>(
+          this->getSrc(0));
+  assert(Mem->getSegmentRegister() ==
+         InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment);
+  const typename InstX86Base<Machine>::Traits::Address Addr =
+      Mem->toAsmAddress(Asm);
+  const auto VarReg = llvm::cast<Variable>(this->getSrc(1));
+  assert(VarReg->hasReg());
+  const typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister Reg =
+      InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
+          VarReg->getRegNum());
+  Asm->xadd(Ty, Addr, Reg, this->Locked);
+}
+
+template <class Machine>
+void InstX86Xadd<Machine>::dump(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrDump();
+  if (this->Locked) {
+    Str << "lock ";
+  }
+  Type Ty = this->getSrc(0)->getType();
+  Str << "xadd." << Ty << " ";
+  this->dumpSources(Func);
+}
+
+template <class Machine>
+void InstX86Xchg<Machine>::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrEmit();
+  Str << "\txchg" << this->getWidthString(this->getSrc(0)->getType()) << "\t";
+  this->getSrc(1)->emit(Func);
+  Str << ", ";
+  this->getSrc(0)->emit(Func);
+}
+
+template <class Machine>
+void InstX86Xchg<Machine>::emitIAS(const Cfg *Func) const {
+  assert(this->getSrcSize() == 2);
+  typename InstX86Base<Machine>::Traits::Assembler *Asm =
+      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
+  Type Ty = this->getSrc(0)->getType();
+  const auto Mem =
+      llvm::cast<typename InstX86Base<Machine>::Traits::X86OperandMem>(
+          this->getSrc(0));
+  assert(Mem->getSegmentRegister() ==
+         InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment);
+  const typename InstX86Base<Machine>::Traits::Address Addr =
+      Mem->toAsmAddress(Asm);
+  const auto VarReg = llvm::cast<Variable>(this->getSrc(1));
+  assert(VarReg->hasReg());
+  const typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister Reg =
+      InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
+          VarReg->getRegNum());
+  Asm->xchg(Ty, Addr, Reg);
+}
+
+template <class Machine>
+void InstX86Xchg<Machine>::dump(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrDump();
+  Type Ty = this->getSrc(0)->getType();
+  Str << "xchg." << Ty << " ";
+  this->dumpSources(Func);
+}
+
+} // end of namespace X86Internal
+
+} // end of namespace Ice
+
+#endif // SUBZERO_SRC_ICEINSTX86BASEIMPL_H
diff --git a/src/IceTargetLoweringX8632.cpp b/src/IceTargetLoweringX8632.cpp
index c6a72d6..0d9572a 100644
--- a/src/IceTargetLoweringX8632.cpp
+++ b/src/IceTargetLoweringX8632.cpp
@@ -77,6 +77,7 @@
     llvm::array_lengthof(TableTypeX8632Attributes);
 
 const uint32_t MachineTraits<TargetX8632>::X86_STACK_ALIGNMENT_BYTES = 16;
+const char *MachineTraits<TargetX8632>::TargetName = "X8632";
 
 } // end of namespace X86Internal
 
diff --git a/src/IceTargetLoweringX8632Traits.h b/src/IceTargetLoweringX8632Traits.h
index 4cd22fa..ae9abe1 100644
--- a/src/IceTargetLoweringX8632Traits.h
+++ b/src/IceTargetLoweringX8632Traits.h
@@ -6,9 +6,10 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-//
-// This file defines the X8632 Target Lowering Traits.
-//
+///
+/// \file
+/// This file declares the X8632 Target Lowering Traits.
+///
 //===----------------------------------------------------------------------===//
 
 #ifndef SUBZERO_SRC_ICETARGETLOWERINGX8632TRAITS_H
@@ -19,15 +20,22 @@
 #include "IceDefs.h"
 #include "IceInst.h"
 #include "IceInstX8632.def"
+#include "IceOperand.h"
 #include "IceRegistersX8632.h"
 #include "IceTargetLoweringX8632.def"
+#include "IceTargetLowering.h"
 
 namespace Ice {
 
 class TargetX8632;
 
+namespace X8632 {
+class AssemblerX8632;
+} // end of namespace X8632
+
 namespace X86Internal {
 
+template <class Machine> struct Insts;
 template <class Machine> struct MachineTraits;
 
 template <> struct MachineTraits<TargetX8632> {
@@ -56,7 +64,7 @@
   class Operand {
   public:
     Operand(const Operand &other)
-        : length_(other.length_), fixup_(other.fixup_) {
+        : fixup_(other.fixup_), length_(other.length_) {
       memmove(&encoding_[0], &other.encoding_[0], other.length_);
     }
 
@@ -98,7 +106,7 @@
     AssemblerFixup *fixup() const { return fixup_; }
 
   protected:
-    Operand() : length_(0), fixup_(nullptr) {} // Needed by subclass Address.
+    Operand() : fixup_(nullptr), length_(0) {} // Needed by subclass Address.
 
     void SetModRM(int mod, GPRRegister rm) {
       assert((mod & ~3) == 0);
@@ -128,20 +136,20 @@
     void SetFixup(AssemblerFixup *fixup) { fixup_ = fixup; }
 
   private:
-    uint8_t length_;
-    uint8_t encoding_[6];
     AssemblerFixup *fixup_;
+    uint8_t encoding_[6];
+    uint8_t length_;
 
     explicit Operand(GPRRegister reg) : fixup_(nullptr) { SetModRM(3, reg); }
 
-    // Get the operand encoding byte at the given index.
+    /// Get the operand encoding byte at the given index.
     uint8_t encoding_at(intptr_t index) const {
       assert(index >= 0 && index < length_);
       return encoding_[index];
     }
 
-    // Returns whether or not this operand is really the given register in
-    // disguise. Used from the assembler to generate better encodings.
+    /// Returns whether or not this operand is really the given register in
+    /// disguise. Used from the assembler to generate better encodings.
     bool IsRegister(GPRRegister reg) const {
       return ((encoding_[0] & 0xF8) ==
               0xC0) // Addressing mode is register only.
@@ -205,8 +213,8 @@
       }
     }
 
-    // AbsoluteTag is a special tag used by clients to create an absolute
-    // Address.
+    /// AbsoluteTag is a special tag used by clients to create an absolute
+    /// Address.
     enum AbsoluteTag { ABSOLUTE };
 
     Address(AbsoluteTag, const uintptr_t Addr) {
@@ -255,27 +263,182 @@
     End
   };
 
-  // The maximum number of arguments to pass in XMM registers
+  static const char *TargetName;
+
+  static IceString getRegName(SizeT RegNum, Type Ty) {
+    assert(RegNum < RegisterSet::Reg_NUM);
+    static const char *RegNames8[] = {
+#define X(val, encode, name, name16, name8, scratch, preserved, stackptr,      \
+          frameptr, isI8, isInt, isFP)                                         \
+  name8,
+        REGX8632_TABLE
+#undef X
+    };
+
+    static const char *RegNames16[] = {
+#define X(val, encode, name, name16, name8, scratch, preserved, stackptr,      \
+          frameptr, isI8, isInt, isFP)                                         \
+  name16,
+        REGX8632_TABLE
+#undef X
+    };
+
+    static const char *RegNames[] = {
+#define X(val, encode, name, name16, name8, scratch, preserved, stackptr,      \
+          frameptr, isI8, isInt, isFP)                                         \
+  name,
+        REGX8632_TABLE
+#undef X
+    };
+
+    switch (Ty) {
+    case IceType_i1:
+    case IceType_i8:
+      return RegNames8[RegNum];
+    case IceType_i16:
+      return RegNames16[RegNum];
+    default:
+      return RegNames[RegNum];
+    }
+  }
+
+  static void initRegisterSet(llvm::SmallBitVector *IntegerRegisters,
+                              llvm::SmallBitVector *IntegerRegistersI8,
+                              llvm::SmallBitVector *FloatRegisters,
+                              llvm::SmallBitVector *VectorRegisters,
+                              llvm::SmallBitVector *ScratchRegs) {
+#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;                                 \
+  (*ScratchRegs)[RegisterSet::val] = scratch;
+    REGX8632_TABLE;
+#undef X
+  }
+
+  static llvm::SmallBitVector
+  getRegisterSet(TargetLowering::RegSetMask Include,
+                 TargetLowering::RegSetMask Exclude) {
+    llvm::SmallBitVector Registers(RegisterSet::Reg_NUM);
+
+#define X(val, encode, name, name16, name8, scratch, preserved, stackptr,      \
+          frameptr, isI8, isInt, isFP)                                         \
+  if (scratch && (Include & ::Ice::TargetLowering::RegSet_CallerSave))         \
+    Registers[RegisterSet::val] = true;                                        \
+  if (preserved && (Include & ::Ice::TargetLowering::RegSet_CalleeSave))       \
+    Registers[RegisterSet::val] = true;                                        \
+  if (stackptr && (Include & ::Ice::TargetLowering::RegSet_StackPointer))      \
+    Registers[RegisterSet::val] = true;                                        \
+  if (frameptr && (Include & ::Ice::TargetLowering::RegSet_FramePointer))      \
+    Registers[RegisterSet::val] = true;                                        \
+  if (scratch && (Exclude & ::Ice::TargetLowering::RegSet_CallerSave))         \
+    Registers[RegisterSet::val] = false;                                       \
+  if (preserved && (Exclude & ::Ice::TargetLowering::RegSet_CalleeSave))       \
+    Registers[RegisterSet::val] = false;                                       \
+  if (stackptr && (Exclude & ::Ice::TargetLowering::RegSet_StackPointer))      \
+    Registers[RegisterSet::val] = false;                                       \
+  if (frameptr && (Exclude & ::Ice::TargetLowering::RegSet_FramePointer))      \
+    Registers[RegisterSet::val] = false;
+
+    REGX8632_TABLE
+
+#undef X
+
+    return Registers;
+  }
+
+  static void
+  makeRandomRegisterPermutation(GlobalContext *Ctx, Cfg *Func,
+                                llvm::SmallVectorImpl<int32_t> &Permutation,
+                                const llvm::SmallBitVector &ExcludeRegisters) {
+    // TODO(stichnot): Declaring Permutation this way loses type/size
+    // information.  Fix this in conjunction with the caller-side TODO.
+    assert(Permutation.size() >= RegisterSet::Reg_NUM);
+    // Expected upper bound on the number of registers in a single equivalence
+    // class.  For x86-32, this would comprise the 8 XMM registers.  This is for
+    // performance, not correctness.
+    static const unsigned MaxEquivalenceClassSize = 8;
+    typedef llvm::SmallVector<int32_t, MaxEquivalenceClassSize> RegisterList;
+    typedef std::map<uint32_t, RegisterList> EquivalenceClassMap;
+    EquivalenceClassMap EquivalenceClasses;
+    SizeT NumShuffled = 0, NumPreserved = 0;
+
+// 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)                                         \
+  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);                         \
+    /* val is assigned to an equivalence class based on its properties. */     \
+    EquivalenceClasses[Index].push_back(RegisterSet::val);                     \
+  }
+    REGX8632_TABLE
+#undef X
+
+    RandomNumberGeneratorWrapper RNG(Ctx->getRNG());
+
+    // Shuffle the resulting equivalence classes.
+    for (auto I : EquivalenceClasses) {
+      const RegisterList &List = I.second;
+      RegisterList Shuffled(List);
+      RandomShuffle(Shuffled.begin(), Shuffled.end(), RNG);
+      for (size_t SI = 0, SE = Shuffled.size(); SI < SE; ++SI) {
+        Permutation[List[SI]] = Shuffled[SI];
+        ++NumShuffled;
+      }
+    }
+
+    assert(NumShuffled + NumPreserved == RegisterSet::Reg_NUM);
+
+    if (Func->isVerbose(IceV_Random)) {
+      OstreamLocker L(Func->getContext());
+      Ostream &Str = Func->getContext()->getStrDump();
+      Str << "Register equivalence classes:\n";
+      for (auto I : EquivalenceClasses) {
+        Str << "{";
+        const RegisterList &List = I.second;
+        bool First = true;
+        for (int32_t Register : List) {
+          if (!First)
+            Str << " ";
+          First = false;
+          Str << getRegName(Register, IceType_i32);
+        }
+        Str << "}\n";
+      }
+    }
+  }
+
+  /// The maximum number of arguments to pass in XMM registers
   static const uint32_t X86_MAX_XMM_ARGS = 4;
-  // The number of bits in a byte
+  /// The number of bits in a byte
   static const uint32_t X86_CHAR_BIT = 8;
-  // Stack alignment. This is defined in IceTargetLoweringX8632.cpp because it
-  // is used as an argument to std::max(), and the default std::less<T> has an
-  // operator(T const&, T const&) which requires this member to have an address.
+  /// Stack alignment. This is defined in IceTargetLoweringX8632.cpp because it
+  /// is used as an argument to std::max(), and the default std::less<T> has an
+  /// operator(T const&, T const&) which requires this member to have an
+  /// address.
   static const uint32_t X86_STACK_ALIGNMENT_BYTES;
-  // Size of the return address on the stack
+  /// Size of the return address on the stack
   static const uint32_t X86_RET_IP_SIZE_BYTES = 4;
-  // The number of different NOP instructions
+  /// The number of different NOP instructions
   static const uint32_t X86_NUM_NOP_VARIANTS = 5;
 
-  // Value is in bytes. Return Value adjusted to the next highest multiple
-  // of the stack alignment.
+  /// Value is in bytes. Return Value adjusted to the next highest multiple
+  /// of the stack alignment.
   static uint32_t applyStackAlignment(uint32_t Value) {
     return Utils::applyAlignment(Value, X86_STACK_ALIGNMENT_BYTES);
   }
 
-  // Return the type which the elements of the vector have in the X86
-  // representation of the vector.
+  /// Return the type which the elements of the vector have in the X86
+  /// representation of the vector.
   static Type getInVectorElementType(Type Ty) {
     assert(isVectorType(Ty));
     size_t Index = static_cast<size_t>(Ty);
@@ -287,51 +450,54 @@
   // Note: The following data structures are defined in
   // IceTargetLoweringX8632.cpp.
 
-  // The following table summarizes the logic for lowering the fcmp
-  // instruction.  There is one table entry for each of the 16 conditions.
-  //
-  // The first four columns describe the case when the operands are
-  // floating point scalar values.  A comment in lowerFcmp() describes the
-  // lowering template.  In the most general case, there is a compare
-  // followed by two conditional branches, because some fcmp conditions
-  // don't map to a single x86 conditional branch.  However, in many cases
-  // it is possible to swap the operands in the comparison and have a
-  // single conditional branch.  Since it's quite tedious to validate the
-  // table by hand, good execution tests are helpful.
-  //
-  // The last two columns describe the case when the operands are vectors
-  // of floating point values.  For most fcmp conditions, there is a clear
-  // mapping to a single x86 cmpps instruction variant.  Some fcmp
-  // conditions require special code to handle and these are marked in the
-  // table with a Cmpps_Invalid predicate.
+  /// The following table summarizes the logic for lowering the fcmp
+  /// instruction. There is one table entry for each of the 16 conditions.
+  ///
+  /// The first four columns describe the case when the operands are floating
+  /// point scalar values.  A comment in lowerFcmp() describes the lowering
+  /// template.  In the most general case, there is a compare followed by two
+  /// conditional branches, because some fcmp conditions don't map to a single
+  /// x86 conditional branch.  However, in many cases it is possible to swap the
+  /// operands in the comparison and have a single conditional branch.  Since
+  /// it's quite tedious to validate the table by hand, good execution tests are
+  /// helpful.
+  ///
+  /// The last two columns describe the case when the operands are vectors of
+  /// floating point values.  For most fcmp conditions, there is a clear mapping
+  /// to a single x86 cmpps instruction variant.  Some fcmp conditions require
+  /// special code to handle and these are marked in the table with a
+  /// Cmpps_Invalid predicate.
+  /// {@
   static const struct TableFcmpType {
     uint32_t Default;
     bool SwapScalarOperands;
-    CondX86::BrCond C1, C2;
+    Cond::BrCond C1, C2;
     bool SwapVectorOperands;
-    CondX86::CmppsCond Predicate;
+    Cond::CmppsCond Predicate;
   } TableFcmp[];
   static const size_t TableFcmpSize;
+  /// @}
 
-  // The following table summarizes the logic for lowering the icmp instruction
-  // for i32 and narrower types.  Each icmp condition has a clear mapping to an
-  // x86 conditional branch instruction.
-
-  static const struct TableIcmp32Type {
-    CondX86::BrCond Mapping;
-  } TableIcmp32[];
+  /// The following table summarizes the logic for lowering the icmp instruction
+  /// for i32 and narrower types.  Each icmp condition has a clear mapping to an
+  /// x86 conditional branch instruction.
+  /// {@
+  static const struct TableIcmp32Type { Cond::BrCond Mapping; } TableIcmp32[];
   static const size_t TableIcmp32Size;
+  /// @}
 
-  // The following table summarizes the logic for lowering the icmp instruction
-  // for the i64 type.  For Eq and Ne, two separate 32-bit comparisons and
-  // conditional branches are needed.  For the other conditions, three separate
-  // conditional branches are needed.
+  /// The following table summarizes the logic for lowering the icmp instruction
+  /// for the i64 type.  For Eq and Ne, two separate 32-bit comparisons and
+  /// conditional branches are needed.  For the other conditions, three separate
+  /// conditional branches are needed.
+  /// {@
   static const struct TableIcmp64Type {
-    CondX86::BrCond C1, C2, C3;
+    Cond::BrCond C1, C2, C3;
   } TableIcmp64[];
   static const size_t TableIcmp64Size;
+  /// @}
 
-  static CondX86::BrCond getIcmp32Mapping(InstIcmp::ICond Cond) {
+  static Cond::BrCond getIcmp32Mapping(InstIcmp::ICond Cond) {
     size_t Index = static_cast<size_t>(Cond);
     assert(Index < TableIcmp32Size);
     return TableIcmp32[Index].Mapping;
@@ -341,6 +507,190 @@
     Type InVectorElementType;
   } TableTypeX8632Attributes[];
   static const size_t TableTypeX8632AttributesSize;
+
+  //----------------------------------------------------------------------------
+  //      __  __   __  ______  ______
+  //    /\ \/\ "-.\ \/\  ___\/\__  _\
+  //    \ \ \ \ \-.  \ \___  \/_/\ \/
+  //     \ \_\ \_\\"\_\/\_____\ \ \_\
+  //      \/_/\/_/ \/_/\/_____/  \/_/
+  //
+  //----------------------------------------------------------------------------
+  using Insts = ::Ice::X86Internal::Insts<TargetX8632>;
+
+  using TargetLowering = TargetX8632;
+  using Assembler = X8632::AssemblerX8632;
+
+  /// X86Operand extends the Operand hierarchy.  Its subclasses are
+  /// X86OperandMem and VariableSplit.
+  class X86Operand : public ::Ice::Operand {
+    X86Operand() = delete;
+    X86Operand(const X86Operand &) = delete;
+    X86Operand &operator=(const X86Operand &) = delete;
+
+  public:
+    enum OperandKindX8632 { k__Start = ::Ice::Operand::kTarget, kMem, kSplit };
+    using ::Ice::Operand::dump;
+
+    void dump(const Cfg *, Ostream &Str) const override;
+
+  protected:
+    X86Operand(OperandKindX8632 Kind, Type Ty)
+        : Operand(static_cast<::Ice::Operand::OperandKind>(Kind), Ty) {}
+  };
+
+  /// X86OperandMem represents the m32 addressing mode, with optional base and
+  /// index registers, a constant offset, and a fixed shift value for the index
+  /// register.
+  class X86OperandMem : public X86Operand {
+    X86OperandMem() = delete;
+    X86OperandMem(const X86OperandMem &) = delete;
+    X86OperandMem &operator=(const X86OperandMem &) = delete;
+
+  public:
+    enum SegmentRegisters {
+      DefaultSegment = -1,
+#define X(val, name, prefix) val,
+      SEG_REGX8632_TABLE
+#undef X
+          SegReg_NUM
+    };
+    static X86OperandMem *create(Cfg *Func, Type Ty, Variable *Base,
+                                 Constant *Offset, Variable *Index = nullptr,
+                                 uint16_t Shift = 0,
+                                 SegmentRegisters SegmentReg = DefaultSegment) {
+      return new (Func->allocate<X86OperandMem>())
+          X86OperandMem(Func, Ty, Base, Offset, Index, Shift, SegmentReg);
+    }
+    Variable *getBase() const { return Base; }
+    Constant *getOffset() const { return Offset; }
+    Variable *getIndex() const { return Index; }
+    uint16_t getShift() const { return Shift; }
+    SegmentRegisters getSegmentRegister() const { return SegmentReg; }
+    void emitSegmentOverride(Assembler *Asm) const;
+    Address toAsmAddress(Assembler *Asm) const;
+
+    void emit(const Cfg *Func) const override;
+    using X86Operand::dump;
+    void dump(const Cfg *Func, Ostream &Str) const override;
+
+    static bool classof(const Operand *Operand) {
+      return Operand->getKind() == static_cast<OperandKind>(kMem);
+    }
+
+    void setRandomized(bool R) { Randomized = R; }
+
+    bool getRandomized() const { return Randomized; }
+
+  private:
+    X86OperandMem(Cfg *Func, Type Ty, Variable *Base, Constant *Offset,
+                  Variable *Index, uint16_t Shift, SegmentRegisters SegmentReg);
+
+    Variable *Base;
+    Constant *Offset;
+    Variable *Index;
+    uint16_t Shift;
+    SegmentRegisters SegmentReg : 16;
+    /// A flag to show if this memory operand is a randomized one. Randomized
+    /// memory operands are generated in
+    /// TargetX86Base::randomizeOrPoolImmediate()
+    bool Randomized;
+  };
+
+  /// VariableSplit is a way to treat an f64 memory location as a pair of i32
+  /// locations (Low and High).  This is needed for some cases of the Bitcast
+  /// instruction.  Since it's not possible for integer registers to access the
+  /// XMM registers and vice versa, the lowering forces the f64 to be spilled to
+  /// the stack and then accesses through the VariableSplit.
+  // TODO(jpp): remove references to VariableSplit from IceInstX86Base as 64bit
+  // targets can natively handle these.
+  class VariableSplit : public X86Operand {
+    VariableSplit() = delete;
+    VariableSplit(const VariableSplit &) = delete;
+    VariableSplit &operator=(const VariableSplit &) = delete;
+
+  public:
+    enum Portion { Low, High };
+    static VariableSplit *create(Cfg *Func, Variable *Var, Portion Part) {
+      return new (Func->allocate<VariableSplit>())
+          VariableSplit(Func, Var, Part);
+    }
+    int32_t getOffset() const { return Part == High ? 4 : 0; }
+
+    Address toAsmAddress(const Cfg *Func) const;
+    void emit(const Cfg *Func) const override;
+    using X86Operand::dump;
+    void dump(const Cfg *Func, Ostream &Str) const override;
+
+    static bool classof(const Operand *Operand) {
+      return Operand->getKind() == static_cast<OperandKind>(kSplit);
+    }
+
+  private:
+    VariableSplit(Cfg *Func, Variable *Var, Portion Part)
+        : X86Operand(kSplit, IceType_i32), Var(Var), Part(Part) {
+      assert(Var->getType() == IceType_f64);
+      Vars = Func->allocateArrayOf<Variable *>(1);
+      Vars[0] = Var;
+      NumVars = 1;
+    }
+
+    Variable *Var;
+    Portion Part;
+  };
+
+  /// SpillVariable decorates a Variable by linking it to another Variable.
+  /// When stack frame offsets are computed, the SpillVariable is given a
+  /// distinct stack slot only if its linked Variable has a register.  If the
+  /// linked Variable has a stack slot, then the Variable and SpillVariable
+  /// share that slot.
+  class SpillVariable : public Variable {
+    SpillVariable() = delete;
+    SpillVariable(const SpillVariable &) = delete;
+    SpillVariable &operator=(const SpillVariable &) = delete;
+
+  public:
+    static SpillVariable *create(Cfg *Func, Type Ty, SizeT Index) {
+      return new (Func->allocate<SpillVariable>()) SpillVariable(Ty, Index);
+    }
+    const static OperandKind SpillVariableKind =
+        static_cast<OperandKind>(kVariable_Target);
+    static bool classof(const Operand *Operand) {
+      return Operand->getKind() == SpillVariableKind;
+    }
+    void setLinkedTo(Variable *Var) { LinkedTo = Var; }
+    Variable *getLinkedTo() const { return LinkedTo; }
+    // Inherit dump() and emit() from Variable.
+
+  private:
+    SpillVariable(Type Ty, SizeT Index)
+        : Variable(SpillVariableKind, Ty, Index), LinkedTo(nullptr) {}
+    Variable *LinkedTo;
+  };
+
+  // Note: The following data structures are defined in IceInstX8632.cpp.
+
+  static const struct InstBrAttributesType {
+    Cond::BrCond Opposite;
+    const char *DisplayString;
+    const char *EmitString;
+  } InstBrAttributes[];
+
+  static const struct InstCmppsAttributesType {
+    const char *EmitString;
+  } InstCmppsAttributes[];
+
+  static const struct TypeAttributesType {
+    const char *CvtString;   // i (integer), s (single FP), d (double FP)
+    const char *SdSsString;  // ss, sd, or <blank>
+    const char *PackString;  // b, w, d, or <blank>
+    const char *WidthString; // b, w, l, q, or <blank>
+    const char *FldString;   // s, l, or <blank>
+  } TypeAttributes[];
+
+  static const char *InstSegmentRegNames[];
+
+  static uint8_t InstSegmentPrefixes[];
 };
 
 } // end of namespace X86Internal
diff --git a/src/IceTargetLoweringX86Base.h b/src/IceTargetLoweringX86Base.h
index 37a1107..32d7d6b 100644
--- a/src/IceTargetLoweringX86Base.h
+++ b/src/IceTargetLoweringX86Base.h
@@ -183,7 +183,7 @@
   void lowerSwitch(const InstSwitch *Inst) override;
   void lowerUnreachable(const InstUnreachable *Inst) override;
   void lowerOther(const Inst *Instr) override;
-  void lowerRMW(const InstX8632FakeRMW *RMW);
+  void lowerRMW(const typename Traits::Insts::FakeRMW *RMW);
   void prelowerPhis() override;
   void lowerPhiAssignments(CfgNode *Node,
                            const AssignList &Assignments) override;
@@ -234,8 +234,8 @@
   /// Turn a pointer operand into a memory operand that can be
   /// used by a real load/store operation. Legalizes the operand as well.
   /// This is a nop if the operand is already a legal memory operand.
-  OperandX8632Mem *formMemoryOperand(Operand *Ptr, Type Ty,
-                                     bool DoLegalize = true);
+  typename Traits::X86OperandMem *formMemoryOperand(Operand *Ptr, Type Ty,
+                                                    bool DoLegalize = true);
 
   Variable *makeReg(Type Ty, int32_t RegNum = Variable::NoRegister);
   static Type stackSlotType();
@@ -253,99 +253,99 @@
                                  int32_t RegNum = Variable::NoRegister);
 
   /// Return a memory operand corresponding to a stack allocated Variable.
-  OperandX8632Mem *getMemoryOperandForStackSlot(Type Ty, Variable *Slot,
-                                                uint32_t Offset = 0);
+  typename Traits::X86OperandMem *
+  getMemoryOperandForStackSlot(Type Ty, Variable *Slot, uint32_t Offset = 0);
 
   void makeRandomRegisterPermutation(
       llvm::SmallVectorImpl<int32_t> &Permutation,
       const llvm::SmallBitVector &ExcludeRegisters) const override;
 
-  // TODO(jpp): move the helper methods below to the MachineTraits.
   /// The following are helpers that insert lowered x86 instructions
   /// with minimal syntactic overhead, so that the lowering code can
   /// look as close to assembly as practical.
   void _adc(Variable *Dest, Operand *Src0) {
-    Context.insert(InstX8632Adc::create(Func, Dest, Src0));
+    Context.insert(Traits::Insts::Adc::create(Func, Dest, Src0));
   }
-  void _adc_rmw(OperandX8632Mem *DestSrc0, Operand *Src1) {
-    Context.insert(InstX8632AdcRMW::create(Func, DestSrc0, Src1));
+  void _adc_rmw(typename Traits::X86OperandMem *DestSrc0, Operand *Src1) {
+    Context.insert(Traits::Insts::AdcRMW::create(Func, DestSrc0, Src1));
   }
   void _add(Variable *Dest, Operand *Src0) {
-    Context.insert(InstX8632Add::create(Func, Dest, Src0));
+    Context.insert(Traits::Insts::Add::create(Func, Dest, Src0));
   }
-  void _add_rmw(OperandX8632Mem *DestSrc0, Operand *Src1) {
-    Context.insert(InstX8632AddRMW::create(Func, DestSrc0, Src1));
+  void _add_rmw(typename Traits::X86OperandMem *DestSrc0, Operand *Src1) {
+    Context.insert(Traits::Insts::AddRMW::create(Func, DestSrc0, Src1));
   }
   void _adjust_stack(int32_t Amount) {
-    Context.insert(InstX8632AdjustStack::create(
+    Context.insert(Traits::Insts::AdjustStack::create(
         Func, Amount, getPhysicalRegister(Traits::RegisterSet::Reg_esp)));
   }
   void _addps(Variable *Dest, Operand *Src0) {
-    Context.insert(InstX8632Addps::create(Func, Dest, Src0));
+    Context.insert(Traits::Insts::Addps::create(Func, Dest, Src0));
   }
   void _addss(Variable *Dest, Operand *Src0) {
-    Context.insert(InstX8632Addss::create(Func, Dest, Src0));
+    Context.insert(Traits::Insts::Addss::create(Func, Dest, Src0));
   }
   void _and(Variable *Dest, Operand *Src0) {
-    Context.insert(InstX8632And::create(Func, Dest, Src0));
+    Context.insert(Traits::Insts::And::create(Func, Dest, Src0));
   }
-  void _and_rmw(OperandX8632Mem *DestSrc0, Operand *Src1) {
-    Context.insert(InstX8632AndRMW::create(Func, DestSrc0, Src1));
+  void _and_rmw(typename Traits::X86OperandMem *DestSrc0, Operand *Src1) {
+    Context.insert(Traits::Insts::AndRMW::create(Func, DestSrc0, Src1));
   }
   void _blendvps(Variable *Dest, Operand *Src0, Operand *Src1) {
-    Context.insert(InstX8632Blendvps::create(Func, Dest, Src0, Src1));
+    Context.insert(Traits::Insts::Blendvps::create(Func, Dest, Src0, Src1));
   }
   void _br(typename Traits::Cond::BrCond Condition, CfgNode *TargetTrue,
            CfgNode *TargetFalse) {
     Context.insert(
-        InstX8632Br::create(Func, TargetTrue, TargetFalse, Condition));
+        Traits::Insts::Br::create(Func, TargetTrue, TargetFalse, Condition));
   }
   void _br(CfgNode *Target) {
-    Context.insert(InstX8632Br::create(Func, Target));
+    Context.insert(Traits::Insts::Br::create(Func, Target));
   }
   void _br(typename Traits::Cond::BrCond Condition, CfgNode *Target) {
-    Context.insert(InstX8632Br::create(Func, Target, Condition));
+    Context.insert(Traits::Insts::Br::create(Func, Target, Condition));
   }
-  void _br(typename Traits::Cond::BrCond Condition, InstX8632Label *Label) {
-    Context.insert(InstX8632Br::create(Func, Label, Condition));
+  void _br(typename Traits::Cond::BrCond Condition,
+           typename Traits::Insts::Label *Label) {
+    Context.insert(Traits::Insts::Br::create(Func, Label, Condition));
   }
   void _bsf(Variable *Dest, Operand *Src0) {
-    Context.insert(InstX8632Bsf::create(Func, Dest, Src0));
+    Context.insert(Traits::Insts::Bsf::create(Func, Dest, Src0));
   }
   void _bsr(Variable *Dest, Operand *Src0) {
-    Context.insert(InstX8632Bsr::create(Func, Dest, Src0));
+    Context.insert(Traits::Insts::Bsr::create(Func, Dest, Src0));
   }
   void _bswap(Variable *SrcDest) {
-    Context.insert(InstX8632Bswap::create(Func, SrcDest));
+    Context.insert(Traits::Insts::Bswap::create(Func, SrcDest));
   }
   void _cbwdq(Variable *Dest, Operand *Src0) {
-    Context.insert(InstX8632Cbwdq::create(Func, Dest, Src0));
+    Context.insert(Traits::Insts::Cbwdq::create(Func, Dest, Src0));
   }
   void _cmov(Variable *Dest, Operand *Src0,
              typename Traits::Cond::BrCond Condition) {
-    Context.insert(InstX8632Cmov::create(Func, Dest, Src0, Condition));
+    Context.insert(Traits::Insts::Cmov::create(Func, Dest, Src0, Condition));
   }
   void _cmp(Operand *Src0, Operand *Src1) {
-    Context.insert(InstX8632Icmp::create(Func, Src0, Src1));
+    Context.insert(Traits::Insts::Icmp::create(Func, Src0, Src1));
   }
   void _cmpps(Variable *Dest, Operand *Src0,
               typename Traits::Cond::CmppsCond Condition) {
-    Context.insert(InstX8632Cmpps::create(Func, Dest, Src0, Condition));
+    Context.insert(Traits::Insts::Cmpps::create(Func, Dest, Src0, Condition));
   }
   void _cmpxchg(Operand *DestOrAddr, Variable *Eax, Variable *Desired,
                 bool Locked) {
     Context.insert(
-        InstX8632Cmpxchg::create(Func, DestOrAddr, Eax, Desired, Locked));
+        Traits::Insts::Cmpxchg::create(Func, DestOrAddr, Eax, Desired, Locked));
     // Mark eax as possibly modified by cmpxchg.
     Context.insert(
         InstFakeDef::create(Func, Eax, llvm::dyn_cast<Variable>(DestOrAddr)));
     _set_dest_nonkillable();
     Context.insert(InstFakeUse::create(Func, Eax));
   }
-  void _cmpxchg8b(OperandX8632Mem *Addr, Variable *Edx, Variable *Eax,
-                  Variable *Ecx, Variable *Ebx, bool Locked) {
-    Context.insert(
-        InstX8632Cmpxchg8b::create(Func, Addr, Edx, Eax, Ecx, Ebx, Locked));
+  void _cmpxchg8b(typename Traits::X86OperandMem *Addr, Variable *Edx,
+                  Variable *Eax, Variable *Ecx, Variable *Ebx, bool Locked) {
+    Context.insert(Traits::Insts::Cmpxchg8b::create(Func, Addr, Edx, Eax, Ecx,
+                                                    Ebx, Locked));
     // Mark edx, and eax as possibly modified by cmpxchg8b.
     Context.insert(InstFakeDef::create(Func, Edx));
     _set_dest_nonkillable();
@@ -354,38 +354,41 @@
     _set_dest_nonkillable();
     Context.insert(InstFakeUse::create(Func, Eax));
   }
-  void _cvt(Variable *Dest, Operand *Src0, InstX8632Cvt::CvtVariant Variant) {
-    Context.insert(InstX8632Cvt::create(Func, Dest, Src0, Variant));
+  void _cvt(Variable *Dest, Operand *Src0,
+            typename Traits::Insts::Cvt::CvtVariant Variant) {
+    Context.insert(Traits::Insts::Cvt::create(Func, Dest, Src0, Variant));
   }
   void _div(Variable *Dest, Operand *Src0, Operand *Src1) {
-    Context.insert(InstX8632Div::create(Func, Dest, Src0, Src1));
+    Context.insert(Traits::Insts::Div::create(Func, Dest, Src0, Src1));
   }
   void _divps(Variable *Dest, Operand *Src0) {
-    Context.insert(InstX8632Divps::create(Func, Dest, Src0));
+    Context.insert(Traits::Insts::Divps::create(Func, Dest, Src0));
   }
   void _divss(Variable *Dest, Operand *Src0) {
-    Context.insert(InstX8632Divss::create(Func, Dest, Src0));
+    Context.insert(Traits::Insts::Divss::create(Func, Dest, Src0));
   }
-  void _fld(Operand *Src0) { Context.insert(InstX8632Fld::create(Func, Src0)); }
+  void _fld(Operand *Src0) {
+    Context.insert(Traits::Insts::Fld::create(Func, Src0));
+  }
   void _fstp(Variable *Dest) {
-    Context.insert(InstX8632Fstp::create(Func, Dest));
+    Context.insert(Traits::Insts::Fstp::create(Func, Dest));
   }
   void _idiv(Variable *Dest, Operand *Src0, Operand *Src1) {
-    Context.insert(InstX8632Idiv::create(Func, Dest, Src0, Src1));
+    Context.insert(Traits::Insts::Idiv::create(Func, Dest, Src0, Src1));
   }
   void _imul(Variable *Dest, Operand *Src0) {
-    Context.insert(InstX8632Imul::create(Func, Dest, Src0));
+    Context.insert(Traits::Insts::Imul::create(Func, Dest, Src0));
   }
   void _insertps(Variable *Dest, Operand *Src0, Operand *Src1) {
-    Context.insert(InstX8632Insertps::create(Func, Dest, Src0, Src1));
+    Context.insert(Traits::Insts::Insertps::create(Func, Dest, Src0, Src1));
   }
   void _jmp(Operand *Target) {
-    Context.insert(InstX8632Jmp::create(Func, Target));
+    Context.insert(Traits::Insts::Jmp::create(Func, Target));
   }
   void _lea(Variable *Dest, Operand *Src0) {
-    Context.insert(InstX8632Lea::create(Func, Dest, Src0));
+    Context.insert(Traits::Insts::Lea::create(Func, Dest, Src0));
   }
-  void _mfence() { Context.insert(InstX8632Mfence::create(Func)); }
+  void _mfence() { Context.insert(Traits::Insts::Mfence::create(Func)); }
   /// If Dest=nullptr is passed in, then a new variable is created,
   /// marked as infinite register allocation weight, and returned
   /// through the in/out Dest argument.
@@ -393,175 +396,175 @@
             int32_t RegNum = Variable::NoRegister) {
     if (Dest == nullptr)
       Dest = makeReg(Src0->getType(), RegNum);
-    Context.insert(InstX8632Mov::create(Func, Dest, Src0));
+    Context.insert(Traits::Insts::Mov::create(Func, Dest, Src0));
   }
   void _mov_nonkillable(Variable *Dest, Operand *Src0) {
-    Inst *NewInst = InstX8632Mov::create(Func, Dest, Src0);
+    Inst *NewInst = Traits::Insts::Mov::create(Func, Dest, Src0);
     NewInst->setDestNonKillable();
     Context.insert(NewInst);
   }
   void _movd(Variable *Dest, Operand *Src0) {
-    Context.insert(InstX8632Movd::create(Func, Dest, Src0));
+    Context.insert(Traits::Insts::Movd::create(Func, Dest, Src0));
   }
   void _movp(Variable *Dest, Operand *Src0) {
-    Context.insert(InstX8632Movp::create(Func, Dest, Src0));
+    Context.insert(Traits::Insts::Movp::create(Func, Dest, Src0));
   }
   void _movq(Variable *Dest, Operand *Src0) {
-    Context.insert(InstX8632Movq::create(Func, Dest, Src0));
+    Context.insert(Traits::Insts::Movq::create(Func, Dest, Src0));
   }
   void _movss(Variable *Dest, Variable *Src0) {
-    Context.insert(InstX8632MovssRegs::create(Func, Dest, Src0));
+    Context.insert(Traits::Insts::MovssRegs::create(Func, Dest, Src0));
   }
   void _movsx(Variable *Dest, Operand *Src0) {
-    Context.insert(InstX8632Movsx::create(Func, Dest, Src0));
+    Context.insert(Traits::Insts::Movsx::create(Func, Dest, Src0));
   }
   void _movzx(Variable *Dest, Operand *Src0) {
-    Context.insert(InstX8632Movzx::create(Func, Dest, Src0));
+    Context.insert(Traits::Insts::Movzx::create(Func, Dest, Src0));
   }
   void _mul(Variable *Dest, Variable *Src0, Operand *Src1) {
-    Context.insert(InstX8632Mul::create(Func, Dest, Src0, Src1));
+    Context.insert(Traits::Insts::Mul::create(Func, Dest, Src0, Src1));
   }
   void _mulps(Variable *Dest, Operand *Src0) {
-    Context.insert(InstX8632Mulps::create(Func, Dest, Src0));
+    Context.insert(Traits::Insts::Mulps::create(Func, Dest, Src0));
   }
   void _mulss(Variable *Dest, Operand *Src0) {
-    Context.insert(InstX8632Mulss::create(Func, Dest, Src0));
+    Context.insert(Traits::Insts::Mulss::create(Func, Dest, Src0));
   }
   void _neg(Variable *SrcDest) {
-    Context.insert(InstX8632Neg::create(Func, SrcDest));
+    Context.insert(Traits::Insts::Neg::create(Func, SrcDest));
   }
   void _nop(SizeT Variant) {
-    Context.insert(InstX8632Nop::create(Func, Variant));
+    Context.insert(Traits::Insts::Nop::create(Func, Variant));
   }
   void _or(Variable *Dest, Operand *Src0) {
-    Context.insert(InstX8632Or::create(Func, Dest, Src0));
+    Context.insert(Traits::Insts::Or::create(Func, Dest, Src0));
   }
-  void _or_rmw(OperandX8632Mem *DestSrc0, Operand *Src1) {
-    Context.insert(InstX8632OrRMW::create(Func, DestSrc0, Src1));
+  void _or_rmw(typename Traits::X86OperandMem *DestSrc0, Operand *Src1) {
+    Context.insert(Traits::Insts::OrRMW::create(Func, DestSrc0, Src1));
   }
   void _padd(Variable *Dest, Operand *Src0) {
-    Context.insert(InstX8632Padd::create(Func, Dest, Src0));
+    Context.insert(Traits::Insts::Padd::create(Func, Dest, Src0));
   }
   void _pand(Variable *Dest, Operand *Src0) {
-    Context.insert(InstX8632Pand::create(Func, Dest, Src0));
+    Context.insert(Traits::Insts::Pand::create(Func, Dest, Src0));
   }
   void _pandn(Variable *Dest, Operand *Src0) {
-    Context.insert(InstX8632Pandn::create(Func, Dest, Src0));
+    Context.insert(Traits::Insts::Pandn::create(Func, Dest, Src0));
   }
   void _pblendvb(Variable *Dest, Operand *Src0, Operand *Src1) {
-    Context.insert(InstX8632Pblendvb::create(Func, Dest, Src0, Src1));
+    Context.insert(Traits::Insts::Pblendvb::create(Func, Dest, Src0, Src1));
   }
   void _pcmpeq(Variable *Dest, Operand *Src0) {
-    Context.insert(InstX8632Pcmpeq::create(Func, Dest, Src0));
+    Context.insert(Traits::Insts::Pcmpeq::create(Func, Dest, Src0));
   }
   void _pcmpgt(Variable *Dest, Operand *Src0) {
-    Context.insert(InstX8632Pcmpgt::create(Func, Dest, Src0));
+    Context.insert(Traits::Insts::Pcmpgt::create(Func, Dest, Src0));
   }
   void _pextr(Variable *Dest, Operand *Src0, Operand *Src1) {
-    Context.insert(InstX8632Pextr::create(Func, Dest, Src0, Src1));
+    Context.insert(Traits::Insts::Pextr::create(Func, Dest, Src0, Src1));
   }
   void _pinsr(Variable *Dest, Operand *Src0, Operand *Src1) {
-    Context.insert(InstX8632Pinsr::create(Func, Dest, Src0, Src1));
+    Context.insert(Traits::Insts::Pinsr::create(Func, Dest, Src0, Src1));
   }
   void _pmull(Variable *Dest, Operand *Src0) {
-    Context.insert(InstX8632Pmull::create(Func, Dest, Src0));
+    Context.insert(Traits::Insts::Pmull::create(Func, Dest, Src0));
   }
   void _pmuludq(Variable *Dest, Operand *Src0) {
-    Context.insert(InstX8632Pmuludq::create(Func, Dest, Src0));
+    Context.insert(Traits::Insts::Pmuludq::create(Func, Dest, Src0));
   }
   void _pop(Variable *Dest) {
-    Context.insert(InstX8632Pop::create(Func, Dest));
+    Context.insert(Traits::Insts::Pop::create(Func, Dest));
   }
   void _por(Variable *Dest, Operand *Src0) {
-    Context.insert(InstX8632Por::create(Func, Dest, Src0));
+    Context.insert(Traits::Insts::Por::create(Func, Dest, Src0));
   }
   void _pshufd(Variable *Dest, Operand *Src0, Operand *Src1) {
-    Context.insert(InstX8632Pshufd::create(Func, Dest, Src0, Src1));
+    Context.insert(Traits::Insts::Pshufd::create(Func, Dest, Src0, Src1));
   }
   void _psll(Variable *Dest, Operand *Src0) {
-    Context.insert(InstX8632Psll::create(Func, Dest, Src0));
+    Context.insert(Traits::Insts::Psll::create(Func, Dest, Src0));
   }
   void _psra(Variable *Dest, Operand *Src0) {
-    Context.insert(InstX8632Psra::create(Func, Dest, Src0));
+    Context.insert(Traits::Insts::Psra::create(Func, Dest, Src0));
   }
   void _psrl(Variable *Dest, Operand *Src0) {
-    Context.insert(InstX8632Psrl::create(Func, Dest, Src0));
+    Context.insert(Traits::Insts::Psrl::create(Func, Dest, Src0));
   }
   void _psub(Variable *Dest, Operand *Src0) {
-    Context.insert(InstX8632Psub::create(Func, Dest, Src0));
+    Context.insert(Traits::Insts::Psub::create(Func, Dest, Src0));
   }
   void _push(Variable *Src0) {
-    Context.insert(InstX8632Push::create(Func, Src0));
+    Context.insert(Traits::Insts::Push::create(Func, Src0));
   }
   void _pxor(Variable *Dest, Operand *Src0) {
-    Context.insert(InstX8632Pxor::create(Func, Dest, Src0));
+    Context.insert(Traits::Insts::Pxor::create(Func, Dest, Src0));
   }
   void _ret(Variable *Src0 = nullptr) {
-    Context.insert(InstX8632Ret::create(Func, Src0));
+    Context.insert(Traits::Insts::Ret::create(Func, Src0));
   }
   void _rol(Variable *Dest, Operand *Src0) {
-    Context.insert(InstX8632Rol::create(Func, Dest, Src0));
+    Context.insert(Traits::Insts::Rol::create(Func, Dest, Src0));
   }
   void _sar(Variable *Dest, Operand *Src0) {
-    Context.insert(InstX8632Sar::create(Func, Dest, Src0));
+    Context.insert(Traits::Insts::Sar::create(Func, Dest, Src0));
   }
   void _sbb(Variable *Dest, Operand *Src0) {
-    Context.insert(InstX8632Sbb::create(Func, Dest, Src0));
+    Context.insert(Traits::Insts::Sbb::create(Func, Dest, Src0));
   }
-  void _sbb_rmw(OperandX8632Mem *DestSrc0, Operand *Src1) {
-    Context.insert(InstX8632SbbRMW::create(Func, DestSrc0, Src1));
+  void _sbb_rmw(typename Traits::X86OperandMem *DestSrc0, Operand *Src1) {
+    Context.insert(Traits::Insts::SbbRMW::create(Func, DestSrc0, Src1));
   }
   void _setcc(Variable *Dest, typename Traits::Cond::BrCond Condition) {
-    Context.insert(InstX8632Setcc::create(Func, Dest, Condition));
+    Context.insert(Traits::Insts::Setcc::create(Func, Dest, Condition));
   }
   void _shl(Variable *Dest, Operand *Src0) {
-    Context.insert(InstX8632Shl::create(Func, Dest, Src0));
+    Context.insert(Traits::Insts::Shl::create(Func, Dest, Src0));
   }
   void _shld(Variable *Dest, Variable *Src0, Variable *Src1) {
-    Context.insert(InstX8632Shld::create(Func, Dest, Src0, Src1));
+    Context.insert(Traits::Insts::Shld::create(Func, Dest, Src0, Src1));
   }
   void _shr(Variable *Dest, Operand *Src0) {
-    Context.insert(InstX8632Shr::create(Func, Dest, Src0));
+    Context.insert(Traits::Insts::Shr::create(Func, Dest, Src0));
   }
   void _shrd(Variable *Dest, Variable *Src0, Variable *Src1) {
-    Context.insert(InstX8632Shrd::create(Func, Dest, Src0, Src1));
+    Context.insert(Traits::Insts::Shrd::create(Func, Dest, Src0, Src1));
   }
   void _shufps(Variable *Dest, Operand *Src0, Operand *Src1) {
-    Context.insert(InstX8632Shufps::create(Func, Dest, Src0, Src1));
+    Context.insert(Traits::Insts::Shufps::create(Func, Dest, Src0, Src1));
   }
   void _sqrtss(Variable *Dest, Operand *Src0) {
-    Context.insert(InstX8632Sqrtss::create(Func, Dest, Src0));
+    Context.insert(Traits::Insts::Sqrtss::create(Func, Dest, Src0));
   }
-  void _store(Operand *Value, OperandX8632 *Mem) {
-    Context.insert(InstX8632Store::create(Func, Value, Mem));
+  void _store(Operand *Value, typename Traits::X86Operand *Mem) {
+    Context.insert(Traits::Insts::Store::create(Func, Value, Mem));
   }
-  void _storep(Variable *Value, OperandX8632Mem *Mem) {
-    Context.insert(InstX8632StoreP::create(Func, Value, Mem));
+  void _storep(Variable *Value, typename Traits::X86OperandMem *Mem) {
+    Context.insert(Traits::Insts::StoreP::create(Func, Value, Mem));
   }
-  void _storeq(Variable *Value, OperandX8632Mem *Mem) {
-    Context.insert(InstX8632StoreQ::create(Func, Value, Mem));
+  void _storeq(Variable *Value, typename Traits::X86OperandMem *Mem) {
+    Context.insert(Traits::Insts::StoreQ::create(Func, Value, Mem));
   }
   void _sub(Variable *Dest, Operand *Src0) {
-    Context.insert(InstX8632Sub::create(Func, Dest, Src0));
+    Context.insert(Traits::Insts::Sub::create(Func, Dest, Src0));
   }
-  void _sub_rmw(OperandX8632Mem *DestSrc0, Operand *Src1) {
-    Context.insert(InstX8632SubRMW::create(Func, DestSrc0, Src1));
+  void _sub_rmw(typename Traits::X86OperandMem *DestSrc0, Operand *Src1) {
+    Context.insert(Traits::Insts::SubRMW::create(Func, DestSrc0, Src1));
   }
   void _subps(Variable *Dest, Operand *Src0) {
-    Context.insert(InstX8632Subps::create(Func, Dest, Src0));
+    Context.insert(Traits::Insts::Subps::create(Func, Dest, Src0));
   }
   void _subss(Variable *Dest, Operand *Src0) {
-    Context.insert(InstX8632Subss::create(Func, Dest, Src0));
+    Context.insert(Traits::Insts::Subss::create(Func, Dest, Src0));
   }
   void _test(Operand *Src0, Operand *Src1) {
-    Context.insert(InstX8632Test::create(Func, Src0, Src1));
+    Context.insert(Traits::Insts::Test::create(Func, Src0, Src1));
   }
   void _ucomiss(Operand *Src0, Operand *Src1) {
-    Context.insert(InstX8632Ucomiss::create(Func, Src0, Src1));
+    Context.insert(Traits::Insts::Ucomiss::create(Func, Src0, Src1));
   }
-  void _ud2() { Context.insert(InstX8632UD2::create(Func)); }
+  void _ud2() { Context.insert(Traits::Insts::UD2::create(Func)); }
   void _xadd(Operand *Dest, Variable *Src, bool Locked) {
-    Context.insert(InstX8632Xadd::create(Func, Dest, Src, Locked));
+    Context.insert(Traits::Insts::Xadd::create(Func, Dest, Src, Locked));
     // The xadd exchanges Dest and Src (modifying Src).
     // Model that update with a FakeDef followed by a FakeUse.
     Context.insert(
@@ -570,7 +573,7 @@
     Context.insert(InstFakeUse::create(Func, Src));
   }
   void _xchg(Operand *Dest, Variable *Src) {
-    Context.insert(InstX8632Xchg::create(Func, Dest, Src));
+    Context.insert(Traits::Insts::Xchg::create(Func, Dest, Src));
     // The xchg modifies Dest and Src -- model that update with a
     // FakeDef/FakeUse.
     Context.insert(
@@ -579,10 +582,10 @@
     Context.insert(InstFakeUse::create(Func, Src));
   }
   void _xor(Variable *Dest, Operand *Src0) {
-    Context.insert(InstX8632Xor::create(Func, Dest, Src0));
+    Context.insert(Traits::Insts::Xor::create(Func, Dest, Src0));
   }
-  void _xor_rmw(OperandX8632Mem *DestSrc0, Operand *Src1) {
-    Context.insert(InstX8632XorRMW::create(Func, DestSrc0, Src1));
+  void _xor_rmw(typename Traits::X86OperandMem *DestSrc0, Operand *Src1) {
+    Context.insert(Traits::Insts::XorRMW::create(Func, DestSrc0, Src1));
   }
   void _set_dest_nonkillable() {
     Context.getLastInserted()->setDestNonKillable();
@@ -600,13 +603,12 @@
   llvm::SmallBitVector ScratchRegs;
   llvm::SmallBitVector RegsUsed;
   VarList PhysicalRegisters[IceType_NUM];
-  static IceString RegNames[];
 
   /// Randomize a given immediate operand
   Operand *randomizeOrPoolImmediate(Constant *Immediate,
                                     int32_t RegNum = Variable::NoRegister);
-  OperandX8632Mem *
-  randomizeOrPoolImmediate(OperandX8632Mem *MemOperand,
+  typename Traits::X86OperandMem *
+  randomizeOrPoolImmediate(typename Traits::X86OperandMem *MemOperand,
                            int32_t RegNum = Variable::NoRegister);
   bool RandomizationPoolingPaused = false;
 
diff --git a/src/IceTargetLoweringX86BaseImpl.h b/src/IceTargetLoweringX86BaseImpl.h
index 6a0f3b3..68cbf94 100644
--- a/src/IceTargetLoweringX86BaseImpl.h
+++ b/src/IceTargetLoweringX86BaseImpl.h
@@ -23,20 +23,16 @@
 #include "IceDefs.h"
 #include "IceELFObjectWriter.h"
 #include "IceGlobalInits.h"
-#include "IceInstX8632.h"
 #include "IceLiveness.h"
 #include "IceOperand.h"
-#include "IceRegistersX8632.h"
-#include "IceTargetLoweringX8632.def"
-#include "IceTargetLoweringX8632.h"
 #include "IceUtils.h"
 #include "llvm/Support/MathExtras.h"
 
 namespace Ice {
 namespace X86Internal {
 
-/// A helper class to ease the settings of RandomizationPoolingPause
-/// to disable constant blinding or pooling for some translation phases.
+/// A helper class to ease the settings of RandomizationPoolingPause to disable
+/// constant blinding or pooling for some translation phases.
 class BoolFlagSaver {
   BoolFlagSaver() = delete;
   BoolFlagSaver(const BoolFlagSaver &) = delete;
@@ -85,8 +81,7 @@
   };
 
   /// Currently the actual enum values are not used (other than CK_None), but we
-  /// go
-  /// ahead and produce them anyway for symmetry with the
+  /// go ahead and produce them anyway for symmetry with the
   /// BoolFoldingProducerKind.
   enum BoolFoldingConsumerKind { CK_None, CK_Br, CK_Select, CK_Sext, CK_Zext };
 
@@ -163,12 +158,11 @@
   return CK_None;
 }
 
-/// Returns true if the producing instruction has a "complex" lowering
-/// sequence.  This generally means that its lowering sequence requires
-/// more than one conditional branch, namely 64-bit integer compares
-/// and some floating-point compares.  When this is true, and there is
-/// more than one consumer, we prefer to disable the folding
-/// optimization because it minimizes branches.
+/// Returns true if the producing instruction has a "complex" lowering sequence.
+/// This generally means that its lowering sequence requires more than one
+/// conditional branch, namely 64-bit integer compares and some floating-point
+/// compares.  When this is true, and there is more than one consumer, we prefer
+/// to disable the folding optimization because it minimizes branches.
 template <class MachineTraits>
 bool BoolFolding<MachineTraits>::hasComplexLowering(const Inst *Instr) {
   switch (getProducerKind(Instr)) {
@@ -226,10 +220,10 @@
       setInvalid(I.first);
       continue;
     }
-    // Mark as "dead" rather than outright deleting.  This is so that
-    // other peephole style optimizations during or before lowering
-    // have access to this instruction in undeleted form.  See for
-    // example tryOptimizedCmpxchgCmpBr().
+    // Mark as "dead" rather than outright deleting.  This is so that other
+    // peephole style optimizations during or before lowering have access to
+    // this instruction in undeleted form.  See for example
+    // tryOptimizedCmpxchgCmpBr().
     I.second.Instr->setDead();
   }
 }
@@ -283,24 +277,18 @@
          TargetInstructionSet::X86InstructionSet_Begin) +
         Traits::InstructionSet::Begin);
   }
-  // TODO: Don't initialize IntegerRegisters and friends every time.
-  // Instead, initialize in some sort of static initializer for the
-  // class.
+  // TODO: Don't initialize IntegerRegisters and friends every time. Instead,
+  // initialize in some sort of static initializer for the class.
   llvm::SmallBitVector IntegerRegisters(Traits::RegisterSet::Reg_NUM);
   llvm::SmallBitVector IntegerRegistersI8(Traits::RegisterSet::Reg_NUM);
   llvm::SmallBitVector FloatRegisters(Traits::RegisterSet::Reg_NUM);
   llvm::SmallBitVector VectorRegisters(Traits::RegisterSet::Reg_NUM);
   llvm::SmallBitVector InvalidRegisters(Traits::RegisterSet::Reg_NUM);
   ScratchRegs.resize(Traits::RegisterSet::Reg_NUM);
-#define X(val, encode, name, name16, name8, scratch, preserved, stackptr,      \
-          frameptr, isI8, isInt, isFP)                                         \
-  IntegerRegisters[Traits::RegisterSet::val] = isInt;                          \
-  IntegerRegistersI8[Traits::RegisterSet::val] = isI8;                         \
-  FloatRegisters[Traits::RegisterSet::val] = isFP;                             \
-  VectorRegisters[Traits::RegisterSet::val] = isFP;                            \
-  ScratchRegs[Traits::RegisterSet::val] = scratch;
-  REGX8632_TABLE;
-#undef X
+
+  Traits::initRegisterSet(&IntegerRegisters, &IntegerRegistersI8,
+                          &FloatRegisters, &VectorRegisters, &ScratchRegs);
+
   TypeToRegisterSet[IceType_void] = InvalidRegisters;
   TypeToRegisterSet[IceType_i1] = IntegerRegistersI8;
   TypeToRegisterSet[IceType_i8] = IntegerRegistersI8;
@@ -348,19 +336,18 @@
   // Argument lowering
   Func->doArgLowering();
 
-  // Target lowering.  This requires liveness analysis for some parts
-  // of the lowering decisions, such as compare/branch fusing.  If
-  // non-lightweight liveness analysis is used, the instructions need
-  // to be renumbered first.  TODO: This renumbering should only be
-  // necessary if we're actually calculating live intervals, which we
-  // only do for register allocation.
+  // Target lowering.  This requires liveness analysis for some parts of the
+  // lowering decisions, such as compare/branch fusing.  If non-lightweight
+  // liveness analysis is used, the instructions need to be renumbered first
+  // TODO: This renumbering should only be necessary if we're actually
+  // calculating live intervals, which we only do for register allocation.
   Func->renumberInstructions();
   if (Func->hasError())
     return;
 
-  // TODO: It should be sufficient to use the fastest liveness
-  // calculation, i.e. livenessLightweight().  However, for some
-  // reason that slows down the rest of the translation.  Investigate.
+  // TODO: It should be sufficient to use the fastest liveness calculation, i.e.
+  // livenessLightweight().  However, for some reason that slows down the rest
+  // of the translation.  Investigate.
   Func->liveness(Liveness_Basic);
   if (Func->hasError())
     return;
@@ -376,19 +363,19 @@
     return;
   Func->dump("After x86 codegen");
 
-  // Register allocation.  This requires instruction renumbering and
-  // full liveness analysis.
+  // Register allocation.  This requires instruction renumbering and full
+  // liveness analysis.
   Func->renumberInstructions();
   if (Func->hasError())
     return;
   Func->liveness(Liveness_Intervals);
   if (Func->hasError())
     return;
-  // Validate the live range computations.  The expensive validation
-  // call is deliberately only made when assertions are enabled.
+  // Validate the live range computations.  The expensive validation call is
+  // deliberately only made when assertions are enabled.
   assert(Func->validateLiveness());
-  // The post-codegen dump is done here, after liveness analysis and
-  // associated cleanup, to make the dump cleaner and more useful.
+  // The post-codegen dump is done here, after liveness analysis and associated
+  // cleanup, to make the dump cleaner and more useful.
   Func->dump("After initial x8632 codegen");
   Func->getVMetadata()->init(VMK_All);
   regAlloc(RAK_Global);
@@ -397,9 +384,9 @@
   Func->dump("After linear scan regalloc");
 
   if (Ctx->getFlags().getPhiEdgeSplit()) {
-    // We need to pause constant blinding or pooling during advanced
-    // phi lowering, unless the lowering assignment has a physical
-    // register for the dest Variable.
+    // We need to pause constant blinding or pooling during advanced phi
+    // lowering, unless the lowering assignment has a physical register for the
+    // dest Variable.
     {
       BoolFlagSaver B(RandomizationPoolingPaused, true);
       Func->advancedPhiLowering();
@@ -416,11 +403,10 @@
   Func->contractEmptyNodes();
   Func->reorderNodes();
 
-  // Branch optimization.  This needs to be done just before code
-  // emission.  In particular, no transformations that insert or
-  // reorder CfgNodes should be done after branch optimization.  We go
-  // ahead and do it before nop insertion to reduce the amount of work
-  // needed for searching for opportunities.
+  // Branch optimization.  This needs to be done just before code emission.  In
+  // particular, no transformations that insert or reorder CfgNodes should be
+  // done after branch optimization.  We go ahead and do it before nop insertion
+  // to reduce the amount of work needed for searching for opportunities.
   Func->doBranchOpt();
   Func->dump("After branch optimization");
 
@@ -468,8 +454,7 @@
 
 bool canRMW(const InstArithmetic *Arith) {
   Type Ty = Arith->getDest()->getType();
-  // X86 vector instructions write to a register and have no RMW
-  // option.
+  // X86 vector instructions write to a register and have no RMW option.
   if (isVectorType(Ty))
     return false;
   bool isI64 = Ty == IceType_i64;
@@ -496,11 +481,14 @@
   }
 }
 
+template <class Machine>
 bool isSameMemAddressOperand(const Operand *A, const Operand *B) {
   if (A == B)
     return true;
-  if (auto *MemA = llvm::dyn_cast<OperandX8632Mem>(A)) {
-    if (auto *MemB = llvm::dyn_cast<OperandX8632Mem>(B)) {
+  if (auto *MemA = llvm::dyn_cast<
+          typename TargetX86Base<Machine>::Traits::X86OperandMem>(A)) {
+    if (auto *MemB = llvm::dyn_cast<
+            typename TargetX86Base<Machine>::Traits::X86OperandMem>(B)) {
       return MemA->getBase() == MemB->getBase() &&
              MemA->getOffset() == MemB->getOffset() &&
              MemA->getIndex() == MemB->getIndex() &&
@@ -565,8 +553,8 @@
             // still trigger, resulting in two loads and one store, which is
             // worse than the original one load and one store.  However, this is
             // probably rare, and caching probably keeps it just as fast.
-            if (!isSameMemAddressOperand(Load->getSourceAddress(),
-                                         Store->getAddr()))
+            if (!isSameMemAddressOperand<Machine>(Load->getSourceAddress(),
+                                                  Store->getAddr()))
               continue;
             Operand *ArithSrcFromLoad = Arith->getSrc(0);
             Operand *ArithSrcOther = Arith->getSrc(1);
@@ -593,7 +581,7 @@
             Store->setRmwBeacon(Beacon);
             InstFakeDef *BeaconDef = InstFakeDef::create(Func, Beacon);
             Node->getInsts().insert(I3, BeaconDef);
-            InstX8632FakeRMW *RMW = InstX8632FakeRMW::create(
+            auto *RMW = Traits::Insts::FakeRMW::create(
                 Func, ArithSrcOther, Store->getAddr(), Beacon, Arith->getOp());
             Node->getInsts().insert(I3, RMW);
           }
@@ -721,22 +709,13 @@
 
 template <class Machine>
 bool TargetX86Base<Machine>::doBranchOpt(Inst *I, const CfgNode *NextNode) {
-  if (InstX8632Br *Br = llvm::dyn_cast<InstX8632Br>(I)) {
+  if (auto *Br = llvm::dyn_cast<typename Traits::Insts::Br>(I)) {
     return Br->optimizeBranch(NextNode);
   }
   return false;
 }
 
 template <class Machine>
-IceString TargetX86Base<Machine>::RegNames[] = {
-#define X(val, encode, name, name16, name8, scratch, preserved, stackptr,      \
-          frameptr, isI8, isInt, isFP)                                         \
-  name,
-    REGX8632_TABLE
-#undef X
-};
-
-template <class Machine>
 Variable *TargetX86Base<Machine>::getPhysicalRegister(SizeT RegNum, Type Ty) {
   if (Ty == IceType_void)
     Ty = IceType_i32;
@@ -760,30 +739,7 @@
 
 template <class Machine>
 IceString TargetX86Base<Machine>::getRegName(SizeT RegNum, Type Ty) const {
-  assert(RegNum < Traits::RegisterSet::Reg_NUM);
-  static IceString RegNames8[] = {
-#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, encode, name, name16, name8, scratch, preserved, stackptr,      \
-          frameptr, isI8, isInt, isFP)                                         \
-  name16,
-      REGX8632_TABLE
-#undef X
-  };
-  switch (Ty) {
-  case IceType_i1:
-  case IceType_i8:
-    return RegNames8[RegNum];
-  case IceType_i16:
-    return RegNames16[RegNum];
-  default:
-    return RegNames[RegNum];
-  }
+  return Traits::getRegName(RegNum, Ty);
 }
 
 template <class Machine>
@@ -884,17 +840,16 @@
   InArgsSizeBytes += typeWidthInBytesOnStack(Ty);
   if (Arg->hasReg()) {
     assert(Ty != IceType_i64);
-    OperandX8632Mem *Mem = OperandX8632Mem::create(
+    typename Traits::X86OperandMem *Mem = Traits::X86OperandMem::create(
         Func, Ty, FramePtr, Ctx->getConstantInt32(Arg->getStackOffset()));
     if (isVectorType(Arg->getType())) {
       _movp(Arg, Mem);
     } else {
       _mov(Arg, Mem);
     }
-    // This argument-copying instruction uses an explicit
-    // OperandX8632Mem operand instead of a Variable, so its
-    // fill-from-stack operation has to be tracked separately for
-    // statistics.
+    // This argument-copying instruction uses an explicit Traits::X86OperandMem
+    // operand instead of a Variable, so its fill-from-stack operation has to be
+    // tracked separately for statistics.
     Ctx->statsUpdateFills();
   }
 }
@@ -965,7 +920,8 @@
   // that stack slot.
   std::function<bool(Variable *)> TargetVarHook =
       [&VariablesLinkedToSpillSlots](Variable *Var) {
-        if (SpillVariable *SpillVar = llvm::dyn_cast<SpillVariable>(Var)) {
+        if (auto *SpillVar =
+                llvm::dyn_cast<typename Traits::SpillVariable>(Var)) {
           assert(Var->getWeight().isZero());
           if (SpillVar->getLinkedTo() && !SpillVar->getLinkedTo()->hasReg()) {
             VariablesLinkedToSpillSlots.push_back(Var);
@@ -1069,7 +1025,8 @@
   // Assign stack offsets to variables that have been linked to spilled
   // variables.
   for (Variable *Var : VariablesLinkedToSpillSlots) {
-    Variable *Linked = (llvm::cast<SpillVariable>(Var))->getLinkedTo();
+    Variable *Linked =
+        (llvm::cast<typename Traits::SpillVariable>(Var))->getLinkedTo();
     Var->setStackOffset(Linked->getStackOffset());
   }
   this->HasComputedFrame = true;
@@ -1106,7 +1063,7 @@
   InstList &Insts = Node->getInsts();
   InstList::reverse_iterator RI, E;
   for (RI = Insts.rbegin(), E = Insts.rend(); RI != E; ++RI) {
-    if (llvm::isa<InstX8632Ret>(*RI))
+    if (llvm::isa<typename Traits::Insts::Ret>(*RI))
       break;
   }
   if (RI == E)
@@ -1216,8 +1173,8 @@
         Ctx->getConstantInt32(static_cast<int32_t>(Const->getValue())));
     return legalize(ConstInt);
   }
-  if (OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Operand)) {
-    OperandX8632Mem *MemOperand = OperandX8632Mem::create(
+  if (auto *Mem = llvm::dyn_cast<typename Traits::X86OperandMem>(Operand)) {
+    auto *MemOperand = Traits::X86OperandMem::create(
         Func, IceType_i32, Mem->getBase(), Mem->getOffset(), Mem->getIndex(),
         Mem->getShift(), Mem->getSegmentRegister());
     // Test if we should randomize or pool the offset, if so randomize it or
@@ -1245,7 +1202,7 @@
     // check if we need to blind/pool the constant
     return legalize(ConstInt);
   }
-  if (OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Operand)) {
+  if (auto *Mem = llvm::dyn_cast<typename Traits::X86OperandMem>(Operand)) {
     Constant *Offset = Mem->getOffset();
     if (Offset == nullptr) {
       Offset = Ctx->getConstantInt32(4);
@@ -1259,7 +1216,7 @@
           Ctx->getConstantSym(4 + SymOffset->getOffset(), SymOffset->getName(),
                               SymOffset->getSuppressMangling());
     }
-    OperandX8632Mem *MemOperand = OperandX8632Mem::create(
+    auto *MemOperand = Traits::X86OperandMem::create(
         Func, IceType_i32, Mem->getBase(), Offset, Mem->getIndex(),
         Mem->getShift(), Mem->getSegmentRegister());
     // Test if the Offset is an eligible i32 constants for randomization and
@@ -1275,32 +1232,7 @@
 llvm::SmallBitVector
 TargetX86Base<Machine>::getRegisterSet(RegSetMask Include,
                                        RegSetMask Exclude) const {
-  llvm::SmallBitVector Registers(Traits::RegisterSet::Reg_NUM);
-
-#define X(val, encode, name, name16, name8, scratch, preserved, stackptr,      \
-          frameptr, isI8, isInt, isFP)                                         \
-  if (scratch && (Include & RegSet_CallerSave))                                \
-    Registers[Traits::RegisterSet::val] = true;                                \
-  if (preserved && (Include & RegSet_CalleeSave))                              \
-    Registers[Traits::RegisterSet::val] = true;                                \
-  if (stackptr && (Include & RegSet_StackPointer))                             \
-    Registers[Traits::RegisterSet::val] = true;                                \
-  if (frameptr && (Include & RegSet_FramePointer))                             \
-    Registers[Traits::RegisterSet::val] = true;                                \
-  if (scratch && (Exclude & RegSet_CallerSave))                                \
-    Registers[Traits::RegisterSet::val] = false;                               \
-  if (preserved && (Exclude & RegSet_CalleeSave))                              \
-    Registers[Traits::RegisterSet::val] = false;                               \
-  if (stackptr && (Exclude & RegSet_StackPointer))                             \
-    Registers[Traits::RegisterSet::val] = false;                               \
-  if (frameptr && (Exclude & RegSet_FramePointer))                             \
-    Registers[Traits::RegisterSet::val] = false;
-
-  REGX8632_TABLE
-
-#undef X
-
-  return Registers;
+  return Traits::getRegisterSet(Include, Exclude);
 }
 
 template <class Machine>
@@ -1423,17 +1355,20 @@
   Constant *Zero = Ctx->getConstantZero(IceType_i32);
   for (uint32_t i = 0; i < Count9; ++i) {
     const uint16_t Shift = 3; // log2(9-1)
-    _lea(T, OperandX8632Mem::create(Func, IceType_void, T, Zero, T, Shift));
+    _lea(T,
+         Traits::X86OperandMem::create(Func, IceType_void, T, Zero, T, Shift));
     _set_dest_nonkillable();
   }
   for (uint32_t i = 0; i < Count5; ++i) {
     const uint16_t Shift = 2; // log2(5-1)
-    _lea(T, OperandX8632Mem::create(Func, IceType_void, T, Zero, T, Shift));
+    _lea(T,
+         Traits::X86OperandMem::create(Func, IceType_void, T, Zero, T, Shift));
     _set_dest_nonkillable();
   }
   for (uint32_t i = 0; i < Count3; ++i) {
     const uint16_t Shift = 1; // log2(3-1)
-    _lea(T, OperandX8632Mem::create(Func, IceType_void, T, Zero, T, Shift));
+    _lea(T,
+         Traits::X86OperandMem::create(Func, IceType_void, T, Zero, T, Shift));
     _set_dest_nonkillable();
   }
   if (Count2) {
@@ -1601,7 +1536,8 @@
       Variable *T_1 = nullptr, *T_2 = nullptr, *T_3 = nullptr;
       Constant *BitTest = Ctx->getConstantInt32(0x20);
       Constant *Zero = Ctx->getConstantZero(IceType_i32);
-      InstX8632Label *Label = InstX8632Label::create(Func, this);
+      typename Traits::Insts::Label *Label =
+          Traits::Insts::Label::create(Func, this);
       _mov(T_1, Src1Lo, Traits::RegisterSet::Reg_ecx);
       _mov(T_2, Src0Lo);
       _mov(T_3, Src0Hi);
@@ -1636,7 +1572,8 @@
       Variable *T_1 = nullptr, *T_2 = nullptr, *T_3 = nullptr;
       Constant *BitTest = Ctx->getConstantInt32(0x20);
       Constant *Zero = Ctx->getConstantZero(IceType_i32);
-      InstX8632Label *Label = InstX8632Label::create(Func, this);
+      typename Traits::Insts::Label *Label =
+          Traits::Insts::Label::create(Func, this);
       _mov(T_1, Src1Lo, Traits::RegisterSet::Reg_ecx);
       _mov(T_2, Src0Lo);
       _mov(T_3, Src0Hi);
@@ -1671,7 +1608,8 @@
       Variable *T_1 = nullptr, *T_2 = nullptr, *T_3 = nullptr;
       Constant *BitTest = Ctx->getConstantInt32(0x20);
       Constant *SignExtend = Ctx->getConstantInt32(0x1f);
-      InstX8632Label *Label = InstX8632Label::create(Func, this);
+      typename Traits::Insts::Label *Label =
+          Traits::Insts::Label::create(Func, this);
       _mov(T_1, Src1Lo, Traits::RegisterSet::Reg_ecx);
       _mov(T_2, Src0Lo);
       _mov(T_3, Src0Hi);
@@ -1709,7 +1647,7 @@
   if (isVectorType(Dest->getType())) {
     // TODO: Trap on integer divide and integer modulo by zero.
     // See: https://code.google.com/p/nativeclient/issues/detail?id=3899
-    if (llvm::isa<OperandX8632Mem>(Src1))
+    if (llvm::isa<typename Traits::X86OperandMem>(Src1))
       Src1 = legalizeToVar(Src1);
     switch (Inst->getOp()) {
     case InstArithmetic::_num:
@@ -2208,7 +2146,8 @@
       Variable *esp =
           Func->getTarget()->getPhysicalRegister(Traits::RegisterSet::Reg_esp);
       Constant *Loc = Ctx->getConstantInt32(ParameterAreaSizeBytes);
-      StackArgLocations.push_back(OperandX8632Mem::create(Func, Ty, esp, Loc));
+      StackArgLocations.push_back(
+          Traits::X86OperandMem::create(Func, Ty, esp, Loc));
       ParameterAreaSizeBytes += typeWidthInBytesOnStack(Arg->getType());
     }
   }
@@ -2305,7 +2244,7 @@
       CallTarget = CallTargetVar;
     }
   }
-  Inst *NewCall = InstX8632Call::create(Func, ReturnReg, CallTarget);
+  Inst *NewCall = Traits::Insts::Call::create(Func, ReturnReg, CallTarget);
   Context.insert(NewCall);
   if (NeedSandboxing)
     _bundle_unlock();
@@ -2532,7 +2471,7 @@
     Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem);
     // t1 = cvt Src0RM; Dest = t1
     Variable *T = makeReg(Dest->getType());
-    _cvt(T, Src0RM, InstX8632Cvt::Float2float);
+    _cvt(T, Src0RM, Traits::Insts::Cvt::Float2float);
     _mov(Dest, T);
     break;
   }
@@ -2541,10 +2480,10 @@
       assert(Dest->getType() == IceType_v4i32 &&
              Inst->getSrc(0)->getType() == IceType_v4f32);
       Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem);
-      if (llvm::isa<OperandX8632Mem>(Src0RM))
+      if (llvm::isa<typename Traits::X86OperandMem>(Src0RM))
         Src0RM = legalizeToVar(Src0RM);
       Variable *T = makeReg(Dest->getType());
-      _cvt(T, Src0RM, InstX8632Cvt::Tps2dq);
+      _cvt(T, Src0RM, Traits::Insts::Cvt::Tps2dq);
       _movp(Dest, T);
     } else if (Dest->getType() == IceType_i64) {
       // Use a helper for converting floating-point values to 64-bit
@@ -2567,7 +2506,7 @@
       // t1.i32 = cvt Src0RM; t2.dest_type = t1; Dest = t2.dest_type
       Variable *T_1 = makeReg(IceType_i32);
       Variable *T_2 = makeReg(Dest->getType());
-      _cvt(T_1, Src0RM, InstX8632Cvt::Tss2si);
+      _cvt(T_1, Src0RM, Traits::Insts::Cvt::Tss2si);
       _mov(T_2, T_1); // T_1 and T_2 may have different integer types
       if (Dest->getType() == IceType_i1)
         _and(T_2, Ctx->getConstantInt1(1));
@@ -2606,7 +2545,7 @@
       // t1.i32 = cvt Src0RM; t2.dest_type = t1; Dest = t2.dest_type
       Variable *T_1 = makeReg(IceType_i32);
       Variable *T_2 = makeReg(Dest->getType());
-      _cvt(T_1, Src0RM, InstX8632Cvt::Tss2si);
+      _cvt(T_1, Src0RM, Traits::Insts::Cvt::Tss2si);
       _mov(T_2, T_1); // T_1 and T_2 may have different integer types
       if (Dest->getType() == IceType_i1)
         _and(T_2, Ctx->getConstantInt1(1));
@@ -2618,10 +2557,10 @@
       assert(Dest->getType() == IceType_v4f32 &&
              Inst->getSrc(0)->getType() == IceType_v4i32);
       Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem);
-      if (llvm::isa<OperandX8632Mem>(Src0RM))
+      if (llvm::isa<typename Traits::X86OperandMem>(Src0RM))
         Src0RM = legalizeToVar(Src0RM);
       Variable *T = makeReg(Dest->getType());
-      _cvt(T, Src0RM, InstX8632Cvt::Dq2ps);
+      _cvt(T, Src0RM, Traits::Insts::Cvt::Dq2ps);
       _movp(Dest, T);
     } else if (Inst->getSrc(0)->getType() == IceType_i64) {
       // Use a helper for x86-32.
@@ -2645,7 +2584,7 @@
         _mov(T_1, Src0RM);
       else
         _movsx(T_1, Src0RM);
-      _cvt(T_2, T_1, InstX8632Cvt::Si2ss);
+      _cvt(T_2, T_1, Traits::Insts::Cvt::Si2ss);
       _mov(Dest, T_2);
     }
     break;
@@ -2686,7 +2625,7 @@
         _mov(T_1, Src0RM);
       else
         _movzx(T_1, Src0RM);
-      _cvt(T_2, T_1, InstX8632Cvt::Si2ss);
+      _cvt(T_2, T_1, Traits::Insts::Cvt::Si2ss);
       _mov(Dest, T_2);
     }
     break;
@@ -2728,8 +2667,8 @@
       Variable *T = nullptr;
       // TODO: Should be able to force a spill setup by calling legalize() with
       // Legal_Mem and not Legal_Reg or Legal_Imm.
-      SpillVariable *SpillVar =
-          Func->template makeVariable<SpillVariable>(SrcType);
+      typename Traits::SpillVariable *SpillVar =
+          Func->template makeVariable<typename Traits::SpillVariable>(SrcType);
       SpillVar->setLinkedTo(Dest);
       Variable *Spill = SpillVar;
       Spill->setWeight(RegWeight::Zero);
@@ -2748,14 +2687,17 @@
       //   a_hi.i32 = t_hi.i32
       Operand *SpillLo, *SpillHi;
       if (auto *Src0Var = llvm::dyn_cast<Variable>(Src0RM)) {
-        SpillVariable *SpillVar =
-            Func->template makeVariable<SpillVariable>(IceType_f64);
+        typename Traits::SpillVariable *SpillVar =
+            Func->template makeVariable<typename Traits::SpillVariable>(
+                IceType_f64);
         SpillVar->setLinkedTo(Src0Var);
         Variable *Spill = SpillVar;
         Spill->setWeight(RegWeight::Zero);
         _movq(Spill, Src0RM);
-        SpillLo = VariableSplit::create(Func, Spill, VariableSplit::Low);
-        SpillHi = VariableSplit::create(Func, Spill, VariableSplit::High);
+        SpillLo = Traits::VariableSplit::create(Func, Spill,
+                                                Traits::VariableSplit::Low);
+        SpillHi = Traits::VariableSplit::create(Func, Spill,
+                                                Traits::VariableSplit::High);
       } else {
         SpillLo = loOperand(Src0RM);
         SpillHi = hiOperand(Src0RM);
@@ -2774,7 +2716,7 @@
     case IceType_f64: {
       Src0 = legalize(Src0);
       assert(Src0->getType() == IceType_i64);
-      if (llvm::isa<OperandX8632Mem>(Src0)) {
+      if (llvm::isa<typename Traits::X86OperandMem>(Src0)) {
         Variable *T = Func->template makeVariable(Dest->getType());
         _movq(T, Src0);
         _movq(Dest, T);
@@ -2787,17 +2729,18 @@
       //   t_hi.i32 = b_hi.i32
       //   hi(s.f64) = t_hi.i32
       //   a.f64 = s.f64
-      SpillVariable *SpillVar =
-          Func->template makeVariable<SpillVariable>(IceType_f64);
+      typename Traits::SpillVariable *SpillVar =
+          Func->template makeVariable<typename Traits::SpillVariable>(
+              IceType_f64);
       SpillVar->setLinkedTo(Dest);
       Variable *Spill = SpillVar;
       Spill->setWeight(RegWeight::Zero);
 
       Variable *T_Lo = nullptr, *T_Hi = nullptr;
-      VariableSplit *SpillLo =
-          VariableSplit::create(Func, Spill, VariableSplit::Low);
-      VariableSplit *SpillHi =
-          VariableSplit::create(Func, Spill, VariableSplit::High);
+      typename Traits::VariableSplit *SpillLo = Traits::VariableSplit::create(
+          Func, Spill, Traits::VariableSplit::Low);
+      typename Traits::VariableSplit *SpillHi = Traits::VariableSplit::create(
+          Func, Spill, Traits::VariableSplit::High);
       _mov(T_Lo, loOperand(Src0));
       // Technically, the Spill is defined after the _store happens, but
       // SpillLo is considered a "use" of Spill so define Spill before it
@@ -2897,7 +2840,7 @@
 
     // Compute the location of the element in memory.
     unsigned Offset = Index * typeWidthInBytes(InVectorElementTy);
-    OperandX8632Mem *Loc =
+    typename Traits::X86OperandMem *Loc =
         getMemoryOperandForStackSlot(InVectorElementTy, Slot, Offset);
     _mov(ExtractedElementR, Loc);
   }
@@ -2943,7 +2886,7 @@
     } else {
       Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem);
       Operand *Src1RM = legalize(Src1, Legal_Reg | Legal_Mem);
-      if (llvm::isa<OperandX8632Mem>(Src1RM))
+      if (llvm::isa<typename Traits::X86OperandMem>(Src1RM))
         Src1RM = legalizeToVar(Src1RM);
 
       switch (Condition) {
@@ -3018,7 +2961,8 @@
   Constant *Default = Ctx->getConstantInt32(Traits::TableFcmp[Index].Default);
   _mov(Dest, Default);
   if (HasC1) {
-    InstX8632Label *Label = InstX8632Label::create(Func, this);
+    typename Traits::Insts::Label *Label =
+        Traits::Insts::Label::create(Func, this);
     _br(Traits::TableFcmp[Index].C1, Label);
     if (HasC2) {
       _br(Traits::TableFcmp[Index].C2, Label);
@@ -3091,13 +3035,13 @@
       llvm_unreachable("unexpected condition");
       break;
     case InstIcmp::Eq: {
-      if (llvm::isa<OperandX8632Mem>(Src1RM))
+      if (llvm::isa<typename Traits::X86OperandMem>(Src1RM))
         Src1RM = legalizeToVar(Src1RM);
       _movp(T, Src0RM);
       _pcmpeq(T, Src1RM);
     } break;
     case InstIcmp::Ne: {
-      if (llvm::isa<OperandX8632Mem>(Src1RM))
+      if (llvm::isa<typename Traits::X86OperandMem>(Src1RM))
         Src1RM = legalizeToVar(Src1RM);
       _movp(T, Src0RM);
       _pcmpeq(T, Src1RM);
@@ -3106,7 +3050,7 @@
     } break;
     case InstIcmp::Ugt:
     case InstIcmp::Sgt: {
-      if (llvm::isa<OperandX8632Mem>(Src1RM))
+      if (llvm::isa<typename Traits::X86OperandMem>(Src1RM))
         Src1RM = legalizeToVar(Src1RM);
       _movp(T, Src0RM);
       _pcmpgt(T, Src1RM);
@@ -3114,7 +3058,7 @@
     case InstIcmp::Uge:
     case InstIcmp::Sge: {
       // !(Src1RM > Src0RM)
-      if (llvm::isa<OperandX8632Mem>(Src0RM))
+      if (llvm::isa<typename Traits::X86OperandMem>(Src0RM))
         Src0RM = legalizeToVar(Src0RM);
       _movp(T, Src1RM);
       _pcmpgt(T, Src0RM);
@@ -3123,7 +3067,7 @@
     } break;
     case InstIcmp::Ult:
     case InstIcmp::Slt: {
-      if (llvm::isa<OperandX8632Mem>(Src0RM))
+      if (llvm::isa<typename Traits::X86OperandMem>(Src0RM))
         Src0RM = legalizeToVar(Src0RM);
       _movp(T, Src1RM);
       _pcmpgt(T, Src0RM);
@@ -3131,7 +3075,7 @@
     case InstIcmp::Ule:
     case InstIcmp::Sle: {
       // !(Src0RM > Src1RM)
-      if (llvm::isa<OperandX8632Mem>(Src1RM))
+      if (llvm::isa<typename Traits::X86OperandMem>(Src1RM))
         Src1RM = legalizeToVar(Src1RM);
       _movp(T, Src0RM);
       _pcmpgt(T, Src1RM);
@@ -3156,8 +3100,10 @@
     Operand *Src1HiRI = legalize(hiOperand(Src1), Legal_Reg | Legal_Imm);
     Constant *Zero = Ctx->getConstantZero(IceType_i32);
     Constant *One = Ctx->getConstantInt32(1);
-    InstX8632Label *LabelFalse = InstX8632Label::create(Func, this);
-    InstX8632Label *LabelTrue = InstX8632Label::create(Func, this);
+    typename Traits::Insts::Label *LabelFalse =
+        Traits::Insts::Label::create(Func, this);
+    typename Traits::Insts::Label *LabelTrue =
+        Traits::Insts::Label::create(Func, this);
     _mov(Dest, One);
     _cmp(Src0HiRM, Src1HiRI);
     if (Traits::TableIcmp64[Index].C1 != Traits::Cond::Br_None)
@@ -3293,7 +3239,7 @@
 
     // Compute the location of the position to insert in memory.
     unsigned Offset = Index * typeWidthInBytes(InVectorElementTy);
-    OperandX8632Mem *Loc =
+    typename Traits::X86OperandMem *Loc =
         getMemoryOperandForStackSlot(InVectorElementTy, Slot, Offset);
     _store(legalizeToVar(ElementToInsertNotLegalized), Loc);
 
@@ -3383,7 +3329,8 @@
       // can't happen anyway, since this is x86-32 and integer arithmetic only
       // happens on 32-bit quantities.
       Variable *T = makeReg(IceType_f64);
-      OperandX8632Mem *Addr = formMemoryOperand(Instr->getArg(0), IceType_f64);
+      typename Traits::X86OperandMem *Addr =
+          formMemoryOperand(Instr->getArg(0), IceType_f64);
       _movq(T, Addr);
       // Then cast the bits back out of the XMM register to the i64 Dest.
       InstCast *Cast = InstCast::create(Func, InstCast::Bitcast, Dest, T);
@@ -3433,7 +3380,8 @@
       InstCast *Cast = InstCast::create(Func, InstCast::Bitcast, T, Value);
       lowerCast(Cast);
       // Then store XMM w/ a movq.
-      OperandX8632Mem *Addr = formMemoryOperand(Ptr, IceType_f64);
+      typename Traits::X86OperandMem *Addr =
+          formMemoryOperand(Ptr, IceType_f64);
       _storeq(T, Addr);
       _mfence();
       return;
@@ -3535,7 +3483,7 @@
     // The pand instruction operates on an m128 memory operand, so if
     // Src is an f32 or f64, we need to make sure it's in a register.
     if (isVectorType(Ty)) {
-      if (llvm::isa<OperandX8632Mem>(Src))
+      if (llvm::isa<typename Traits::X86OperandMem>(Src))
         Src = legalizeToVar(Src);
     } else {
       Src = legalizeToVar(Src);
@@ -3590,9 +3538,9 @@
   case Intrinsics::NaClReadTP: {
     if (Ctx->getFlags().getUseSandboxing()) {
       Constant *Zero = Ctx->getConstantZero(IceType_i32);
-      Operand *Src =
-          OperandX8632Mem::create(Func, IceType_i32, nullptr, Zero, nullptr, 0,
-                                  OperandX8632Mem::SegReg_GS);
+      Operand *Src = Traits::X86OperandMem::create(
+          Func, IceType_i32, nullptr, Zero, nullptr, 0,
+          Traits::X86OperandMem::SegReg_GS);
       Variable *Dest = Instr->getDest();
       Variable *T = nullptr;
       _mov(T, Src);
@@ -3655,7 +3603,8 @@
     _mov(T_edx, hiOperand(Expected));
     _mov(T_ebx, loOperand(Desired));
     _mov(T_ecx, hiOperand(Desired));
-    OperandX8632Mem *Addr = formMemoryOperand(Ptr, Expected->getType());
+    typename Traits::X86OperandMem *Addr =
+        formMemoryOperand(Ptr, Expected->getType());
     const bool Locked = true;
     _cmpxchg8b(Addr, T_edx, T_eax, T_ecx, T_ebx, Locked);
     Variable *DestLo = llvm::cast<Variable>(loOperand(DestPrev));
@@ -3666,7 +3615,8 @@
   }
   Variable *T_eax = makeReg(Expected->getType(), Traits::RegisterSet::Reg_eax);
   _mov(T_eax, Expected);
-  OperandX8632Mem *Addr = formMemoryOperand(Ptr, Expected->getType());
+  typename Traits::X86OperandMem *Addr =
+      formMemoryOperand(Ptr, Expected->getType());
   Variable *DesiredReg = legalizeToVar(Desired);
   const bool Locked = true;
   _cmpxchg(Addr, T_eax, DesiredReg, Locked);
@@ -3768,7 +3718,8 @@
       Op_Hi = &TargetX86Base<Machine>::_adc;
       break;
     }
-    OperandX8632Mem *Addr = formMemoryOperand(Ptr, Dest->getType());
+    typename Traits::X86OperandMem *Addr =
+        formMemoryOperand(Ptr, Dest->getType());
     const bool Locked = true;
     Variable *T = nullptr;
     _mov(T, Val);
@@ -3783,7 +3734,8 @@
       Op_Hi = &TargetX86Base<Machine>::_sbb;
       break;
     }
-    OperandX8632Mem *Addr = formMemoryOperand(Ptr, Dest->getType());
+    typename Traits::X86OperandMem *Addr =
+        formMemoryOperand(Ptr, Dest->getType());
     const bool Locked = true;
     Variable *T = nullptr;
     _mov(T, Val);
@@ -3821,7 +3773,8 @@
       Op_Hi = nullptr;
       break;
     }
-    OperandX8632Mem *Addr = formMemoryOperand(Ptr, Dest->getType());
+    typename Traits::X86OperandMem *Addr =
+        formMemoryOperand(Ptr, Dest->getType());
     Variable *T = nullptr;
     _mov(T, Val);
     _xchg(Addr, T);
@@ -3869,12 +3822,13 @@
   if (Ty == IceType_i64) {
     Variable *T_edx = makeReg(IceType_i32, Traits::RegisterSet::Reg_edx);
     Variable *T_eax = makeReg(IceType_i32, Traits::RegisterSet::Reg_eax);
-    OperandX8632Mem *Addr = formMemoryOperand(Ptr, Ty);
+    typename Traits::X86OperandMem *Addr = formMemoryOperand(Ptr, Ty);
     _mov(T_eax, loOperand(Addr));
     _mov(T_edx, hiOperand(Addr));
     Variable *T_ecx = makeReg(IceType_i32, Traits::RegisterSet::Reg_ecx);
     Variable *T_ebx = makeReg(IceType_i32, Traits::RegisterSet::Reg_ebx);
-    InstX8632Label *Label = InstX8632Label::create(Func, this);
+    typename Traits::Insts::Label *Label =
+        Traits::Insts::Label::create(Func, this);
     const bool IsXchg8b = Op_Lo == nullptr && Op_Hi == nullptr;
     if (!IsXchg8b) {
       Context.insert(Label);
@@ -3916,10 +3870,11 @@
     _mov(DestHi, T_edx);
     return;
   }
-  OperandX8632Mem *Addr = formMemoryOperand(Ptr, Ty);
+  typename Traits::X86OperandMem *Addr = formMemoryOperand(Ptr, Ty);
   Variable *T_eax = makeReg(Ty, Traits::RegisterSet::Reg_eax);
   _mov(T_eax, Addr);
-  InstX8632Label *Label = InstX8632Label::create(Func, this);
+  typename Traits::Insts::Label *Label =
+      Traits::Insts::Label::create(Func, this);
   Context.insert(Label);
   // We want to pick a different register for T than Eax, so don't use
   // _mov(T == nullptr, T_eax).
@@ -4260,11 +4215,11 @@
 
 template <class Machine>
 void TargetX86Base<Machine>::lowerLoad(const InstLoad *Load) {
-  // A Load instruction can be treated the same as an Assign
-  // instruction, after the source operand is transformed into an
-  // OperandX8632Mem operand.  Note that the address mode
-  // optimization already creates an OperandX8632Mem operand, so it
-  // doesn't need another level of transformation.
+  // A Load instruction can be treated the same as an Assign instruction, after
+  // the source operand is transformed into an Traits::X86OperandMem operand.
+  // Note that the address mode optimization already creates an
+  // Traits::X86OperandMem operand, so it doesn't need another level of
+  // transformation.
   Variable *DestLoad = Load->getDest();
   Type Ty = DestLoad->getType();
   Operand *Src0 = formMemoryOperand(Load->getSourceAddress(), Ty);
@@ -4279,19 +4234,19 @@
   Variable *Index = nullptr;
   uint16_t Shift = 0;
   int32_t Offset = 0; // TODO: make Constant
-  // Vanilla ICE load instructions should not use the segment registers,
-  // and computeAddressOpt only works at the level of Variables and Constants,
-  // not other OperandX8632Mem, so there should be no mention of segment
+  // Vanilla ICE load instructions should not use the segment registers, and
+  // computeAddressOpt only works at the level of Variables and Constants, not
+  // other Traits::X86OperandMem, so there should be no mention of segment
   // registers there either.
-  const OperandX8632Mem::SegmentRegisters SegmentReg =
-      OperandX8632Mem::DefaultSegment;
+  const typename Traits::X86OperandMem::SegmentRegisters SegmentReg =
+      Traits::X86OperandMem::DefaultSegment;
   Variable *Base = llvm::dyn_cast<Variable>(Addr);
   computeAddressOpt(Func, Inst, Base, Index, Shift, Offset);
   if (Base && Addr != Base) {
     Inst->setDeleted();
     Constant *OffsetOp = Ctx->getConstantInt32(Offset);
-    Addr = OperandX8632Mem::create(Func, Dest->getType(), Base, OffsetOp, Index,
-                                   Shift, SegmentReg);
+    Addr = Traits::X86OperandMem::create(Func, Dest->getType(), Base, OffsetOp,
+                                         Index, Shift, SegmentReg);
     Context.insert(InstLoad::create(Func, Dest, Addr));
   }
 }
@@ -4438,7 +4393,8 @@
     // The cmov instruction doesn't allow 8-bit or FP operands, so
     // we need explicit control flow.
     // d=cmp e,f; a=d?b:c ==> cmp e,f; a=b; jne L1; a=c; L1:
-    InstX8632Label *Label = InstX8632Label::create(Func, this);
+    typename Traits::Insts::Label *Label =
+        Traits::Insts::Label::create(Func, this);
     SrcT = legalize(SrcT, Legal_Reg | Legal_Imm);
     _mov(Dest, SrcT);
     _br(Cond, Label);
@@ -4453,7 +4409,7 @@
   // mov t, SrcT; cmov_!cond t, SrcF; mov dest, t
   if (llvm::isa<Constant>(SrcT) && !llvm::isa<Constant>(SrcF)) {
     std::swap(SrcT, SrcF);
-    Cond = InstX8632::getOppositeCondition(Cond);
+    Cond = InstX86Base<Machine>::getOppositeCondition(Cond);
   }
   if (DestTy == IceType_i64) {
     // Set the low portion.
@@ -4488,15 +4444,18 @@
 void TargetX86Base<Machine>::lowerStore(const InstStore *Inst) {
   Operand *Value = Inst->getData();
   Operand *Addr = Inst->getAddr();
-  OperandX8632Mem *NewAddr = formMemoryOperand(Addr, Value->getType());
+  typename Traits::X86OperandMem *NewAddr =
+      formMemoryOperand(Addr, Value->getType());
   Type Ty = NewAddr->getType();
 
   if (Ty == IceType_i64) {
     Value = legalize(Value);
     Operand *ValueHi = legalize(hiOperand(Value), Legal_Reg | Legal_Imm);
     Operand *ValueLo = legalize(loOperand(Value), Legal_Reg | Legal_Imm);
-    _store(ValueHi, llvm::cast<OperandX8632Mem>(hiOperand(NewAddr)));
-    _store(ValueLo, llvm::cast<OperandX8632Mem>(loOperand(NewAddr)));
+    _store(ValueHi,
+           llvm::cast<typename Traits::X86OperandMem>(hiOperand(NewAddr)));
+    _store(ValueLo,
+           llvm::cast<typename Traits::X86OperandMem>(loOperand(NewAddr)));
   } else if (isVectorType(Ty)) {
     _storep(legalizeToVar(Value), NewAddr);
   } else {
@@ -4513,18 +4472,18 @@
   uint16_t Shift = 0;
   int32_t Offset = 0; // TODO: make Constant
   Variable *Base = llvm::dyn_cast<Variable>(Addr);
-  // Vanilla ICE store instructions should not use the segment registers,
-  // and computeAddressOpt only works at the level of Variables and Constants,
-  // not other OperandX8632Mem, so there should be no mention of segment
+  // Vanilla ICE store instructions should not use the segment registers, and
+  // computeAddressOpt only works at the level of Variables and Constants, not
+  // other Traits::X86OperandMem, so there should be no mention of segment
   // registers there either.
-  const OperandX8632Mem::SegmentRegisters SegmentReg =
-      OperandX8632Mem::DefaultSegment;
+  const typename Traits::X86OperandMem::SegmentRegisters SegmentReg =
+      Traits::X86OperandMem::DefaultSegment;
   computeAddressOpt(Func, Inst, Base, Index, Shift, Offset);
   if (Base && Addr != Base) {
     Inst->setDeleted();
     Constant *OffsetOp = Ctx->getConstantInt32(Offset);
-    Addr = OperandX8632Mem::create(Func, Data->getType(), Base, OffsetOp, Index,
-                                   Shift, SegmentReg);
+    Addr = Traits::X86OperandMem::create(Func, Data->getType(), Base, OffsetOp,
+                                         Index, Shift, SegmentReg);
     InstStore *NewStore = InstStore::create(Func, Data, Addr);
     if (Inst->getDest())
       NewStore->setRmwBeacon(Inst->getRmwBeacon());
@@ -4552,7 +4511,8 @@
     for (SizeT I = 0; I < NumCases; ++I) {
       Constant *ValueLo = Ctx->getConstantInt32(Inst->getValue(I));
       Constant *ValueHi = Ctx->getConstantInt32(Inst->getValue(I) >> 32);
-      InstX8632Label *Label = InstX8632Label::create(Func, this);
+      typename Traits::Insts::Label *Label =
+          Traits::Insts::Label::create(Func, this);
       _cmp(Src0Lo, ValueLo);
       _br(Traits::Cond::Br_ne, Label);
       _cmp(Src0Hi, ValueHi);
@@ -4639,7 +4599,8 @@
 }
 
 template <class Machine>
-void TargetX86Base<Machine>::lowerRMW(const InstX8632FakeRMW *RMW) {
+void TargetX86Base<Machine>::lowerRMW(
+    const typename Traits::Insts::FakeRMW *RMW) {
   // If the beacon variable's live range does not end in this
   // instruction, then it must end in the modified Store instruction
   // that follows.  This means that the original Store instruction is
@@ -4651,12 +4612,14 @@
     return;
   Operand *Src = RMW->getData();
   Type Ty = Src->getType();
-  OperandX8632Mem *Addr = formMemoryOperand(RMW->getAddr(), Ty);
+  typename Traits::X86OperandMem *Addr = formMemoryOperand(RMW->getAddr(), Ty);
   if (Ty == IceType_i64) {
     Operand *SrcLo = legalize(loOperand(Src), Legal_Reg | Legal_Imm);
     Operand *SrcHi = legalize(hiOperand(Src), Legal_Reg | Legal_Imm);
-    OperandX8632Mem *AddrLo = llvm::cast<OperandX8632Mem>(loOperand(Addr));
-    OperandX8632Mem *AddrHi = llvm::cast<OperandX8632Mem>(hiOperand(Addr));
+    typename Traits::X86OperandMem *AddrLo =
+        llvm::cast<typename Traits::X86OperandMem>(loOperand(Addr));
+    typename Traits::X86OperandMem *AddrHi =
+        llvm::cast<typename Traits::X86OperandMem>(hiOperand(Addr));
     switch (RMW->getOp()) {
     default:
       // TODO(stichnot): Implement other arithmetic operators.
@@ -4715,7 +4678,8 @@
 
 template <class Machine>
 void TargetX86Base<Machine>::lowerOther(const Inst *Instr) {
-  if (const auto *RMW = llvm::dyn_cast<InstX8632FakeRMW>(Instr)) {
+  if (const auto *RMW =
+          llvm::dyn_cast<typename Traits::Insts::FakeRMW>(Instr)) {
     lowerRMW(RMW);
   } else {
     TargetLowering::lowerOther(Instr);
@@ -4991,7 +4955,7 @@
 }
 
 template <class Machine>
-OperandX8632Mem *
+typename TargetX86Base<Machine>::Traits::X86OperandMem *
 TargetX86Base<Machine>::getMemoryOperandForStackSlot(Type Ty, Variable *Slot,
                                                      uint32_t Offset) {
   // Ensure that Loc is a stack slot.
@@ -5005,7 +4969,7 @@
   Variable *Loc = makeReg(PointerType);
   _lea(Loc, Slot);
   Constant *ConstantOffset = Ctx->getConstantInt32(Offset);
-  return OperandX8632Mem::create(Func, Ty, Loc, ConstantOffset);
+  return Traits::X86OperandMem::create(Func, Ty, Loc, ConstantOffset);
 }
 
 /// Helper for legalize() to emit the right code to lower an operand to a
@@ -5037,7 +5001,7 @@
   // or in ecx.)
   assert(RegNum == Variable::NoRegister || Allowed == Legal_Reg);
 
-  if (auto Mem = llvm::dyn_cast<OperandX8632Mem>(From)) {
+  if (auto Mem = llvm::dyn_cast<typename Traits::X86OperandMem>(From)) {
     // Before doing anything with a Mem operand, we need to ensure
     // that the Base and Index components are in physical registers.
     Variable *Base = Mem->getBase();
@@ -5051,9 +5015,9 @@
       RegIndex = legalizeToVar(Index);
     }
     if (Base != RegBase || Index != RegIndex) {
-      Mem =
-          OperandX8632Mem::create(Func, Ty, RegBase, Mem->getOffset(), RegIndex,
-                                  Mem->getShift(), Mem->getSegmentRegister());
+      Mem = Traits::X86OperandMem::create(Func, Ty, RegBase, Mem->getOffset(),
+                                          RegIndex, Mem->getShift(),
+                                          Mem->getSegmentRegister());
     }
 
     // For all Memory Operands, we do randomization/pooling here
@@ -5103,7 +5067,7 @@
       llvm::cast<Constant>(From)->emitPoolLabel(StrBuf);
       llvm::cast<Constant>(From)->setShouldBePooled(true);
       Constant *Offset = Ctx->getConstantSym(0, StrBuf.str(), true);
-      From = OperandX8632Mem::create(Func, Ty, Base, Offset);
+      From = Traits::X86OperandMem::create(Func, Ty, Base, Offset);
     }
     bool NeedsReg = false;
     if (!(Allowed & Legal_Imm) && !isScalarFloatingType(Ty))
@@ -5162,13 +5126,13 @@
 }
 
 template <class Machine>
-OperandX8632Mem *TargetX86Base<Machine>::formMemoryOperand(Operand *Opnd,
-                                                           Type Ty,
-                                                           bool DoLegalize) {
-  OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Opnd);
-  // It may be the case that address mode optimization already creates
-  // an OperandX8632Mem, so in that case it wouldn't need another level
-  // of transformation.
+typename TargetX86Base<Machine>::Traits::X86OperandMem *
+TargetX86Base<Machine>::formMemoryOperand(Operand *Opnd, Type Ty,
+                                          bool DoLegalize) {
+  auto *Mem = llvm::dyn_cast<typename Traits::X86OperandMem>(Opnd);
+  // It may be the case that address mode optimization already creates an
+  // Traits::X86OperandMem, so in that case it wouldn't need another level of
+  // transformation.
   if (!Mem) {
     Variable *Base = llvm::dyn_cast<Variable>(Opnd);
     Constant *Offset = llvm::dyn_cast<Constant>(Opnd);
@@ -5188,11 +5152,11 @@
       assert(llvm::isa<ConstantInteger32>(Offset) ||
              llvm::isa<ConstantRelocatable>(Offset));
     }
-    Mem = OperandX8632Mem::create(Func, Ty, Base, Offset);
+    Mem = Traits::X86OperandMem::create(Func, Ty, Base, Offset);
   }
   // Do legalization, which contains randomization/pooling
   // or do randomization/pooling.
-  return llvm::cast<OperandX8632Mem>(
+  return llvm::cast<typename Traits::X86OperandMem>(
       DoLegalize ? legalize(Mem) : randomizeOrPoolImmediate(Mem));
 }
 
@@ -5218,68 +5182,8 @@
 void TargetX86Base<Machine>::makeRandomRegisterPermutation(
     llvm::SmallVectorImpl<int32_t> &Permutation,
     const llvm::SmallBitVector &ExcludeRegisters) const {
-  // TODO(stichnot): Declaring Permutation this way loses type/size
-  // information.  Fix this in conjunction with the caller-side TODO.
-  assert(Permutation.size() >= Traits::RegisterSet::Reg_NUM);
-  // Expected upper bound on the number of registers in a single
-  // equivalence class.  For x86-32, this would comprise the 8 XMM
-  // registers.  This is for performance, not correctness.
-  static const unsigned MaxEquivalenceClassSize = 8;
-  typedef llvm::SmallVector<int32_t, MaxEquivalenceClassSize> RegisterList;
-  typedef std::map<uint32_t, RegisterList> EquivalenceClassMap;
-  EquivalenceClassMap EquivalenceClasses;
-  SizeT NumShuffled = 0, NumPreserved = 0;
-
-// 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)                                         \
-  if (ExcludeRegisters[Traits::RegisterSet::val]) {                            \
-    /* val stays the same in the resulting permutation. */                     \
-    Permutation[Traits::RegisterSet::val] = Traits::RegisterSet::val;          \
-    ++NumPreserved;                                                            \
-  } else {                                                                     \
-    const uint32_t Index = (scratch << 0) | (preserved << 1) | (isI8 << 2) |   \
-                           (isInt << 3) | (isFP << 4);                         \
-    /* val is assigned to an equivalence class based on its properties. */     \
-    EquivalenceClasses[Index].push_back(Traits::RegisterSet::val);             \
-  }
-  REGX8632_TABLE
-#undef X
-
-  RandomNumberGeneratorWrapper RNG(Ctx->getRNG());
-
-  // Shuffle the resulting equivalence classes.
-  for (auto I : EquivalenceClasses) {
-    const RegisterList &List = I.second;
-    RegisterList Shuffled(List);
-    RandomShuffle(Shuffled.begin(), Shuffled.end(), RNG);
-    for (size_t SI = 0, SE = Shuffled.size(); SI < SE; ++SI) {
-      Permutation[List[SI]] = Shuffled[SI];
-      ++NumShuffled;
-    }
-  }
-
-  assert(NumShuffled + NumPreserved == Traits::RegisterSet::Reg_NUM);
-
-  if (Func->isVerbose(IceV_Random)) {
-    OstreamLocker L(Func->getContext());
-    Ostream &Str = Func->getContext()->getStrDump();
-    Str << "Register equivalence classes:\n";
-    for (auto I : EquivalenceClasses) {
-      Str << "{";
-      const RegisterList &List = I.second;
-      bool First = true;
-      for (int32_t Register : List) {
-        if (!First)
-          Str << " ";
-        First = false;
-        Str << getRegName(Register, IceType_i32);
-      }
-      Str << "}\n";
-    }
-  }
+  Traits::makeRandomRegisterPermutation(Ctx, Func, Permutation,
+                                        ExcludeRegisters);
 }
 
 template <class Machine>
@@ -5350,8 +5254,8 @@
       uint32_t Cookie = Ctx->getRandomizationCookie();
       _mov(Reg, Ctx->getConstantInt(IceType_i32, Cookie + Value));
       Constant *Offset = Ctx->getConstantInt(IceType_i32, 0 - Cookie);
-      _lea(Reg,
-           OperandX8632Mem::create(Func, IceType_i32, Reg, Offset, nullptr, 0));
+      _lea(Reg, Traits::X86OperandMem::create(Func, IceType_i32, Reg, Offset,
+                                              nullptr, 0));
       // make sure liveness analysis won't kill this variable, otherwise a
       // liveness
       // assertion will be triggered.
@@ -5384,8 +5288,9 @@
       const bool SuppressMangling = true;
       Constant *Symbol =
           Ctx->getConstantSym(Offset, Label_stream.str(), SuppressMangling);
-      OperandX8632Mem *MemOperand =
-          OperandX8632Mem::create(Func, Immediate->getType(), nullptr, Symbol);
+      typename Traits::X86OperandMem *MemOperand =
+          Traits::X86OperandMem::create(Func, Immediate->getType(), nullptr,
+                                        Symbol);
       _mov(Reg, MemOperand);
       return Reg;
     }
@@ -5396,9 +5301,9 @@
 }
 
 template <class Machine>
-OperandX8632Mem *
-TargetX86Base<Machine>::randomizeOrPoolImmediate(OperandX8632Mem *MemOperand,
-                                                 int32_t RegNum) {
+typename TargetX86Base<Machine>::Traits::X86OperandMem *
+TargetX86Base<Machine>::randomizeOrPoolImmediate(
+    typename Traits::X86OperandMem *MemOperand, int32_t RegNum) {
   assert(MemOperand);
   if (Ctx->getFlags().getRandomizeAndPoolImmediatesOption() == RPI_None ||
       RandomizationPoolingPaused == true) {
@@ -5432,8 +5337,9 @@
         Constant *Mask2 =
             Ctx->getConstantInt(MemOperand->getOffset()->getType(), 0 - Cookie);
 
-        OperandX8632Mem *TempMemOperand = OperandX8632Mem::create(
-            Func, MemOperand->getType(), MemOperand->getBase(), Mask1);
+        typename Traits::X86OperandMem *TempMemOperand =
+            Traits::X86OperandMem::create(Func, MemOperand->getType(),
+                                          MemOperand->getBase(), Mask1);
         // If we have already assigned a physical register, we must come from
         // advancedPhiLowering()=>lowerAssign(). In this case we should reuse
         // the assigned register as this assignment is that start of its use-def
@@ -5447,9 +5353,11 @@
         if (RegNum != Variable::NoRegister)
           _set_dest_nonkillable();
 
-        OperandX8632Mem *NewMemOperand = OperandX8632Mem::create(
-            Func, MemOperand->getType(), RegTemp, Mask2, MemOperand->getIndex(),
-            MemOperand->getShift(), MemOperand->getSegmentRegister());
+        typename Traits::X86OperandMem *NewMemOperand =
+            Traits::X86OperandMem::create(Func, MemOperand->getType(), RegTemp,
+                                          Mask2, MemOperand->getIndex(),
+                                          MemOperand->getShift(),
+                                          MemOperand->getSegmentRegister());
 
         // Label this memory operand as randomize, so we won't randomize it
         // again in case we call legalize() mutiple times on this memory
@@ -5484,23 +5392,26 @@
         bool SuppressMangling = true;
         Constant *Symbol = Ctx->getConstantSym(SymOffset, Label_stream.str(),
                                                SuppressMangling);
-        OperandX8632Mem *SymbolOperand = OperandX8632Mem::create(
-            Func, MemOperand->getOffset()->getType(), nullptr, Symbol);
+        typename Traits::X86OperandMem *SymbolOperand =
+            Traits::X86OperandMem::create(
+                Func, MemOperand->getOffset()->getType(), nullptr, Symbol);
         _mov(RegTemp, SymbolOperand);
         // If we have a base variable here, we should add the lea instruction
         // to add the value of the base variable to RegTemp. If there is no
         // base variable, we won't need this lea instruction.
         if (MemOperand->getBase()) {
-          OperandX8632Mem *CalculateOperand = OperandX8632Mem::create(
-              Func, MemOperand->getType(), MemOperand->getBase(), nullptr,
-              RegTemp, 0, MemOperand->getSegmentRegister());
+          typename Traits::X86OperandMem *CalculateOperand =
+              Traits::X86OperandMem::create(
+                  Func, MemOperand->getType(), MemOperand->getBase(), nullptr,
+                  RegTemp, 0, MemOperand->getSegmentRegister());
           _lea(RegTemp, CalculateOperand);
           _set_dest_nonkillable();
         }
-        OperandX8632Mem *NewMemOperand = OperandX8632Mem::create(
-            Func, MemOperand->getType(), RegTemp, nullptr,
-            MemOperand->getIndex(), MemOperand->getShift(),
-            MemOperand->getSegmentRegister());
+        typename Traits::X86OperandMem *NewMemOperand =
+            Traits::X86OperandMem::create(Func, MemOperand->getType(), RegTemp,
+                                          nullptr, MemOperand->getIndex(),
+                                          MemOperand->getShift(),
+                                          MemOperand->getSegmentRegister());
         return NewMemOperand;
       }
       assert("Unsupported -randomize-pool-immediates option" && false);
