//===- subzero/src/IceInstX86BaseImpl.h - Generic X86 instructions -*- C++ -*=//
//
//                        The Subzero Code Generator
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file implements the InstX86Base class and its descendants.
///
//===----------------------------------------------------------------------===//

#ifndef SUBZERO_SRC_ICEINSTX86BASEIMPL_H
#define SUBZERO_SRC_ICEINSTX86BASEIMPL_H

#include "IceInstX86Base.h"

#include "IceAssemblerX86Base.h"
#include "IceCfg.h"
#include "IceCfgNode.h"
#include "IceDefs.h"
#include "IceInst.h"
#include "IceOperand.h"
#include "IceTargetLowering.h"

namespace Ice {

namespace X86Internal {

template <class Machine>
const char *InstX86Base<Machine>::getWidthString(Type Ty) {
  return Traits::TypeAttributes[Ty].WidthString;
}

template <class Machine>
const char *InstX86Base<Machine>::getFldString(Type Ty) {
  return Traits::TypeAttributes[Ty].FldString;
}

template <class Machine>
typename InstX86Base<Machine>::Traits::Cond::BrCond
InstX86Base<Machine>::getOppositeCondition(typename Traits::Cond::BrCond Cond) {
  return Traits::InstBrAttributes[Cond].Opposite;
}

template <class Machine>
InstX86FakeRMW<Machine>::InstX86FakeRMW(Cfg *Func, Operand *Data, Operand *Addr,
                                        InstArithmetic::OpKind Op,
                                        Variable *Beacon)
    : InstX86Base<Machine>(Func, InstX86Base<Machine>::FakeRMW, 3, nullptr),
      Op(Op) {
  this->addSource(Data);
  this->addSource(Addr);
  this->addSource(Beacon);
}

template <class Machine>
InstX86Mul<Machine>::InstX86Mul(Cfg *Func, Variable *Dest, Variable *Source1,
                                Operand *Source2)
    : InstX86Base<Machine>(Func, InstX86Base<Machine>::Mul, 2, Dest) {
  this->addSource(Source1);
  this->addSource(Source2);
}

template <class Machine>
InstX86Shld<Machine>::InstX86Shld(Cfg *Func, Variable *Dest, Variable *Source1,
                                  Operand *Source2)
    : InstX86Base<Machine>(Func, InstX86Base<Machine>::Shld, 3, Dest) {
  this->addSource(Dest);
  this->addSource(Source1);
  this->addSource(Source2);
}

template <class Machine>
InstX86Shrd<Machine>::InstX86Shrd(Cfg *Func, Variable *Dest, Variable *Source1,
                                  Operand *Source2)
    : InstX86Base<Machine>(Func, InstX86Base<Machine>::Shrd, 3, Dest) {
  this->addSource(Dest);
  this->addSource(Source1);
  this->addSource(Source2);
}

template <class Machine>
InstX86Label<Machine>::InstX86Label(
    Cfg *Func, typename InstX86Base<Machine>::Traits::TargetLowering *Target)
    : InstX86Base<Machine>(Func, InstX86Base<Machine>::Label, 0, nullptr),
      Number(Target->makeNextLabelNumber()) {}

template <class Machine>
IceString InstX86Label<Machine>::getName(const Cfg *Func) const {
  return ".L" + Func->getFunctionName() + "$local$__" + std::to_string(Number);
}

template <class Machine>
InstX86Br<Machine>::InstX86Br(
    Cfg *Func, const CfgNode *TargetTrue, const CfgNode *TargetFalse,
    const InstX86Label<Machine> *Label,
    typename InstX86Base<Machine>::Traits::Cond::BrCond Condition, Mode Kind)
    : InstX86Base<Machine>(Func, InstX86Base<Machine>::Br, 0, nullptr),
      Condition(Condition), TargetTrue(TargetTrue), TargetFalse(TargetFalse),
      Label(Label), Kind(Kind) {}

template <class Machine>
bool InstX86Br<Machine>::optimizeBranch(const CfgNode *NextNode) {
  // If there is no next block, then there can be no fallthrough to optimize.
  if (NextNode == nullptr)
    return false;
  // Intra-block conditional branches can't be optimized.
  if (Label)
    return false;
  // If there is no fallthrough node, such as a non-default case label for a
  // switch instruction, then there is no opportunity to optimize.
  if (getTargetFalse() == nullptr)
    return false;

  // Unconditional branch to the next node can be removed.
  if (Condition == InstX86Base<Machine>::Traits::Cond::Br_None &&
      getTargetFalse() == NextNode) {
    assert(getTargetTrue() == nullptr);
    this->setDeleted();
    return true;
  }
  // If the fallthrough is to the next node, set fallthrough to nullptr to
  // indicate.
  if (getTargetFalse() == NextNode) {
    TargetFalse = nullptr;
    return true;
  }
  // If TargetTrue is the next node, and TargetFalse is not nullptr (which was
  // already tested above), then invert the branch condition, swap the targets,
  // and set new fallthrough to nullptr.
  if (getTargetTrue() == NextNode) {
    assert(Condition != InstX86Base<Machine>::Traits::Cond::Br_None);
    Condition = this->getOppositeCondition(Condition);
    TargetTrue = getTargetFalse();
    TargetFalse = nullptr;
    return true;
  }
  return false;
}

template <class Machine>
bool InstX86Br<Machine>::repointEdges(CfgNode *OldNode, CfgNode *NewNode) {
  bool Found = false;
  if (TargetFalse == OldNode) {
    TargetFalse = NewNode;
    Found = true;
  }
  if (TargetTrue == OldNode) {
    TargetTrue = NewNode;
    Found = true;
  }
  return Found;
}

template <class Machine>
InstX86Jmp<Machine>::InstX86Jmp(Cfg *Func, Operand *Target)
    : InstX86Base<Machine>(Func, InstX86Base<Machine>::Jmp, 1, nullptr) {
  this->addSource(Target);
}

template <class Machine>
InstX86Call<Machine>::InstX86Call(Cfg *Func, Variable *Dest,
                                  Operand *CallTarget)
    : InstX86Base<Machine>(Func, InstX86Base<Machine>::Call, 1, Dest) {
  this->HasSideEffects = true;
  this->addSource(CallTarget);
}

template <class Machine>
InstX86Cmov<Machine>::InstX86Cmov(
    Cfg *Func, Variable *Dest, Operand *Source,
    typename InstX86Base<Machine>::Traits::Cond::BrCond Condition)
    : InstX86Base<Machine>(Func, InstX86Base<Machine>::Cmov, 2, Dest),
      Condition(Condition) {
  // The final result is either the original Dest, or Source, so mark both as
  // sources.
  this->addSource(Dest);
  this->addSource(Source);
}

template <class Machine>
InstX86Cmpps<Machine>::InstX86Cmpps(
    Cfg *Func, Variable *Dest, Operand *Source,
    typename InstX86Base<Machine>::Traits::Cond::CmppsCond Condition)
    : InstX86Base<Machine>(Func, InstX86Base<Machine>::Cmpps, 2, Dest),
      Condition(Condition) {
  this->addSource(Dest);
  this->addSource(Source);
}

template <class Machine>
InstX86Cmpxchg<Machine>::InstX86Cmpxchg(Cfg *Func, Operand *DestOrAddr,
                                        Variable *Eax, Variable *Desired,
                                        bool Locked)
    : InstX86BaseLockable<Machine>(Func, InstX86Base<Machine>::Cmpxchg, 3,
                                   llvm::dyn_cast<Variable>(DestOrAddr),
                                   Locked) {
  assert(InstX86Base<Machine>::Traits::getBaseReg(Eax->getRegNum()) ==
         InstX86Base<Machine>::Traits::RegisterSet::Reg_eax);
  this->addSource(DestOrAddr);
  this->addSource(Eax);
  this->addSource(Desired);
}

template <class Machine>
InstX86Cmpxchg8b<Machine>::InstX86Cmpxchg8b(
    Cfg *Func, typename InstX86Base<Machine>::Traits::X86OperandMem *Addr,
    Variable *Edx, Variable *Eax, Variable *Ecx, Variable *Ebx, bool Locked)
    : InstX86BaseLockable<Machine>(Func, InstX86Base<Machine>::Cmpxchg, 5,
                                   nullptr, Locked) {
  assert(Edx->getRegNum() ==
         InstX86Base<Machine>::Traits::RegisterSet::Reg_edx);
  assert(Eax->getRegNum() ==
         InstX86Base<Machine>::Traits::RegisterSet::Reg_eax);
  assert(Ecx->getRegNum() ==
         InstX86Base<Machine>::Traits::RegisterSet::Reg_ecx);
  assert(Ebx->getRegNum() ==
         InstX86Base<Machine>::Traits::RegisterSet::Reg_ebx);
  this->addSource(Addr);
  this->addSource(Edx);
  this->addSource(Eax);
  this->addSource(Ecx);
  this->addSource(Ebx);
}

template <class Machine>
InstX86Cvt<Machine>::InstX86Cvt(Cfg *Func, Variable *Dest, Operand *Source,
                                CvtVariant Variant)
    : InstX86Base<Machine>(Func, InstX86Base<Machine>::Cvt, 1, Dest),
      Variant(Variant) {
  this->addSource(Source);
}

template <class Machine>
InstX86Icmp<Machine>::InstX86Icmp(Cfg *Func, Operand *Src0, Operand *Src1)
    : InstX86Base<Machine>(Func, InstX86Base<Machine>::Icmp, 2, nullptr) {
  this->addSource(Src0);
  this->addSource(Src1);
}

template <class Machine>
InstX86Ucomiss<Machine>::InstX86Ucomiss(Cfg *Func, Operand *Src0, Operand *Src1)
    : InstX86Base<Machine>(Func, InstX86Base<Machine>::Ucomiss, 2, nullptr) {
  this->addSource(Src0);
  this->addSource(Src1);
}

template <class Machine>
InstX86UD2<Machine>::InstX86UD2(Cfg *Func)
    : InstX86Base<Machine>(Func, InstX86Base<Machine>::UD2, 0, nullptr) {}

template <class Machine>
InstX86Test<Machine>::InstX86Test(Cfg *Func, Operand *Src1, Operand *Src2)
    : InstX86Base<Machine>(Func, InstX86Base<Machine>::Test, 2, nullptr) {
  this->addSource(Src1);
  this->addSource(Src2);
}

template <class Machine>
InstX86Mfence<Machine>::InstX86Mfence(Cfg *Func)
    : InstX86Base<Machine>(Func, InstX86Base<Machine>::Mfence, 0, nullptr) {
  this->HasSideEffects = true;
}

template <class Machine>
InstX86Store<Machine>::InstX86Store(
    Cfg *Func, Operand *Value,
    typename InstX86Base<Machine>::Traits::X86Operand *Mem)
    : InstX86Base<Machine>(Func, InstX86Base<Machine>::Store, 2, nullptr) {
  this->addSource(Value);
  this->addSource(Mem);
}

template <class Machine>
InstX86StoreP<Machine>::InstX86StoreP(
    Cfg *Func, Variable *Value,
    typename InstX86Base<Machine>::Traits::X86OperandMem *Mem)
    : InstX86Base<Machine>(Func, InstX86Base<Machine>::StoreP, 2, nullptr) {
  this->addSource(Value);
  this->addSource(Mem);
}

template <class Machine>
InstX86StoreQ<Machine>::InstX86StoreQ(
    Cfg *Func, Variable *Value,
    typename InstX86Base<Machine>::Traits::X86OperandMem *Mem)
    : InstX86Base<Machine>(Func, InstX86Base<Machine>::StoreQ, 2, nullptr) {
  this->addSource(Value);
  this->addSource(Mem);
}

template <class Machine>
InstX86Nop<Machine>::InstX86Nop(Cfg *Func, InstX86Nop::NopVariant Variant)
    : InstX86Base<Machine>(Func, InstX86Base<Machine>::Nop, 0, nullptr),
      Variant(Variant) {}

template <class Machine>
InstX86Fld<Machine>::InstX86Fld(Cfg *Func, Operand *Src)
    : InstX86Base<Machine>(Func, InstX86Base<Machine>::Fld, 1, nullptr) {
  this->addSource(Src);
}

template <class Machine>
InstX86Fstp<Machine>::InstX86Fstp(Cfg *Func, Variable *Dest)
    : InstX86Base<Machine>(Func, InstX86Base<Machine>::Fstp, 0, Dest) {}

template <class Machine>
InstX86Pop<Machine>::InstX86Pop(Cfg *Func, Variable *Dest)
    : InstX86Base<Machine>(Func, InstX86Base<Machine>::Pop, 0, Dest) {
  // A pop instruction affects the stack pointer and so it should not be
  // allowed to be automatically dead-code eliminated. (The corresponding push
  // instruction doesn't need this treatment because it has no dest variable
  // and therefore won't be dead-code eliminated.) This is needed for
  // late-stage liveness analysis (e.g. asm-verbose mode).
  this->HasSideEffects = true;
}

template <class Machine>
InstX86Push<Machine>::InstX86Push(Cfg *Func, Variable *Source)
    : InstX86Base<Machine>(Func, InstX86Base<Machine>::Push, 1, nullptr) {
  this->addSource(Source);
}

template <class Machine>
InstX86Ret<Machine>::InstX86Ret(Cfg *Func, Variable *Source)
    : InstX86Base<Machine>(Func, InstX86Base<Machine>::Ret, Source ? 1 : 0,
                           nullptr) {
  if (Source)
    this->addSource(Source);
}

template <class Machine>
InstX86Setcc<Machine>::InstX86Setcc(
    Cfg *Func, Variable *Dest,
    typename InstX86Base<Machine>::Traits::Cond::BrCond Cond)
    : InstX86Base<Machine>(Func, InstX86Base<Machine>::Setcc, 0, Dest),
      Condition(Cond) {}

template <class Machine>
InstX86Xadd<Machine>::InstX86Xadd(Cfg *Func, Operand *Dest, Variable *Source,
                                  bool Locked)
    : InstX86BaseLockable<Machine>(Func, InstX86Base<Machine>::Xadd, 2,
                                   llvm::dyn_cast<Variable>(Dest), Locked) {
  this->addSource(Dest);
  this->addSource(Source);
}

template <class Machine>
InstX86Xchg<Machine>::InstX86Xchg(Cfg *Func, Operand *Dest, Variable *Source)
    : InstX86Base<Machine>(Func, InstX86Base<Machine>::Xchg, 2,
                           llvm::dyn_cast<Variable>(Dest)) {
  this->addSource(Dest);
  this->addSource(Source);
}

template <class Machine>
InstX86IacaStart<Machine>::InstX86IacaStart(Cfg *Func)
    : InstX86Base<Machine>(Func, InstX86Base<Machine>::IacaStart, 0, nullptr) {
  assert(Func->getContext()->getFlags().getAllowIacaMarks());
}

template <class Machine>
InstX86IacaEnd<Machine>::InstX86IacaEnd(Cfg *Func)
    : InstX86Base<Machine>(Func, InstX86Base<Machine>::IacaEnd, 0, nullptr) {
  assert(Func->getContext()->getFlags().getAllowIacaMarks());
}

// ======================== Dump routines ======================== //

template <class Machine>
void InstX86Base<Machine>::dump(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  Str << "[" << Traits::TargetName << "] ";
  Inst::dump(Func);
}

template <class Machine>
void InstX86FakeRMW<Machine>::dump(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  Type Ty = getData()->getType();
  Str << "rmw " << InstArithmetic::getOpName(getOp()) << " " << Ty << " *";
  getAddr()->dump(Func);
  Str << ", ";
  getData()->dump(Func);
  Str << ", beacon=";
  getBeacon()->dump(Func);
}

template <class Machine>
void InstX86Label<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  Str << getName(Func) << ":";
}

template <class Machine>
void InstX86Label<Machine>::emitIAS(const Cfg *Func) const {
  typename InstX86Base<Machine>::Traits::Assembler *Asm =
      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
  Asm->bindLocalLabel(Number);
}

template <class Machine>
void InstX86Label<Machine>::dump(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  Str << getName(Func) << ":";
}

template <class Machine> void InstX86Br<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  Str << "\t";

  if (Condition == InstX86Base<Machine>::Traits::Cond::Br_None) {
    Str << "jmp";
  } else {
    Str << InstX86Base<Machine>::Traits::InstBrAttributes[Condition].EmitString;
  }

  if (Label) {
    Str << "\t" << Label->getName(Func);
  } else {
    if (Condition == InstX86Base<Machine>::Traits::Cond::Br_None) {
      Str << "\t" << getTargetFalse()->getAsmName();
    } else {
      Str << "\t" << getTargetTrue()->getAsmName();
      if (getTargetFalse()) {
        Str << "\n\tjmp\t" << getTargetFalse()->getAsmName();
      }
    }
  }
}

template <class Machine>
void InstX86Br<Machine>::emitIAS(const Cfg *Func) const {
  typename InstX86Base<Machine>::Traits::Assembler *Asm =
      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
  if (Label) {
    class Label *L = Asm->getOrCreateLocalLabel(Label->getNumber());
    if (Condition == InstX86Base<Machine>::Traits::Cond::Br_None) {
      Asm->jmp(L, isNear());
    } else {
      Asm->j(Condition, L, isNear());
    }
  } else {
    if (Condition == InstX86Base<Machine>::Traits::Cond::Br_None) {
      class Label *L =
          Asm->getOrCreateCfgNodeLabel(getTargetFalse()->getIndex());
      assert(!getTargetTrue());
      Asm->jmp(L, isNear());
    } else {
      class Label *L =
          Asm->getOrCreateCfgNodeLabel(getTargetTrue()->getIndex());
      Asm->j(Condition, L, isNear());
      if (getTargetFalse()) {
        class Label *L2 =
            Asm->getOrCreateCfgNodeLabel(getTargetFalse()->getIndex());
        Asm->jmp(L2, isNear());
      }
    }
  }
}

template <class Machine> void InstX86Br<Machine>::dump(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  Str << "br ";

  if (Condition == InstX86Base<Machine>::Traits::Cond::Br_None) {
    Str << "label %"
        << (Label ? Label->getName(Func) : getTargetFalse()->getName());
    return;
  }

  Str << InstX86Base<Machine>::Traits::InstBrAttributes[Condition]
             .DisplayString;
  if (Label) {
    Str << ", label %" << Label->getName(Func);
  } else {
    Str << ", label %" << getTargetTrue()->getName();
    if (getTargetFalse()) {
      Str << ", label %" << getTargetFalse()->getName();
    }
  }

  Str << " // (" << (isNear() ? "near" : "far") << " jump)";
}

template <class Machine> void InstX86Jmp<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(this->getSrcSize() == 1);
  Str << "\tjmp\t*";
  getJmpTarget()->emit(Func);
}

template <class Machine>
void InstX86Jmp<Machine>::emitIAS(const Cfg *Func) const {
  // Note: Adapted (mostly copied) from InstX86Call<Machine>::emitIAS().
  typename InstX86Base<Machine>::Traits::Assembler *Asm =
      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
  Operand *Target = getJmpTarget();
  if (const auto *Var = llvm::dyn_cast<Variable>(Target)) {
    if (Var->hasReg()) {
      Asm->jmp(InstX86Base<Machine>::Traits::getEncodedGPR(Var->getRegNum()));
    } else {
      // The jmp instruction with a memory operand should be possible to
      // encode, but it isn't a valid sandboxed instruction, and there
      // shouldn't be a register allocation issue to jump through a scratch
      // register, so we don't really need to bother implementing it.
      llvm::report_fatal_error("Assembler can't jmp to memory operand");
    }
  } else if (const auto *Mem = llvm::dyn_cast<
                 typename InstX86Base<Machine>::Traits::X86OperandMem>(
                 Target)) {
    (void)Mem;
    assert(Mem->getSegmentRegister() ==
           InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment);
    llvm::report_fatal_error("Assembler can't jmp to memory operand");
  } else if (const auto *CR = llvm::dyn_cast<ConstantRelocatable>(Target)) {
    assert(CR->getOffset() == 0 && "We only support jumping to a function");
    Asm->jmp(CR);
  } else if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Target)) {
    // NaCl trampoline calls refer to an address within the sandbox directly.
    // This is usually only needed for non-IRT builds and otherwise not very
    // portable or stable. Usually this is only done for "calls" and not jumps.
    // TODO(jvoung): Support this when there is a lowering that actually
    // triggers this case.
    (void)Imm;
    llvm::report_fatal_error("Unexpected jmp to absolute address");
  } else {
    llvm::report_fatal_error("Unexpected operand type");
  }
}

template <class Machine> void InstX86Jmp<Machine>::dump(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  Str << "jmp ";
  getJmpTarget()->dump(Func);
}

template <class Machine>
void InstX86Call<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(this->getSrcSize() == 1);
  Str << "\tcall\t";
  Operand *CallTarget = getCallTarget();
  auto *Target = InstX86Base<Machine>::getTarget(Func);
  if (const auto *CI = llvm::dyn_cast<ConstantInteger32>(CallTarget)) {
    // Emit without a leading '$'.
    Str << CI->getValue();
  } else if (const auto DirectCallTarget =
                 llvm::dyn_cast<ConstantRelocatable>(CallTarget)) {
    DirectCallTarget->emitWithoutPrefix(Target);
  } else {
    Str << "*";
    CallTarget->emit(Func);
  }
}

template <class Machine>
void InstX86Call<Machine>::emitIAS(const Cfg *Func) const {
  typename InstX86Base<Machine>::Traits::Assembler *Asm =
      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
  Operand *CallTarget = getCallTarget();
  auto *Target = InstX86Base<Machine>::getTarget(Func);
  if (const auto *Var = llvm::dyn_cast<Variable>(CallTarget)) {
    if (Var->hasReg()) {
      Asm->call(InstX86Base<Machine>::Traits::getEncodedGPR(Var->getRegNum()));
    } else {
      Asm->call(Target->stackVarToAsmOperand(Var));
    }
  } else if (const auto *Mem = llvm::dyn_cast<
                 typename InstX86Base<Machine>::Traits::X86OperandMem>(
                 CallTarget)) {
    assert(Mem->getSegmentRegister() ==
           InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment);
    Asm->call(Mem->toAsmAddress(Asm, Target));
  } else if (const auto *CR = llvm::dyn_cast<ConstantRelocatable>(CallTarget)) {
    assert(CR->getOffset() == 0 && "We only support calling a function");
    Asm->call(CR);
  } else if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(CallTarget)) {
    Asm->call(Immediate(Imm->getValue()));
  } else {
    llvm_unreachable("Unexpected operand type");
  }
}

template <class Machine>
void InstX86Call<Machine>::dump(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  if (this->getDest()) {
    this->dumpDest(Func);
    Str << " = ";
  }
  Str << "call ";
  getCallTarget()->dump(Func);
}

// The this->Opcode parameter needs to be char* and not IceString because of
// template issues.
template <class Machine>
void InstX86Base<Machine>::emitTwoAddress(const char *Opcode, const Inst *Inst,
                                          const Cfg *Func) {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(Inst->getSrcSize() == 2);
  Operand *Dest = Inst->getDest();
  if (Dest == nullptr)
    Dest = Inst->getSrc(0);
  assert(Dest == Inst->getSrc(0));
  Operand *Src1 = Inst->getSrc(1);
  Str << "\t" << Opcode << InstX86Base<Machine>::getWidthString(Dest->getType())
      << "\t";
  Src1->emit(Func);
  Str << ", ";
  Dest->emit(Func);
}

template <class Machine>
void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Op,
                    const typename InstX86Base<
                        Machine>::Traits::Assembler::GPREmitterOneOp &Emitter) {
  auto *Target = InstX86Base<Machine>::getTarget(Func);
  typename InstX86Base<Machine>::Traits::Assembler *Asm =
      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
  if (const auto *Var = llvm::dyn_cast<Variable>(Op)) {
    if (Var->hasReg()) {
      // We cheat a little and use GPRRegister even for byte operations.
      typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister VarReg =
          InstX86Base<Machine>::Traits::getEncodedGPR(Var->getRegNum());
      (Asm->*(Emitter.Reg))(Ty, VarReg);
    } else {
      typename InstX86Base<Machine>::Traits::Address StackAddr(
          Target->stackVarToAsmOperand(Var));
      (Asm->*(Emitter.Addr))(Ty, StackAddr);
    }
  } else if (const auto *Mem = llvm::dyn_cast<
                 typename InstX86Base<Machine>::Traits::X86OperandMem>(Op)) {
    Mem->emitSegmentOverride(Asm);
    (Asm->*(Emitter.Addr))(Ty, Mem->toAsmAddress(Asm, Target));
  } else {
    llvm_unreachable("Unexpected operand type");
  }
}

template <class Machine, bool VarCanBeByte, bool SrcCanBeByte>
void emitIASRegOpTyGPR(
    const Cfg *Func, Type Ty, const Variable *Var, const Operand *Src,
    const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterRegOp
        &Emitter) {
  auto *Target = InstX86Base<Machine>::getTarget(Func);
  typename InstX86Base<Machine>::Traits::Assembler *Asm =
      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
  assert(Var->hasReg());
  // We cheat a little and use GPRRegister even for byte operations.
  typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister VarReg =
      VarCanBeByte
          ? InstX86Base<Machine>::Traits::getEncodedGPR(Var->getRegNum())
          : InstX86Base<Machine>::Traits::getEncodedGPR(Var->getRegNum());
  if (const auto *SrcVar = llvm::dyn_cast<Variable>(Src)) {
    if (SrcVar->hasReg()) {
      typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister SrcReg =
          SrcCanBeByte
              ? InstX86Base<Machine>::Traits::getEncodedGPR(SrcVar->getRegNum())
              : InstX86Base<Machine>::Traits::getEncodedGPR(
                    SrcVar->getRegNum());
      (Asm->*(Emitter.GPRGPR))(Ty, VarReg, SrcReg);
    } else {
      typename InstX86Base<Machine>::Traits::Address SrcStackAddr =
          Target->stackVarToAsmOperand(SrcVar);
      (Asm->*(Emitter.GPRAddr))(Ty, VarReg, SrcStackAddr);
    }
  } else if (const auto *Mem = llvm::dyn_cast<
                 typename InstX86Base<Machine>::Traits::X86OperandMem>(Src)) {
    Mem->emitSegmentOverride(Asm);
    (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Mem->toAsmAddress(Asm, Target));
  } else if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src)) {
    (Asm->*(Emitter.GPRImm))(Ty, VarReg, Immediate(Imm->getValue()));
  } else if (const auto *Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) {
    AssemblerFixup *Fixup =
        Asm->createFixup(InstX86Base<Machine>::Traits::RelFixup, Reloc);
    (Asm->*(Emitter.GPRImm))(Ty, VarReg, Immediate(Reloc->getOffset(), Fixup));
  } else if (const auto *Split = llvm::dyn_cast<
                 typename InstX86Base<Machine>::Traits::VariableSplit>(Src)) {
    (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Split->toAsmAddress(Func));
  } else {
    llvm_unreachable("Unexpected operand type");
  }
}

template <class Machine>
void emitIASAddrOpTyGPR(
    const Cfg *Func, Type Ty,
    const typename InstX86Base<Machine>::Traits::Address &Addr,
    const Operand *Src,
    const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterAddrOp
        &Emitter) {
  typename InstX86Base<Machine>::Traits::Assembler *Asm =
      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
  // Src can only be Reg or Immediate.
  if (const auto *SrcVar = llvm::dyn_cast<Variable>(Src)) {
    assert(SrcVar->hasReg());
    typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister SrcReg =
        InstX86Base<Machine>::Traits::getEncodedGPR(SrcVar->getRegNum());
    (Asm->*(Emitter.AddrGPR))(Ty, Addr, SrcReg);
  } else if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src)) {
    (Asm->*(Emitter.AddrImm))(Ty, Addr, Immediate(Imm->getValue()));
  } else if (const auto *Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) {
    AssemblerFixup *Fixup =
        Asm->createFixup(InstX86Base<Machine>::Traits::RelFixup, Reloc);
    (Asm->*(Emitter.AddrImm))(Ty, Addr, Immediate(Reloc->getOffset(), Fixup));
  } else {
    llvm_unreachable("Unexpected operand type");
  }
}

template <class Machine>
void emitIASAsAddrOpTyGPR(
    const Cfg *Func, Type Ty, const Operand *Op0, const Operand *Op1,
    const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterAddrOp
        &Emitter) {
  auto *Target = InstX86Base<Machine>::getTarget(Func);
  if (const auto *Op0Var = llvm::dyn_cast<Variable>(Op0)) {
    assert(!Op0Var->hasReg());
    typename InstX86Base<Machine>::Traits::Address StackAddr(
        Target->stackVarToAsmOperand(Op0Var));
    emitIASAddrOpTyGPR<Machine>(Func, Ty, StackAddr, Op1, Emitter);
  } else if (const auto *Op0Mem = llvm::dyn_cast<
                 typename InstX86Base<Machine>::Traits::X86OperandMem>(Op0)) {
    typename InstX86Base<Machine>::Traits::Assembler *Asm =
        Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
    Op0Mem->emitSegmentOverride(Asm);
    emitIASAddrOpTyGPR<Machine>(Func, Ty, Op0Mem->toAsmAddress(Asm, Target),
                                Op1, Emitter);
  } else if (const auto *Split = llvm::dyn_cast<
                 typename InstX86Base<Machine>::Traits::VariableSplit>(Op0)) {
    emitIASAddrOpTyGPR<Machine>(Func, Ty, Split->toAsmAddress(Func), Op1,
                                Emitter);
  } else {
    llvm_unreachable("Unexpected operand type");
  }
}

template <class Machine>
void InstX86Base<Machine>::emitIASGPRShift(
    const Cfg *Func, Type Ty, const Variable *Var, const Operand *Src,
    const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterShiftOp
        &Emitter) {
  typename InstX86Base<Machine>::Traits::Assembler *Asm =
      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
  // Technically, the Dest Var can be mem as well, but we only use Reg. We can
  // extend this to check Dest if we decide to use that form.
  assert(Var->hasReg());
  // We cheat a little and use GPRRegister even for byte operations.
  typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister VarReg =
      InstX86Base<Machine>::Traits::getEncodedGPR(Var->getRegNum());
  // Src must be reg == ECX or an Imm8. This is asserted by the assembler.
  if (const auto *SrcVar = llvm::dyn_cast<Variable>(Src)) {
    assert(SrcVar->hasReg());
    typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister SrcReg =
        InstX86Base<Machine>::Traits::getEncodedGPR(SrcVar->getRegNum());
    (Asm->*(Emitter.GPRGPR))(Ty, VarReg, SrcReg);
  } else if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src)) {
    (Asm->*(Emitter.GPRImm))(Ty, VarReg, Immediate(Imm->getValue()));
  } else {
    llvm_unreachable("Unexpected operand type");
  }
}

template <class Machine>
void emitIASGPRShiftDouble(
    const Cfg *Func, const Variable *Dest, const Operand *Src1Op,
    const Operand *Src2Op,
    const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterShiftD
        &Emitter) {
  typename InstX86Base<Machine>::Traits::Assembler *Asm =
      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
  // Dest can be reg or mem, but we only use the reg variant.
  assert(Dest->hasReg());
  typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister DestReg =
      InstX86Base<Machine>::Traits::getEncodedGPR(Dest->getRegNum());
  // SrcVar1 must be reg.
  const auto *SrcVar1 = llvm::cast<Variable>(Src1Op);
  assert(SrcVar1->hasReg());
  typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister SrcReg =
      InstX86Base<Machine>::Traits::getEncodedGPR(SrcVar1->getRegNum());
  Type Ty = SrcVar1->getType();
  // Src2 can be the implicit CL register or an immediate.
  if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src2Op)) {
    (Asm->*(Emitter.GPRGPRImm))(Ty, DestReg, SrcReg,
                                Immediate(Imm->getValue()));
  } else {
    assert(llvm::cast<Variable>(Src2Op)->getRegNum() ==
           InstX86Base<Machine>::Traits::RegisterSet::Reg_cl);
    (Asm->*(Emitter.GPRGPR))(Ty, DestReg, SrcReg);
  }
}

template <class Machine>
void emitIASXmmShift(
    const Cfg *Func, Type Ty, const Variable *Var, const Operand *Src,
    const typename InstX86Base<Machine>::Traits::Assembler::XmmEmitterShiftOp
        &Emitter) {
  auto *Target = InstX86Base<Machine>::getTarget(Func);
  typename InstX86Base<Machine>::Traits::Assembler *Asm =
      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
  assert(Var->hasReg());
  typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister VarReg =
      InstX86Base<Machine>::Traits::getEncodedXmm(Var->getRegNum());
  if (const auto *SrcVar = llvm::dyn_cast<Variable>(Src)) {
    if (SrcVar->hasReg()) {
      typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister SrcReg =
          InstX86Base<Machine>::Traits::getEncodedXmm(SrcVar->getRegNum());
      (Asm->*(Emitter.XmmXmm))(Ty, VarReg, SrcReg);
    } else {
      typename InstX86Base<Machine>::Traits::Address SrcStackAddr =
          Target->stackVarToAsmOperand(SrcVar);
      (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcStackAddr);
    }
  } else if (const auto *Mem = llvm::dyn_cast<
                 typename InstX86Base<Machine>::Traits::X86OperandMem>(Src)) {
    assert(Mem->getSegmentRegister() ==
           InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment);
    (Asm->*(Emitter.XmmAddr))(Ty, VarReg, Mem->toAsmAddress(Asm, Target));
  } else if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src)) {
    (Asm->*(Emitter.XmmImm))(Ty, VarReg, Immediate(Imm->getValue()));
  } else {
    llvm_unreachable("Unexpected operand type");
  }
}

template <class Machine>
void emitIASRegOpTyXMM(
    const Cfg *Func, Type Ty, const Variable *Var, const Operand *Src,
    const typename InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp
        &Emitter) {
  auto *Target = InstX86Base<Machine>::getTarget(Func);
  typename InstX86Base<Machine>::Traits::Assembler *Asm =
      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
  assert(Var->hasReg());
  typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister VarReg =
      InstX86Base<Machine>::Traits::getEncodedXmm(Var->getRegNum());
  if (const auto *SrcVar = llvm::dyn_cast<Variable>(Src)) {
    if (SrcVar->hasReg()) {
      typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister SrcReg =
          InstX86Base<Machine>::Traits::getEncodedXmm(SrcVar->getRegNum());
      (Asm->*(Emitter.XmmXmm))(Ty, VarReg, SrcReg);
    } else {
      typename InstX86Base<Machine>::Traits::Address SrcStackAddr =
          Target->stackVarToAsmOperand(SrcVar);
      (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcStackAddr);
    }
  } else if (const auto *Mem = llvm::dyn_cast<
                 typename InstX86Base<Machine>::Traits::X86OperandMem>(Src)) {
    assert(Mem->getSegmentRegister() ==
           InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment);
    (Asm->*(Emitter.XmmAddr))(Ty, VarReg, Mem->toAsmAddress(Asm, Target));
  } else if (const auto *Imm = llvm::dyn_cast<Constant>(Src)) {
    (Asm->*(Emitter.XmmAddr))(
        Ty, VarReg,
        InstX86Base<Machine>::Traits::Address::ofConstPool(Asm, Imm));
  } else {
    llvm_unreachable("Unexpected operand type");
  }
}

template <class Machine, typename DReg_t, typename SReg_t,
          DReg_t (*destEnc)(int32_t), SReg_t (*srcEnc)(int32_t)>
void emitIASCastRegOp(const Cfg *Func, Type DestTy, const Variable *Dest,
                      Type SrcTy, const Operand *Src,
                      const typename InstX86Base<Machine>::Traits::Assembler::
                          template CastEmitterRegOp<DReg_t, SReg_t> &Emitter) {
  auto *Target = InstX86Base<Machine>::getTarget(Func);
  typename InstX86Base<Machine>::Traits::Assembler *Asm =
      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
  assert(Dest->hasReg());
  DReg_t DestReg = destEnc(Dest->getRegNum());
  if (const auto *SrcVar = llvm::dyn_cast<Variable>(Src)) {
    if (SrcVar->hasReg()) {
      SReg_t SrcReg = srcEnc(SrcVar->getRegNum());
      (Asm->*(Emitter.RegReg))(DestTy, DestReg, SrcTy, SrcReg);
    } else {
      typename InstX86Base<Machine>::Traits::Address SrcStackAddr =
          Target->stackVarToAsmOperand(SrcVar);
      (Asm->*(Emitter.RegAddr))(DestTy, DestReg, SrcTy, SrcStackAddr);
    }
  } else if (const auto *Mem = llvm::dyn_cast<
                 typename InstX86Base<Machine>::Traits::X86OperandMem>(Src)) {
    Mem->emitSegmentOverride(Asm);
    (Asm->*(Emitter.RegAddr))(DestTy, DestReg, SrcTy,
                              Mem->toAsmAddress(Asm, Target));
  } else {
    llvm_unreachable("Unexpected operand type");
  }
}

template <class Machine, typename DReg_t, typename SReg_t,
          DReg_t (*destEnc)(int32_t), SReg_t (*srcEnc)(int32_t)>
void emitIASThreeOpImmOps(
    const Cfg *Func, Type DispatchTy, const Variable *Dest, const Operand *Src0,
    const Operand *Src1,
    const typename InstX86Base<Machine>::Traits::Assembler::
        template ThreeOpImmEmitter<DReg_t, SReg_t> Emitter) {
  auto *Target = InstX86Base<Machine>::getTarget(Func);
  typename InstX86Base<Machine>::Traits::Assembler *Asm =
      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
  // This only handles Dest being a register, and Src1 being an immediate.
  assert(Dest->hasReg());
  DReg_t DestReg = destEnc(Dest->getRegNum());
  Immediate Imm(llvm::cast<ConstantInteger32>(Src1)->getValue());
  if (const auto *SrcVar = llvm::dyn_cast<Variable>(Src0)) {
    if (SrcVar->hasReg()) {
      SReg_t SrcReg = srcEnc(SrcVar->getRegNum());
      (Asm->*(Emitter.RegRegImm))(DispatchTy, DestReg, SrcReg, Imm);
    } else {
      typename InstX86Base<Machine>::Traits::Address SrcStackAddr =
          Target->stackVarToAsmOperand(SrcVar);
      (Asm->*(Emitter.RegAddrImm))(DispatchTy, DestReg, SrcStackAddr, Imm);
    }
  } else if (const auto *Mem = llvm::dyn_cast<
                 typename InstX86Base<Machine>::Traits::X86OperandMem>(Src0)) {
    Mem->emitSegmentOverride(Asm);
    (Asm->*(Emitter.RegAddrImm))(DispatchTy, DestReg,
                                 Mem->toAsmAddress(Asm, Target), Imm);
  } else {
    llvm_unreachable("Unexpected operand type");
  }
}

template <class Machine>
void emitIASMovlikeXMM(
    const Cfg *Func, const Variable *Dest, const Operand *Src,
    const typename InstX86Base<Machine>::Traits::Assembler::XmmEmitterMovOps
        Emitter) {
  auto *Target = InstX86Base<Machine>::getTarget(Func);
  typename InstX86Base<Machine>::Traits::Assembler *Asm =
      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
  if (Dest->hasReg()) {
    typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister DestReg =
        InstX86Base<Machine>::Traits::getEncodedXmm(Dest->getRegNum());
    if (const auto *SrcVar = llvm::dyn_cast<Variable>(Src)) {
      if (SrcVar->hasReg()) {
        (Asm->*(Emitter.XmmXmm))(
            DestReg,
            InstX86Base<Machine>::Traits::getEncodedXmm(SrcVar->getRegNum()));
      } else {
        typename InstX86Base<Machine>::Traits::Address StackAddr(
            Target->stackVarToAsmOperand(SrcVar));
        (Asm->*(Emitter.XmmAddr))(DestReg, StackAddr);
      }
    } else if (const auto *SrcMem = llvm::dyn_cast<
                   typename InstX86Base<Machine>::Traits::X86OperandMem>(Src)) {
      assert(SrcMem->getSegmentRegister() ==
             InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment);
      (Asm->*(Emitter.XmmAddr))(DestReg, SrcMem->toAsmAddress(Asm, Target));
    } else {
      llvm_unreachable("Unexpected operand type");
    }
  } else {
    typename InstX86Base<Machine>::Traits::Address StackAddr(
        Target->stackVarToAsmOperand(Dest));
    // Src must be a register in this case.
    const auto *SrcVar = llvm::cast<Variable>(Src);
    assert(SrcVar->hasReg());
    (Asm->*(Emitter.AddrXmm))(
        StackAddr,
        InstX86Base<Machine>::Traits::getEncodedXmm(SrcVar->getRegNum()));
  }
}

template <class Machine>
void InstX86Sqrtss<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(this->getSrcSize() == 1);
  Type Ty = this->getSrc(0)->getType();
  assert(isScalarFloatingType(Ty));
  Str << "\tsqrt" << InstX86Base<Machine>::Traits::TypeAttributes[Ty].SdSsString
      << "\t";
  this->getSrc(0)->emit(Func);
  Str << ", ";
  this->getDest()->emit(Func);
}

template <class Machine>
void InstX86Addss<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  char buf[30];
  snprintf(
      buf, llvm::array_lengthof(buf), "add%s",
      InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()]
          .SdSsString);
  this->emitTwoAddress(buf, this, Func);
}

template <class Machine>
void InstX86Padd<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  char buf[30];
  snprintf(
      buf, llvm::array_lengthof(buf), "padd%s",
      InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()]
          .PackString);
  this->emitTwoAddress(buf, this, Func);
}

template <class Machine>
void InstX86Pmull<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  char buf[30];
  bool TypesAreValid = this->getDest()->getType() == IceType_v4i32 ||
                       this->getDest()->getType() == IceType_v8i16;
  auto *Target = InstX86Base<Machine>::getTarget(Func);
  bool InstructionSetIsValid =
      this->getDest()->getType() == IceType_v8i16 ||
      Target->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1;
  (void)TypesAreValid;
  (void)InstructionSetIsValid;
  assert(TypesAreValid);
  assert(InstructionSetIsValid);
  snprintf(
      buf, llvm::array_lengthof(buf), "pmull%s",
      InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()]
          .PackString);
  this->emitTwoAddress(buf, this, Func);
}

template <class Machine>
void InstX86Pmull<Machine>::emitIAS(const Cfg *Func) const {
  Type Ty = this->getDest()->getType();
  bool TypesAreValid = Ty == IceType_v4i32 || Ty == IceType_v8i16;
  auto *Target = InstX86Base<Machine>::getTarget(Func);
  bool InstructionSetIsValid =
      Ty == IceType_v8i16 ||
      Target->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1;
  (void)TypesAreValid;
  (void)InstructionSetIsValid;
  assert(TypesAreValid);
  assert(InstructionSetIsValid);
  assert(this->getSrcSize() == 2);
  Type ElementTy = typeElementType(Ty);
  emitIASRegOpTyXMM<Machine>(Func, ElementTy, this->getDest(), this->getSrc(1),
                             this->Emitter);
}

template <class Machine>
void InstX86Subss<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  char buf[30];
  snprintf(
      buf, llvm::array_lengthof(buf), "sub%s",
      InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()]
          .SdSsString);
  this->emitTwoAddress(buf, this, Func);
}

template <class Machine>
void InstX86Psub<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  char buf[30];
  snprintf(
      buf, llvm::array_lengthof(buf), "psub%s",
      InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()]
          .PackString);
  this->emitTwoAddress(buf, this, Func);
}

template <class Machine>
void InstX86Mulss<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  char buf[30];
  snprintf(
      buf, llvm::array_lengthof(buf), "mul%s",
      InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()]
          .SdSsString);
  this->emitTwoAddress(buf, this, Func);
}

template <class Machine>
void InstX86Pmuludq<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  assert(this->getSrc(0)->getType() == IceType_v4i32 &&
         this->getSrc(1)->getType() == IceType_v4i32);
  this->emitTwoAddress(this->Opcode, this, Func);
}

template <class Machine>
void InstX86Divss<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  char buf[30];
  snprintf(
      buf, llvm::array_lengthof(buf), "div%s",
      InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()]
          .SdSsString);
  this->emitTwoAddress(buf, this, Func);
}

template <class Machine> void InstX86Div<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(this->getSrcSize() == 3);
  Operand *Src1 = this->getSrc(1);
  Str << "\t" << this->Opcode << this->getWidthString(Src1->getType()) << "\t";
  Src1->emit(Func);
}

template <class Machine>
void InstX86Div<Machine>::emitIAS(const Cfg *Func) const {
  assert(this->getSrcSize() == 3);
  const Operand *Src = this->getSrc(1);
  Type Ty = Src->getType();
  static const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterOneOp
      Emitter = {&InstX86Base<Machine>::Traits::Assembler::div,
                 &InstX86Base<Machine>::Traits::Assembler::div};
  emitIASOpTyGPR<Machine>(Func, Ty, Src, Emitter);
}

template <class Machine>
void InstX86Idiv<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(this->getSrcSize() == 3);
  Operand *Src1 = this->getSrc(1);
  Str << "\t" << this->Opcode << this->getWidthString(Src1->getType()) << "\t";
  Src1->emit(Func);
}

template <class Machine>
void InstX86Idiv<Machine>::emitIAS(const Cfg *Func) const {
  assert(this->getSrcSize() == 3);
  const Operand *Src = this->getSrc(1);
  Type Ty = Src->getType();
  static const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterOneOp
      Emitter = {&InstX86Base<Machine>::Traits::Assembler::idiv,
                 &InstX86Base<Machine>::Traits::Assembler::idiv};
  emitIASOpTyGPR<Machine>(Func, Ty, Src, Emitter);
}

// pblendvb and blendvps take xmm0 as a final implicit argument.
template <class Machine>
void emitVariableBlendInst(const char *Opcode, const Inst *Inst,
                           const Cfg *Func) {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(Inst->getSrcSize() == 3);
  assert(llvm::cast<Variable>(Inst->getSrc(2))->getRegNum() ==
         InstX86Base<Machine>::Traits::RegisterSet::Reg_xmm0);
  Str << "\t" << Opcode << "\t";
  Inst->getSrc(1)->emit(Func);
  Str << ", ";
  Inst->getDest()->emit(Func);
}

template <class Machine>
void emitIASVariableBlendInst(
    const Inst *Inst, const Cfg *Func,
    const typename InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp
        &Emitter) {
  assert(Inst->getSrcSize() == 3);
  assert(llvm::cast<Variable>(Inst->getSrc(2))->getRegNum() ==
         InstX86Base<Machine>::Traits::RegisterSet::Reg_xmm0);
  const Variable *Dest = Inst->getDest();
  const Operand *Src = Inst->getSrc(1);
  emitIASRegOpTyXMM<Machine>(Func, Dest->getType(), Dest, Src, Emitter);
}

template <class Machine>
void InstX86Blendvps<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  assert(InstX86Base<Machine>::getTarget(Func)->getInstructionSet() >=
         InstX86Base<Machine>::Traits::SSE4_1);
  emitVariableBlendInst<Machine>(this->Opcode, this, Func);
}

template <class Machine>
void InstX86Blendvps<Machine>::emitIAS(const Cfg *Func) const {
  assert(InstX86Base<Machine>::getTarget(Func)->getInstructionSet() >=
         InstX86Base<Machine>::Traits::SSE4_1);
  static const typename InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp
      Emitter = {&InstX86Base<Machine>::Traits::Assembler::blendvps,
                 &InstX86Base<Machine>::Traits::Assembler::blendvps};
  emitIASVariableBlendInst<Machine>(this, Func, Emitter);
}

template <class Machine>
void InstX86Pblendvb<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  assert(InstX86Base<Machine>::getTarget(Func)->getInstructionSet() >=
         InstX86Base<Machine>::Traits::SSE4_1);
  emitVariableBlendInst<Machine>(this->Opcode, this, Func);
}

template <class Machine>
void InstX86Pblendvb<Machine>::emitIAS(const Cfg *Func) const {
  assert(InstX86Base<Machine>::getTarget(Func)->getInstructionSet() >=
         InstX86Base<Machine>::Traits::SSE4_1);
  static const typename InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp
      Emitter = {&InstX86Base<Machine>::Traits::Assembler::pblendvb,
                 &InstX86Base<Machine>::Traits::Assembler::pblendvb};
  emitIASVariableBlendInst<Machine>(this, Func, Emitter);
}

template <class Machine>
void InstX86Imul<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(this->getSrcSize() == 2);
  Variable *Dest = this->getDest();
  if (isByteSizedArithType(Dest->getType())) {
    // The 8-bit version of imul only allows the form "imul r/m8".
    const auto *Src0Var = llvm::dyn_cast<Variable>(this->getSrc(0));
    (void)Src0Var;
    assert(Src0Var->getRegNum() ==
           InstX86Base<Machine>::Traits::RegisterSet::Reg_al);
    Str << "\timulb\t";
    this->getSrc(1)->emit(Func);
  } else if (llvm::isa<Constant>(this->getSrc(1))) {
    Str << "\timul" << this->getWidthString(Dest->getType()) << "\t";
    this->getSrc(1)->emit(Func);
    Str << ", ";
    this->getSrc(0)->emit(Func);
    Str << ", ";
    Dest->emit(Func);
  } else {
    this->emitTwoAddress("imul", this, Func);
  }
}

template <class Machine>
void InstX86Imul<Machine>::emitIAS(const Cfg *Func) const {
  assert(this->getSrcSize() == 2);
  const Variable *Var = this->getDest();
  Type Ty = Var->getType();
  const Operand *Src = this->getSrc(1);
  if (isByteSizedArithType(Ty)) {
    // The 8-bit version of imul only allows the form "imul r/m8".
    const auto *Src0Var = llvm::dyn_cast<Variable>(this->getSrc(0));
    (void)Src0Var;
    assert(Src0Var->getRegNum() ==
           InstX86Base<Machine>::Traits::RegisterSet::Reg_al);
    static const typename InstX86Base<
        Machine>::Traits::Assembler::GPREmitterOneOp Emitter = {
        &InstX86Base<Machine>::Traits::Assembler::imul,
        &InstX86Base<Machine>::Traits::Assembler::imul};
    emitIASOpTyGPR<Machine>(Func, Ty, this->getSrc(1), Emitter);
  } else {
    // The two-address version is used when multiplying by a non-constant
    // or doing an 8-bit multiply.
    assert(Var == this->getSrc(0));
    static const typename InstX86Base<
        Machine>::Traits::Assembler::GPREmitterRegOp Emitter = {
        &InstX86Base<Machine>::Traits::Assembler::imul,
        &InstX86Base<Machine>::Traits::Assembler::imul,
        &InstX86Base<Machine>::Traits::Assembler::imul};
    emitIASRegOpTyGPR<Machine>(Func, Ty, Var, Src, Emitter);
  }
}

template <class Machine>
void InstX86ImulImm<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(this->getSrcSize() == 2);
  Variable *Dest = this->getDest();
  assert(Dest->getType() == IceType_i16 || Dest->getType() == IceType_i32);
  assert(llvm::isa<Constant>(this->getSrc(1)));
  Str << "\timul" << this->getWidthString(Dest->getType()) << "\t";
  this->getSrc(1)->emit(Func);
  Str << ", ";
  this->getSrc(0)->emit(Func);
  Str << ", ";
  Dest->emit(Func);
}

template <class Machine>
void InstX86ImulImm<Machine>::emitIAS(const Cfg *Func) const {
  assert(this->getSrcSize() == 2);
  const Variable *Dest = this->getDest();
  Type Ty = Dest->getType();
  assert(llvm::isa<Constant>(this->getSrc(1)));
  static const typename InstX86Base<Machine>::Traits::Assembler::
      template ThreeOpImmEmitter<
          typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister,
          typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister>
          Emitter = {&InstX86Base<Machine>::Traits::Assembler::imul,
                     &InstX86Base<Machine>::Traits::Assembler::imul};
  emitIASThreeOpImmOps<
      Machine, typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister,
      typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister,
      InstX86Base<Machine>::Traits::getEncodedGPR,
      InstX86Base<Machine>::Traits::getEncodedGPR>(
      Func, Ty, Dest, this->getSrc(0), this->getSrc(1), Emitter);
}

template <class Machine>
void InstX86Insertps<Machine>::emitIAS(const Cfg *Func) const {
  assert(this->getSrcSize() == 3);
  assert(InstX86Base<Machine>::getTarget(Func)->getInstructionSet() >=
         InstX86Base<Machine>::Traits::SSE4_1);
  const Variable *Dest = this->getDest();
  assert(Dest == this->getSrc(0));
  Type Ty = Dest->getType();
  static const typename InstX86Base<Machine>::Traits::Assembler::
      template ThreeOpImmEmitter<
          typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
          typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister>
          Emitter = {&InstX86Base<Machine>::Traits::Assembler::insertps,
                     &InstX86Base<Machine>::Traits::Assembler::insertps};
  emitIASThreeOpImmOps<
      Machine, typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
      typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
      InstX86Base<Machine>::Traits::getEncodedXmm,
      InstX86Base<Machine>::Traits::getEncodedXmm>(
      Func, Ty, Dest, this->getSrc(1), this->getSrc(2), Emitter);
}

template <class Machine>
void InstX86Cbwdq<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(this->getSrcSize() == 1);
  Operand *Src0 = this->getSrc(0);
  int32_t DestReg = this->getDest()->getRegNum();
  int32_t SrcReg = llvm::cast<Variable>(Src0)->getRegNum();
  (void)DestReg;
  (void)SrcReg;
  switch (Src0->getType()) {
  default:
    llvm_unreachable("unexpected source type!");
    break;
  case IceType_i8:
    assert(SrcReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_al);
    assert(DestReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_ax ||
           DestReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_ah);
    Str << "\t"
        << "cbtw";
    break;
  case IceType_i16:
    assert(SrcReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_ax);
    assert(DestReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_dx);
    Str << "\t"
        << "cwtd";
    break;
  case IceType_i32:
    assert(SrcReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_eax);
    assert(DestReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_edx);
    Str << "\t"
        << "cltd";
    break;
  case IceType_i64:
    assert(DestReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_edx);
    Str << "\t"
        << "cdto";
    break;
  }
}

template <class Machine>
void InstX86Cbwdq<Machine>::emitIAS(const Cfg *Func) const {
  typename InstX86Base<Machine>::Traits::Assembler *Asm =
      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
  assert(this->getSrcSize() == 1);
  Operand *Src0 = this->getSrc(0);
  int32_t DestReg = this->getDest()->getRegNum();
  int32_t SrcReg = llvm::cast<Variable>(Src0)->getRegNum();
  (void)DestReg;
  (void)SrcReg;
  switch (Src0->getType()) {
  default:
    llvm_unreachable("unexpected source type!");
    break;
  case IceType_i8:
    assert(SrcReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_al);
    assert(DestReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_ax ||
           DestReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_ah);
    Asm->cbw();
    break;
  case IceType_i16:
    assert(SrcReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_ax);
    assert(DestReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_dx);
    Asm->cwd();
    break;
  case IceType_i32:
    assert(SrcReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_eax);
    assert(DestReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_edx);
    Asm->cdq();
    break;
  case IceType_i64:
    assert(DestReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_edx);
    Asm->cqo();
    break;
  }
}

template <class Machine> void InstX86Mul<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(this->getSrcSize() == 2);
  assert(llvm::isa<Variable>(this->getSrc(0)));
  assert(llvm::cast<Variable>(this->getSrc(0))->getRegNum() ==
         InstX86Base<Machine>::Traits::RegisterSet::Reg_eax);
  assert(
      this->getDest()->getRegNum() ==
      InstX86Base<Machine>::Traits::RegisterSet::Reg_eax); // TODO: allow edx?
  Str << "\tmul" << this->getWidthString(this->getDest()->getType()) << "\t";
  this->getSrc(1)->emit(Func);
}

template <class Machine>
void InstX86Mul<Machine>::emitIAS(const Cfg *Func) const {
  assert(this->getSrcSize() == 2);
  assert(llvm::isa<Variable>(this->getSrc(0)));
  assert(llvm::cast<Variable>(this->getSrc(0))->getRegNum() ==
         InstX86Base<Machine>::Traits::RegisterSet::Reg_eax);
  assert(
      this->getDest()->getRegNum() ==
      InstX86Base<Machine>::Traits::RegisterSet::Reg_eax); // TODO: allow edx?
  const Operand *Src = this->getSrc(1);
  Type Ty = Src->getType();
  static const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterOneOp
      Emitter = {&InstX86Base<Machine>::Traits::Assembler::mul,
                 &InstX86Base<Machine>::Traits::Assembler::mul};
  emitIASOpTyGPR<Machine>(Func, Ty, Src, Emitter);
}

template <class Machine> void InstX86Mul<Machine>::dump(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  this->dumpDest(Func);
  Str << " = mul." << this->getDest()->getType() << " ";
  this->dumpSources(Func);
}

template <class Machine>
void InstX86Shld<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  Variable *Dest = this->getDest();
  assert(this->getSrcSize() == 3);
  assert(Dest == this->getSrc(0));
  Str << "\tshld" << this->getWidthString(Dest->getType()) << "\t";
  this->getSrc(2)->emit(Func);
  Str << ", ";
  this->getSrc(1)->emit(Func);
  Str << ", ";
  Dest->emit(Func);
}

template <class Machine>
void InstX86Shld<Machine>::emitIAS(const Cfg *Func) const {
  assert(this->getSrcSize() == 3);
  assert(this->getDest() == this->getSrc(0));
  const Variable *Dest = this->getDest();
  const Operand *Src1 = this->getSrc(1);
  const Operand *Src2 = this->getSrc(2);
  static const typename InstX86Base<
      Machine>::Traits::Assembler::GPREmitterShiftD Emitter = {
      &InstX86Base<Machine>::Traits::Assembler::shld,
      &InstX86Base<Machine>::Traits::Assembler::shld};
  emitIASGPRShiftDouble<Machine>(Func, Dest, Src1, Src2, Emitter);
}

template <class Machine>
void InstX86Shld<Machine>::dump(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  this->dumpDest(Func);
  Str << " = shld." << this->getDest()->getType() << " ";
  this->dumpSources(Func);
}

template <class Machine>
void InstX86Shrd<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  Variable *Dest = this->getDest();
  assert(this->getSrcSize() == 3);
  assert(Dest == this->getSrc(0));
  Str << "\tshrd" << this->getWidthString(Dest->getType()) << "\t";
  this->getSrc(2)->emit(Func);
  Str << ", ";
  this->getSrc(1)->emit(Func);
  Str << ", ";
  Dest->emit(Func);
}

template <class Machine>
void InstX86Shrd<Machine>::emitIAS(const Cfg *Func) const {
  assert(this->getSrcSize() == 3);
  assert(this->getDest() == this->getSrc(0));
  const Variable *Dest = this->getDest();
  const Operand *Src1 = this->getSrc(1);
  const Operand *Src2 = this->getSrc(2);
  static const typename InstX86Base<
      Machine>::Traits::Assembler::GPREmitterShiftD Emitter = {
      &InstX86Base<Machine>::Traits::Assembler::shrd,
      &InstX86Base<Machine>::Traits::Assembler::shrd};
  emitIASGPRShiftDouble<Machine>(Func, Dest, Src1, Src2, Emitter);
}

template <class Machine>
void InstX86Shrd<Machine>::dump(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  this->dumpDest(Func);
  Str << " = shrd." << this->getDest()->getType() << " ";
  this->dumpSources(Func);
}

template <class Machine>
void InstX86Cmov<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  Variable *Dest = this->getDest();
  Str << "\t";
  assert(Condition != InstX86Base<Machine>::Traits::Cond::Br_None);
  assert(this->getDest()->hasReg());
  Str << "cmov"
      << InstX86Base<Machine>::Traits::InstBrAttributes[Condition].DisplayString
      << this->getWidthString(Dest->getType()) << "\t";
  this->getSrc(1)->emit(Func);
  Str << ", ";
  Dest->emit(Func);
}

template <class Machine>
void InstX86Cmov<Machine>::emitIAS(const Cfg *Func) const {
  assert(Condition != InstX86Base<Machine>::Traits::Cond::Br_None);
  assert(this->getDest()->hasReg());
  assert(this->getSrcSize() == 2);
  Operand *Src = this->getSrc(1);
  Type SrcTy = Src->getType();
  assert(SrcTy == IceType_i16 || SrcTy == IceType_i32 ||
         (InstX86Base<Machine>::Traits::Is64Bit));
  typename InstX86Base<Machine>::Traits::Assembler *Asm =
      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
  auto *Target = InstX86Base<Machine>::getTarget(Func);
  if (const auto *SrcVar = llvm::dyn_cast<Variable>(Src)) {
    if (SrcVar->hasReg()) {
      Asm->cmov(
          SrcTy, Condition, InstX86Base<Machine>::Traits::getEncodedGPR(
                                this->getDest()->getRegNum()),
          InstX86Base<Machine>::Traits::getEncodedGPR(SrcVar->getRegNum()));
    } else {
      Asm->cmov(SrcTy, Condition, InstX86Base<Machine>::Traits::getEncodedGPR(
                                      this->getDest()->getRegNum()),
                Target->stackVarToAsmOperand(SrcVar));
    }
  } else if (const auto *Mem = llvm::dyn_cast<
                 typename InstX86Base<Machine>::Traits::X86OperandMem>(Src)) {
    assert(Mem->getSegmentRegister() ==
           InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment);
    Asm->cmov(SrcTy, Condition, InstX86Base<Machine>::Traits::getEncodedGPR(
                                    this->getDest()->getRegNum()),
              Mem->toAsmAddress(Asm, Target));
  } else {
    llvm_unreachable("Unexpected operand type");
  }
}

template <class Machine>
void InstX86Cmov<Machine>::dump(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  Str << "cmov"
      << InstX86Base<Machine>::Traits::InstBrAttributes[Condition].DisplayString
      << ".";
  Str << this->getDest()->getType() << " ";
  this->dumpDest(Func);
  Str << ", ";
  this->dumpSources(Func);
}

template <class Machine>
void InstX86Cmpps<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(this->getSrcSize() == 2);
  assert(Condition < InstX86Base<Machine>::Traits::Cond::Cmpps_Invalid);
  Str << "\t";
  Str << "cmp"
      << InstX86Base<Machine>::Traits::InstCmppsAttributes[Condition].EmitString
      << "ps"
      << "\t";
  this->getSrc(1)->emit(Func);
  Str << ", ";
  this->getDest()->emit(Func);
}

template <class Machine>
void InstX86Cmpps<Machine>::emitIAS(const Cfg *Func) const {
  typename InstX86Base<Machine>::Traits::Assembler *Asm =
      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
  assert(this->getSrcSize() == 2);
  assert(Condition < InstX86Base<Machine>::Traits::Cond::Cmpps_Invalid);
  // Assuming there isn't any load folding for cmpps, and vector constants are
  // not allowed in PNaCl.
  assert(llvm::isa<Variable>(this->getSrc(1)));
  auto *Target = InstX86Base<Machine>::getTarget(Func);
  const auto *SrcVar = llvm::cast<Variable>(this->getSrc(1));
  if (SrcVar->hasReg()) {
    Asm->cmpps(InstX86Base<Machine>::Traits::getEncodedXmm(
                   this->getDest()->getRegNum()),
               InstX86Base<Machine>::Traits::getEncodedXmm(SrcVar->getRegNum()),
               Condition);
  } else {
    typename InstX86Base<Machine>::Traits::Address SrcStackAddr =
        Target->stackVarToAsmOperand(SrcVar);
    Asm->cmpps(InstX86Base<Machine>::Traits::getEncodedXmm(
                   this->getDest()->getRegNum()),
               SrcStackAddr, Condition);
  }
}

template <class Machine>
void InstX86Cmpps<Machine>::dump(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  assert(Condition < InstX86Base<Machine>::Traits::Cond::Cmpps_Invalid);
  this->dumpDest(Func);
  Str << " = cmp"
      << InstX86Base<Machine>::Traits::InstCmppsAttributes[Condition].EmitString
      << "ps"
      << "\t";
  this->dumpSources(Func);
}

template <class Machine>
void InstX86Cmpxchg<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(this->getSrcSize() == 3);
  if (this->Locked) {
    Str << "\tlock";
  }
  Str << "\tcmpxchg" << this->getWidthString(this->getSrc(0)->getType())
      << "\t";
  this->getSrc(2)->emit(Func);
  Str << ", ";
  this->getSrc(0)->emit(Func);
}

template <class Machine>
void InstX86Cmpxchg<Machine>::emitIAS(const Cfg *Func) const {
  assert(this->getSrcSize() == 3);
  typename InstX86Base<Machine>::Traits::Assembler *Asm =
      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
  Type Ty = this->getSrc(0)->getType();
  auto *Target = InstX86Base<Machine>::getTarget(Func);
  const auto Mem =
      llvm::cast<typename InstX86Base<Machine>::Traits::X86OperandMem>(
          this->getSrc(0));
  assert(Mem->getSegmentRegister() ==
         InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment);
  const typename InstX86Base<Machine>::Traits::Address Addr =
      Mem->toAsmAddress(Asm, Target);
  const auto *VarReg = llvm::cast<Variable>(this->getSrc(2));
  assert(VarReg->hasReg());
  const typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister Reg =
      InstX86Base<Machine>::Traits::getEncodedGPR(VarReg->getRegNum());
  Asm->cmpxchg(Ty, Addr, Reg, this->Locked);
}

template <class Machine>
void InstX86Cmpxchg<Machine>::dump(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  if (this->Locked) {
    Str << "lock ";
  }
  Str << "cmpxchg." << this->getSrc(0)->getType() << " ";
  this->dumpSources(Func);
}

template <class Machine>
void InstX86Cmpxchg8b<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(this->getSrcSize() == 5);
  if (this->Locked) {
    Str << "\tlock";
  }
  Str << "\tcmpxchg8b\t";
  this->getSrc(0)->emit(Func);
}

template <class Machine>
void InstX86Cmpxchg8b<Machine>::emitIAS(const Cfg *Func) const {
  assert(this->getSrcSize() == 5);
  typename InstX86Base<Machine>::Traits::Assembler *Asm =
      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
  const auto Mem =
      llvm::cast<typename InstX86Base<Machine>::Traits::X86OperandMem>(
          this->getSrc(0));
  assert(Mem->getSegmentRegister() ==
         InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment);
  auto *Target = InstX86Base<Machine>::getTarget(Func);
  const typename InstX86Base<Machine>::Traits::Address Addr =
      Mem->toAsmAddress(Asm, Target);
  Asm->cmpxchg8b(Addr, this->Locked);
}

template <class Machine>
void InstX86Cmpxchg8b<Machine>::dump(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  if (this->Locked) {
    Str << "lock ";
  }
  Str << "cmpxchg8b ";
  this->dumpSources(Func);
}

template <class Machine> void InstX86Cvt<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(this->getSrcSize() == 1);
  Str << "\tcvt";
  if (isTruncating())
    Str << "t";
  Str << InstX86Base<Machine>::Traits::TypeAttributes[this->getSrc(0)
                                                          ->getType()]
             .CvtString << "2"
      << InstX86Base<
             Machine>::Traits::TypeAttributes[this->getDest()->getType()]
             .CvtString << "\t";
  this->getSrc(0)->emit(Func);
  Str << ", ";
  this->getDest()->emit(Func);
}

template <class Machine>
void InstX86Cvt<Machine>::emitIAS(const Cfg *Func) const {
  assert(this->getSrcSize() == 1);
  const Variable *Dest = this->getDest();
  const Operand *Src = this->getSrc(0);
  Type DestTy = Dest->getType();
  Type SrcTy = Src->getType();
  switch (Variant) {
  case Si2ss: {
    assert(isScalarIntegerType(SrcTy));
    if (!InstX86Base<Machine>::Traits::Is64Bit) {
      assert(typeWidthInBytes(SrcTy) <= 4);
    } else {
      assert(SrcTy == IceType_i32 || SrcTy == IceType_i64);
    }
    assert(isScalarFloatingType(DestTy));
    static const typename InstX86Base<Machine>::Traits::Assembler::
        template CastEmitterRegOp<
            typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
            typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister>
            Emitter = {&InstX86Base<Machine>::Traits::Assembler::cvtsi2ss,
                       &InstX86Base<Machine>::Traits::Assembler::cvtsi2ss};
    emitIASCastRegOp<
        Machine,
        typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
        typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister,
        InstX86Base<Machine>::Traits::getEncodedXmm,
        InstX86Base<Machine>::Traits::getEncodedGPR>(Func, DestTy, Dest, SrcTy,
                                                     Src, Emitter);
    return;
  }
  case Tss2si: {
    assert(isScalarFloatingType(SrcTy));
    assert(isScalarIntegerType(DestTy));
    if (!InstX86Base<Machine>::Traits::Is64Bit) {
      assert(typeWidthInBytes(DestTy) <= 4);
    } else {
      assert(DestTy == IceType_i32 || DestTy == IceType_i64);
    }
    static const typename InstX86Base<Machine>::Traits::Assembler::
        template CastEmitterRegOp<
            typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister,
            typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister>
            Emitter = {&InstX86Base<Machine>::Traits::Assembler::cvttss2si,
                       &InstX86Base<Machine>::Traits::Assembler::cvttss2si};
    emitIASCastRegOp<
        Machine,
        typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister,
        typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
        InstX86Base<Machine>::Traits::getEncodedGPR,
        InstX86Base<Machine>::Traits::getEncodedXmm>(Func, DestTy, Dest, SrcTy,
                                                     Src, Emitter);
    return;
  }
  case Float2float: {
    assert(isScalarFloatingType(SrcTy));
    assert(isScalarFloatingType(DestTy));
    assert(DestTy != SrcTy);
    static const typename InstX86Base<
        Machine>::Traits::Assembler::XmmEmitterRegOp Emitter = {
        &InstX86Base<Machine>::Traits::Assembler::cvtfloat2float,
        &InstX86Base<Machine>::Traits::Assembler::cvtfloat2float};
    emitIASRegOpTyXMM<Machine>(Func, SrcTy, Dest, Src, Emitter);
    return;
  }
  case Dq2ps: {
    assert(isVectorIntegerType(SrcTy));
    assert(isVectorFloatingType(DestTy));
    static const typename InstX86Base<
        Machine>::Traits::Assembler::XmmEmitterRegOp Emitter = {
        &InstX86Base<Machine>::Traits::Assembler::cvtdq2ps,
        &InstX86Base<Machine>::Traits::Assembler::cvtdq2ps};
    emitIASRegOpTyXMM<Machine>(Func, DestTy, Dest, Src, Emitter);
    return;
  }
  case Tps2dq: {
    assert(isVectorFloatingType(SrcTy));
    assert(isVectorIntegerType(DestTy));
    static const typename InstX86Base<
        Machine>::Traits::Assembler::XmmEmitterRegOp Emitter = {
        &InstX86Base<Machine>::Traits::Assembler::cvttps2dq,
        &InstX86Base<Machine>::Traits::Assembler::cvttps2dq};
    emitIASRegOpTyXMM<Machine>(Func, DestTy, Dest, Src, Emitter);
    return;
  }
  }
}

template <class Machine> void InstX86Cvt<Machine>::dump(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  this->dumpDest(Func);
  Str << " = cvt";
  if (isTruncating())
    Str << "t";
  Str << InstX86Base<Machine>::Traits::TypeAttributes[this->getSrc(0)
                                                          ->getType()]
             .CvtString << "2"
      << InstX86Base<
             Machine>::Traits::TypeAttributes[this->getDest()->getType()]
             .CvtString << " ";
  this->dumpSources(Func);
}

template <class Machine>
void InstX86Icmp<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(this->getSrcSize() == 2);
  Str << "\tcmp" << this->getWidthString(this->getSrc(0)->getType()) << "\t";
  this->getSrc(1)->emit(Func);
  Str << ", ";
  this->getSrc(0)->emit(Func);
}

template <class Machine>
void InstX86Icmp<Machine>::emitIAS(const Cfg *Func) const {
  assert(this->getSrcSize() == 2);
  const Operand *Src0 = this->getSrc(0);
  const Operand *Src1 = this->getSrc(1);
  Type Ty = Src0->getType();
  static const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterRegOp
      RegEmitter = {&InstX86Base<Machine>::Traits::Assembler::cmp,
                    &InstX86Base<Machine>::Traits::Assembler::cmp,
                    &InstX86Base<Machine>::Traits::Assembler::cmp};
  static const typename InstX86Base<
      Machine>::Traits::Assembler::GPREmitterAddrOp AddrEmitter = {
      &InstX86Base<Machine>::Traits::Assembler::cmp,
      &InstX86Base<Machine>::Traits::Assembler::cmp};
  if (const auto *SrcVar0 = llvm::dyn_cast<Variable>(Src0)) {
    if (SrcVar0->hasReg()) {
      emitIASRegOpTyGPR<Machine>(Func, Ty, SrcVar0, Src1, RegEmitter);
      return;
    }
  }
  emitIASAsAddrOpTyGPR<Machine>(Func, Ty, Src0, Src1, AddrEmitter);
}

template <class Machine>
void InstX86Icmp<Machine>::dump(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  Str << "cmp." << this->getSrc(0)->getType() << " ";
  this->dumpSources(Func);
}

template <class Machine>
void InstX86Ucomiss<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(this->getSrcSize() == 2);
  Str << "\tucomi"
      << InstX86Base<Machine>::Traits::TypeAttributes[this->getSrc(0)
                                                          ->getType()]
             .SdSsString << "\t";
  this->getSrc(1)->emit(Func);
  Str << ", ";
  this->getSrc(0)->emit(Func);
}

template <class Machine>
void InstX86Ucomiss<Machine>::emitIAS(const Cfg *Func) const {
  assert(this->getSrcSize() == 2);
  // Currently src0 is always a variable by convention, to avoid having two
  // memory operands.
  assert(llvm::isa<Variable>(this->getSrc(0)));
  const auto *Src0Var = llvm::cast<Variable>(this->getSrc(0));
  Type Ty = Src0Var->getType();
  static const typename InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp
      Emitter = {&InstX86Base<Machine>::Traits::Assembler::ucomiss,
                 &InstX86Base<Machine>::Traits::Assembler::ucomiss};
  emitIASRegOpTyXMM<Machine>(Func, Ty, Src0Var, this->getSrc(1), Emitter);
}

template <class Machine>
void InstX86Ucomiss<Machine>::dump(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  Str << "ucomiss." << this->getSrc(0)->getType() << " ";
  this->dumpSources(Func);
}

template <class Machine> void InstX86UD2<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(this->getSrcSize() == 0);
  Str << "\tud2";
}

template <class Machine>
void InstX86UD2<Machine>::emitIAS(const Cfg *Func) const {
  typename InstX86Base<Machine>::Traits::Assembler *Asm =
      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
  Asm->ud2();
}

template <class Machine> void InstX86UD2<Machine>::dump(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  Str << "ud2";
}

template <class Machine>
void InstX86Test<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(this->getSrcSize() == 2);
  Str << "\ttest" << this->getWidthString(this->getSrc(0)->getType()) << "\t";
  this->getSrc(1)->emit(Func);
  Str << ", ";
  this->getSrc(0)->emit(Func);
}

template <class Machine>
void InstX86Test<Machine>::emitIAS(const Cfg *Func) const {
  assert(this->getSrcSize() == 2);
  const Operand *Src0 = this->getSrc(0);
  const Operand *Src1 = this->getSrc(1);
  Type Ty = Src0->getType();
  // The Reg/Addr form of test is not encodeable.
  static const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterRegOp
      RegEmitter = {&InstX86Base<Machine>::Traits::Assembler::test, nullptr,
                    &InstX86Base<Machine>::Traits::Assembler::test};
  static const typename InstX86Base<
      Machine>::Traits::Assembler::GPREmitterAddrOp AddrEmitter = {
      &InstX86Base<Machine>::Traits::Assembler::test,
      &InstX86Base<Machine>::Traits::Assembler::test};
  if (const auto *SrcVar0 = llvm::dyn_cast<Variable>(Src0)) {
    if (SrcVar0->hasReg()) {
      emitIASRegOpTyGPR<Machine>(Func, Ty, SrcVar0, Src1, RegEmitter);
      return;
    }
  }
  emitIASAsAddrOpTyGPR<Machine>(Func, Ty, Src0, Src1, AddrEmitter);
}

template <class Machine>
void InstX86Test<Machine>::dump(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  Str << "test." << this->getSrc(0)->getType() << " ";
  this->dumpSources(Func);
}

template <class Machine>
void InstX86Mfence<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(this->getSrcSize() == 0);
  Str << "\tmfence";
}

template <class Machine>
void InstX86Mfence<Machine>::emitIAS(const Cfg *Func) const {
  typename InstX86Base<Machine>::Traits::Assembler *Asm =
      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
  Asm->mfence();
}

template <class Machine>
void InstX86Mfence<Machine>::dump(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  Str << "mfence";
}

template <class Machine>
void InstX86Store<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(this->getSrcSize() == 2);
  Type Ty = this->getSrc(0)->getType();
  Str << "\tmov" << this->getWidthString(Ty)
      << InstX86Base<Machine>::Traits::TypeAttributes[Ty].SdSsString << "\t";
  this->getSrc(0)->emit(Func);
  Str << ", ";
  this->getSrc(1)->emit(Func);
}

template <class Machine>
void InstX86Store<Machine>::emitIAS(const Cfg *Func) const {
  assert(this->getSrcSize() == 2);
  const Operand *Dest = this->getSrc(1);
  const Operand *Src = this->getSrc(0);
  Type DestTy = Dest->getType();
  if (isScalarFloatingType(DestTy)) {
    // Src must be a register, since Dest is a Mem operand of some kind.
    const auto *SrcVar = llvm::cast<Variable>(Src);
    assert(SrcVar->hasReg());
    typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister SrcReg =
        InstX86Base<Machine>::Traits::getEncodedXmm(SrcVar->getRegNum());
    typename InstX86Base<Machine>::Traits::Assembler *Asm =
        Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
    auto *Target = InstX86Base<Machine>::getTarget(Func);
    if (const auto *DestVar = llvm::dyn_cast<Variable>(Dest)) {
      assert(!DestVar->hasReg());
      typename InstX86Base<Machine>::Traits::Address StackAddr(
          Target->stackVarToAsmOperand(DestVar));
      Asm->movss(DestTy, StackAddr, SrcReg);
    } else {
      const auto DestMem =
          llvm::cast<typename InstX86Base<Machine>::Traits::X86OperandMem>(
              Dest);
      assert(DestMem->getSegmentRegister() ==
             InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment);
      Asm->movss(DestTy, DestMem->toAsmAddress(Asm, Target), SrcReg);
    }
    return;
  } else {
    assert(isScalarIntegerType(DestTy));
    static const typename InstX86Base<
        Machine>::Traits::Assembler::GPREmitterAddrOp GPRAddrEmitter = {
        &InstX86Base<Machine>::Traits::Assembler::mov,
        &InstX86Base<Machine>::Traits::Assembler::mov};
    emitIASAsAddrOpTyGPR<Machine>(Func, DestTy, Dest, Src, GPRAddrEmitter);
  }
}

template <class Machine>
void InstX86Store<Machine>::dump(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  Str << "mov." << this->getSrc(0)->getType() << " ";
  this->getSrc(1)->dump(Func);
  Str << ", ";
  this->getSrc(0)->dump(Func);
}

template <class Machine>
void InstX86StoreP<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(this->getSrcSize() == 2);
  assert(isVectorType(this->getSrc(1)->getType()));
  Str << "\tmovups\t";
  this->getSrc(0)->emit(Func);
  Str << ", ";
  this->getSrc(1)->emit(Func);
}

template <class Machine>
void InstX86StoreP<Machine>::emitIAS(const Cfg *Func) const {
  typename InstX86Base<Machine>::Traits::Assembler *Asm =
      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
  assert(this->getSrcSize() == 2);
  const auto *SrcVar = llvm::cast<Variable>(this->getSrc(0));
  const auto DestMem =
      llvm::cast<typename InstX86Base<Machine>::Traits::X86OperandMem>(
          this->getSrc(1));
  assert(DestMem->getSegmentRegister() ==
         InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment);
  assert(SrcVar->hasReg());
  auto *Target = InstX86Base<Machine>::getTarget(Func);
  Asm->movups(DestMem->toAsmAddress(Asm, Target),
              InstX86Base<Machine>::Traits::getEncodedXmm(SrcVar->getRegNum()));
}

template <class Machine>
void InstX86StoreP<Machine>::dump(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  Str << "storep." << this->getSrc(0)->getType() << " ";
  this->getSrc(1)->dump(Func);
  Str << ", ";
  this->getSrc(0)->dump(Func);
}

template <class Machine>
void InstX86StoreQ<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(this->getSrcSize() == 2);
  assert(this->getSrc(1)->getType() == IceType_i64 ||
         this->getSrc(1)->getType() == IceType_f64 ||
         isVectorType(this->getSrc(1)->getType()));
  Str << "\tmovq\t";
  this->getSrc(0)->emit(Func);
  Str << ", ";
  this->getSrc(1)->emit(Func);
}

template <class Machine>
void InstX86StoreQ<Machine>::emitIAS(const Cfg *Func) const {
  typename InstX86Base<Machine>::Traits::Assembler *Asm =
      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
  assert(this->getSrcSize() == 2);
  const auto *SrcVar = llvm::cast<Variable>(this->getSrc(0));
  const auto DestMem =
      llvm::cast<typename InstX86Base<Machine>::Traits::X86OperandMem>(
          this->getSrc(1));
  assert(DestMem->getSegmentRegister() ==
         InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment);
  assert(SrcVar->hasReg());
  auto *Target = InstX86Base<Machine>::getTarget(Func);
  Asm->movq(DestMem->toAsmAddress(Asm, Target),
            InstX86Base<Machine>::Traits::getEncodedXmm(SrcVar->getRegNum()));
}

template <class Machine>
void InstX86StoreQ<Machine>::dump(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  Str << "storeq." << this->getSrc(0)->getType() << " ";
  this->getSrc(1)->dump(Func);
  Str << ", ";
  this->getSrc(0)->dump(Func);
}

template <class Machine> void InstX86Lea<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(this->getSrcSize() == 1);
  assert(this->getDest()->hasReg());
  Str << "\tleal\t";
  Operand *Src0 = this->getSrc(0);
  if (const auto *Src0Var = llvm::dyn_cast<Variable>(Src0)) {
    Type Ty = Src0Var->getType();
    // lea on x86-32 doesn't accept mem128 operands, so cast VSrc0 to an
    // acceptable type.
    Src0Var->asType(isVectorType(Ty) ? IceType_i32 : Ty, Variable::NoRegister)
        ->emit(Func);
  } else {
    Src0->emit(Func);
  }
  Str << ", ";
  this->getDest()->emit(Func);
}

inline bool isIntegerConstant(const Operand *Op) {
  return llvm::isa<ConstantInteger32>(Op) || llvm::isa<ConstantInteger64>(Op);
}

template <class Machine> void InstX86Mov<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(this->getSrcSize() == 1);
  Operand *Src = this->getSrc(0);
  Type SrcTy = Src->getType();
  Type DestTy = this->getDest()->getType();
  if (InstX86Base<Machine>::Traits::Is64Bit && DestTy == IceType_i64 &&
      isIntegerConstant(Src)) {
    Str << "\tmovabs\t";
  } else {
    Str << "\tmov"
        << (!isScalarFloatingType(DestTy)
                ? this->getWidthString(DestTy)
                : InstX86Base<Machine>::Traits::TypeAttributes[DestTy]
                      .SdSsString) << "\t";
  }
  // For an integer truncation operation, src is wider than dest. In this case,
  // we use a mov instruction whose data width matches the narrower dest.
  // 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(
      InstX86Base<Machine>::getTarget(Func)->typeWidthInBytesOnStack(DestTy) ==
      InstX86Base<Machine>::getTarget(Func)->typeWidthInBytesOnStack(SrcTy));
  const Operand *NewSrc = Src;
  if (auto *SrcVar = llvm::dyn_cast<Variable>(Src)) {
    int32_t NewRegNum = Variable::NoRegister;
    if (SrcVar->hasReg())
      NewRegNum = InstX86Base<Machine>::Traits::getGprForType(
          DestTy, SrcVar->getRegNum());
    if (SrcTy != DestTy)
      NewSrc = SrcVar->asType(DestTy, NewRegNum);
  }
  NewSrc->emit(Func);
  Str << ", ";
  this->getDest()->emit(Func);
}

template <class Machine>
void InstX86Mov<Machine>::emitIAS(const Cfg *Func) const {
  assert(this->getSrcSize() == 1);
  const Variable *Dest = this->getDest();
  const Operand *Src = this->getSrc(0);
  Type DestTy = Dest->getType();
  Type SrcTy = Src->getType();
  // Mov can be used for GPRs or XMM registers. Also, the type does not
  // necessarily match (Mov can be used for bitcasts). However, when the type
  // does not match, one of the operands must be a register. Thus, the strategy
  // is to find out if Src or Dest are a register, then use that register's
  // type to decide on which emitter set to use. The emitter set will include
  // reg-reg movs, but that case should be unused when the types don't match.
  static const typename InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp
      XmmRegEmitter = {&InstX86Base<Machine>::Traits::Assembler::movss,
                       &InstX86Base<Machine>::Traits::Assembler::movss};
  static const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterRegOp
      GPRRegEmitter = {&InstX86Base<Machine>::Traits::Assembler::mov,
                       &InstX86Base<Machine>::Traits::Assembler::mov,
                       &InstX86Base<Machine>::Traits::Assembler::mov};
  static const typename InstX86Base<
      Machine>::Traits::Assembler::GPREmitterAddrOp GPRAddrEmitter = {
      &InstX86Base<Machine>::Traits::Assembler::mov,
      &InstX86Base<Machine>::Traits::Assembler::mov};
  // For an integer truncation operation, src is wider than dest. In this case,
  // we use a mov instruction whose data width matches the narrower dest.
  // 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.
  auto *Target = InstX86Base<Machine>::getTarget(Func);
  assert(Target->typeWidthInBytesOnStack(this->getDest()->getType()) ==
         Target->typeWidthInBytesOnStack(Src->getType()));
  if (Dest->hasReg()) {
    if (isScalarFloatingType(DestTy)) {
      emitIASRegOpTyXMM<Machine>(Func, DestTy, Dest, Src, XmmRegEmitter);
      return;
    } else {
      assert(isScalarIntegerType(DestTy));
      // Widen DestTy for truncation (see above note). We should only do this
      // when both Src and Dest are integer types.
      if (InstX86Base<Machine>::Traits::Is64Bit && DestTy == IceType_i64 &&
          isIntegerConstant(Src)) {
        uint64_t Value = -1;
        if (const auto *C64 = llvm::dyn_cast<ConstantInteger64>(Src)) {
          Value = C64->getValue();
        } else {
          Value = llvm::cast<ConstantInteger32>(Src)->getValue();
        }
        Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>()
            ->movabs(
                InstX86Base<Machine>::Traits::getEncodedGPR(Dest->getRegNum()),
                Value);
        return;
      }
      if (isScalarIntegerType(SrcTy)) {
        SrcTy = DestTy;
      }
      emitIASRegOpTyGPR<Machine>(Func, DestTy, Dest, Src, GPRRegEmitter);
      return;
    }
  } else {
    // Dest must be Stack and Src *could* be a register. Use Src's type to
    // decide on the emitters.
    typename InstX86Base<Machine>::Traits::Address StackAddr(
        Target->stackVarToAsmOperand(Dest));
    if (isScalarFloatingType(SrcTy)) {
      // Src must be a register.
      const auto *SrcVar = llvm::cast<Variable>(Src);
      assert(SrcVar->hasReg());
      typename InstX86Base<Machine>::Traits::Assembler *Asm =
          Func->getAssembler<
              typename InstX86Base<Machine>::Traits::Assembler>();
      Asm->movss(SrcTy, StackAddr, InstX86Base<Machine>::Traits::getEncodedXmm(
                                       SrcVar->getRegNum()));
      return;
    } else {
      // Src can be a register or immediate.
      assert(isScalarIntegerType(SrcTy));
      emitIASAddrOpTyGPR<Machine>(Func, SrcTy, StackAddr, Src, GPRAddrEmitter);
      return;
    }
    return;
  }
}

template <class Machine>
void InstX86Movd<Machine>::emitIAS(const Cfg *Func) const {
  typename InstX86Base<Machine>::Traits::Assembler *Asm =
      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
  assert(this->getSrcSize() == 1);
  const Variable *Dest = this->getDest();
  const auto *SrcVar = llvm::cast<Variable>(this->getSrc(0));
  auto *Target = InstX86Base<Machine>::getTarget(Func);
  // For insert/extract element (one of Src/Dest is an Xmm vector and the other
  // is an int type).
  if (SrcVar->getType() == IceType_i32 ||
      (InstX86Base<Machine>::Traits::Is64Bit &&
       SrcVar->getType() == IceType_i64)) {
    assert(isVectorType(Dest->getType()) ||
           (isScalarFloatingType(Dest->getType()) &&
            typeWidthInBytes(SrcVar->getType()) ==
                typeWidthInBytes(Dest->getType())));
    assert(Dest->hasReg());
    typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister DestReg =
        InstX86Base<Machine>::Traits::getEncodedXmm(Dest->getRegNum());
    if (SrcVar->hasReg()) {
      Asm->movd(
          SrcVar->getType(), DestReg,
          InstX86Base<Machine>::Traits::getEncodedGPR(SrcVar->getRegNum()));
    } else {
      typename InstX86Base<Machine>::Traits::Address StackAddr(
          Target->stackVarToAsmOperand(SrcVar));
      Asm->movd(SrcVar->getType(), DestReg, StackAddr);
    }
  } else {
    assert(isVectorType(SrcVar->getType()) ||
           (isScalarFloatingType(SrcVar->getType()) &&
            typeWidthInBytes(SrcVar->getType()) ==
                typeWidthInBytes(Dest->getType())));
    assert(SrcVar->hasReg());
    assert(Dest->getType() == IceType_i32 ||
           (InstX86Base<Machine>::Traits::Is64Bit &&
            Dest->getType() == IceType_i64));
    typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister SrcReg =
        InstX86Base<Machine>::Traits::getEncodedXmm(SrcVar->getRegNum());
    if (Dest->hasReg()) {
      Asm->movd(Dest->getType(),
                InstX86Base<Machine>::Traits::getEncodedGPR(Dest->getRegNum()),
                SrcReg);
    } else {
      typename InstX86Base<Machine>::Traits::Address StackAddr(
          Target->stackVarToAsmOperand(Dest));
      Asm->movd(Dest->getType(), StackAddr, SrcReg);
    }
  }
}

template <class Machine>
void InstX86Movp<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  // TODO(wala,stichnot): movups works with all vector operands, but there
  // exist other instructions (movaps, movdqa, movdqu) that may perform better,
  // depending on the data type and alignment of the operands.
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(this->getSrcSize() == 1);
  Str << "\tmovups\t";
  this->getSrc(0)->emit(Func);
  Str << ", ";
  this->getDest()->emit(Func);
}

template <class Machine>
void InstX86Movp<Machine>::emitIAS(const Cfg *Func) const {
  assert(this->getSrcSize() == 1);
  assert(isVectorType(this->getDest()->getType()));
  const Variable *Dest = this->getDest();
  const Operand *Src = this->getSrc(0);
  static const typename InstX86Base<
      Machine>::Traits::Assembler::XmmEmitterMovOps Emitter = {
      &InstX86Base<Machine>::Traits::Assembler::movups,
      &InstX86Base<Machine>::Traits::Assembler::movups,
      &InstX86Base<Machine>::Traits::Assembler::movups};
  emitIASMovlikeXMM<Machine>(Func, Dest, Src, Emitter);
}

template <class Machine>
void InstX86Movq<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(this->getSrcSize() == 1);
  assert(this->getDest()->getType() == IceType_i64 ||
         this->getDest()->getType() == IceType_f64);
  Str << "\tmovq\t";
  this->getSrc(0)->emit(Func);
  Str << ", ";
  this->getDest()->emit(Func);
}

template <class Machine>
void InstX86Movq<Machine>::emitIAS(const Cfg *Func) const {
  assert(this->getSrcSize() == 1);
  assert(this->getDest()->getType() == IceType_i64 ||
         this->getDest()->getType() == IceType_f64);
  const Variable *Dest = this->getDest();
  const Operand *Src = this->getSrc(0);
  static const typename InstX86Base<
      Machine>::Traits::Assembler::XmmEmitterMovOps Emitter = {
      &InstX86Base<Machine>::Traits::Assembler::movq,
      &InstX86Base<Machine>::Traits::Assembler::movq,
      &InstX86Base<Machine>::Traits::Assembler::movq};
  emitIASMovlikeXMM<Machine>(Func, Dest, Src, Emitter);
}

template <class Machine>
void InstX86MovssRegs<Machine>::emitIAS(const Cfg *Func) const {
  // This is Binop variant is only intended to be used for reg-reg moves where
  // part of the Dest register is untouched.
  assert(this->getSrcSize() == 2);
  const Variable *Dest = this->getDest();
  assert(Dest == this->getSrc(0));
  const auto *SrcVar = llvm::cast<Variable>(this->getSrc(1));
  assert(Dest->hasReg() && SrcVar->hasReg());
  typename InstX86Base<Machine>::Traits::Assembler *Asm =
      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
  Asm->movss(IceType_f32,
             InstX86Base<Machine>::Traits::getEncodedXmm(Dest->getRegNum()),
             InstX86Base<Machine>::Traits::getEncodedXmm(SrcVar->getRegNum()));
}

template <class Machine>
void InstX86Movsx<Machine>::emitIAS(const Cfg *Func) const {
  assert(this->getSrcSize() == 1);
  const Variable *Dest = this->getDest();
  const Operand *Src = this->getSrc(0);
  // Dest must be a > 8-bit register, but Src can be 8-bit. In practice we just
  // use the full register for Dest to avoid having an OperandSizeOverride
  // prefix. It also allows us to only dispatch on SrcTy.
  Type SrcTy = Src->getType();
  assert(typeWidthInBytes(Dest->getType()) > 1);
  assert(typeWidthInBytes(Dest->getType()) > typeWidthInBytes(SrcTy));
  emitIASRegOpTyGPR<Machine, false, true>(Func, SrcTy, Dest, Src,
                                          this->Emitter);
}

template <class Machine>
void InstX86Movzx<Machine>::emitIAS(const Cfg *Func) const {
  assert(this->getSrcSize() == 1);
  const Variable *Dest = this->getDest();
  const Operand *Src = this->getSrc(0);
  Type SrcTy = Src->getType();
  assert(typeWidthInBytes(Dest->getType()) > 1);
  assert(typeWidthInBytes(Dest->getType()) > typeWidthInBytes(SrcTy));
  emitIASRegOpTyGPR<Machine, false, true>(Func, SrcTy, Dest, Src,
                                          this->Emitter);
}

template <class Machine> void InstX86Nop<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  // TODO: Emit the right code for each variant.
  Str << "\tnop\t# variant = " << Variant;
}

template <class Machine>
void InstX86Nop<Machine>::emitIAS(const Cfg *Func) const {
  typename InstX86Base<Machine>::Traits::Assembler *Asm =
      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
  // TODO: Emit the right code for the variant.
  Asm->nop();
}

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

template <class Machine> void InstX86Fld<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(this->getSrcSize() == 1);
  Type Ty = this->getSrc(0)->getType();
  const auto *Var = llvm::dyn_cast<Variable>(this->getSrc(0));
  if (Var && Var->hasReg()) {
    // This is a physical xmm register, so we need to spill it to a temporary
    // stack slot.  Function prolog emission guarantees that there is sufficient
    // space to do this.
    Str << "\tmov"
        << InstX86Base<Machine>::Traits::TypeAttributes[Ty].SdSsString << "\t";
    Var->emit(Func);
    Str << ", (%esp)\n";
    Str << "\tfld" << this->getFldString(Ty) << "\t"
        << "(%esp)";
    return;
  }
  Str << "\tfld" << this->getFldString(Ty) << "\t";
  this->getSrc(0)->emit(Func);
}

template <class Machine>
void InstX86Fld<Machine>::emitIAS(const Cfg *Func) const {
  typename InstX86Base<Machine>::Traits::Assembler *Asm =
      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
  assert(this->getSrcSize() == 1);
  const Operand *Src = this->getSrc(0);
  auto *Target = InstX86Base<Machine>::getTarget(Func);
  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.  Function prolog emission guarantees that there is
      // sufficient space to do this.
      typename InstX86Base<Machine>::Traits::Address StackSlot =
          typename InstX86Base<Machine>::Traits::Address(
              InstX86Base<Machine>::Traits::RegisterSet::Encoded_Reg_esp, 0,
              AssemblerFixup::NoFixup);
      Asm->movss(Ty, StackSlot,
                 InstX86Base<Machine>::Traits::getEncodedXmm(Var->getRegNum()));
      Asm->fld(Ty, StackSlot);
    } else {
      typename InstX86Base<Machine>::Traits::Address StackAddr(
          Target->stackVarToAsmOperand(Var));
      Asm->fld(Ty, StackAddr);
    }
  } else if (const auto *Mem = llvm::dyn_cast<
                 typename InstX86Base<Machine>::Traits::X86OperandMem>(Src)) {
    assert(Mem->getSegmentRegister() ==
           InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment);
    Asm->fld(Ty, Mem->toAsmAddress(Asm, Target));
  } else if (const auto *Imm = llvm::dyn_cast<Constant>(Src)) {
    Asm->fld(Ty, InstX86Base<Machine>::Traits::Address::ofConstPool(Asm, Imm));
  } else {
    llvm_unreachable("Unexpected operand type");
  }
}

template <class Machine> void InstX86Fld<Machine>::dump(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  Str << "fld." << this->getSrc(0)->getType() << " ";
  this->dumpSources(Func);
}

template <class Machine>
void InstX86Fstp<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(this->getSrcSize() == 0);
  // TODO(jvoung,stichnot): Utilize this by setting Dest to nullptr to
  // "partially" delete the fstp if the Dest is unused. Even if Dest is unused,
  // the fstp should be kept for the SideEffects of popping the stack.
  if (!this->getDest()) {
    Str << "\tfstp\tst(0)";
    return;
  }
  Type Ty = this->getDest()->getType();
  if (!this->getDest()->hasReg()) {
    Str << "\tfstp" << this->getFldString(Ty) << "\t";
    this->getDest()->emit(Func);
    return;
  }
  // Dest is a physical (xmm) register, so st(0) needs to go through memory.
  // Hack this by using caller-reserved memory at the top of stack, spilling
  // st(0) there, and loading it into the xmm register.
  Str << "\tfstp" << this->getFldString(Ty) << "\t"
      << "(%esp)\n";
  Str << "\tmov" << InstX86Base<Machine>::Traits::TypeAttributes[Ty].SdSsString
      << "\t"
      << "(%esp), ";
  this->getDest()->emit(Func);
}

template <class Machine>
void InstX86Fstp<Machine>::emitIAS(const Cfg *Func) const {
  typename InstX86Base<Machine>::Traits::Assembler *Asm =
      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
  assert(this->getSrcSize() == 0);
  const Variable *Dest = this->getDest();
  // TODO(jvoung,stichnot): Utilize this by setting Dest to nullptr to
  // "partially" delete the fstp if the Dest is unused. Even if Dest is unused,
  // the fstp should be kept for the SideEffects of popping the stack.
  if (!Dest) {
    Asm->fstp(InstX86Base<Machine>::Traits::RegisterSet::getEncodedSTReg(0));
    return;
  }
  auto *Target = InstX86Base<Machine>::getTarget(Func);
  Type Ty = Dest->getType();
  if (!Dest->hasReg()) {
    typename InstX86Base<Machine>::Traits::Address StackAddr(
        Target->stackVarToAsmOperand(Dest));
    Asm->fstp(Ty, StackAddr);
  } else {
    // Dest is a physical (xmm) register, so st(0) needs to go through memory.
    // Hack this by using caller-reserved memory at the top of stack, spilling
    // st(0) there, and loading it into the xmm register.
    typename InstX86Base<Machine>::Traits::Address StackSlot =
        typename InstX86Base<Machine>::Traits::Address(
            InstX86Base<Machine>::Traits::RegisterSet::Encoded_Reg_esp, 0,
            AssemblerFixup::NoFixup);
    Asm->fstp(Ty, StackSlot);
    Asm->movss(Ty,
               InstX86Base<Machine>::Traits::getEncodedXmm(Dest->getRegNum()),
               StackSlot);
  }
}

template <class Machine>
void InstX86Fstp<Machine>::dump(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  this->dumpDest(Func);
  Str << " = fstp." << this->getDest()->getType() << ", st(0)";
}

template <class Machine>
void InstX86Pcmpeq<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  char buf[30];
  snprintf(
      buf, llvm::array_lengthof(buf), "pcmpeq%s",
      InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()]
          .PackString);
  this->emitTwoAddress(buf, this, Func);
}

template <class Machine>
void InstX86Pcmpgt<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  char buf[30];
  snprintf(
      buf, llvm::array_lengthof(buf), "pcmpgt%s",
      InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()]
          .PackString);
  this->emitTwoAddress(buf, this, Func);
}

template <class Machine>
void InstX86Pextr<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(this->getSrcSize() == 2);
  // pextrb and pextrd are SSE4.1 instructions.
  assert(this->getSrc(0)->getType() == IceType_v8i16 ||
         this->getSrc(0)->getType() == IceType_v8i1 ||
         InstX86Base<Machine>::getTarget(Func)->getInstructionSet() >=
             InstX86Base<Machine>::Traits::SSE4_1);
  Str << "\t" << this->Opcode
      << InstX86Base<Machine>::Traits::TypeAttributes[this->getSrc(0)
                                                          ->getType()]
             .PackString << "\t";
  this->getSrc(1)->emit(Func);
  Str << ", ";
  this->getSrc(0)->emit(Func);
  Str << ", ";
  Variable *Dest = this->getDest();
  // pextrw must take a register dest. There is an SSE4.1 version that takes a
  // memory dest, but we aren't using it. For uniformity, just restrict them
  // all to have a register dest for now.
  assert(Dest->hasReg());
  Dest->asType(IceType_i32, Dest->getRegNum())->emit(Func);
}

template <class Machine>
void InstX86Pextr<Machine>::emitIAS(const Cfg *Func) const {
  assert(this->getSrcSize() == 2);
  // pextrb and pextrd are SSE4.1 instructions.
  const Variable *Dest = this->getDest();
  Type DispatchTy = InstX86Base<Machine>::Traits::getInVectorElementType(
      this->getSrc(0)->getType());
  assert(DispatchTy == IceType_i16 ||
         InstX86Base<Machine>::getTarget(Func)->getInstructionSet() >=
             InstX86Base<Machine>::Traits::SSE4_1);
  // pextrw must take a register dest. There is an SSE4.1 version that takes a
  // memory dest, but we aren't using it. For uniformity, just restrict them
  // all to have a register dest for now.
  assert(Dest->hasReg());
  // pextrw's Src(0) must be a register (both SSE4.1 and SSE2).
  assert(llvm::cast<Variable>(this->getSrc(0))->hasReg());
  static const typename InstX86Base<Machine>::Traits::Assembler::
      template ThreeOpImmEmitter<
          typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister,
          typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister>
          Emitter = {&InstX86Base<Machine>::Traits::Assembler::pextr, nullptr};
  emitIASThreeOpImmOps<
      Machine, typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister,
      typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
      InstX86Base<Machine>::Traits::getEncodedGPR,
      InstX86Base<Machine>::Traits::getEncodedXmm>(
      Func, DispatchTy, Dest, this->getSrc(0), this->getSrc(1), Emitter);
}

template <class Machine>
void InstX86Pinsr<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(this->getSrcSize() == 3);
  // pinsrb and pinsrd are SSE4.1 instructions.
  assert(this->getDest()->getType() == IceType_v8i16 ||
         this->getDest()->getType() == IceType_v8i1 ||
         InstX86Base<Machine>::getTarget(Func)->getInstructionSet() >=
             InstX86Base<Machine>::Traits::SSE4_1);
  Str << "\t" << this->Opcode
      << InstX86Base<
             Machine>::Traits::TypeAttributes[this->getDest()->getType()]
             .PackString << "\t";
  this->getSrc(2)->emit(Func);
  Str << ", ";
  Operand *Src1 = this->getSrc(1);
  if (const auto *Src1Var = llvm::dyn_cast<Variable>(Src1)) {
    // If src1 is a register, it should always be r32.
    if (Src1Var->hasReg()) {
      int32_t NewRegNum =
          InstX86Base<Machine>::Traits::getBaseReg(Src1Var->getRegNum());
      const Variable *NewSrc = Src1Var->asType(IceType_i32, NewRegNum);
      NewSrc->emit(Func);
    } else {
      Src1Var->emit(Func);
    }
  } else {
    Src1->emit(Func);
  }
  Str << ", ";
  this->getDest()->emit(Func);
}

template <class Machine>
void InstX86Pinsr<Machine>::emitIAS(const Cfg *Func) const {
  assert(this->getSrcSize() == 3);
  assert(this->getDest() == this->getSrc(0));
  // pinsrb and pinsrd are SSE4.1 instructions.
  const Operand *Src0 = this->getSrc(1);
  Type DispatchTy = Src0->getType();
  assert(DispatchTy == IceType_i16 ||
         InstX86Base<Machine>::getTarget(Func)->getInstructionSet() >=
             InstX86Base<Machine>::Traits::SSE4_1);
  // If src1 is a register, it should always be r32 (this should fall out from
  // the encodings for ByteRegs overlapping the encodings for r32), but we have
  // to make sure the register allocator didn't choose an 8-bit high register
  // like "ah".
  if (BuildDefs::asserts()) {
    if (auto *Src0Var = llvm::dyn_cast<Variable>(Src0)) {
      if (Src0Var->hasReg()) {
        int32_t RegNum = Src0Var->getRegNum();
        int32_t BaseRegNum = InstX86Base<Machine>::Traits::getBaseReg(RegNum);
        (void)BaseRegNum;
        assert(InstX86Base<Machine>::Traits::getEncodedGPR(RegNum) ==
               InstX86Base<Machine>::Traits::getEncodedGPR(BaseRegNum));
      }
    }
  }
  static const typename InstX86Base<Machine>::Traits::Assembler::
      template ThreeOpImmEmitter<
          typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
          typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister>
          Emitter = {&InstX86Base<Machine>::Traits::Assembler::pinsr,
                     &InstX86Base<Machine>::Traits::Assembler::pinsr};
  emitIASThreeOpImmOps<
      Machine, typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
      typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister,
      InstX86Base<Machine>::Traits::getEncodedXmm,
      InstX86Base<Machine>::Traits::getEncodedGPR>(
      Func, DispatchTy, this->getDest(), Src0, this->getSrc(2), Emitter);
}

template <class Machine>
void InstX86Pshufd<Machine>::emitIAS(const Cfg *Func) const {
  assert(this->getSrcSize() == 2);
  const Variable *Dest = this->getDest();
  Type Ty = Dest->getType();
  static const typename InstX86Base<Machine>::Traits::Assembler::
      template ThreeOpImmEmitter<
          typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
          typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister>
          Emitter = {&InstX86Base<Machine>::Traits::Assembler::pshufd,
                     &InstX86Base<Machine>::Traits::Assembler::pshufd};
  emitIASThreeOpImmOps<
      Machine, typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
      typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
      InstX86Base<Machine>::Traits::getEncodedXmm,
      InstX86Base<Machine>::Traits::getEncodedXmm>(
      Func, Ty, Dest, this->getSrc(0), this->getSrc(1), Emitter);
}

template <class Machine>
void InstX86Shufps<Machine>::emitIAS(const Cfg *Func) const {
  assert(this->getSrcSize() == 3);
  const Variable *Dest = this->getDest();
  assert(Dest == this->getSrc(0));
  Type Ty = Dest->getType();
  static const typename InstX86Base<Machine>::Traits::Assembler::
      template ThreeOpImmEmitter<
          typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
          typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister>
          Emitter = {&InstX86Base<Machine>::Traits::Assembler::shufps,
                     &InstX86Base<Machine>::Traits::Assembler::shufps};
  emitIASThreeOpImmOps<
      Machine, typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
      typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
      InstX86Base<Machine>::Traits::getEncodedXmm,
      InstX86Base<Machine>::Traits::getEncodedXmm>(
      Func, Ty, Dest, this->getSrc(1), this->getSrc(2), Emitter);
}

template <class Machine> void InstX86Pop<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(this->getSrcSize() == 0);
  Str << "\tpop\t";
  this->getDest()->emit(Func);
}

template <class Machine>
void InstX86Pop<Machine>::emitIAS(const Cfg *Func) const {
  assert(this->getSrcSize() == 0);
  typename InstX86Base<Machine>::Traits::Assembler *Asm =
      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
  if (this->getDest()->hasReg()) {
    Asm->popl(InstX86Base<Machine>::Traits::getEncodedGPR(
        this->getDest()->getRegNum()));
  } else {
    auto *Target = InstX86Base<Machine>::getTarget(Func);
    Asm->popl(Target->stackVarToAsmOperand(this->getDest()));
  }
}

template <class Machine> void InstX86Pop<Machine>::dump(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  this->dumpDest(Func);
  Str << " = pop." << this->getDest()->getType() << " ";
}

template <class Machine>
void InstX86Push<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(this->getSrcSize() == 1);
  // Push is currently only used for saving GPRs.
  const auto *Var = llvm::cast<Variable>(this->getSrc(0));
  assert(Var->hasReg());
  Str << "\tpush\t";
  Var->emit(Func);
}

template <class Machine>
void InstX86Push<Machine>::emitIAS(const Cfg *Func) const {
  assert(this->getSrcSize() == 1);
  // Push is currently only used for saving GPRs.
  const auto *Var = llvm::cast<Variable>(this->getSrc(0));
  assert(Var->hasReg());
  typename InstX86Base<Machine>::Traits::Assembler *Asm =
      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
  Asm->pushl(InstX86Base<Machine>::Traits::getEncodedGPR(Var->getRegNum()));
}

template <class Machine>
void InstX86Push<Machine>::dump(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  Str << "push." << this->getSrc(0)->getType() << " ";
  this->dumpSources(Func);
}

template <class Machine>
void InstX86Psll<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  assert(this->getDest()->getType() == IceType_v8i16 ||
         this->getDest()->getType() == IceType_v8i1 ||
         this->getDest()->getType() == IceType_v4i32 ||
         this->getDest()->getType() == IceType_v4i1);
  char buf[30];
  snprintf(
      buf, llvm::array_lengthof(buf), "psll%s",
      InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()]
          .PackString);
  this->emitTwoAddress(buf, this, Func);
}

template <class Machine>
void InstX86Psra<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  assert(this->getDest()->getType() == IceType_v8i16 ||
         this->getDest()->getType() == IceType_v8i1 ||
         this->getDest()->getType() == IceType_v4i32 ||
         this->getDest()->getType() == IceType_v4i1);
  char buf[30];
  snprintf(
      buf, llvm::array_lengthof(buf), "psra%s",
      InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()]
          .PackString);
  this->emitTwoAddress(buf, this, Func);
}

template <class Machine>
void InstX86Psrl<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  char buf[30];
  snprintf(
      buf, llvm::array_lengthof(buf), "psrl%s",
      InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()]
          .PackString);
  this->emitTwoAddress(buf, this, Func);
}

template <class Machine> void InstX86Ret<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  Str << "\tret";
}

template <class Machine>
void InstX86Ret<Machine>::emitIAS(const Cfg *Func) const {
  typename InstX86Base<Machine>::Traits::Assembler *Asm =
      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
  Asm->ret();
}

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

template <class Machine>
void InstX86Setcc<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  Str << "\tset"
      << InstX86Base<Machine>::Traits::InstBrAttributes[Condition].DisplayString
      << "\t";
  this->Dest->emit(Func);
}

template <class Machine>
void InstX86Setcc<Machine>::emitIAS(const Cfg *Func) const {
  assert(Condition != InstX86Base<Machine>::Traits::Cond::Br_None);
  assert(this->getDest()->getType() == IceType_i1);
  assert(this->getSrcSize() == 0);
  typename InstX86Base<Machine>::Traits::Assembler *Asm =
      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
  auto *Target = InstX86Base<Machine>::getTarget(Func);
  if (this->getDest()->hasReg())
    Asm->setcc(Condition, InstX86Base<Machine>::Traits::getEncodedByteReg(
                              this->getDest()->getRegNum()));
  else
    Asm->setcc(Condition, Target->stackVarToAsmOperand(this->getDest()));
  return;
}

template <class Machine>
void InstX86Setcc<Machine>::dump(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  Str << "setcc."
      << InstX86Base<Machine>::Traits::InstBrAttributes[Condition].DisplayString
      << " ";
  this->dumpDest(Func);
}

template <class Machine>
void InstX86Xadd<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  if (this->Locked) {
    Str << "\tlock";
  }
  Str << "\txadd" << this->getWidthString(this->getSrc(0)->getType()) << "\t";
  this->getSrc(1)->emit(Func);
  Str << ", ";
  this->getSrc(0)->emit(Func);
}

template <class Machine>
void InstX86Xadd<Machine>::emitIAS(const Cfg *Func) const {
  assert(this->getSrcSize() == 2);
  typename InstX86Base<Machine>::Traits::Assembler *Asm =
      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
  Type Ty = this->getSrc(0)->getType();
  const auto Mem =
      llvm::cast<typename InstX86Base<Machine>::Traits::X86OperandMem>(
          this->getSrc(0));
  assert(Mem->getSegmentRegister() ==
         InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment);
  auto *Target = InstX86Base<Machine>::getTarget(Func);
  const typename InstX86Base<Machine>::Traits::Address Addr =
      Mem->toAsmAddress(Asm, Target);
  const auto *VarReg = llvm::cast<Variable>(this->getSrc(1));
  assert(VarReg->hasReg());
  const typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister Reg =
      InstX86Base<Machine>::Traits::getEncodedGPR(VarReg->getRegNum());
  Asm->xadd(Ty, Addr, Reg, this->Locked);
}

template <class Machine>
void InstX86Xadd<Machine>::dump(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  if (this->Locked) {
    Str << "lock ";
  }
  Type Ty = this->getSrc(0)->getType();
  Str << "xadd." << Ty << " ";
  this->dumpSources(Func);
}

template <class Machine>
void InstX86Xchg<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  Str << "\txchg" << this->getWidthString(this->getSrc(0)->getType()) << "\t";
  this->getSrc(1)->emit(Func);
  Str << ", ";
  this->getSrc(0)->emit(Func);
}

template <class Machine>
void InstX86Xchg<Machine>::emitIAS(const Cfg *Func) const {
  assert(this->getSrcSize() == 2);
  typename InstX86Base<Machine>::Traits::Assembler *Asm =
      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
  Type Ty = this->getSrc(0)->getType();
  const auto *VarReg1 = llvm::cast<Variable>(this->getSrc(1));
  assert(VarReg1->hasReg());
  const typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister Reg1 =
      InstX86Base<Machine>::Traits::getEncodedGPR(VarReg1->getRegNum());

  if (const auto *VarReg0 = llvm::dyn_cast<Variable>(this->getSrc(0))) {
    assert(VarReg0->hasReg());
    const typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister Reg0 =
        InstX86Base<Machine>::Traits::getEncodedGPR(VarReg0->getRegNum());
    Asm->xchg(Ty, Reg0, Reg1);
    return;
  }

  const auto *Mem =
      llvm::cast<typename InstX86Base<Machine>::Traits::X86OperandMem>(
          this->getSrc(0));
  assert(Mem->getSegmentRegister() ==
         InstX86Base<Machine>::Traits::X86OperandMem::DefaultSegment);
  auto *Target = InstX86Base<Machine>::getTarget(Func);
  const typename InstX86Base<Machine>::Traits::Address Addr =
      Mem->toAsmAddress(Asm, Target);
  Asm->xchg(Ty, Addr, Reg1);
}

template <class Machine>
void InstX86Xchg<Machine>::dump(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  Type Ty = this->getSrc(0)->getType();
  Str << "xchg." << Ty << " ";
  this->dumpSources(Func);
}

template <class Machine>
void InstX86IacaStart<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  Str << "\t# IACA_START\n"
      << "\t.byte 0x0F, 0x0B\n"
      << "\tmovl\t$111, %ebx\n"
      << "\t.byte 0x64, 0x67, 0x90";
}

template <class Machine>
void InstX86IacaStart<Machine>::emitIAS(const Cfg *Func) const {
  typename InstX86Base<Machine>::Traits::Assembler *Asm =
      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
  Asm->iaca_start();
}

template <class Machine>
void InstX86IacaStart<Machine>::dump(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  Str << "IACA_START";
}

template <class Machine>
void InstX86IacaEnd<Machine>::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  Str << "\t# IACA_END\n"
      << "\tmovl\t$222, %ebx\n"
      << "\t.byte 0x64, 0x67, 0x90\n"
      << "\t.byte 0x0F, 0x0B";
}

template <class Machine>
void InstX86IacaEnd<Machine>::emitIAS(const Cfg *Func) const {
  typename InstX86Base<Machine>::Traits::Assembler *Asm =
      Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
  Asm->iaca_end();
}

template <class Machine>
void InstX86IacaEnd<Machine>::dump(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  Str << "IACA_END";
}

} // end of namespace X86Internal

} // end of namespace Ice

#endif // SUBZERO_SRC_ICEINSTX86BASEIMPL_H
