//===- subzero/src/IceInstX8632.cpp - X86-32 instruction implementation ---===//
//
//                        The Subzero Code Generator
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the InstX8632 and OperandX8632 classes,
// primarily the constructors and the dump()/emit() methods.
//
//===----------------------------------------------------------------------===//

#include "assembler_ia32.h"
#include "IceCfg.h"
#include "IceCfgNode.h"
#include "IceConditionCodesX8632.h"
#include "IceInst.h"
#include "IceInstX8632.h"
#include "IceRegistersX8632.h"
#include "IceTargetLoweringX8632.h"
#include "IceOperand.h"

namespace Ice {

namespace {

const struct InstX8632BrAttributes_ {
  CondX86::BrCond Opposite;
  const char *DisplayString;
  const char *EmitString;
} InstX8632BrAttributes[] = {
#define X(tag, encode, opp, dump, emit)                                        \
  { CondX86::opp, dump, emit }                                                 \
  ,
    ICEINSTX8632BR_TABLE
#undef X
  };

const struct InstX8632CmppsAttributes_ {
  const char *EmitString;
} InstX8632CmppsAttributes[] = {
#define X(tag, emit)                                                           \
  { emit }                                                                     \
  ,
    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[] = {
#define X(tag, elementty, cvt, sdss, pack, width, fld)                         \
  { cvt, sdss, pack, width, fld }                                              \
  ,
    ICETYPEX8632_TABLE
#undef X
  };

const char *InstX8632SegmentRegNames[] = {
#define X(val, name, prefix) name,
    SEG_REGX8632_TABLE
#undef X
};

uint8_t InstX8632SegmentPrefixes[] = {
#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;
}

const char *InstX8632::getFldString(Type Ty) {
  return TypeX8632Attributes[Ty].FldString;
}

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),
      Shift(Shift), SegmentReg(SegmentReg) {
  assert(Shift <= 3);
  Vars = NULL;
  NumVars = 0;
  if (Base)
    ++NumVars;
  if (Index)
    ++NumVars;
  if (NumVars) {
    Vars = Func->allocateArrayOf<Variable *>(NumVars);
    SizeT I = 0;
    if (Base)
      Vars[I++] = Base;
    if (Index)
      Vars[I++] = Index;
    assert(I == NumVars);
  }
}

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, NULL),
      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, CondX86::BrCond Condition)
    : InstX8632(Func, InstX8632::Br, 0, NULL), 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 == NULL)
    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() == NULL)
    return false;

  // Unconditional branch to the next node can be removed.
  if (Condition == CondX86::Br_None && getTargetFalse() == NextNode) {
    assert(getTargetTrue() == NULL);
    setDeleted();
    return true;
  }
  // If the fallthrough is to the next node, set fallthrough to NULL
  // to indicate.
  if (getTargetFalse() == NextNode) {
    TargetFalse = NULL;
    return true;
  }
  // If TargetTrue is the next node, and TargetFalse is non-NULL
  // (which was already tested above), then invert the branch
  // condition, swap the targets, and set new fallthrough to NULL.
  if (getTargetTrue() == NextNode) {
    assert(Condition != CondX86::Br_None);
    Condition = InstX8632BrAttributes[Condition].Opposite;
    TargetTrue = getTargetFalse();
    TargetFalse = NULL;
    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;
}

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,
                             CondX86::BrCond Condition)
    : InstX8632(Func, InstX8632::Cmov, 2, Dest), Condition(Condition) {
  // The final result is either the original Dest, or Source, so mark
  // both as sources.
  addSource(Dest);
  addSource(Source);
}

InstX8632Cmpps::InstX8632Cmpps(Cfg *Func, Variable *Dest, Operand *Source,
                               CondX86::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, NULL, 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, NULL) {
  addSource(Src0);
  addSource(Src1);
}

InstX8632Ucomiss::InstX8632Ucomiss(Cfg *Func, Operand *Src0, Operand *Src1)
    : InstX8632(Func, InstX8632::Ucomiss, 2, NULL) {
  addSource(Src0);
  addSource(Src1);
}

InstX8632UD2::InstX8632UD2(Cfg *Func)
    : InstX8632(Func, InstX8632::UD2, 0, NULL) {}

InstX8632Test::InstX8632Test(Cfg *Func, Operand *Src1, Operand *Src2)
    : InstX8632(Func, InstX8632::Test, 2, NULL) {
  addSource(Src1);
  addSource(Src2);
}

InstX8632Mfence::InstX8632Mfence(Cfg *Func)
    : InstX8632(Func, InstX8632::Mfence, 0, NULL) {
  HasSideEffects = true;
}

InstX8632Store::InstX8632Store(Cfg *Func, Operand *Value, OperandX8632 *Mem)
    : InstX8632(Func, InstX8632::Store, 2, NULL) {
  addSource(Value);
  addSource(Mem);
}

InstX8632StoreP::InstX8632StoreP(Cfg *Func, Variable *Value,
                                 OperandX8632Mem *Mem)
    : InstX8632(Func, InstX8632::StoreP, 2, NULL) {
  addSource(Value);
  addSource(Mem);
}

InstX8632StoreQ::InstX8632StoreQ(Cfg *Func, Variable *Value,
                                 OperandX8632Mem *Mem)
    : InstX8632(Func, InstX8632::StoreQ, 2, NULL) {
  addSource(Value);
  addSource(Mem);
}

InstX8632Nop::InstX8632Nop(Cfg *Func, InstX8632Nop::NopVariant Variant)
    : InstX8632(Func, InstX8632::Nop, 0, NULL), Variant(Variant) {}

InstX8632Fld::InstX8632Fld(Cfg *Func, Operand *Src)
    : InstX8632(Func, InstX8632::Fld, 1, NULL) {
  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) {}

InstX8632Push::InstX8632Push(Cfg *Func, Variable *Source)
    : InstX8632(Func, InstX8632::Push, 1, NULL) {
  addSource(Source);
}

InstX8632Ret::InstX8632Ret(Cfg *Func, Variable *Source)
    : InstX8632(Func, InstX8632::Ret, Source ? 1 : 0, NULL) {
  if (Source)
    addSource(Source);
}

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 (!ALLOW_DUMP)
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  Str << "[X8632] ";
  Inst::dump(Func);
}

void InstX8632Label::emit(const Cfg *Func) const {
  if (!ALLOW_DUMP)
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  Str << getName(Func) << ":";
}

void InstX8632Label::emitIAS(const Cfg *Func) const {
  x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
  Asm->BindLocalLabel(Number);
}

void InstX8632Label::dump(const Cfg *Func) const {
  if (!ALLOW_DUMP)
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  Str << getName(Func) << ":";
}

void InstX8632Br::emit(const Cfg *Func) const {
  if (!ALLOW_DUMP)
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  Str << "\t";

  if (Condition == CondX86::Br_None) {
    Str << "jmp";
  } else {
    Str << InstX8632BrAttributes[Condition].EmitString;
  }

  if (Label) {
    Str << "\t" << Label->getName(Func);
  } else {
    if (Condition == CondX86::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 {
  x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
  if (Label) {
    x86::Label *L = Asm->GetOrCreateLocalLabel(Label->getNumber());
    // In all these cases, local Labels should only be used for Near.
    const bool Near = true;
    if (Condition == CondX86::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 == CondX86::Br_None) {
      x86::Label *L =
          Asm->GetOrCreateCfgNodeLabel(getTargetFalse()->getIndex());
      assert(!getTargetTrue());
      Asm->jmp(L, Near);
    } else {
      x86::Label *L = Asm->GetOrCreateCfgNodeLabel(getTargetTrue()->getIndex());
      Asm->j(Condition, L, Near);
      if (getTargetFalse()) {
        x86::Label *L2 =
            Asm->GetOrCreateCfgNodeLabel(getTargetFalse()->getIndex());
        Asm->jmp(L2, Near);
      }
    }
  }
}

void InstX8632Br::dump(const Cfg *Func) const {
  if (!ALLOW_DUMP)
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  Str << "br ";

  if (Condition == CondX86::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 InstX8632Call::emit(const Cfg *Func) const {
  if (!ALLOW_DUMP)
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(getSrcSize() == 1);
  Str << "\tcall\t";
  if (const auto CallTarget =
          llvm::dyn_cast<ConstantRelocatable>(getCallTarget())) {
    // TODO(stichnot): All constant targets should suppress the '$',
    // not just relocatables.
    CallTarget->emitWithoutDollar(Func->getContext());
  } else {
    Str << "*";
    getCallTarget()->emit(Func);
  }
  Func->getTarget()->resetStackAdjustment();
}

void InstX8632Call::emitIAS(const Cfg *Func) const {
  x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
  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)) {
    // 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. For this, we would use the 0xE8 opcode
    // (relative version of call) and there should be a PC32 reloc too.
    // The PC32 reloc will have symbol index 0, and the absolute address
    // would be encoded as an offset relative to the next instruction.
    // TODO(jvoung): Do we need to support this?
    (void)Imm;
    llvm_unreachable("Unexpected call to absolute address");
  } else {
    llvm_unreachable("Unexpected operand type");
  }
  Func->getTarget()->resetStackAdjustment();
}

void InstX8632Call::dump(const Cfg *Func) const {
  if (!ALLOW_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 emitTwoAddress(const char *Opcode, const Inst *Inst, const Cfg *Func,
                    bool ShiftHack) {
  if (!ALLOW_DUMP)
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(Inst->getSrcSize() == 2);
  Variable *Dest = Inst->getDest();
  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 x86::AssemblerX86::GPREmitterOneOp &Emitter) {
  x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
  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 {
      x86::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 x86::AssemblerX86::GPREmitterRegOp &Emitter) {
  x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
  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 {
      x86::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, x86::Immediate(Imm->getValue()));
  } else if (const auto Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) {
    AssemblerFixup *Fixup =
        x86::DisplacementRelocation::create(Asm, FK_Abs_4, Reloc);
    (Asm->*(Emitter.GPRImm))(Ty, VarReg, x86::Immediate(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 x86::Address &Addr,
                        const Operand *Src,
                        const x86::AssemblerX86::GPREmitterAddrOp &Emitter) {
  x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
  // 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, x86::Immediate(Imm->getValue()));
  } else if (const auto Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) {
    AssemblerFixup *Fixup =
        x86::DisplacementRelocation::create(Asm, FK_Abs_4, Reloc);
    (Asm->*(Emitter.AddrImm))(Ty, Addr, x86::Immediate(Fixup));
  } else {
    llvm_unreachable("Unexpected operand type");
  }
}

void emitIASAsAddrOpTyGPR(const Cfg *Func, Type Ty, const Operand *Op0,
                          const Operand *Op1,
                          const x86::AssemblerX86::GPREmitterAddrOp &Emitter) {
  if (const auto Op0Var = llvm::dyn_cast<Variable>(Op0)) {
    assert(!Op0Var->hasReg());
    x86::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)) {
    x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
    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 emitIASGPRShift(const Cfg *Func, Type Ty, const Variable *Var,
                     const Operand *Src,
                     const x86::AssemblerX86::GPREmitterShiftOp &Emitter) {
  x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
  // 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, x86::Immediate(Imm->getValue()));
  } else {
    llvm_unreachable("Unexpected operand type");
  }
}

void emitIASGPRShiftDouble(const Cfg *Func, const Variable *Dest,
                           const Operand *Src1Op, const Operand *Src2Op,
                           const x86::AssemblerX86::GPREmitterShiftD &Emitter) {
  x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
  // 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,
                                x86::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 x86::AssemblerX86::XmmEmitterShiftOp &Emitter) {
  x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
  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 {
      x86::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, x86::Immediate(Imm->getValue()));
  } else {
    llvm_unreachable("Unexpected operand type");
  }
}

void emitIASRegOpTyXMM(const Cfg *Func, Type Ty, const Variable *Var,
                       const Operand *Src,
                       const x86::AssemblerX86::XmmEmitterRegOp &Emitter) {
  x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
  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 {
      x86::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, x86::Address::ofConstPool(Func->getContext(), 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 x86::AssemblerX86::CastEmitterRegOp<DReg_t, SReg_t> Emitter) {
  x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
  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 {
      x86::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 x86::AssemblerX86::ThreeOpImmEmitter<DReg_t, SReg_t> Emitter) {
  x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
  // This only handles Dest being a register, and Src1 being an immediate.
  assert(Dest->hasReg());
  DReg_t DestReg = destEnc(Dest->getRegNum());
  x86::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 {
      x86::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 x86::AssemblerX86::XmmEmitterMovOps Emitter) {
  x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
  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 {
        x86::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 {
    x86::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()));
  }
}

bool checkForRedundantAssign(const Variable *Dest, const Operand *Source) {
  const auto SrcVar = llvm::dyn_cast<const Variable>(Source);
  if (!SrcVar)
    return false;
  if (Dest->hasReg() && Dest->getRegNum() == SrcVar->getRegNum()) {
    // TODO: On x86-64, instructions like "mov eax, eax" are used to
    // clear the upper 32 bits of rax.  We need to recognize and
    // preserve these.
    return true;
  }
  if (!Dest->hasReg() && !SrcVar->hasReg() &&
      Dest->getStackOffset() == SrcVar->getStackOffset())
    return true;
  return false;
}

// 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 *InstX8632Addps::Opcode = "addps";
template <> const char *InstX8632Adc::Opcode = "adc";
template <> const char *InstX8632Addss::Opcode = "addss";
template <> const char *InstX8632Padd::Opcode = "padd";
template <> const char *InstX8632Sub::Opcode = "sub";
template <> const char *InstX8632Subps::Opcode = "subps";
template <> const char *InstX8632Subss::Opcode = "subss";
template <> const char *InstX8632Sbb::Opcode = "sbb";
template <> const char *InstX8632Psub::Opcode = "psub";
template <> const char *InstX8632And::Opcode = "and";
template <> const char *InstX8632Pand::Opcode = "pand";
template <> const char *InstX8632Pandn::Opcode = "pandn";
template <> const char *InstX8632Or::Opcode = "or";
template <> const char *InstX8632Por::Opcode = "por";
template <> const char *InstX8632Xor::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 *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 x86::AssemblerX86::GPREmitterOneOp InstX8632Bswap::Emitter = {
    &x86::AssemblerX86::bswap, nullptr /* only a reg form exists */};
template <>
const x86::AssemblerX86::GPREmitterOneOp InstX8632Neg::Emitter = {
    &x86::AssemblerX86::neg, &x86::AssemblerX86::neg};

// Unary GPR ops
template <>
const x86::AssemblerX86::GPREmitterRegOp InstX8632Bsf::Emitter = {
    &x86::AssemblerX86::bsf, &x86::AssemblerX86::bsf, nullptr};
template <>
const x86::AssemblerX86::GPREmitterRegOp InstX8632Bsr::Emitter = {
    &x86::AssemblerX86::bsr, &x86::AssemblerX86::bsr, nullptr};
template <>
const x86::AssemblerX86::GPREmitterRegOp InstX8632Lea::Emitter = {
    /* reg/reg and reg/imm are illegal */ nullptr, &x86::AssemblerX86::lea,
    nullptr};
template <>
const x86::AssemblerX86::GPREmitterRegOp InstX8632Movsx::Emitter = {
    &x86::AssemblerX86::movsx, &x86::AssemblerX86::movsx, nullptr};
template <>
const x86::AssemblerX86::GPREmitterRegOp InstX8632Movzx::Emitter = {
    &x86::AssemblerX86::movzx, &x86::AssemblerX86::movzx, nullptr};

// Unary XMM ops
template <>
const x86::AssemblerX86::XmmEmitterRegOp InstX8632Sqrtss::Emitter = {
  &x86::AssemblerX86::sqrtss, &x86::AssemblerX86::sqrtss
};

// Binary GPR ops
template <>
const x86::AssemblerX86::GPREmitterRegOp InstX8632Add::Emitter = {
    &x86::AssemblerX86::add, &x86::AssemblerX86::add, &x86::AssemblerX86::add};
template <>
const x86::AssemblerX86::GPREmitterRegOp InstX8632Adc::Emitter = {
    &x86::AssemblerX86::adc, &x86::AssemblerX86::adc, &x86::AssemblerX86::adc};
template <>
const x86::AssemblerX86::GPREmitterRegOp InstX8632And::Emitter = {
    &x86::AssemblerX86::And, &x86::AssemblerX86::And, &x86::AssemblerX86::And};
template <>
const x86::AssemblerX86::GPREmitterRegOp InstX8632Or::Emitter = {
    &x86::AssemblerX86::Or, &x86::AssemblerX86::Or, &x86::AssemblerX86::Or};
template <>
const x86::AssemblerX86::GPREmitterRegOp InstX8632Sbb::Emitter = {
    &x86::AssemblerX86::sbb, &x86::AssemblerX86::sbb, &x86::AssemblerX86::sbb};
template <>
const x86::AssemblerX86::GPREmitterRegOp InstX8632Sub::Emitter = {
    &x86::AssemblerX86::sub, &x86::AssemblerX86::sub, &x86::AssemblerX86::sub};
template <>
const x86::AssemblerX86::GPREmitterRegOp InstX8632Xor::Emitter = {
    &x86::AssemblerX86::Xor, &x86::AssemblerX86::Xor, &x86::AssemblerX86::Xor};

// Binary Shift GPR ops
template <>
const x86::AssemblerX86::GPREmitterShiftOp InstX8632Rol::Emitter = {
    &x86::AssemblerX86::rol, &x86::AssemblerX86::rol};
template <>
const x86::AssemblerX86::GPREmitterShiftOp InstX8632Sar::Emitter = {
    &x86::AssemblerX86::sar, &x86::AssemblerX86::sar};
template <>
const x86::AssemblerX86::GPREmitterShiftOp InstX8632Shl::Emitter = {
    &x86::AssemblerX86::shl, &x86::AssemblerX86::shl};
template <>
const x86::AssemblerX86::GPREmitterShiftOp InstX8632Shr::Emitter = {
    &x86::AssemblerX86::shr, &x86::AssemblerX86::shr};

// Binary XMM ops
template <>
const x86::AssemblerX86::XmmEmitterRegOp InstX8632Addss::Emitter = {
  &x86::AssemblerX86::addss, &x86::AssemblerX86::addss
};
template <>
const x86::AssemblerX86::XmmEmitterRegOp InstX8632Addps::Emitter = {
  &x86::AssemblerX86::addps, &x86::AssemblerX86::addps
};
template <>
const x86::AssemblerX86::XmmEmitterRegOp InstX8632Divss::Emitter = {
  &x86::AssemblerX86::divss, &x86::AssemblerX86::divss
};
template <>
const x86::AssemblerX86::XmmEmitterRegOp InstX8632Divps::Emitter = {
  &x86::AssemblerX86::divps, &x86::AssemblerX86::divps
};
template <>
const x86::AssemblerX86::XmmEmitterRegOp InstX8632Mulss::Emitter = {
  &x86::AssemblerX86::mulss, &x86::AssemblerX86::mulss
};
template <>
const x86::AssemblerX86::XmmEmitterRegOp InstX8632Mulps::Emitter = {
  &x86::AssemblerX86::mulps, &x86::AssemblerX86::mulps
};
template <>
const x86::AssemblerX86::XmmEmitterRegOp InstX8632Padd::Emitter = {
  &x86::AssemblerX86::padd, &x86::AssemblerX86::padd
};
template <>
const x86::AssemblerX86::XmmEmitterRegOp InstX8632Pand::Emitter = {
  &x86::AssemblerX86::pand, &x86::AssemblerX86::pand
};
template <>
const x86::AssemblerX86::XmmEmitterRegOp InstX8632Pandn::Emitter = {
  &x86::AssemblerX86::pandn, &x86::AssemblerX86::pandn
};
template <>
const x86::AssemblerX86::XmmEmitterRegOp InstX8632Pcmpeq::Emitter = {
  &x86::AssemblerX86::pcmpeq, &x86::AssemblerX86::pcmpeq
};
template <>
const x86::AssemblerX86::XmmEmitterRegOp InstX8632Pcmpgt::Emitter = {
  &x86::AssemblerX86::pcmpgt, &x86::AssemblerX86::pcmpgt
};
template <>
const x86::AssemblerX86::XmmEmitterRegOp InstX8632Pmull::Emitter = {
  &x86::AssemblerX86::pmull, &x86::AssemblerX86::pmull
};
template <>
const x86::AssemblerX86::XmmEmitterRegOp InstX8632Pmuludq::Emitter = {
  &x86::AssemblerX86::pmuludq, &x86::AssemblerX86::pmuludq
};
template <>
const x86::AssemblerX86::XmmEmitterRegOp InstX8632Por::Emitter = {
  &x86::AssemblerX86::por, &x86::AssemblerX86::por
};
template <>
const x86::AssemblerX86::XmmEmitterRegOp InstX8632Psub::Emitter = {
  &x86::AssemblerX86::psub, &x86::AssemblerX86::psub
};
template <>
const x86::AssemblerX86::XmmEmitterRegOp InstX8632Pxor::Emitter = {
  &x86::AssemblerX86::pxor, &x86::AssemblerX86::pxor
};
template <>
const x86::AssemblerX86::XmmEmitterRegOp InstX8632Subss::Emitter = {
  &x86::AssemblerX86::subss, &x86::AssemblerX86::subss
};
template <>
const x86::AssemblerX86::XmmEmitterRegOp InstX8632Subps::Emitter = {
  &x86::AssemblerX86::subps, &x86::AssemblerX86::subps
};

// Binary XMM Shift ops
template <>
const x86::AssemblerX86::XmmEmitterShiftOp InstX8632Psll::Emitter = {
    &x86::AssemblerX86::psll, &x86::AssemblerX86::psll,
    &x86::AssemblerX86::psll};
template <>
const x86::AssemblerX86::XmmEmitterShiftOp InstX8632Psra::Emitter = {
    &x86::AssemblerX86::psra, &x86::AssemblerX86::psra,
    &x86::AssemblerX86::psra};

template <> void InstX8632Sqrtss::emit(const Cfg *Func) const {
  if (!ALLOW_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 (!ALLOW_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 (!ALLOW_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 (!ALLOW_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() >=
          TargetX8632::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() >=
          TargetX8632::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 (!ALLOW_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 (!ALLOW_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 (!ALLOW_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 (!ALLOW_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 (!ALLOW_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 (!ALLOW_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 x86::AssemblerX86::GPREmitterOneOp Emitter = {
      &x86::AssemblerX86::div, &x86::AssemblerX86::div};
  emitIASOpTyGPR(Func, Ty, Src, Emitter);
}

template <> void InstX8632Idiv::emit(const Cfg *Func) const {
  if (!ALLOW_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 x86::AssemblerX86::GPREmitterOneOp Emitter = {
      &x86::AssemblerX86::idiv, &x86::AssemblerX86::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 (!ALLOW_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 x86::AssemblerX86::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 (!ALLOW_DUMP)
    return;
  assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >=
         TargetX8632::SSE4_1);
  emitVariableBlendInst(Opcode, this, Func);
}

template <> void InstX8632Blendvps::emitIAS(const Cfg *Func) const {
  assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >=
         TargetX8632::SSE4_1);
  static const x86::AssemblerX86::XmmEmitterRegOp Emitter = {
      &x86::AssemblerX86::blendvps, &x86::AssemblerX86::blendvps};
  emitIASVariableBlendInst(this, Func, Emitter);
}

template <> void InstX8632Pblendvb::emit(const Cfg *Func) const {
  if (!ALLOW_DUMP)
    return;
  assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >=
         TargetX8632::SSE4_1);
  emitVariableBlendInst(Opcode, this, Func);
}

template <> void InstX8632Pblendvb::emitIAS(const Cfg *Func) const {
  assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >=
         TargetX8632::SSE4_1);
  static const x86::AssemblerX86::XmmEmitterRegOp Emitter = {
      &x86::AssemblerX86::pblendvb, &x86::AssemblerX86::pblendvb};
  emitIASVariableBlendInst(this, Func, Emitter);
}

template <> void InstX8632Imul::emit(const Cfg *Func) const {
  if (!ALLOW_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 x86::AssemblerX86::GPREmitterOneOp Emitter = {
        &x86::AssemblerX86::imul, &x86::AssemblerX86::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 x86::AssemblerX86::GPREmitterRegOp Emitter = {
        &x86::AssemblerX86::imul, &x86::AssemblerX86::imul,
        &x86::AssemblerX86::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() >=
         TargetX8632::SSE4_1);
  const Variable *Dest = getDest();
  assert(Dest == getSrc(0));
  Type Ty = Dest->getType();
  static const x86::AssemblerX86::ThreeOpImmEmitter<
      RegX8632::XmmRegister, RegX8632::XmmRegister> Emitter = {
      &x86::AssemblerX86::insertps, &x86::AssemblerX86::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 (!ALLOW_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 {
  x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
  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 (!ALLOW_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 x86::AssemblerX86::GPREmitterOneOp Emitter = {
      &x86::AssemblerX86::mul, &x86::AssemblerX86::mul};
  emitIASOpTyGPR(Func, Ty, Src, Emitter);
}

void InstX8632Mul::dump(const Cfg *Func) const {
  if (!ALLOW_DUMP)
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  dumpDest(Func);
  Str << " = mul." << getDest()->getType() << " ";
  dumpSources(Func);
}

void InstX8632Shld::emit(const Cfg *Func) const {
  if (!ALLOW_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 x86::AssemblerX86::GPREmitterShiftD Emitter = {
      &x86::AssemblerX86::shld, &x86::AssemblerX86::shld};
  emitIASGPRShiftDouble(Func, Dest, Src1, Src2, Emitter);
}

void InstX8632Shld::dump(const Cfg *Func) const {
  if (!ALLOW_DUMP)
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  dumpDest(Func);
  Str << " = shld." << getDest()->getType() << " ";
  dumpSources(Func);
}

void InstX8632Shrd::emit(const Cfg *Func) const {
  if (!ALLOW_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 x86::AssemblerX86::GPREmitterShiftD Emitter = {
      &x86::AssemblerX86::shrd, &x86::AssemblerX86::shrd};
  emitIASGPRShiftDouble(Func, Dest, Src1, Src2, Emitter);
}

void InstX8632Shrd::dump(const Cfg *Func) const {
  if (!ALLOW_DUMP)
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  dumpDest(Func);
  Str << " = shrd." << getDest()->getType() << " ";
  dumpSources(Func);
}

void InstX8632Cmov::emit(const Cfg *Func) const {
  if (!ALLOW_DUMP)
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  Variable *Dest = getDest();
  Str << "\t";
  assert(Condition != CondX86::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 != CondX86::Br_None);
  assert(getDest()->hasReg());
  assert(getSrcSize() == 2);
  // Only need the reg/reg form now.
  const auto SrcVar = llvm::cast<Variable>(getSrc(1));
  assert(SrcVar->hasReg());
  assert(SrcVar->getType() == IceType_i32);
  x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
  Asm->cmov(Condition, RegX8632::getEncodedGPR(getDest()->getRegNum()),
            RegX8632::getEncodedGPR(SrcVar->getRegNum()));
}

void InstX8632Cmov::dump(const Cfg *Func) const {
  if (!ALLOW_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 (!ALLOW_DUMP)
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(getSrcSize() == 2);
  assert(Condition < CondX86::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 {
  x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
  assert(getSrcSize() == 2);
  assert(Condition < CondX86::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 {
    x86::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 (!ALLOW_DUMP)
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  assert(Condition < CondX86::Cmpps_Invalid);
  dumpDest(Func);
  Str << " = cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps"
      << "\t";
  dumpSources(Func);
}

void InstX8632Cmpxchg::emit(const Cfg *Func) const {
  if (!ALLOW_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);
  x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
  Type Ty = getSrc(0)->getType();
  const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0));
  assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
  const x86::Address Addr = Mem->toAsmAddress(Asm);
  const auto VarReg = llvm::cast<Variable>(getSrc(2));
  assert(VarReg->hasReg());
  const RegX8632::GPRRegister Reg =
      RegX8632::getEncodedGPR(VarReg->getRegNum());
  if (Locked) {
    Asm->LockCmpxchg(Ty, Addr, Reg);
  } else {
    Asm->cmpxchg(Ty, Addr, Reg);
  }
}

void InstX8632Cmpxchg::dump(const Cfg *Func) const {
  if (!ALLOW_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 (!ALLOW_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);
  x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
  const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0));
  assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
  const x86::Address Addr = Mem->toAsmAddress(Asm);
  if (Locked) {
    Asm->lock();
  }
  Asm->cmpxchg8b(Addr);
}

void InstX8632Cmpxchg8b::dump(const Cfg *Func) const {
  if (!ALLOW_DUMP)
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  if (Locked) {
    Str << "lock ";
  }
  Str << "cmpxchg8b ";
  dumpSources(Func);
}

void InstX8632Cvt::emit(const Cfg *Func) const {
  if (!ALLOW_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 x86::AssemblerX86::CastEmitterRegOp<
        RegX8632::XmmRegister, RegX8632::GPRRegister> Emitter = {
        &x86::AssemblerX86::cvtsi2ss, &x86::AssemblerX86::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 x86::AssemblerX86::CastEmitterRegOp<
        RegX8632::GPRRegister, RegX8632::XmmRegister> Emitter = {
        &x86::AssemblerX86::cvttss2si, &x86::AssemblerX86::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 x86::AssemblerX86::XmmEmitterRegOp Emitter = {
        &x86::AssemblerX86::cvtfloat2float, &x86::AssemblerX86::cvtfloat2float};
    emitIASRegOpTyXMM(Func, SrcTy, Dest, Src, Emitter);
    return;
  }
  case Dq2ps: {
    assert(isVectorIntegerType(SrcTy));
    assert(isVectorFloatingType(DestTy));
    static const x86::AssemblerX86::XmmEmitterRegOp Emitter = {
        &x86::AssemblerX86::cvtdq2ps, &x86::AssemblerX86::cvtdq2ps};
    emitIASRegOpTyXMM(Func, DestTy, Dest, Src, Emitter);
    return;
  }
  case Tps2dq: {
    assert(isVectorFloatingType(SrcTy));
    assert(isVectorIntegerType(DestTy));
    static const x86::AssemblerX86::XmmEmitterRegOp Emitter = {
        &x86::AssemblerX86::cvttps2dq, &x86::AssemblerX86::cvttps2dq};
    emitIASRegOpTyXMM(Func, DestTy, Dest, Src, Emitter);
    return;
  }
  }
}

void InstX8632Cvt::dump(const Cfg *Func) const {
  if (!ALLOW_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 (!ALLOW_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 x86::AssemblerX86::GPREmitterRegOp RegEmitter = {
    &x86::AssemblerX86::cmp, &x86::AssemblerX86::cmp, &x86::AssemblerX86::cmp
  };
  static const x86::AssemblerX86::GPREmitterAddrOp AddrEmitter = {
    &x86::AssemblerX86::cmp, &x86::AssemblerX86::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 (!ALLOW_DUMP)
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  Str << "cmp." << getSrc(0)->getType() << " ";
  dumpSources(Func);
}

void InstX8632Ucomiss::emit(const Cfg *Func) const {
  if (!ALLOW_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 x86::AssemblerX86::XmmEmitterRegOp Emitter = {
    &x86::AssemblerX86::ucomiss, &x86::AssemblerX86::ucomiss
  };
  emitIASRegOpTyXMM(Func, Ty, Src0Var, getSrc(1), Emitter);
}

void InstX8632Ucomiss::dump(const Cfg *Func) const {
  if (!ALLOW_DUMP)
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  Str << "ucomiss." << getSrc(0)->getType() << " ";
  dumpSources(Func);
}

void InstX8632UD2::emit(const Cfg *Func) const {
  if (!ALLOW_DUMP)
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(getSrcSize() == 0);
  Str << "\tud2";
}

void InstX8632UD2::emitIAS(const Cfg *Func) const {
  x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
  Asm->ud2();
}

void InstX8632UD2::dump(const Cfg *Func) const {
  if (!ALLOW_DUMP)
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  Str << "ud2\n";
}

void InstX8632Test::emit(const Cfg *Func) const {
  if (!ALLOW_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 x86::AssemblerX86::GPREmitterRegOp RegEmitter = {
      &x86::AssemblerX86::test, nullptr, &x86::AssemblerX86::test};
  static const x86::AssemblerX86::GPREmitterAddrOp AddrEmitter = {
    &x86::AssemblerX86::test, &x86::AssemblerX86::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 (!ALLOW_DUMP)
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  Str << "test." << getSrc(0)->getType() << " ";
  dumpSources(Func);
}

void InstX8632Mfence::emit(const Cfg *Func) const {
  if (!ALLOW_DUMP)
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(getSrcSize() == 0);
  Str << "\tmfence";
}

void InstX8632Mfence::emitIAS(const Cfg *Func) const {
  x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
  Asm->mfence();
}

void InstX8632Mfence::dump(const Cfg *Func) const {
  if (!ALLOW_DUMP)
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  Str << "mfence\n";
}

void InstX8632Store::emit(const Cfg *Func) const {
  if (!ALLOW_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());
    x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
    if (const auto DestVar = llvm::dyn_cast<Variable>(Dest)) {
      assert(!DestVar->hasReg());
      x86::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 x86::AssemblerX86::GPREmitterAddrOp GPRAddrEmitter = {
        &x86::AssemblerX86::mov, &x86::AssemblerX86::mov};
    emitIASAsAddrOpTyGPR(Func, DestTy, Dest, Src, GPRAddrEmitter);
  }
}

void InstX8632Store::dump(const Cfg *Func) const {
  if (!ALLOW_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 (!ALLOW_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 {
  x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
  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 (!ALLOW_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 (!ALLOW_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 {
  x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
  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 (!ALLOW_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 (!ALLOW_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 (!ALLOW_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 x86::AssemblerX86::XmmEmitterRegOp XmmRegEmitter = {
      &x86::AssemblerX86::movss, &x86::AssemblerX86::movss};
  static const x86::AssemblerX86::GPREmitterRegOp GPRRegEmitter = {
      &x86::AssemblerX86::mov, &x86::AssemblerX86::mov,
      &x86::AssemblerX86::mov};
  static const x86::AssemblerX86::GPREmitterAddrOp GPRAddrEmitter = {
      &x86::AssemblerX86::mov, &x86::AssemblerX86::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.
    x86::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());
      x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
      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 {
  x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
  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 {
      x86::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 {
      x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget())
                                 ->stackVarToAsmOperand(Dest));
      Asm->movd(StackAddr, SrcReg);
    }
  }
}

template <> void InstX8632Movp::emit(const Cfg *Func) const {
  if (!ALLOW_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 x86::AssemblerX86::XmmEmitterMovOps Emitter = {
    &x86::AssemblerX86::movups, &x86::AssemblerX86::movups,
    &x86::AssemblerX86::movups
  };
  emitIASMovlikeXMM(Func, Dest, Src, Emitter);
}

template <> void InstX8632Movq::emit(const Cfg *Func) const {
  if (!ALLOW_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 x86::AssemblerX86::XmmEmitterMovOps Emitter = {
    &x86::AssemblerX86::movq, &x86::AssemblerX86::movq, &x86::AssemblerX86::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());
  x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
  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 (!ALLOW_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 {
  x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
  // TODO: Emit the right code for the variant.
  Asm->nop();
}

void InstX8632Nop::dump(const Cfg *Func) const {
  if (!ALLOW_DUMP)
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  Str << "nop (variant = " << Variant << ")";
}

void InstX8632Fld::emit(const Cfg *Func) const {
  if (!ALLOW_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 {
  x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
  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.
      x86::Immediate Width(typeWidthInBytes(Ty));
      Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, Width);
      x86::Address StackSlot = x86::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 {
      x86::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, x86::Address::ofConstPool(Func->getContext(), Asm, Imm));
  } else {
    llvm_unreachable("Unexpected operand type");
  }
}

void InstX8632Fld::dump(const Cfg *Func) const {
  if (!ALLOW_DUMP)
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  Str << "fld." << getSrc(0)->getType() << " ";
  dumpSources(Func);
}

void InstX8632Fstp::emit(const Cfg *Func) const {
  if (!ALLOW_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 {
  x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
  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()) {
    x86::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.
    x86::Immediate Width(typeWidthInBytes(Ty));
    Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, Width);
    x86::Address StackSlot = x86::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 (!ALLOW_DUMP)
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  dumpDest(Func);
  Str << " = fstp." << getDest()->getType() << ", st(0)";
  Str << "\n";
}

template <> void InstX8632Pcmpeq::emit(const Cfg *Func) const {
  if (!ALLOW_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 (!ALLOW_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 (!ALLOW_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()
             >= TargetX8632::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() >=
             TargetX8632::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 x86::AssemblerX86::ThreeOpImmEmitter<
      RegX8632::GPRRegister, RegX8632::XmmRegister> Emitter = {
      &x86::AssemblerX86::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 (!ALLOW_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()
             >= TargetX8632::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() >=
             TargetX8632::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 x86::AssemblerX86::ThreeOpImmEmitter<
      RegX8632::XmmRegister, RegX8632::GPRRegister> Emitter = {
      &x86::AssemblerX86::pinsr, &x86::AssemblerX86::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 x86::AssemblerX86::ThreeOpImmEmitter<
      RegX8632::XmmRegister, RegX8632::XmmRegister> Emitter = {
      &x86::AssemblerX86::pshufd, &x86::AssemblerX86::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 x86::AssemblerX86::ThreeOpImmEmitter<
      RegX8632::XmmRegister, RegX8632::XmmRegister> Emitter = {
      &x86::AssemblerX86::shufps, &x86::AssemblerX86::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 (!ALLOW_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);
  x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
  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 (!ALLOW_DUMP)
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  dumpDest(Func);
  Str << " = pop." << getDest()->getType() << " ";
}

void InstX8632AdjustStack::emit(const Cfg *Func) const {
  if (!ALLOW_DUMP)
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  Str << "\tsubl\t$" << Amount << ", %esp";
  Func->getTarget()->updateStackAdjustment(Amount);
}

void InstX8632AdjustStack::emitIAS(const Cfg *Func) const {
  x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
  Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, x86::Immediate(Amount));
  Func->getTarget()->updateStackAdjustment(Amount);
}

void InstX8632AdjustStack::dump(const Cfg *Func) const {
  if (!ALLOW_DUMP)
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  Str << "esp = sub.i32 esp, " << Amount;
}

void InstX8632Push::emit(const Cfg *Func) const {
  if (!ALLOW_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());
  x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
  Asm->pushl(RegX8632::getEncodedGPR(Var->getRegNum()));
}

void InstX8632Push::dump(const Cfg *Func) const {
  if (!ALLOW_DUMP)
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  Str << "push." << getSrc(0)->getType() << " ";
  dumpSources(Func);
}

template <> void InstX8632Psll::emit(const Cfg *Func) const {
  if (!ALLOW_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 (!ALLOW_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);
}

void InstX8632Ret::emit(const Cfg *Func) const {
  if (!ALLOW_DUMP)
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  Str << "\tret";
}

void InstX8632Ret::emitIAS(const Cfg *Func) const {
  x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
  Asm->ret();
}

void InstX8632Ret::dump(const Cfg *Func) const {
  if (!ALLOW_DUMP)
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  Type Ty = (getSrcSize() == 0 ? IceType_void : getSrc(0)->getType());
  Str << "ret." << Ty << " ";
  dumpSources(Func);
}

void InstX8632Xadd::emit(const Cfg *Func) const {
  if (!ALLOW_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);
  x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
  Type Ty = getSrc(0)->getType();
  const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0));
  assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
  const x86::Address Addr = Mem->toAsmAddress(Asm);
  const auto VarReg = llvm::cast<Variable>(getSrc(1));
  assert(VarReg->hasReg());
  const RegX8632::GPRRegister Reg =
      RegX8632::getEncodedGPR(VarReg->getRegNum());
  if (Locked) {
    Asm->lock();
  }
  Asm->xadd(Ty, Addr, Reg);
}

void InstX8632Xadd::dump(const Cfg *Func) const {
  if (!ALLOW_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 (!ALLOW_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);
  x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
  Type Ty = getSrc(0)->getType();
  const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0));
  assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
  const x86::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 (!ALLOW_DUMP)
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  Type Ty = getSrc(0)->getType();
  Str << "xchg." << Ty << " ";
  dumpSources(Func);
}

void OperandX8632Mem::emit(const Cfg *Func) const {
  if (!ALLOW_DUMP)
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  if (SegmentReg != DefaultSegment) {
    assert(SegmentReg >= 0 && SegmentReg < SegReg_NUM);
    Str << InstX8632SegmentRegNames[SegmentReg] << ":";
  }
  // Emit as Offset(Base,Index,1<<Shift).
  // Offset is emitted without the leading '$'.
  // Omit the (Base,Index,1<<Shift) part if Base==nullptr.
  if (!Offset) {
    // No offset, emit nothing.
  } else if (const auto CI = llvm::dyn_cast<ConstantInteger32>(Offset)) {
    if (CI->getValue())
      // Emit a non-zero offset without a leading '$'.
      Str << CI->getValue();
  } else if (const auto CR = llvm::dyn_cast<ConstantRelocatable>(Offset)) {
    CR->emitWithoutDollar(Func->getContext());
  } else {
    llvm_unreachable("Invalid offset type for x86 mem operand");
  }

  if (Base) {
    Str << "(";
    Base->emit(Func);
    if (Index) {
      Str << ",";
      Index->emit(Func);
      if (Shift)
        Str << "," << (1u << Shift);
    }
    Str << ")";
  }
}

void OperandX8632Mem::dump(const Cfg *Func, Ostream &Str) const {
  if (!ALLOW_DUMP)
    return;
  if (SegmentReg != DefaultSegment) {
    assert(SegmentReg >= 0 && SegmentReg < SegReg_NUM);
    Str << InstX8632SegmentRegNames[SegmentReg] << ":";
  }
  bool Dumped = false;
  Str << "[";
  if (Base) {
    if (Func)
      Base->dump(Func);
    else
      Base->dump(Str);
    Dumped = true;
  }
  if (Index) {
    assert(Base);
    Str << "+";
    if (Shift > 0)
      Str << (1u << Shift) << "*";
    if (Func)
      Index->dump(Func);
    else
      Index->dump(Str);
    Dumped = true;
  }
  // Pretty-print the Offset.
  bool OffsetIsZero = false;
  bool OffsetIsNegative = false;
  if (!Offset) {
    OffsetIsZero = true;
  } else if (const auto CI = llvm::dyn_cast<ConstantInteger32>(Offset)) {
    OffsetIsZero = (CI->getValue() == 0);
    OffsetIsNegative = (static_cast<int32_t>(CI->getValue()) < 0);
  } else {
    assert(llvm::isa<ConstantRelocatable>(Offset));
  }
  if (Dumped) {
    if (!OffsetIsZero) {     // Suppress if Offset is known to be 0
      if (!OffsetIsNegative) // Suppress if Offset is known to be negative
        Str << "+";
      Offset->dump(Func, Str);
    }
  } else {
    // There is only the offset.
    Offset->dump(Func, Str);
  }
  Str << "]";
}

void OperandX8632Mem::emitSegmentOverride(x86::AssemblerX86 *Asm) const {
  if (SegmentReg != DefaultSegment) {
    assert(SegmentReg >= 0 && SegmentReg < SegReg_NUM);
    Asm->EmitSegmentOverride(InstX8632SegmentPrefixes[SegmentReg]);
  }
}

x86::Address OperandX8632Mem::toAsmAddress(Assembler *Asm) const {
  int32_t Disp = 0;
  AssemblerFixup *Fixup = nullptr;
  // Determine the offset (is it relocatable?)
  if (getOffset()) {
    if (const auto CI = llvm::dyn_cast<ConstantInteger32>(getOffset())) {
      Disp = static_cast<int32_t>(CI->getValue());
    } else if (const auto CR =
                   llvm::dyn_cast<ConstantRelocatable>(getOffset())) {
      Fixup = x86::DisplacementRelocation::create(Asm, FK_Abs_4, CR);
    } else {
      llvm_unreachable("Unexpected offset type");
    }
  }

  // Now convert to the various possible forms.
  if (getBase() && getIndex()) {
    return x86::Address(RegX8632::getEncodedGPR(getBase()->getRegNum()),
                        RegX8632::getEncodedGPR(getIndex()->getRegNum()),
                        x86::ScaleFactor(getShift()), Disp);
  } else if (getBase()) {
    return x86::Address(RegX8632::getEncodedGPR(getBase()->getRegNum()), Disp);
  } else if (getIndex()) {
    return x86::Address(RegX8632::getEncodedGPR(getIndex()->getRegNum()),
                        x86::ScaleFactor(getShift()), Disp);
  } else if (Fixup) {
    // The fixup itself has an offset, so Disp should still be 0.
    assert(Disp == 0);
    return x86::Address::Absolute(Fixup);
  } else {
    return x86::Address::Absolute(Disp);
  }
}

x86::Address VariableSplit::toAsmAddress(const Cfg *Func) const {
  assert(!Var->hasReg());
  const TargetLowering *Target = Func->getTarget();
  int32_t Offset =
      Var->getStackOffset() + Target->getStackAdjustment() + getOffset();
  return x86::Address(RegX8632::getEncodedGPR(Target->getFrameOrStackReg()),
                      Offset);
}

void VariableSplit::emit(const Cfg *Func) const {
  if (!ALLOW_DUMP)
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(!Var->hasReg());
  // The following is copied/adapted from TargetX8632::emitVariable().
  const TargetLowering *Target = Func->getTarget();
  const Type Ty = IceType_i32;
  int32_t Offset =
      Var->getStackOffset() + Target->getStackAdjustment() + getOffset();
  if (Offset)
    Str << Offset;
  Str << "(%" << Target->getRegName(Target->getFrameOrStackReg(), Ty) << ")";
}

void VariableSplit::dump(const Cfg *Func, Ostream &Str) const {
  if (!ALLOW_DUMP)
    return;
  switch (Part) {
  case Low:
    Str << "low";
    break;
  case High:
    Str << "high";
    break;
  default:
    Str << "???";
    break;
  }
  Str << "(";
  if (Func)
    Var->dump(Func);
  else
    Var->dump(Str);
  Str << ")";
}

} // end of namespace Ice
