Home | History | Annotate | Download | only in src
      1 //===- subzero/src/IceInstX86Base.h - Generic x86 instructions -*- C++ -*--===//
      2 //
      3 //                        The Subzero Code Generator
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 ///
     10 /// \file
     11 /// \brief This file defines the InstX86Base template class, as well as the
     12 /// generic X86 Instruction class hierarchy.
     13 ///
     14 /// Only X86 instructions common across all/most X86 targets should be defined
     15 /// here, with target-specific instructions declared in the target's traits.
     16 ///
     17 //===----------------------------------------------------------------------===//
     18 
     19 #ifndef SUBZERO_SRC_ICEINSTX86BASE_H
     20 #define SUBZERO_SRC_ICEINSTX86BASE_H
     21 
     22 #include "IceDefs.h"
     23 #include "IceInst.h"
     24 #include "IceOperand.h"
     25 
     26 namespace Ice {
     27 
     28 #ifndef X86NAMESPACE
     29 #error "You must define the X86 Target namespace."
     30 #endif
     31 
     32 namespace X86NAMESPACE {
     33 
     34 template <typename TraitsType> struct InstImpl {
     35   using Traits = TraitsType;
     36   using Assembler = typename Traits::Assembler;
     37   using AssemblerLabel = typename Assembler::Label;
     38   using AssemblerImmediate = typename Assembler::Immediate;
     39   using TargetLowering = typename Traits::TargetLowering;
     40   using Address = typename Traits::Address;
     41   using X86Operand = typename Traits::X86Operand;
     42   using X86OperandMem = typename Traits::X86OperandMem;
     43   using VariableSplit = typename Traits::VariableSplit;
     44 
     45   using GPRRegister = typename Traits::RegisterSet::GPRRegister;
     46   using RegisterSet = typename Traits::RegisterSet;
     47   using XmmRegister = typename Traits::RegisterSet::XmmRegister;
     48 
     49   using Cond = typename Traits::Cond;
     50   using BrCond = typename Traits::Cond::BrCond;
     51   using CmppsCond = typename Traits::Cond::CmppsCond;
     52 
     53   template <typename SReg_t, typename DReg_t>
     54   using CastEmitterRegOp =
     55       typename Traits::Assembler::template CastEmitterRegOp<SReg_t, DReg_t>;
     56   template <typename SReg_t, typename DReg_t>
     57   using ThreeOpImmEmitter =
     58       typename Traits::Assembler::template ThreeOpImmEmitter<SReg_t, DReg_t>;
     59   using GPREmitterAddrOp = typename Traits::Assembler::GPREmitterAddrOp;
     60   using GPREmitterRegOp = typename Traits::Assembler::GPREmitterRegOp;
     61   using GPREmitterShiftD = typename Traits::Assembler::GPREmitterShiftD;
     62   using GPREmitterShiftOp = typename Traits::Assembler::GPREmitterShiftOp;
     63   using GPREmitterOneOp = typename Traits::Assembler::GPREmitterOneOp;
     64   using XmmEmitterRegOp = typename Traits::Assembler::XmmEmitterRegOp;
     65   using XmmEmitterShiftOp = typename Traits::Assembler::XmmEmitterShiftOp;
     66   using XmmEmitterMovOps = typename Traits::Assembler::XmmEmitterMovOps;
     67 
     68   class InstX86Base : public InstTarget {
     69     InstX86Base() = delete;
     70     InstX86Base(const InstX86Base &) = delete;
     71     InstX86Base &operator=(const InstX86Base &) = delete;
     72 
     73   public:
     74     enum InstKindX86 {
     75       k__Start = Inst::Target,
     76       Adc,
     77       AdcRMW,
     78       Add,
     79       AddRMW,
     80       Addps,
     81       Addss,
     82       And,
     83       Andnps,
     84       Andps,
     85       AndRMW,
     86       Blendvps,
     87       Br,
     88       Bsf,
     89       Bsr,
     90       Bswap,
     91       Call,
     92       Cbwdq,
     93       Cmov,
     94       Cmpps,
     95       Cmpxchg,
     96       Cmpxchg8b,
     97       Cvt,
     98       Div,
     99       Divps,
    100       Divss,
    101       FakeRMW,
    102       Fld,
    103       Fstp,
    104       GetIP,
    105       Icmp,
    106       Idiv,
    107       Imul,
    108       ImulImm,
    109       Insertps,
    110       Int3,
    111       Jmp,
    112       Label,
    113       Lea,
    114       Load,
    115       Mfence,
    116       Minps,
    117       Maxps,
    118       Minss,
    119       Maxss,
    120       Mov,
    121       Movd,
    122       Movmsk,
    123       Movp,
    124       Movq,
    125       MovssRegs,
    126       Movsx,
    127       Movzx,
    128       Mul,
    129       Mulps,
    130       Mulss,
    131       Neg,
    132       Nop,
    133       Or,
    134       Orps,
    135       OrRMW,
    136       Padd,
    137       Padds,
    138       Paddus,
    139       Pand,
    140       Pandn,
    141       Pblendvb,
    142       Pcmpeq,
    143       Pcmpgt,
    144       Pextr,
    145       Pinsr,
    146       Pmull,
    147       Pmulhw,
    148       Pmulhuw,
    149       Pmaddwd,
    150       Pmuludq,
    151       Pop,
    152       Por,
    153       Pshufb,
    154       Pshufd,
    155       Punpckl,
    156       Punpckh,
    157       Packss,
    158       Packus,
    159       Psll,
    160       Psra,
    161       Psrl,
    162       Psub,
    163       Psubs,
    164       Psubus,
    165       Push,
    166       Pxor,
    167       Ret,
    168       Rol,
    169       Round,
    170       Sar,
    171       Sbb,
    172       SbbRMW,
    173       Setcc,
    174       Shl,
    175       Shld,
    176       Shr,
    177       Shrd,
    178       Shufps,
    179       Sqrt,
    180       Store,
    181       StoreP,
    182       StoreQ,
    183       StoreD,
    184       Sub,
    185       SubRMW,
    186       Subps,
    187       Subss,
    188       Test,
    189       Ucomiss,
    190       UD2,
    191       Xadd,
    192       Xchg,
    193       Xor,
    194       Xorps,
    195       XorRMW,
    196 
    197       /// Intel Architecture Code Analyzer markers. These are not executable so
    198       /// must only be used for analysis.
    199       IacaStart,
    200       IacaEnd
    201     };
    202 
    203     enum SseSuffix { None, Packed, Unpack, Scalar, Integral, Pack };
    204 
    205     static const char *getWidthString(Type Ty);
    206     static const char *getFldString(Type Ty);
    207     static BrCond getOppositeCondition(BrCond Cond);
    208     void dump(const Cfg *Func) const override;
    209 
    210     // Shared emit routines for common forms of instructions.
    211     void emitTwoAddress(const Cfg *Func, const char *Opcode,
    212                         const char *Suffix = "") const;
    213 
    214     static TargetLowering *getTarget(const Cfg *Func) {
    215       return static_cast<TargetLowering *>(Func->getTarget());
    216     }
    217 
    218   protected:
    219     InstX86Base(Cfg *Func, InstKindX86 Kind, SizeT Maxsrcs, Variable *Dest)
    220         : InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {}
    221 
    222     static bool isClassof(const Inst *Instr, InstKindX86 MyKind) {
    223       return Instr->getKind() == static_cast<InstKind>(MyKind);
    224     }
    225     // Most instructions that operate on vector arguments require vector memory
    226     // operands to be fully aligned (16-byte alignment for PNaCl vector types).
    227     // The stack frame layout and call ABI ensure proper alignment for stack
    228     // operands, but memory operands (originating from load/store bitcode
    229     // instructions) only have element-size alignment guarantees. This function
    230     // validates that none of the operands is a memory operand of vector type,
    231     // calling report_fatal_error() if one is found. This function should be
    232     // called during emission, and maybe also in the ctor (as long as that fits
    233     // the lowering style).
    234     void validateVectorAddrMode() const {
    235       if (this->getDest())
    236         this->validateVectorAddrModeOpnd(this->getDest());
    237       for (SizeT i = 0; i < this->getSrcSize(); ++i) {
    238         this->validateVectorAddrModeOpnd(this->getSrc(i));
    239       }
    240     }
    241 
    242   private:
    243     static void validateVectorAddrModeOpnd(const Operand *Opnd) {
    244       if (llvm::isa<X86OperandMem>(Opnd) && isVectorType(Opnd->getType())) {
    245         llvm::report_fatal_error("Possible misaligned vector memory operation");
    246       }
    247     }
    248   };
    249 
    250   /// InstX86FakeRMW represents a non-atomic read-modify-write operation on a
    251   /// memory location. An InstX86FakeRMW is a "fake" instruction in that it
    252   /// still needs to be lowered to some actual RMW instruction.
    253   ///
    254   /// If A is some memory address, D is some data value to apply, and OP is an
    255   /// arithmetic operator, the instruction operates as: (*A) = (*A) OP D
    256   class InstX86FakeRMW final : public InstX86Base {
    257     InstX86FakeRMW() = delete;
    258     InstX86FakeRMW(const InstX86FakeRMW &) = delete;
    259     InstX86FakeRMW &operator=(const InstX86FakeRMW &) = delete;
    260 
    261   public:
    262     static InstX86FakeRMW *create(Cfg *Func, Operand *Data, Operand *Addr,
    263                                   Variable *Beacon, InstArithmetic::OpKind Op,
    264                                   uint32_t Align = 1) {
    265       // TODO(stichnot): Stop ignoring alignment specification.
    266       (void)Align;
    267       return new (Func->allocate<InstX86FakeRMW>())
    268           InstX86FakeRMW(Func, Data, Addr, Op, Beacon);
    269     }
    270     Operand *getAddr() const { return this->getSrc(1); }
    271     Operand *getData() const { return this->getSrc(0); }
    272     InstArithmetic::OpKind getOp() const { return Op; }
    273     Variable *getBeacon() const {
    274       return llvm::cast<Variable>(this->getSrc(2));
    275     }
    276     void dump(const Cfg *Func) const override;
    277     static bool classof(const Inst *Instr) {
    278       return InstX86Base::isClassof(Instr, InstX86Base::FakeRMW);
    279     }
    280 
    281   private:
    282     InstArithmetic::OpKind Op;
    283     InstX86FakeRMW(Cfg *Func, Operand *Data, Operand *Addr,
    284                    InstArithmetic::OpKind Op, Variable *Beacon);
    285   };
    286 
    287   class InstX86GetIP final : public InstX86Base {
    288     InstX86GetIP() = delete;
    289     InstX86GetIP(const InstX86GetIP &) = delete;
    290     InstX86GetIP &operator=(const InstX86GetIP &) = delete;
    291 
    292   public:
    293     static InstX86GetIP *create(Cfg *Func, Variable *Dest) {
    294       return new (Func->allocate<InstX86GetIP>()) InstX86GetIP(Func, Dest);
    295     }
    296     void emit(const Cfg *Func) const override;
    297     void emitIAS(const Cfg *Func) const override;
    298     void dump(const Cfg *Func) const override;
    299     static bool classof(const Inst *Instr) {
    300       return InstX86Base::isClassof(Instr, InstX86Base::GetIP);
    301     }
    302 
    303   private:
    304     InstX86GetIP(Cfg *Func, Variable *Dest);
    305   };
    306 
    307   /// InstX86Label represents an intra-block label that is the target of an
    308   /// intra-block branch. The offset between the label and the branch must be
    309   /// fit into one byte (considered "near"). These are used for lowering i1
    310   /// calculations, Select instructions, and 64-bit compares on a 32-bit
    311   /// architecture, without basic block splitting. Basic block splitting is not
    312   /// so desirable for several reasons, one of which is the impact on decisions
    313   /// based on whether a variable's live range spans multiple basic blocks.
    314   ///
    315   /// Intra-block control flow must be used with caution. Consider the sequence
    316   /// for "c = (a >= b ? x : y)".
    317   ///     cmp a, b
    318   ///     br lt, L1
    319   ///     mov c, x
    320   ///     jmp L2
    321   ///   L1:
    322   ///     mov c, y
    323   ///   L2:
    324   ///
    325   /// Labels L1 and L2 are intra-block labels. Without knowledge of the
    326   /// intra-block control flow, liveness analysis will determine the "mov c, x"
    327   /// instruction to be dead. One way to prevent this is to insert a
    328   /// "FakeUse(c)" instruction anywhere between the two "mov c, ..."
    329   /// instructions, e.g.:
    330   ///
    331   ///     cmp a, b
    332   ///     br lt, L1
    333   ///     mov c, x
    334   ///     jmp L2
    335   ///     FakeUse(c)
    336   ///   L1:
    337   ///     mov c, y
    338   ///   L2:
    339   ///
    340   /// The down-side is that "mov c, x" can never be dead-code eliminated even if
    341   /// there are no uses of c. As unlikely as this situation is, it may be
    342   /// prevented by running dead code elimination before lowering.
    343   class InstX86Label final : public InstX86Base {
    344     InstX86Label() = delete;
    345     InstX86Label(const InstX86Label &) = delete;
    346     InstX86Label &operator=(const InstX86Label &) = delete;
    347 
    348   public:
    349     static InstX86Label *create(Cfg *Func, TargetLowering *Target) {
    350       return new (Func->allocate<InstX86Label>()) InstX86Label(Func, Target);
    351     }
    352     uint32_t getEmitInstCount() const override { return 0; }
    353     GlobalString getLabelName() const { return Name; }
    354     SizeT getLabelNumber() const { return LabelNumber; }
    355     bool isLabel() const override { return true; }
    356     void emit(const Cfg *Func) const override;
    357     void emitIAS(const Cfg *Func) const override;
    358     void dump(const Cfg *Func) const override;
    359     void setRelocOffset(RelocOffset *Value) { OffsetReloc = Value; }
    360 
    361   private:
    362     InstX86Label(Cfg *Func, TargetLowering *Target);
    363 
    364     SizeT LabelNumber; // used for unique label generation.
    365     RelocOffset *OffsetReloc = nullptr;
    366     GlobalString Name;
    367   };
    368 
    369   /// Conditional and unconditional branch instruction.
    370   class InstX86Br final : public InstX86Base {
    371     InstX86Br() = delete;
    372     InstX86Br(const InstX86Br &) = delete;
    373     InstX86Br &operator=(const InstX86Br &) = delete;
    374 
    375   public:
    376     enum Mode { Near, Far };
    377 
    378     /// Create a conditional branch to a node.
    379     static InstX86Br *create(Cfg *Func, CfgNode *TargetTrue,
    380                              CfgNode *TargetFalse, BrCond Condition,
    381                              Mode Kind) {
    382       assert(Condition != Cond::Br_None);
    383       constexpr InstX86Label *NoLabel = nullptr;
    384       return new (Func->allocate<InstX86Br>())
    385           InstX86Br(Func, TargetTrue, TargetFalse, NoLabel, Condition, Kind);
    386     }
    387     /// Create an unconditional branch to a node.
    388     static InstX86Br *create(Cfg *Func, CfgNode *Target, Mode Kind) {
    389       constexpr CfgNode *NoCondTarget = nullptr;
    390       constexpr InstX86Label *NoLabel = nullptr;
    391       return new (Func->allocate<InstX86Br>())
    392           InstX86Br(Func, NoCondTarget, Target, NoLabel, Cond::Br_None, Kind);
    393     }
    394     /// Create a non-terminator conditional branch to a node, with a fallthrough
    395     /// to the next instruction in the current node. This is used for switch
    396     /// lowering.
    397     static InstX86Br *create(Cfg *Func, CfgNode *Target, BrCond Condition,
    398                              Mode Kind) {
    399       assert(Condition != Cond::Br_None);
    400       constexpr CfgNode *NoUncondTarget = nullptr;
    401       constexpr InstX86Label *NoLabel = nullptr;
    402       return new (Func->allocate<InstX86Br>())
    403           InstX86Br(Func, Target, NoUncondTarget, NoLabel, Condition, Kind);
    404     }
    405     /// Create a conditional intra-block branch (or unconditional, if
    406     /// Condition==Br_None) to a label in the current block.
    407     static InstX86Br *create(Cfg *Func, InstX86Label *Label, BrCond Condition,
    408                              Mode Kind) {
    409       constexpr CfgNode *NoCondTarget = nullptr;
    410       constexpr CfgNode *NoUncondTarget = nullptr;
    411       return new (Func->allocate<InstX86Br>())
    412           InstX86Br(Func, NoCondTarget, NoUncondTarget, Label, Condition, Kind);
    413     }
    414     const CfgNode *getTargetTrue() const { return TargetTrue; }
    415     const CfgNode *getTargetFalse() const { return TargetFalse; }
    416     bool isNear() const { return Kind == Near; }
    417     bool optimizeBranch(const CfgNode *NextNode);
    418     uint32_t getEmitInstCount() const override {
    419       uint32_t Sum = 0;
    420       if (Label)
    421         ++Sum;
    422       if (getTargetTrue())
    423         ++Sum;
    424       if (getTargetFalse())
    425         ++Sum;
    426       return Sum;
    427     }
    428     bool isUnconditionalBranch() const override {
    429       return !Label && Condition == Cond::Br_None;
    430     }
    431     const Inst *getIntraBlockBranchTarget() const override { return Label; }
    432     bool repointEdges(CfgNode *OldNode, CfgNode *NewNode) override;
    433     void emit(const Cfg *Func) const override;
    434     void emitIAS(const Cfg *Func) const override;
    435     void dump(const Cfg *Func) const override;
    436     static bool classof(const Inst *Instr) {
    437       return InstX86Base::isClassof(Instr, InstX86Base::Br);
    438     }
    439 
    440   private:
    441     InstX86Br(Cfg *Func, const CfgNode *TargetTrue, const CfgNode *TargetFalse,
    442               const InstX86Label *Label, BrCond Condition, Mode Kind);
    443 
    444     BrCond Condition;
    445     const CfgNode *TargetTrue;
    446     const CfgNode *TargetFalse;
    447     const InstX86Label *Label; // Intra-block branch target
    448     const Mode Kind;
    449   };
    450 
    451   /// Jump to a target outside this function, such as tailcall, nacljump,
    452   /// naclret, unreachable. This is different from a Branch instruction in that
    453   /// there is no intra-function control flow to represent.
    454   class InstX86Jmp final : public InstX86Base {
    455     InstX86Jmp() = delete;
    456     InstX86Jmp(const InstX86Jmp &) = delete;
    457     InstX86Jmp &operator=(const InstX86Jmp &) = delete;
    458 
    459   public:
    460     static InstX86Jmp *create(Cfg *Func, Operand *Target) {
    461       return new (Func->allocate<InstX86Jmp>()) InstX86Jmp(Func, Target);
    462     }
    463     Operand *getJmpTarget() const { return this->getSrc(0); }
    464     void emit(const Cfg *Func) const override;
    465     void emitIAS(const Cfg *Func) const override;
    466     void dump(const Cfg *Func) const override;
    467     static bool classof(const Inst *Instr) {
    468       return InstX86Base::isClassof(Instr, InstX86Base::Jmp);
    469     }
    470 
    471   private:
    472     InstX86Jmp(Cfg *Func, Operand *Target);
    473   };
    474 
    475   /// Call instruction. Arguments should have already been pushed.
    476   class InstX86Call final : public InstX86Base {
    477     InstX86Call() = delete;
    478     InstX86Call(const InstX86Call &) = delete;
    479     InstX86Call &operator=(const InstX86Call &) = delete;
    480 
    481   public:
    482     static InstX86Call *create(Cfg *Func, Variable *Dest, Operand *CallTarget) {
    483       return new (Func->allocate<InstX86Call>())
    484           InstX86Call(Func, Dest, CallTarget);
    485     }
    486     Operand *getCallTarget() const { return this->getSrc(0); }
    487     void emit(const Cfg *Func) const override;
    488     void emitIAS(const Cfg *Func) const override;
    489     void dump(const Cfg *Func) const override;
    490     static bool classof(const Inst *Instr) {
    491       return InstX86Base::isClassof(Instr, InstX86Base::Call);
    492     }
    493 
    494   private:
    495     InstX86Call(Cfg *Func, Variable *Dest, Operand *CallTarget);
    496   };
    497 
    498   /// Emit a one-operand (GPR) instruction.
    499   static void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Var,
    500                              const GPREmitterOneOp &Emitter);
    501 
    502   static void emitIASAsAddrOpTyGPR(const Cfg *Func, Type Ty, const Operand *Op0,
    503                                    const Operand *Op1,
    504                                    const GPREmitterAddrOp &Emitter);
    505 
    506   static void emitIASGPRShift(const Cfg *Func, Type Ty, const Variable *Var,
    507                               const Operand *Src,
    508                               const GPREmitterShiftOp &Emitter);
    509 
    510   static void emitIASAddrOpTyGPR(const Cfg *Func, Type Ty, const Address &Addr,
    511                                  const Operand *Src,
    512                                  const GPREmitterAddrOp &Emitter);
    513 
    514   static void emitIASRegOpTyXMM(const Cfg *Func, Type Ty, const Variable *Var,
    515                                 const Operand *Src,
    516                                 const XmmEmitterRegOp &Emitter);
    517 
    518   static void emitIASGPRShiftDouble(const Cfg *Func, const Variable *Dest,
    519                                     const Operand *Src1Op,
    520                                     const Operand *Src2Op,
    521                                     const GPREmitterShiftD &Emitter);
    522 
    523   template <typename DReg_t, typename SReg_t, DReg_t (*destEnc)(RegNumT),
    524             SReg_t (*srcEnc)(RegNumT)>
    525   static void emitIASCastRegOp(const Cfg *Func, Type DestTy,
    526                                const Variable *Dest, Type SrcTy,
    527                                const Operand *Src,
    528                                const CastEmitterRegOp<DReg_t, SReg_t> &Emitter);
    529 
    530   template <typename DReg_t, typename SReg_t, DReg_t (*destEnc)(RegNumT),
    531             SReg_t (*srcEnc)(RegNumT)>
    532   static void
    533   emitIASThreeOpImmOps(const Cfg *Func, Type DispatchTy, const Variable *Dest,
    534                        const Operand *Src0, const Operand *Src1,
    535                        const ThreeOpImmEmitter<DReg_t, SReg_t> Emitter);
    536 
    537   static void emitIASMovlikeXMM(const Cfg *Func, const Variable *Dest,
    538                                 const Operand *Src,
    539                                 const XmmEmitterMovOps Emitter);
    540 
    541   static void emitVariableBlendInst(const char *Opcode, const Inst *Instr,
    542                                     const Cfg *Func);
    543 
    544   static void emitIASVariableBlendInst(const Inst *Instr, const Cfg *Func,
    545                                        const XmmEmitterRegOp &Emitter);
    546 
    547   static void emitIASXmmShift(const Cfg *Func, Type Ty, const Variable *Var,
    548                               const Operand *Src,
    549                               const XmmEmitterShiftOp &Emitter);
    550 
    551   /// Emit a two-operand (GPR) instruction, where the dest operand is a Variable
    552   /// that's guaranteed to be a register.
    553   template <bool VarCanBeByte = true, bool SrcCanBeByte = true>
    554   static void emitIASRegOpTyGPR(const Cfg *Func, bool IsLea, Type Ty,
    555                                 const Variable *Dst, const Operand *Src,
    556                                 const GPREmitterRegOp &Emitter);
    557 
    558   /// Instructions of the form x := op(x).
    559   template <typename InstX86Base::InstKindX86 K>
    560   class InstX86BaseInplaceopGPR : public InstX86Base {
    561     InstX86BaseInplaceopGPR() = delete;
    562     InstX86BaseInplaceopGPR(const InstX86BaseInplaceopGPR &) = delete;
    563     InstX86BaseInplaceopGPR &
    564     operator=(const InstX86BaseInplaceopGPR &) = delete;
    565 
    566   public:
    567     using Base = InstX86BaseInplaceopGPR<K>;
    568 
    569     void emit(const Cfg *Func) const override {
    570       if (!BuildDefs::dump())
    571         return;
    572       Ostream &Str = Func->getContext()->getStrEmit();
    573       assert(this->getSrcSize() == 1);
    574       Str << "\t" << Opcode << "\t";
    575       this->getSrc(0)->emit(Func);
    576     }
    577     void emitIAS(const Cfg *Func) const override {
    578       assert(this->getSrcSize() == 1);
    579       const Variable *Var = this->getDest();
    580       Type Ty = Var->getType();
    581       emitIASOpTyGPR(Func, Ty, Var, Emitter);
    582     }
    583     void dump(const Cfg *Func) const override {
    584       if (!BuildDefs::dump())
    585         return;
    586       Ostream &Str = Func->getContext()->getStrDump();
    587       this->dumpDest(Func);
    588       Str << " = " << Opcode << "." << this->getDest()->getType() << " ";
    589       this->dumpSources(Func);
    590     }
    591     static bool classof(const Inst *Instr) {
    592       return InstX86Base::isClassof(Instr, InstX86Base::K);
    593     }
    594 
    595   protected:
    596     InstX86BaseInplaceopGPR(Cfg *Func, Operand *SrcDest)
    597         : InstX86Base(Func, K, 1, llvm::dyn_cast<Variable>(SrcDest)) {
    598       this->addSource(SrcDest);
    599     }
    600 
    601   private:
    602     static const char *Opcode;
    603     static const GPREmitterOneOp Emitter;
    604   };
    605 
    606   /// Instructions of the form x := op(y).
    607   template <typename InstX86Base::InstKindX86 K>
    608   class InstX86BaseUnaryopGPR : public InstX86Base {
    609     InstX86BaseUnaryopGPR() = delete;
    610     InstX86BaseUnaryopGPR(const InstX86BaseUnaryopGPR &) = delete;
    611     InstX86BaseUnaryopGPR &operator=(const InstX86BaseUnaryopGPR &) = delete;
    612 
    613   public:
    614     using Base = InstX86BaseUnaryopGPR<K>;
    615 
    616     void emit(const Cfg *Func) const override {
    617       if (!BuildDefs::dump())
    618         return;
    619       Ostream &Str = Func->getContext()->getStrEmit();
    620       assert(this->getSrcSize() == 1);
    621       Type SrcTy = this->getSrc(0)->getType();
    622       Type DestTy = this->getDest()->getType();
    623       Str << "\t" << Opcode << this->getWidthString(SrcTy);
    624       // Movsx and movzx need both the source and dest type width letter to
    625       // define the operation. The other unary operations have the same source
    626       // and dest type and as a result need only one letter.
    627       if (SrcTy != DestTy)
    628         Str << this->getWidthString(DestTy);
    629       Str << "\t";
    630       this->getSrc(0)->emit(Func);
    631       Str << ", ";
    632       this->getDest()->emit(Func);
    633     }
    634     void emitIAS(const Cfg *Func) const override {
    635       assert(this->getSrcSize() == 1);
    636       const Variable *Var = this->getDest();
    637       Type Ty = Var->getType();
    638       const Operand *Src = this->getSrc(0);
    639       constexpr bool IsLea = K == InstX86Base::Lea;
    640 
    641       if (IsLea) {
    642         if (auto *Add = deoptLeaToAddOrNull(Func)) {
    643           Add->emitIAS(Func);
    644           return;
    645         }
    646       }
    647       emitIASRegOpTyGPR(Func, IsLea, Ty, Var, Src, Emitter);
    648     }
    649     void dump(const Cfg *Func) const override {
    650       if (!BuildDefs::dump())
    651         return;
    652       Ostream &Str = Func->getContext()->getStrDump();
    653       this->dumpDest(Func);
    654       Str << " = " << Opcode << "." << this->getSrc(0)->getType() << " ";
    655       this->dumpSources(Func);
    656     }
    657 
    658     static bool classof(const Inst *Instr) {
    659       return InstX86Base::isClassof(Instr, InstX86Base::K);
    660     }
    661 
    662   protected:
    663     InstX86BaseUnaryopGPR(Cfg *Func, Variable *Dest, Operand *Src)
    664         : InstX86Base(Func, K, 1, Dest) {
    665       this->addSource(Src);
    666     }
    667 
    668     Inst *deoptLeaToAddOrNull(const Cfg *Func) const {
    669       // Revert back to Add when the Lea is a 2-address instruction.
    670       // Caller has to emit, this just produces the add instruction.
    671       if (auto *MemOp = llvm::dyn_cast<X86OperandMem>(this->getSrc(0))) {
    672         if (getFlags().getAggressiveLea() &&
    673             MemOp->getBase()->getRegNum() == this->getDest()->getRegNum() &&
    674             MemOp->getIndex() == nullptr && MemOp->getShift() == 0) {
    675           auto *Add = InstImpl<TraitsType>::InstX86Add::create(
    676               const_cast<Cfg *>(Func), this->getDest(), MemOp->getOffset());
    677           // TODO(manasijm): Remove const_cast by emitting code for add
    678           // directly.
    679           return Add;
    680         }
    681       }
    682       return nullptr;
    683     }
    684 
    685     static const char *Opcode;
    686     static const GPREmitterRegOp Emitter;
    687   };
    688 
    689   template <typename InstX86Base::InstKindX86 K>
    690   class InstX86BaseUnaryopXmm : public InstX86Base {
    691     InstX86BaseUnaryopXmm() = delete;
    692     InstX86BaseUnaryopXmm(const InstX86BaseUnaryopXmm &) = delete;
    693     InstX86BaseUnaryopXmm &operator=(const InstX86BaseUnaryopXmm &) = delete;
    694 
    695   public:
    696     using Base = InstX86BaseUnaryopXmm<K>;
    697 
    698     void emit(const Cfg *Func) const override {
    699       if (!BuildDefs::dump())
    700         return;
    701       Ostream &Str = Func->getContext()->getStrEmit();
    702       assert(this->getSrcSize() == 1);
    703       Str << "\t" << Opcode << "\t";
    704       this->getSrc(0)->emit(Func);
    705       Str << ", ";
    706       this->getDest()->emit(Func);
    707     }
    708     void emitIAS(const Cfg *Func) const override {
    709       Type Ty = this->getDest()->getType();
    710       assert(this->getSrcSize() == 1);
    711       emitIASRegOpTyXMM(Func, Ty, this->getDest(), this->getSrc(0), Emitter);
    712     }
    713     void dump(const Cfg *Func) const override {
    714       if (!BuildDefs::dump())
    715         return;
    716       Ostream &Str = Func->getContext()->getStrDump();
    717       this->dumpDest(Func);
    718       Str << " = " << Opcode << "." << this->getDest()->getType() << " ";
    719       this->dumpSources(Func);
    720     }
    721     static bool classof(const Inst *Instr) {
    722       return InstX86Base::isClassof(Instr, InstX86Base::K);
    723     }
    724 
    725   protected:
    726     InstX86BaseUnaryopXmm(Cfg *Func, Variable *Dest, Operand *Src)
    727         : InstX86Base(Func, K, 1, Dest) {
    728       this->addSource(Src);
    729     }
    730 
    731     static const char *Opcode;
    732     static const XmmEmitterRegOp Emitter;
    733   };
    734 
    735   template <typename InstX86Base::InstKindX86 K>
    736   class InstX86BaseBinopGPRShift : public InstX86Base {
    737     InstX86BaseBinopGPRShift() = delete;
    738     InstX86BaseBinopGPRShift(const InstX86BaseBinopGPRShift &) = delete;
    739     InstX86BaseBinopGPRShift &
    740     operator=(const InstX86BaseBinopGPRShift &) = delete;
    741 
    742   public:
    743     using Base = InstX86BaseBinopGPRShift<K>;
    744 
    745     void emit(const Cfg *Func) const override {
    746       if (!BuildDefs::dump())
    747         return;
    748       this->emitTwoAddress(Func, Opcode);
    749     }
    750     void emitIAS(const Cfg *Func) const override {
    751       Type Ty = this->getDest()->getType();
    752       assert(this->getSrcSize() == 2);
    753       emitIASGPRShift(Func, Ty, this->getDest(), this->getSrc(1), Emitter);
    754     }
    755     void dump(const Cfg *Func) const override {
    756       if (!BuildDefs::dump())
    757         return;
    758       Ostream &Str = Func->getContext()->getStrDump();
    759       this->dumpDest(Func);
    760       Str << " = " << Opcode << "." << this->getDest()->getType() << " ";
    761       this->dumpSources(Func);
    762     }
    763     static bool classof(const Inst *Instr) {
    764       return InstX86Base::isClassof(Instr, InstX86Base::K);
    765     }
    766 
    767   protected:
    768     InstX86BaseBinopGPRShift(Cfg *Func, Variable *Dest, Operand *Source)
    769         : InstX86Base(Func, K, 2, Dest) {
    770       this->addSource(Dest);
    771       this->addSource(Source);
    772     }
    773 
    774     static const char *Opcode;
    775     static const GPREmitterShiftOp Emitter;
    776   };
    777 
    778   template <typename InstX86Base::InstKindX86 K>
    779   class InstX86BaseBinopGPR : public InstX86Base {
    780     InstX86BaseBinopGPR() = delete;
    781     InstX86BaseBinopGPR(const InstX86BaseBinopGPR &) = delete;
    782     InstX86BaseBinopGPR &operator=(const InstX86BaseBinopGPR &) = delete;
    783 
    784   public:
    785     using Base = InstX86BaseBinopGPR<K>;
    786 
    787     void emit(const Cfg *Func) const override {
    788       if (!BuildDefs::dump())
    789         return;
    790       this->emitTwoAddress(Func, Opcode);
    791     }
    792     void emitIAS(const Cfg *Func) const override {
    793       Type Ty = this->getDest()->getType();
    794       assert(this->getSrcSize() == 2);
    795       constexpr bool ThisIsLEA = K == InstX86Base::Lea;
    796       static_assert(!ThisIsLEA, "Lea should be a unaryop.");
    797       emitIASRegOpTyGPR(Func, !ThisIsLEA, Ty, this->getDest(), this->getSrc(1),
    798                         Emitter);
    799     }
    800     void dump(const Cfg *Func) const override {
    801       if (!BuildDefs::dump())
    802         return;
    803       Ostream &Str = Func->getContext()->getStrDump();
    804       this->dumpDest(Func);
    805       Str << " = " << Opcode << "." << this->getDest()->getType() << " ";
    806       this->dumpSources(Func);
    807     }
    808     static bool classof(const Inst *Instr) {
    809       return InstX86Base::isClassof(Instr, InstX86Base::K);
    810     }
    811 
    812   protected:
    813     InstX86BaseBinopGPR(Cfg *Func, Variable *Dest, Operand *Source)
    814         : InstX86Base(Func, K, 2, Dest) {
    815       this->addSource(Dest);
    816       this->addSource(Source);
    817     }
    818 
    819     static const char *Opcode;
    820     static const GPREmitterRegOp Emitter;
    821   };
    822 
    823   template <typename InstX86Base::InstKindX86 K>
    824   class InstX86BaseBinopRMW : public InstX86Base {
    825     InstX86BaseBinopRMW() = delete;
    826     InstX86BaseBinopRMW(const InstX86BaseBinopRMW &) = delete;
    827     InstX86BaseBinopRMW &operator=(const InstX86BaseBinopRMW &) = delete;
    828 
    829   public:
    830     using Base = InstX86BaseBinopRMW<K>;
    831 
    832     void emit(const Cfg *Func) const override {
    833       if (!BuildDefs::dump())
    834         return;
    835       this->emitTwoAddress(Func, Opcode);
    836     }
    837     void emitIAS(const Cfg *Func) const override {
    838       Type Ty = this->getSrc(0)->getType();
    839       assert(this->getSrcSize() == 2);
    840       emitIASAsAddrOpTyGPR(Func, Ty, this->getSrc(0), this->getSrc(1), Emitter);
    841     }
    842     void dump(const Cfg *Func) const override {
    843       if (!BuildDefs::dump())
    844         return;
    845       Ostream &Str = Func->getContext()->getStrDump();
    846       Str << Opcode << "." << this->getSrc(0)->getType() << " ";
    847       this->dumpSources(Func);
    848     }
    849     static bool classof(const Inst *Instr) {
    850       return InstX86Base::isClassof(Instr, InstX86Base::K);
    851     }
    852 
    853   protected:
    854     InstX86BaseBinopRMW(Cfg *Func, X86OperandMem *DestSrc0, Operand *Src1)
    855         : InstX86Base(Func, K, 2, nullptr) {
    856       this->addSource(DestSrc0);
    857       this->addSource(Src1);
    858     }
    859 
    860     static const char *Opcode;
    861     static const GPREmitterAddrOp Emitter;
    862   };
    863 
    864   template <typename InstX86Base::InstKindX86 K, bool NeedsElementType,
    865             typename InstX86Base::SseSuffix Suffix>
    866   class InstX86BaseBinopXmm : public InstX86Base {
    867     InstX86BaseBinopXmm() = delete;
    868     InstX86BaseBinopXmm(const InstX86BaseBinopXmm &) = delete;
    869     InstX86BaseBinopXmm &operator=(const InstX86BaseBinopXmm &) = delete;
    870 
    871   public:
    872     using Base = InstX86BaseBinopXmm<K, NeedsElementType, Suffix>;
    873 
    874     void emit(const Cfg *Func) const override {
    875       if (!BuildDefs::dump())
    876         return;
    877       this->validateVectorAddrMode();
    878       const Type DestTy = ArithmeticTypeOverride == IceType_void
    879                               ? this->getDest()->getType()
    880                               : ArithmeticTypeOverride;
    881       const char *SuffixString = "";
    882       switch (Suffix) {
    883       case InstX86Base::SseSuffix::None:
    884         break;
    885       case InstX86Base::SseSuffix::Packed:
    886         SuffixString = Traits::TypeAttributes[DestTy].PdPsString;
    887         break;
    888       case InstX86Base::SseSuffix::Unpack:
    889         SuffixString = Traits::TypeAttributes[DestTy].UnpackString;
    890         break;
    891       case InstX86Base::SseSuffix::Scalar:
    892         SuffixString = Traits::TypeAttributes[DestTy].SdSsString;
    893         break;
    894       case InstX86Base::SseSuffix::Integral:
    895         SuffixString = Traits::TypeAttributes[DestTy].IntegralString;
    896         break;
    897       case InstX86Base::SseSuffix::Pack:
    898         SuffixString = Traits::TypeAttributes[DestTy].PackString;
    899         break;
    900       }
    901       this->emitTwoAddress(Func, Opcode, SuffixString);
    902     }
    903     void emitIAS(const Cfg *Func) const override {
    904       this->validateVectorAddrMode();
    905       Type Ty = this->getDest()->getType();
    906       if (NeedsElementType)
    907         Ty = typeElementType(Ty);
    908       assert(this->getSrcSize() == 2);
    909       emitIASRegOpTyXMM(Func, Ty, this->getDest(), this->getSrc(1), Emitter);
    910     }
    911     void dump(const Cfg *Func) const override {
    912       if (!BuildDefs::dump())
    913         return;
    914       Ostream &Str = Func->getContext()->getStrDump();
    915       this->dumpDest(Func);
    916       Str << " = " << Opcode << "." << this->getDest()->getType() << " ";
    917       this->dumpSources(Func);
    918     }
    919     static bool classof(const Inst *Instr) {
    920       return InstX86Base::isClassof(Instr, InstX86Base::K);
    921     }
    922 
    923   protected:
    924     InstX86BaseBinopXmm(Cfg *Func, Variable *Dest, Operand *Source,
    925                         Type ArithmeticTypeOverride = IceType_void)
    926         : InstX86Base(Func, K, 2, Dest),
    927           ArithmeticTypeOverride(ArithmeticTypeOverride) {
    928       this->addSource(Dest);
    929       this->addSource(Source);
    930     }
    931 
    932     const Type ArithmeticTypeOverride;
    933     static const char *Opcode;
    934     static const XmmEmitterRegOp Emitter;
    935   };
    936 
    937   template <typename InstX86Base::InstKindX86 K, bool AllowAllTypes = false>
    938   class InstX86BaseBinopXmmShift : public InstX86Base {
    939     InstX86BaseBinopXmmShift() = delete;
    940     InstX86BaseBinopXmmShift(const InstX86BaseBinopXmmShift &) = delete;
    941     InstX86BaseBinopXmmShift &
    942     operator=(const InstX86BaseBinopXmmShift &) = delete;
    943 
    944   public:
    945     using Base = InstX86BaseBinopXmmShift<K, AllowAllTypes>;
    946 
    947     void emit(const Cfg *Func) const override {
    948       if (!BuildDefs::dump())
    949         return;
    950       this->validateVectorAddrMode();
    951       // Shift operations are always integral, and hence always need a suffix.
    952       const Type DestTy = this->getDest()->getType();
    953       this->emitTwoAddress(Func, this->Opcode,
    954                            Traits::TypeAttributes[DestTy].IntegralString);
    955     }
    956     void emitIAS(const Cfg *Func) const override {
    957       this->validateVectorAddrMode();
    958       Type Ty = this->getDest()->getType();
    959       assert(AllowAllTypes || isVectorType(Ty));
    960       Type ElementTy = typeElementType(Ty);
    961       assert(this->getSrcSize() == 2);
    962       emitIASXmmShift(Func, ElementTy, this->getDest(), this->getSrc(1),
    963                       Emitter);
    964     }
    965     void dump(const Cfg *Func) const override {
    966       if (!BuildDefs::dump())
    967         return;
    968       Ostream &Str = Func->getContext()->getStrDump();
    969       this->dumpDest(Func);
    970       Str << " = " << Opcode << "." << this->getDest()->getType() << " ";
    971       this->dumpSources(Func);
    972     }
    973     static bool classof(const Inst *Instr) {
    974       return InstX86Base::isClassof(Instr, InstX86Base::K);
    975     }
    976 
    977   protected:
    978     InstX86BaseBinopXmmShift(Cfg *Func, Variable *Dest, Operand *Source)
    979         : InstX86Base(Func, K, 2, Dest) {
    980       this->addSource(Dest);
    981       this->addSource(Source);
    982     }
    983 
    984     static const char *Opcode;
    985     static const XmmEmitterShiftOp Emitter;
    986   };
    987 
    988   template <typename InstX86Base::InstKindX86 K>
    989   class InstX86BaseTernop : public InstX86Base {
    990     InstX86BaseTernop() = delete;
    991     InstX86BaseTernop(const InstX86BaseTernop &) = delete;
    992     InstX86BaseTernop &operator=(const InstX86BaseTernop &) = delete;
    993 
    994   public:
    995     using Base = InstX86BaseTernop<K>;
    996 
    997     void emit(const Cfg *Func) const override {
    998       if (!BuildDefs::dump())
    999         return;
   1000       Ostream &Str = Func->getContext()->getStrEmit();
   1001       assert(this->getSrcSize() == 3);
   1002       Str << "\t" << Opcode << "\t";
   1003       this->getSrc(2)->emit(Func);
   1004       Str << ", ";
   1005       this->getSrc(1)->emit(Func);
   1006       Str << ", ";
   1007       this->getDest()->emit(Func);
   1008     }
   1009     void dump(const Cfg *Func) const override {
   1010       if (!BuildDefs::dump())
   1011         return;
   1012       Ostream &Str = Func->getContext()->getStrDump();
   1013       this->dumpDest(Func);
   1014       Str << " = " << Opcode << "." << this->getDest()->getType() << " ";
   1015       this->dumpSources(Func);
   1016     }
   1017     static bool classof(const Inst *Instr) {
   1018       return InstX86Base::isClassof(Instr, InstX86Base::K);
   1019     }
   1020 
   1021   protected:
   1022     InstX86BaseTernop(Cfg *Func, Variable *Dest, Operand *Source1,
   1023                       Operand *Source2)
   1024         : InstX86Base(Func, K, 3, Dest) {
   1025       this->addSource(Dest);
   1026       this->addSource(Source1);
   1027       this->addSource(Source2);
   1028     }
   1029 
   1030     static const char *Opcode;
   1031   };
   1032 
   1033   // Instructions of the form x := y op z
   1034   template <typename InstX86Base::InstKindX86 K>
   1035   class InstX86BaseThreeAddressop : public InstX86Base {
   1036     InstX86BaseThreeAddressop() = delete;
   1037     InstX86BaseThreeAddressop(const InstX86BaseThreeAddressop &) = delete;
   1038     InstX86BaseThreeAddressop &
   1039     operator=(const InstX86BaseThreeAddressop &) = delete;
   1040 
   1041   public:
   1042     using Base = InstX86BaseThreeAddressop<K>;
   1043 
   1044     void emit(const Cfg *Func) const override {
   1045       if (!BuildDefs::dump())
   1046         return;
   1047       Ostream &Str = Func->getContext()->getStrEmit();
   1048       assert(this->getSrcSize() == 2);
   1049       Str << "\t" << Opcode << "\t";
   1050       this->getSrc(1)->emit(Func);
   1051       Str << ", ";
   1052       this->getSrc(0)->emit(Func);
   1053       Str << ", ";
   1054       this->getDest()->emit(Func);
   1055     }
   1056     void dump(const Cfg *Func) const override {
   1057       if (!BuildDefs::dump())
   1058         return;
   1059       Ostream &Str = Func->getContext()->getStrDump();
   1060       this->dumpDest(Func);
   1061       Str << " = " << Opcode << "." << this->getDest()->getType() << " ";
   1062       this->dumpSources(Func);
   1063     }
   1064     static bool classof(const Inst *Instr) {
   1065       return InstX86Base::isClassof(Instr, InstX86Base::K);
   1066     }
   1067 
   1068   protected:
   1069     InstX86BaseThreeAddressop(Cfg *Func, Variable *Dest, Operand *Source0,
   1070                               Operand *Source1)
   1071         : InstX86Base(Func, K, 2, Dest) {
   1072       this->addSource(Source0);
   1073       this->addSource(Source1);
   1074     }
   1075 
   1076     static const char *Opcode;
   1077   };
   1078 
   1079   /// Base class for assignment instructions
   1080   template <typename InstX86Base::InstKindX86 K>
   1081   class InstX86BaseMovlike : public InstX86Base {
   1082     InstX86BaseMovlike() = delete;
   1083     InstX86BaseMovlike(const InstX86BaseMovlike &) = delete;
   1084     InstX86BaseMovlike &operator=(const InstX86BaseMovlike &) = delete;
   1085 
   1086   public:
   1087     using Base = InstX86BaseMovlike<K>;
   1088 
   1089     bool isRedundantAssign() const override {
   1090       if (const auto *SrcVar =
   1091               llvm::dyn_cast<const Variable>(this->getSrc(0))) {
   1092         if (SrcVar->hasReg() && this->Dest->hasReg()) {
   1093           // An assignment between physical registers is considered redundant if
   1094           // they have the same base register and the same encoding. E.g.:
   1095           //   mov cl, ecx ==> redundant
   1096           //   mov ch, ecx ==> not redundant due to different encodings
   1097           //   mov ch, ebp ==> not redundant due to different base registers
   1098           //   mov ecx, ecx ==> redundant, and dangerous in x86-64. i64 zexting
   1099           //                    is handled by Inst86Zext.
   1100           const auto SrcReg = SrcVar->getRegNum();
   1101           const auto DestReg = this->Dest->getRegNum();
   1102           return (Traits::getEncoding(SrcReg) ==
   1103                   Traits::getEncoding(DestReg)) &&
   1104                  (Traits::getBaseReg(SrcReg) == Traits::getBaseReg(DestReg));
   1105         }
   1106       }
   1107       return checkForRedundantAssign(this->getDest(), this->getSrc(0));
   1108     }
   1109     bool isVarAssign() const override {
   1110       return llvm::isa<Variable>(this->getSrc(0));
   1111     }
   1112     void dump(const Cfg *Func) const override {
   1113       if (!BuildDefs::dump())
   1114         return;
   1115       Ostream &Str = Func->getContext()->getStrDump();
   1116       Str << Opcode << "." << this->getDest()->getType() << " ";
   1117       this->dumpDest(Func);
   1118       Str << ", ";
   1119       this->dumpSources(Func);
   1120     }
   1121     static bool classof(const Inst *Instr) {
   1122       return InstX86Base::isClassof(Instr, InstX86Base::K);
   1123     }
   1124 
   1125   protected:
   1126     InstX86BaseMovlike(Cfg *Func, Variable *Dest, Operand *Source)
   1127         : InstX86Base(Func, K, 1, Dest) {
   1128       this->addSource(Source);
   1129       // For an integer assignment, make sure it's either a same-type assignment
   1130       // or a truncation.
   1131       assert(!isScalarIntegerType(Dest->getType()) ||
   1132              (typeWidthInBytes(Dest->getType()) <=
   1133               typeWidthInBytes(Source->getType())));
   1134     }
   1135 
   1136     static const char *Opcode;
   1137   };
   1138 
   1139   class InstX86Bswap : public InstX86BaseInplaceopGPR<InstX86Base::Bswap> {
   1140   public:
   1141     static InstX86Bswap *create(Cfg *Func, Operand *SrcDest) {
   1142       return new (Func->allocate<InstX86Bswap>()) InstX86Bswap(Func, SrcDest);
   1143     }
   1144 
   1145   private:
   1146     InstX86Bswap(Cfg *Func, Operand *SrcDest)
   1147         : InstX86BaseInplaceopGPR<InstX86Base::Bswap>(Func, SrcDest) {}
   1148   };
   1149 
   1150   class InstX86Neg : public InstX86BaseInplaceopGPR<InstX86Base::Neg> {
   1151   public:
   1152     static InstX86Neg *create(Cfg *Func, Operand *SrcDest) {
   1153       return new (Func->allocate<InstX86Neg>()) InstX86Neg(Func, SrcDest);
   1154     }
   1155 
   1156   private:
   1157     InstX86Neg(Cfg *Func, Operand *SrcDest)
   1158         : InstX86BaseInplaceopGPR<InstX86Base::Neg>(Func, SrcDest) {}
   1159   };
   1160 
   1161   class InstX86Bsf : public InstX86BaseUnaryopGPR<InstX86Base::Bsf> {
   1162   public:
   1163     static InstX86Bsf *create(Cfg *Func, Variable *Dest, Operand *Src) {
   1164       return new (Func->allocate<InstX86Bsf>()) InstX86Bsf(Func, Dest, Src);
   1165     }
   1166 
   1167   private:
   1168     InstX86Bsf(Cfg *Func, Variable *Dest, Operand *Src)
   1169         : InstX86BaseUnaryopGPR<InstX86Base::Bsf>(Func, Dest, Src) {}
   1170   };
   1171 
   1172   class InstX86Bsr : public InstX86BaseUnaryopGPR<InstX86Base::Bsr> {
   1173   public:
   1174     static InstX86Bsr *create(Cfg *Func, Variable *Dest, Operand *Src) {
   1175       return new (Func->allocate<InstX86Bsr>()) InstX86Bsr(Func, Dest, Src);
   1176     }
   1177 
   1178   private:
   1179     InstX86Bsr(Cfg *Func, Variable *Dest, Operand *Src)
   1180         : InstX86BaseUnaryopGPR<InstX86Base::Bsr>(Func, Dest, Src) {}
   1181   };
   1182 
   1183   class InstX86Lea : public InstX86BaseUnaryopGPR<InstX86Base::Lea> {
   1184   public:
   1185     static InstX86Lea *create(Cfg *Func, Variable *Dest, Operand *Src) {
   1186       return new (Func->allocate<InstX86Lea>()) InstX86Lea(Func, Dest, Src);
   1187     }
   1188 
   1189     void emit(const Cfg *Func) const override;
   1190 
   1191   private:
   1192     InstX86Lea(Cfg *Func, Variable *Dest, Operand *Src)
   1193         : InstX86BaseUnaryopGPR<InstX86Base::Lea>(Func, Dest, Src) {}
   1194   };
   1195 
   1196   // Cbwdq instruction - wrapper for cbw, cwd, and cdq
   1197   class InstX86Cbwdq : public InstX86BaseUnaryopGPR<InstX86Base::Cbwdq> {
   1198   public:
   1199     static InstX86Cbwdq *create(Cfg *Func, Variable *Dest, Operand *Src) {
   1200       return new (Func->allocate<InstX86Cbwdq>()) InstX86Cbwdq(Func, Dest, Src);
   1201     }
   1202 
   1203     void emit(const Cfg *Func) const override;
   1204     void emitIAS(const Cfg *Func) const override;
   1205 
   1206   private:
   1207     InstX86Cbwdq(Cfg *Func, Variable *Dest, Operand *Src)
   1208         : InstX86BaseUnaryopGPR<InstX86Base::Cbwdq>(Func, Dest, Src) {}
   1209   };
   1210 
   1211   class InstX86Movsx : public InstX86BaseUnaryopGPR<InstX86Base::Movsx> {
   1212   public:
   1213     static InstX86Movsx *create(Cfg *Func, Variable *Dest, Operand *Src) {
   1214       assert(typeWidthInBytes(Dest->getType()) >
   1215              typeWidthInBytes(Src->getType()));
   1216       return new (Func->allocate<InstX86Movsx>()) InstX86Movsx(Func, Dest, Src);
   1217     }
   1218 
   1219     void emitIAS(const Cfg *Func) const override;
   1220 
   1221   private:
   1222     InstX86Movsx(Cfg *Func, Variable *Dest, Operand *Src)
   1223         : InstX86BaseUnaryopGPR<InstX86Base::Movsx>(Func, Dest, Src) {}
   1224   };
   1225 
   1226   class InstX86Movzx : public InstX86BaseUnaryopGPR<InstX86Base::Movzx> {
   1227   public:
   1228     static InstX86Movzx *create(Cfg *Func, Variable *Dest, Operand *Src) {
   1229       assert(typeWidthInBytes(Dest->getType()) >
   1230              typeWidthInBytes(Src->getType()));
   1231       return new (Func->allocate<InstX86Movzx>()) InstX86Movzx(Func, Dest, Src);
   1232     }
   1233 
   1234     void emit(const Cfg *Func) const override;
   1235 
   1236     void emitIAS(const Cfg *Func) const override;
   1237 
   1238     void setMustKeep() { MustKeep = true; }
   1239 
   1240   private:
   1241     bool MustKeep = false;
   1242 
   1243     InstX86Movzx(Cfg *Func, Variable *Dest, Operand *Src)
   1244         : InstX86BaseUnaryopGPR<InstX86Base::Movzx>(Func, Dest, Src) {}
   1245 
   1246     bool mayBeElided(const Variable *Dest, const Operand *Src) const;
   1247   };
   1248 
   1249   class InstX86Movd : public InstX86BaseUnaryopXmm<InstX86Base::Movd> {
   1250   public:
   1251     static InstX86Movd *create(Cfg *Func, Variable *Dest, Operand *Src) {
   1252       return new (Func->allocate<InstX86Movd>()) InstX86Movd(Func, Dest, Src);
   1253     }
   1254 
   1255     void emit(const Cfg *Func) const override;
   1256 
   1257     void emitIAS(const Cfg *Func) const override;
   1258 
   1259   private:
   1260     InstX86Movd(Cfg *Func, Variable *Dest, Operand *Src)
   1261         : InstX86BaseUnaryopXmm<InstX86Base::Movd>(Func, Dest, Src) {}
   1262   };
   1263 
   1264   class InstX86Movmsk final : public InstX86Base {
   1265     InstX86Movmsk() = delete;
   1266     InstX86Movmsk(const InstX86Movmsk &) = delete;
   1267     InstX86Movmsk &operator=(const InstX86Movmsk &) = delete;
   1268 
   1269   public:
   1270     static InstX86Movmsk *create(Cfg *Func, Variable *Dest, Operand *Source) {
   1271       return new (Func->allocate<InstX86Movmsk>())
   1272           InstX86Movmsk(Func, Dest, Source);
   1273     }
   1274     void emit(const Cfg *Func) const override;
   1275     void emitIAS(const Cfg *Func) const override;
   1276     void dump(const Cfg *Func) const override;
   1277     static bool classof(const Inst *Instr) {
   1278       return InstX86Base::isClassof(Instr, InstX86Base::InstX86Movmsk);
   1279     }
   1280 
   1281   private:
   1282     InstX86Movmsk(Cfg *Func, Variable *Dest, Operand *Source);
   1283   };
   1284 
   1285   class InstX86Sqrt : public InstX86BaseUnaryopXmm<InstX86Base::Sqrt> {
   1286   public:
   1287     static InstX86Sqrt *create(Cfg *Func, Variable *Dest, Operand *Src) {
   1288       return new (Func->allocate<InstX86Sqrt>()) InstX86Sqrt(Func, Dest, Src);
   1289     }
   1290 
   1291     virtual void emit(const Cfg *Func) const override;
   1292 
   1293   private:
   1294     InstX86Sqrt(Cfg *Func, Variable *Dest, Operand *Src)
   1295         : InstX86BaseUnaryopXmm<InstX86Base::Sqrt>(Func, Dest, Src) {}
   1296   };
   1297 
   1298   /// Move/assignment instruction - wrapper for mov/movss/movsd.
   1299   class InstX86Mov : public InstX86BaseMovlike<InstX86Base::Mov> {
   1300   public:
   1301     static InstX86Mov *create(Cfg *Func, Variable *Dest, Operand *Source) {
   1302       assert(!isScalarIntegerType(Dest->getType()) ||
   1303              (typeWidthInBytes(Dest->getType()) <=
   1304               typeWidthInBytes(Source->getType())));
   1305       return new (Func->allocate<InstX86Mov>()) InstX86Mov(Func, Dest, Source);
   1306     }
   1307 
   1308     void emit(const Cfg *Func) const override;
   1309     void emitIAS(const Cfg *Func) const override;
   1310 
   1311   private:
   1312     InstX86Mov(Cfg *Func, Variable *Dest, Operand *Source)
   1313         : InstX86BaseMovlike<InstX86Base::Mov>(Func, Dest, Source) {}
   1314   };
   1315 
   1316   /// Move packed - copy 128 bit values between XMM registers, or mem128 and XMM
   1317   /// registers.
   1318   class InstX86Movp : public InstX86BaseMovlike<InstX86Base::Movp> {
   1319   public:
   1320     static InstX86Movp *create(Cfg *Func, Variable *Dest, Operand *Source) {
   1321       return new (Func->allocate<InstX86Movp>())
   1322           InstX86Movp(Func, Dest, Source);
   1323     }
   1324 
   1325     void emit(const Cfg *Func) const override;
   1326     void emitIAS(const Cfg *Func) const override;
   1327 
   1328   private:
   1329     InstX86Movp(Cfg *Func, Variable *Dest, Operand *Source)
   1330         : InstX86BaseMovlike<InstX86Base::Movp>(Func, Dest, Source) {}
   1331   };
   1332 
   1333   /// Movq - copy between XMM registers, or mem64 and XMM registers.
   1334   class InstX86Movq : public InstX86BaseMovlike<InstX86Base::Movq> {
   1335   public:
   1336     static InstX86Movq *create(Cfg *Func, Variable *Dest, Operand *Source) {
   1337       return new (Func->allocate<InstX86Movq>())
   1338           InstX86Movq(Func, Dest, Source);
   1339     }
   1340 
   1341     void emit(const Cfg *Func) const override;
   1342     void emitIAS(const Cfg *Func) const override;
   1343 
   1344   private:
   1345     InstX86Movq(Cfg *Func, Variable *Dest, Operand *Source)
   1346         : InstX86BaseMovlike<InstX86Base::Movq>(Func, Dest, Source) {}
   1347   };
   1348 
   1349   class InstX86Add : public InstX86BaseBinopGPR<InstX86Base::Add> {
   1350   public:
   1351     static InstX86Add *create(Cfg *Func, Variable *Dest, Operand *Source) {
   1352       return new (Func->allocate<InstX86Add>()) InstX86Add(Func, Dest, Source);
   1353     }
   1354 
   1355   private:
   1356     InstX86Add(Cfg *Func, Variable *Dest, Operand *Source)
   1357         : InstX86BaseBinopGPR<InstX86Base::Add>(Func, Dest, Source) {}
   1358   };
   1359 
   1360   class InstX86AddRMW : public InstX86BaseBinopRMW<InstX86Base::AddRMW> {
   1361   public:
   1362     static InstX86AddRMW *create(Cfg *Func, X86OperandMem *DestSrc0,
   1363                                  Operand *Src1) {
   1364       return new (Func->allocate<InstX86AddRMW>())
   1365           InstX86AddRMW(Func, DestSrc0, Src1);
   1366     }
   1367 
   1368   private:
   1369     InstX86AddRMW(Cfg *Func, X86OperandMem *DestSrc0, Operand *Src1)
   1370         : InstX86BaseBinopRMW<InstX86Base::AddRMW>(Func, DestSrc0, Src1) {}
   1371   };
   1372 
   1373   class InstX86Addps
   1374       : public InstX86BaseBinopXmm<InstX86Base::Addps, true,
   1375                                    InstX86Base::SseSuffix::Packed> {
   1376   public:
   1377     static InstX86Addps *create(Cfg *Func, Variable *Dest, Operand *Source) {
   1378       return new (Func->allocate<InstX86Addps>())
   1379           InstX86Addps(Func, Dest, Source);
   1380     }
   1381 
   1382   private:
   1383     InstX86Addps(Cfg *Func, Variable *Dest, Operand *Source)
   1384         : InstX86BaseBinopXmm<InstX86Base::Addps, true,
   1385                               InstX86Base::SseSuffix::Packed>(Func, Dest,
   1386                                                               Source) {}
   1387   };
   1388 
   1389   class InstX86Adc : public InstX86BaseBinopGPR<InstX86Base::Adc> {
   1390   public:
   1391     static InstX86Adc *create(Cfg *Func, Variable *Dest, Operand *Source) {
   1392       return new (Func->allocate<InstX86Adc>()) InstX86Adc(Func, Dest, Source);
   1393     }
   1394 
   1395   private:
   1396     InstX86Adc(Cfg *Func, Variable *Dest, Operand *Source)
   1397         : InstX86BaseBinopGPR<InstX86Base::Adc>(Func, Dest, Source) {}
   1398   };
   1399 
   1400   class InstX86AdcRMW : public InstX86BaseBinopRMW<InstX86Base::AdcRMW> {
   1401   public:
   1402     static InstX86AdcRMW *create(Cfg *Func, X86OperandMem *DestSrc0,
   1403                                  Operand *Src1) {
   1404       return new (Func->allocate<InstX86AdcRMW>())
   1405           InstX86AdcRMW(Func, DestSrc0, Src1);
   1406     }
   1407 
   1408   private:
   1409     InstX86AdcRMW(Cfg *Func, X86OperandMem *DestSrc0, Operand *Src1)
   1410         : InstX86BaseBinopRMW<InstX86Base::AdcRMW>(Func, DestSrc0, Src1) {}
   1411   };
   1412 
   1413   class InstX86Addss
   1414       : public InstX86BaseBinopXmm<InstX86Base::Addss, false,
   1415                                    InstX86Base::SseSuffix::Scalar> {
   1416   public:
   1417     static InstX86Addss *create(Cfg *Func, Variable *Dest, Operand *Source) {
   1418       return new (Func->allocate<InstX86Addss>())
   1419           InstX86Addss(Func, Dest, Source);
   1420     }
   1421 
   1422   private:
   1423     InstX86Addss(Cfg *Func, Variable *Dest, Operand *Source)
   1424         : InstX86BaseBinopXmm<InstX86Base::Addss, false,
   1425                               InstX86Base::SseSuffix::Scalar>(Func, Dest,
   1426                                                               Source) {}
   1427   };
   1428 
   1429   class InstX86Padd
   1430       : public InstX86BaseBinopXmm<InstX86Base::Padd, true,
   1431                                    InstX86Base::SseSuffix::Integral> {
   1432   public:
   1433     static InstX86Padd *create(Cfg *Func, Variable *Dest, Operand *Source) {
   1434       return new (Func->allocate<InstX86Padd>())
   1435           InstX86Padd(Func, Dest, Source);
   1436     }
   1437 
   1438   private:
   1439     InstX86Padd(Cfg *Func, Variable *Dest, Operand *Source)
   1440         : InstX86BaseBinopXmm<InstX86Base::Padd, true,
   1441                               InstX86Base::SseSuffix::Integral>(Func, Dest,
   1442                                                                 Source) {}
   1443   };
   1444 
   1445   class InstX86Padds
   1446       : public InstX86BaseBinopXmm<InstX86Base::Padds, true,
   1447                                    InstX86Base::SseSuffix::Integral> {
   1448   public:
   1449     static InstX86Padds *create(Cfg *Func, Variable *Dest, Operand *Source) {
   1450       return new (Func->allocate<InstX86Padds>())
   1451           InstX86Padds(Func, Dest, Source);
   1452     }
   1453 
   1454   private:
   1455     InstX86Padds(Cfg *Func, Variable *Dest, Operand *Source)
   1456         : InstX86BaseBinopXmm<InstX86Base::Padds, true,
   1457                               InstX86Base::SseSuffix::Integral>(Func, Dest,
   1458                                                                 Source) {}
   1459   };
   1460 
   1461   class InstX86Paddus
   1462       : public InstX86BaseBinopXmm<InstX86Base::Paddus, true,
   1463                                    InstX86Base::SseSuffix::Integral> {
   1464   public:
   1465     static InstX86Paddus *create(Cfg *Func, Variable *Dest, Operand *Source) {
   1466       return new (Func->allocate<InstX86Paddus>())
   1467           InstX86Paddus(Func, Dest, Source);
   1468     }
   1469 
   1470   private:
   1471     InstX86Paddus(Cfg *Func, Variable *Dest, Operand *Source)
   1472         : InstX86BaseBinopXmm<InstX86Base::Paddus, true,
   1473                               InstX86Base::SseSuffix::Integral>(Func, Dest,
   1474                                                                 Source) {}
   1475   };
   1476 
   1477   class InstX86Sub : public InstX86BaseBinopGPR<InstX86Base::Sub> {
   1478   public:
   1479     static InstX86Sub *create(Cfg *Func, Variable *Dest, Operand *Source) {
   1480       return new (Func->allocate<InstX86Sub>()) InstX86Sub(Func, Dest, Source);
   1481     }
   1482 
   1483   private:
   1484     InstX86Sub(Cfg *Func, Variable *Dest, Operand *Source)
   1485         : InstX86BaseBinopGPR<InstX86Base::Sub>(Func, Dest, Source) {}
   1486   };
   1487 
   1488   class InstX86SubRMW : public InstX86BaseBinopRMW<InstX86Base::SubRMW> {
   1489   public:
   1490     static InstX86SubRMW *create(Cfg *Func, X86OperandMem *DestSrc0,
   1491                                  Operand *Src1) {
   1492       return new (Func->allocate<InstX86SubRMW>())
   1493           InstX86SubRMW(Func, DestSrc0, Src1);
   1494     }
   1495 
   1496   private:
   1497     InstX86SubRMW(Cfg *Func, X86OperandMem *DestSrc0, Operand *Src1)
   1498         : InstX86BaseBinopRMW<InstX86Base::SubRMW>(Func, DestSrc0, Src1) {}
   1499   };
   1500 
   1501   class InstX86Subps
   1502       : public InstX86BaseBinopXmm<InstX86Base::Subps, true,
   1503                                    InstX86Base::SseSuffix::Packed> {
   1504   public:
   1505     static InstX86Subps *create(Cfg *Func, Variable *Dest, Operand *Source) {
   1506       return new (Func->allocate<InstX86Subps>())
   1507           InstX86Subps(Func, Dest, Source);
   1508     }
   1509 
   1510   private:
   1511     InstX86Subps(Cfg *Func, Variable *Dest, Operand *Source)
   1512         : InstX86BaseBinopXmm<InstX86Base::Subps, true,
   1513                               InstX86Base::SseSuffix::Packed>(Func, Dest,
   1514                                                               Source) {}
   1515   };
   1516 
   1517   class InstX86Subss
   1518       : public InstX86BaseBinopXmm<InstX86Base::Subss, false,
   1519                                    InstX86Base::SseSuffix::Scalar> {
   1520   public:
   1521     static InstX86Subss *create(Cfg *Func, Variable *Dest, Operand *Source) {
   1522       return new (Func->allocate<InstX86Subss>())
   1523           InstX86Subss(Func, Dest, Source);
   1524     }
   1525 
   1526   private:
   1527     InstX86Subss(Cfg *Func, Variable *Dest, Operand *Source)
   1528         : InstX86BaseBinopXmm<InstX86Base::Subss, false,
   1529                               InstX86Base::SseSuffix::Scalar>(Func, Dest,
   1530                                                               Source) {}
   1531   };
   1532 
   1533   class InstX86Sbb : public InstX86BaseBinopGPR<InstX86Base::Sbb> {
   1534   public:
   1535     static InstX86Sbb *create(Cfg *Func, Variable *Dest, Operand *Source) {
   1536       return new (Func->allocate<InstX86Sbb>()) InstX86Sbb(Func, Dest, Source);
   1537     }
   1538 
   1539   private:
   1540     InstX86Sbb(Cfg *Func, Variable *Dest, Operand *Source)
   1541         : InstX86BaseBinopGPR<InstX86Base::Sbb>(Func, Dest, Source) {}
   1542   };
   1543 
   1544   class InstX86SbbRMW : public InstX86BaseBinopRMW<InstX86Base::SbbRMW> {
   1545   public:
   1546     static InstX86SbbRMW *create(Cfg *Func, X86OperandMem *DestSrc0,
   1547                                  Operand *Src1) {
   1548       return new (Func->allocate<InstX86SbbRMW>())
   1549           InstX86SbbRMW(Func, DestSrc0, Src1);
   1550     }
   1551 
   1552   private:
   1553     InstX86SbbRMW(Cfg *Func, X86OperandMem *DestSrc0, Operand *Src1)
   1554         : InstX86BaseBinopRMW<InstX86Base::SbbRMW>(Func, DestSrc0, Src1) {}
   1555   };
   1556 
   1557   class InstX86Psub
   1558       : public InstX86BaseBinopXmm<InstX86Base::Psub, true,
   1559                                    InstX86Base::SseSuffix::Integral> {
   1560   public:
   1561     static InstX86Psub *create(Cfg *Func, Variable *Dest, Operand *Source) {
   1562       return new (Func->allocate<InstX86Psub>())
   1563           InstX86Psub(Func, Dest, Source);
   1564     }
   1565 
   1566   private:
   1567     InstX86Psub(Cfg *Func, Variable *Dest, Operand *Source)
   1568         : InstX86BaseBinopXmm<InstX86Base::Psub, true,
   1569                               InstX86Base::SseSuffix::Integral>(Func, Dest,
   1570                                                                 Source) {}
   1571   };
   1572 
   1573   class InstX86Psubs
   1574       : public InstX86BaseBinopXmm<InstX86Base::Psubs, true,
   1575                                    InstX86Base::SseSuffix::Integral> {
   1576   public:
   1577     static InstX86Psubs *create(Cfg *Func, Variable *Dest, Operand *Source) {
   1578       return new (Func->allocate<InstX86Psubs>())
   1579           InstX86Psubs(Func, Dest, Source);
   1580     }
   1581 
   1582   private:
   1583     InstX86Psubs(Cfg *Func, Variable *Dest, Operand *Source)
   1584         : InstX86BaseBinopXmm<InstX86Base::Psubs, true,
   1585                               InstX86Base::SseSuffix::Integral>(Func, Dest,
   1586                                                                 Source) {}
   1587   };
   1588 
   1589   class InstX86Psubus
   1590       : public InstX86BaseBinopXmm<InstX86Base::Psubus, true,
   1591                                    InstX86Base::SseSuffix::Integral> {
   1592   public:
   1593     static InstX86Psubus *create(Cfg *Func, Variable *Dest, Operand *Source) {
   1594       return new (Func->allocate<InstX86Psubus>())
   1595           InstX86Psubus(Func, Dest, Source);
   1596     }
   1597 
   1598   private:
   1599     InstX86Psubus(Cfg *Func, Variable *Dest, Operand *Source)
   1600         : InstX86BaseBinopXmm<InstX86Base::Psubus, true,
   1601                               InstX86Base::SseSuffix::Integral>(Func, Dest,
   1602                                                                 Source) {}
   1603   };
   1604 
   1605   class InstX86And : public InstX86BaseBinopGPR<InstX86Base::And> {
   1606   public:
   1607     static InstX86And *create(Cfg *Func, Variable *Dest, Operand *Source) {
   1608       return new (Func->allocate<InstX86And>()) InstX86And(Func, Dest, Source);
   1609     }
   1610 
   1611   private:
   1612     InstX86And(Cfg *Func, Variable *Dest, Operand *Source)
   1613         : InstX86BaseBinopGPR<InstX86Base::And>(Func, Dest, Source) {}
   1614   };
   1615 
   1616   class InstX86Andnps
   1617       : public InstX86BaseBinopXmm<InstX86Base::Andnps, true,
   1618                                    InstX86Base::SseSuffix::Packed> {
   1619   public:
   1620     static InstX86Andnps *create(Cfg *Func, Variable *Dest, Operand *Source) {
   1621       return new (Func->allocate<InstX86Andnps>())
   1622           InstX86Andnps(Func, Dest, Source);
   1623     }
   1624 
   1625   private:
   1626     InstX86Andnps(Cfg *Func, Variable *Dest, Operand *Source)
   1627         : InstX86BaseBinopXmm<InstX86Base::Andnps, true,
   1628                               InstX86Base::SseSuffix::Packed>(Func, Dest,
   1629                                                               Source) {}
   1630   };
   1631 
   1632   class InstX86Andps
   1633       : public InstX86BaseBinopXmm<InstX86Base::Andps, true,
   1634                                    InstX86Base::SseSuffix::Packed> {
   1635   public:
   1636     static InstX86Andps *create(Cfg *Func, Variable *Dest, Operand *Source) {
   1637       return new (Func->allocate<InstX86Andps>())
   1638           InstX86Andps(Func, Dest, Source);
   1639     }
   1640 
   1641   private:
   1642     InstX86Andps(Cfg *Func, Variable *Dest, Operand *Source)
   1643         : InstX86BaseBinopXmm<InstX86Base::Andps, true,
   1644                               InstX86Base::SseSuffix::Packed>(Func, Dest,
   1645                                                               Source) {}
   1646   };
   1647 
   1648   class InstX86AndRMW : public InstX86BaseBinopRMW<InstX86Base::AndRMW> {
   1649   public:
   1650     static InstX86AndRMW *create(Cfg *Func, X86OperandMem *DestSrc0,
   1651                                  Operand *Src1) {
   1652       return new (Func->allocate<InstX86AndRMW>())
   1653           InstX86AndRMW(Func, DestSrc0, Src1);
   1654     }
   1655 
   1656   private:
   1657     InstX86AndRMW(Cfg *Func, X86OperandMem *DestSrc0, Operand *Src1)
   1658         : InstX86BaseBinopRMW<InstX86Base::AndRMW>(Func, DestSrc0, Src1) {}
   1659   };
   1660 
   1661   class InstX86Pand : public InstX86BaseBinopXmm<InstX86Base::Pand, false,
   1662                                                  InstX86Base::SseSuffix::None> {
   1663   public:
   1664     static InstX86Pand *create(Cfg *Func, Variable *Dest, Operand *Source) {
   1665       return new (Func->allocate<InstX86Pand>())
   1666           InstX86Pand(Func, Dest, Source);
   1667     }
   1668 
   1669   private:
   1670     InstX86Pand(Cfg *Func, Variable *Dest, Operand *Source)
   1671         : InstX86BaseBinopXmm<InstX86Base::Pand, false,
   1672                               InstX86Base::SseSuffix::None>(Func, Dest,
   1673                                                             Source) {}
   1674   };
   1675 
   1676   class InstX86Pandn
   1677       : public InstX86BaseBinopXmm<InstX86Base::Pandn, false,
   1678                                    InstX86Base::SseSuffix::None> {
   1679   public:
   1680     static InstX86Pandn *create(Cfg *Func, Variable *Dest, Operand *Source) {
   1681       return new (Func->allocate<InstX86Pandn>())
   1682           InstX86Pandn(Func, Dest, Source);
   1683     }
   1684 
   1685   private:
   1686     InstX86Pandn(Cfg *Func, Variable *Dest, Operand *Source)
   1687         : InstX86BaseBinopXmm<InstX86Base::Pandn, false,
   1688                               InstX86Base::SseSuffix::None>(Func, Dest,
   1689                                                             Source) {}
   1690   };
   1691 
   1692   class InstX86Maxss
   1693       : public InstX86BaseBinopXmm<InstX86Base::Maxss, true,
   1694                                    InstX86Base::SseSuffix::Scalar> {
   1695   public:
   1696     static InstX86Maxss *create(Cfg *Func, Variable *Dest, Operand *Source) {
   1697       return new (Func->allocate<InstX86Maxss>())
   1698           InstX86Maxss(Func, Dest, Source);
   1699     }
   1700 
   1701   private:
   1702     InstX86Maxss(Cfg *Func, Variable *Dest, Operand *Source)
   1703         : InstX86BaseBinopXmm<InstX86Base::Maxss, true,
   1704                               InstX86Base::SseSuffix::Scalar>(Func, Dest,
   1705                                                               Source) {}
   1706   };
   1707 
   1708   class InstX86Minss
   1709       : public InstX86BaseBinopXmm<InstX86Base::Minss, true,
   1710                                    InstX86Base::SseSuffix::Scalar> {
   1711   public:
   1712     static InstX86Minss *create(Cfg *Func, Variable *Dest, Operand *Source) {
   1713       return new (Func->allocate<InstX86Minss>())
   1714           InstX86Minss(Func, Dest, Source);
   1715     }
   1716 
   1717   private:
   1718     InstX86Minss(Cfg *Func, Variable *Dest, Operand *Source)
   1719         : InstX86BaseBinopXmm<InstX86Base::Minss, true,
   1720                               InstX86Base::SseSuffix::Scalar>(Func, Dest,
   1721                                                               Source) {}
   1722   };
   1723 
   1724   class InstX86Maxps
   1725       : public InstX86BaseBinopXmm<InstX86Base::Maxps, true,
   1726                                    InstX86Base::SseSuffix::None> {
   1727   public:
   1728     static InstX86Maxps *create(Cfg *Func, Variable *Dest, Operand *Source) {
   1729       return new (Func->allocate<InstX86Maxps>())
   1730           InstX86Maxps(Func, Dest, Source);
   1731     }
   1732 
   1733   private:
   1734     InstX86Maxps(Cfg *Func, Variable *Dest, Operand *Source)
   1735         : InstX86BaseBinopXmm<InstX86Base::Maxps, true,
   1736                               InstX86Base::SseSuffix::None>(Func, Dest,
   1737                                                             Source) {}
   1738   };
   1739 
   1740   class InstX86Minps
   1741       : public InstX86BaseBinopXmm<InstX86Base::Minps, true,
   1742                                    InstX86Base::SseSuffix::None> {
   1743   public:
   1744     static InstX86Minps *create(Cfg *Func, Variable *Dest, Operand *Source) {
   1745       return new (Func->allocate<InstX86Minps>())
   1746           InstX86Minps(Func, Dest, Source);
   1747     }
   1748 
   1749   private:
   1750     InstX86Minps(Cfg *Func, Variable *Dest, Operand *Source)
   1751         : InstX86BaseBinopXmm<InstX86Base::Minps, true,
   1752                               InstX86Base::SseSuffix::None>(Func, Dest,
   1753                                                             Source) {}
   1754   };
   1755 
   1756   class InstX86Or : public InstX86BaseBinopGPR<InstX86Base::Or> {
   1757   public:
   1758     static InstX86Or *create(Cfg *Func, Variable *Dest, Operand *Source) {
   1759       return new (Func->allocate<InstX86Or>()) InstX86Or(Func, Dest, Source);
   1760     }
   1761 
   1762   private:
   1763     InstX86Or(Cfg *Func, Variable *Dest, Operand *Source)
   1764         : InstX86BaseBinopGPR<InstX86Base::Or>(Func, Dest, Source) {}
   1765   };
   1766 
   1767   class InstX86Orps
   1768       : public InstX86BaseBinopXmm<InstX86Base::Orps, true,
   1769                                    InstX86Base::SseSuffix::Packed> {
   1770   public:
   1771     static InstX86Orps *create(Cfg *Func, Variable *Dest, Operand *Source) {
   1772       return new (Func->allocate<InstX86Orps>())
   1773           InstX86Orps(Func, Dest, Source);
   1774     }
   1775 
   1776   private:
   1777     InstX86Orps(Cfg *Func, Variable *Dest, Operand *Source)
   1778         : InstX86BaseBinopXmm<InstX86Base::Orps, true,
   1779                               InstX86Base::SseSuffix::Packed>(Func, Dest,
   1780                                                               Source) {}
   1781   };
   1782 
   1783   class InstX86OrRMW : public InstX86BaseBinopRMW<InstX86Base::OrRMW> {
   1784   public:
   1785     static InstX86OrRMW *create(Cfg *Func, X86OperandMem *DestSrc0,
   1786                                 Operand *Src1) {
   1787       return new (Func->allocate<InstX86OrRMW>())
   1788           InstX86OrRMW(Func, DestSrc0, Src1);
   1789     }
   1790 
   1791   private:
   1792     InstX86OrRMW(Cfg *Func, X86OperandMem *DestSrc0, Operand *Src1)
   1793         : InstX86BaseBinopRMW<InstX86Base::OrRMW>(Func, DestSrc0, Src1) {}
   1794   };
   1795 
   1796   class InstX86Por : public InstX86BaseBinopXmm<InstX86Base::Por, false,
   1797                                                 InstX86Base::SseSuffix::None> {
   1798   public:
   1799     static InstX86Por *create(Cfg *Func, Variable *Dest, Operand *Source) {
   1800       return new (Func->allocate<InstX86Por>()) InstX86Por(Func, Dest, Source);
   1801     }
   1802 
   1803   private:
   1804     InstX86Por(Cfg *Func, Variable *Dest, Operand *Source)
   1805         : InstX86BaseBinopXmm<InstX86Base::Por, false,
   1806                               InstX86Base::SseSuffix::None>(Func, Dest,
   1807                                                             Source) {}
   1808   };
   1809 
   1810   class InstX86Xor : public InstX86BaseBinopGPR<InstX86Base::Xor> {
   1811   public:
   1812     static InstX86Xor *create(Cfg *Func, Variable *Dest, Operand *Source) {
   1813       return new (Func->allocate<InstX86Xor>()) InstX86Xor(Func, Dest, Source);
   1814     }
   1815 
   1816   private:
   1817     InstX86Xor(Cfg *Func, Variable *Dest, Operand *Source)
   1818         : InstX86BaseBinopGPR<InstX86Base::Xor>(Func, Dest, Source) {}
   1819   };
   1820 
   1821   class InstX86Xorps
   1822       : public InstX86BaseBinopXmm<InstX86Base::Xorps, true,
   1823                                    InstX86Base::SseSuffix::Packed> {
   1824   public:
   1825     static InstX86Xorps *create(Cfg *Func, Variable *Dest, Operand *Source) {
   1826       return new (Func->allocate<InstX86Xorps>())
   1827           InstX86Xorps(Func, Dest, Source);
   1828     }
   1829 
   1830   private:
   1831     InstX86Xorps(Cfg *Func, Variable *Dest, Operand *Source)
   1832         : InstX86BaseBinopXmm<InstX86Base::Xorps, true,
   1833                               InstX86Base::SseSuffix::Packed>(Func, Dest,
   1834                                                               Source) {}
   1835   };
   1836 
   1837   class InstX86XorRMW : public InstX86BaseBinopRMW<InstX86Base::XorRMW> {
   1838   public:
   1839     static InstX86XorRMW *create(Cfg *Func, X86OperandMem *DestSrc0,
   1840                                  Operand *Src1) {
   1841       return new (Func->allocate<InstX86XorRMW>())
   1842           InstX86XorRMW(Func, DestSrc0, Src1);
   1843     }
   1844 
   1845   private:
   1846     InstX86XorRMW(Cfg *Func, X86OperandMem *DestSrc0, Operand *Src1)
   1847         : InstX86BaseBinopRMW<InstX86Base::XorRMW>(Func, DestSrc0, Src1) {}
   1848   };
   1849 
   1850   class InstX86Pxor : public InstX86BaseBinopXmm<InstX86Base::Pxor, false,
   1851                                                  InstX86Base::SseSuffix::None> {
   1852   public:
   1853     static InstX86Pxor *create(Cfg *Func, Variable *Dest, Operand *Source) {
   1854       return new (Func->allocate<InstX86Pxor>())
   1855           InstX86Pxor(Func, Dest, Source);
   1856     }
   1857 
   1858   private:
   1859     InstX86Pxor(Cfg *Func, Variable *Dest, Operand *Source)
   1860         : InstX86BaseBinopXmm<InstX86Base::Pxor, false,
   1861                               InstX86Base::SseSuffix::None>(Func, Dest,
   1862                                                             Source) {}
   1863   };
   1864 
   1865   class InstX86Imul : public InstX86BaseBinopGPR<InstX86Base::Imul> {
   1866   public:
   1867     static InstX86Imul *create(Cfg *Func, Variable *Dest, Operand *Source) {
   1868       return new (Func->allocate<InstX86Imul>())
   1869           InstX86Imul(Func, Dest, Source);
   1870     }
   1871 
   1872     void emit(const Cfg *Func) const override;
   1873     void emitIAS(const Cfg *Func) const override;
   1874 
   1875   private:
   1876     InstX86Imul(Cfg *Func, Variable *Dest, Operand *Source)
   1877         : InstX86BaseBinopGPR<InstX86Base::Imul>(Func, Dest, Source) {}
   1878   };
   1879 
   1880   class InstX86ImulImm
   1881       : public InstX86BaseThreeAddressop<InstX86Base::ImulImm> {
   1882   public:
   1883     static InstX86ImulImm *create(Cfg *Func, Variable *Dest, Operand *Source0,
   1884                                   Operand *Source1) {
   1885       return new (Func->allocate<InstX86ImulImm>())
   1886           InstX86ImulImm(Func, Dest, Source0, Source1);
   1887     }
   1888 
   1889     void emit(const Cfg *Func) const override;
   1890     void emitIAS(const Cfg *Func) const override;
   1891 
   1892   private:
   1893     InstX86ImulImm(Cfg *Func, Variable *Dest, Operand *Source0,
   1894                    Operand *Source1)
   1895         : InstX86BaseThreeAddressop<InstX86Base::ImulImm>(Func, Dest, Source0,
   1896                                                           Source1) {}
   1897   };
   1898 
   1899   class InstX86Mulps
   1900       : public InstX86BaseBinopXmm<InstX86Base::Mulps, true,
   1901                                    InstX86Base::SseSuffix::Packed> {
   1902   public:
   1903     static InstX86Mulps *create(Cfg *Func, Variable *Dest, Operand *Source) {
   1904       return new (Func->allocate<InstX86Mulps>())
   1905           InstX86Mulps(Func, Dest, Source);
   1906     }
   1907 
   1908   private:
   1909     InstX86Mulps(Cfg *Func, Variable *Dest, Operand *Source)
   1910         : InstX86BaseBinopXmm<InstX86Base::Mulps, true,
   1911                               InstX86Base::SseSuffix::Packed>(Func, Dest,
   1912                                                               Source) {}
   1913   };
   1914 
   1915   class InstX86Mulss
   1916       : public InstX86BaseBinopXmm<InstX86Base::Mulss, false,
   1917                                    InstX86Base::SseSuffix::Scalar> {
   1918   public:
   1919     static InstX86Mulss *create(Cfg *Func, Variable *Dest, Operand *Source) {
   1920       return new (Func->allocate<InstX86Mulss>())
   1921           InstX86Mulss(Func, Dest, Source);
   1922     }
   1923 
   1924   private:
   1925     InstX86Mulss(Cfg *Func, Variable *Dest, Operand *Source)
   1926         : InstX86BaseBinopXmm<InstX86Base::Mulss, false,
   1927                               InstX86Base::SseSuffix::Scalar>(Func, Dest,
   1928                                                               Source) {}
   1929   };
   1930 
   1931   class InstX86Pmull
   1932       : public InstX86BaseBinopXmm<InstX86Base::Pmull, true,
   1933                                    InstX86Base::SseSuffix::Integral> {
   1934   public:
   1935     static InstX86Pmull *create(Cfg *Func, Variable *Dest, Operand *Source) {
   1936       bool TypesAreValid =
   1937           Dest->getType() == IceType_v4i32 || Dest->getType() == IceType_v8i16;
   1938       auto *Target = InstX86Base::getTarget(Func);
   1939       bool InstructionSetIsValid =
   1940           Dest->getType() == IceType_v8i16 ||
   1941           Target->getInstructionSet() >= Traits::SSE4_1;
   1942       (void)TypesAreValid;
   1943       (void)InstructionSetIsValid;
   1944       assert(TypesAreValid);
   1945       assert(InstructionSetIsValid);
   1946       return new (Func->allocate<InstX86Pmull>())
   1947           InstX86Pmull(Func, Dest, Source);
   1948     }
   1949 
   1950   private:
   1951     InstX86Pmull(Cfg *Func, Variable *Dest, Operand *Source)
   1952         : InstX86BaseBinopXmm<InstX86Base::Pmull, true,
   1953                               InstX86Base::SseSuffix::Integral>(Func, Dest,
   1954                                                                 Source) {}
   1955   };
   1956 
   1957   class InstX86Pmulhw
   1958       : public InstX86BaseBinopXmm<InstX86Base::Pmulhw, false,
   1959                                    InstX86Base::SseSuffix::None> {
   1960   public:
   1961     static InstX86Pmulhw *create(Cfg *Func, Variable *Dest, Operand *Source) {
   1962       assert(Dest->getType() == IceType_v8i16 &&
   1963              Source->getType() == IceType_v8i16);
   1964       return new (Func->allocate<InstX86Pmulhw>())
   1965           InstX86Pmulhw(Func, Dest, Source);
   1966     }
   1967 
   1968   private:
   1969     InstX86Pmulhw(Cfg *Func, Variable *Dest, Operand *Source)
   1970         : InstX86BaseBinopXmm<InstX86Base::Pmulhw, false,
   1971                               InstX86Base::SseSuffix::None>(Func, Dest,
   1972                                                             Source) {}
   1973   };
   1974 
   1975   class InstX86Pmulhuw
   1976       : public InstX86BaseBinopXmm<InstX86Base::Pmulhuw, false,
   1977                                    InstX86Base::SseSuffix::None> {
   1978   public:
   1979     static InstX86Pmulhuw *create(Cfg *Func, Variable *Dest, Operand *Source) {
   1980       assert(Dest->getType() == IceType_v8i16 &&
   1981              Source->getType() == IceType_v8i16);
   1982       return new (Func->allocate<InstX86Pmulhuw>())
   1983           InstX86Pmulhuw(Func, Dest, Source);
   1984     }
   1985 
   1986   private:
   1987     InstX86Pmulhuw(Cfg *Func, Variable *Dest, Operand *Source)
   1988         : InstX86BaseBinopXmm<InstX86Base::Pmulhuw, false,
   1989                               InstX86Base::SseSuffix::None>(Func, Dest,
   1990                                                             Source) {}
   1991   };
   1992 
   1993   class InstX86Pmaddwd
   1994       : public InstX86BaseBinopXmm<InstX86Base::Pmaddwd, false,
   1995                                    InstX86Base::SseSuffix::None> {
   1996   public:
   1997     static InstX86Pmaddwd *create(Cfg *Func, Variable *Dest, Operand *Source) {
   1998       assert(Dest->getType() == IceType_v8i16 &&
   1999              Source->getType() == IceType_v8i16);
   2000       return new (Func->allocate<InstX86Pmaddwd>())
   2001           InstX86Pmaddwd(Func, Dest, Source);
   2002     }
   2003 
   2004   private:
   2005     InstX86Pmaddwd(Cfg *Func, Variable *Dest, Operand *Source)
   2006         : InstX86BaseBinopXmm<InstX86Base::Pmaddwd, false,
   2007                               InstX86Base::SseSuffix::None>(Func, Dest,
   2008                                                             Source) {}
   2009   };
   2010 
   2011   class InstX86Pmuludq
   2012       : public InstX86BaseBinopXmm<InstX86Base::Pmuludq, false,
   2013                                    InstX86Base::SseSuffix::None> {
   2014   public:
   2015     static InstX86Pmuludq *create(Cfg *Func, Variable *Dest, Operand *Source) {
   2016       assert(Dest->getType() == IceType_v4i32 &&
   2017              Source->getType() == IceType_v4i32);
   2018       return new (Func->allocate<InstX86Pmuludq>())
   2019           InstX86Pmuludq(Func, Dest, Source);
   2020     }
   2021 
   2022   private:
   2023     InstX86Pmuludq(Cfg *Func, Variable *Dest, Operand *Source)
   2024         : InstX86BaseBinopXmm<InstX86Base::Pmuludq, false,
   2025                               InstX86Base::SseSuffix::None>(Func, Dest,
   2026                                                             Source) {}
   2027   };
   2028 
   2029   class InstX86Divps
   2030       : public InstX86BaseBinopXmm<InstX86Base::Divps, true,
   2031                                    InstX86Base::SseSuffix::Packed> {
   2032   public:
   2033     static InstX86Divps *create(Cfg *Func, Variable *Dest, Operand *Source) {
   2034       return new (Func->allocate<InstX86Divps>())
   2035           InstX86Divps(Func, Dest, Source);
   2036     }
   2037 
   2038   private:
   2039     InstX86Divps(Cfg *Func, Variable *Dest, Operand *Source)
   2040         : InstX86BaseBinopXmm<InstX86Base::Divps, true,
   2041                               InstX86Base::SseSuffix::Packed>(Func, Dest,
   2042                                                               Source) {}
   2043   };
   2044 
   2045   class InstX86Divss
   2046       : public InstX86BaseBinopXmm<InstX86Base::Divss, false,
   2047                                    InstX86Base::SseSuffix::Scalar> {
   2048   public:
   2049     static InstX86Divss *create(Cfg *Func, Variable *Dest, Operand *Source) {
   2050       return new (Func->allocate<InstX86Divss>())
   2051           InstX86Divss(Func, Dest, Source);
   2052     }
   2053 
   2054   private:
   2055     InstX86Divss(Cfg *Func, Variable *Dest, Operand *Source)
   2056         : InstX86BaseBinopXmm<InstX86Base::Divss, false,
   2057                               InstX86Base::SseSuffix::Scalar>(Func, Dest,
   2058                                                               Source) {}
   2059   };
   2060 
   2061   class InstX86Rol : public InstX86BaseBinopGPRShift<InstX86Base::Rol> {
   2062   public:
   2063     static InstX86Rol *create(Cfg *Func, Variable *Dest, Operand *Source) {
   2064       return new (Func->allocate<InstX86Rol>()) InstX86Rol(Func, Dest, Source);
   2065     }
   2066 
   2067   private:
   2068     InstX86Rol(Cfg *Func, Variable *Dest, Operand *Source)
   2069         : InstX86BaseBinopGPRShift<InstX86Base::Rol>(Func, Dest, Source) {}
   2070   };
   2071 
   2072   class InstX86Shl : public InstX86BaseBinopGPRShift<InstX86Base::Shl> {
   2073   public:
   2074     static InstX86Shl *create(Cfg *Func, Variable *Dest, Operand *Source) {
   2075       return new (Func->allocate<InstX86Shl>()) InstX86Shl(Func, Dest, Source);
   2076     }
   2077 
   2078   private:
   2079     InstX86Shl(Cfg *Func, Variable *Dest, Operand *Source)
   2080         : InstX86BaseBinopGPRShift<InstX86Base::Shl>(Func, Dest, Source) {}
   2081   };
   2082 
   2083   class InstX86Psll : public InstX86BaseBinopXmmShift<InstX86Base::Psll> {
   2084   public:
   2085     static InstX86Psll *create(Cfg *Func, Variable *Dest, Operand *Source) {
   2086       assert(
   2087           Dest->getType() == IceType_v8i16 || Dest->getType() == IceType_v8i1 ||
   2088           Dest->getType() == IceType_v4i32 || Dest->getType() == IceType_v4i1);
   2089       return new (Func->allocate<InstX86Psll>())
   2090           InstX86Psll(Func, Dest, Source);
   2091     }
   2092 
   2093   private:
   2094     InstX86Psll(Cfg *Func, Variable *Dest, Operand *Source)
   2095         : InstX86BaseBinopXmmShift<InstX86Base::Psll>(Func, Dest, Source) {}
   2096   };
   2097 
   2098   class InstX86Psrl : public InstX86BaseBinopXmmShift<InstX86Base::Psrl, true> {
   2099   public:
   2100     static InstX86Psrl *create(Cfg *Func, Variable *Dest, Operand *Source) {
   2101       return new (Func->allocate<InstX86Psrl>())
   2102           InstX86Psrl(Func, Dest, Source);
   2103     }
   2104 
   2105   private:
   2106     InstX86Psrl(Cfg *Func, Variable *Dest, Operand *Source)
   2107         : InstX86BaseBinopXmmShift<InstX86Base::Psrl, true>(Func, Dest,
   2108                                                             Source) {}
   2109   };
   2110 
   2111   class InstX86Shr : public InstX86BaseBinopGPRShift<InstX86Base::Shr> {
   2112   public:
   2113     static InstX86Shr *create(Cfg *Func, Variable *Dest, Operand *Source) {
   2114       return new (Func->allocate<InstX86Shr>()) InstX86Shr(Func, Dest, Source);
   2115     }
   2116 
   2117   private:
   2118     InstX86Shr(Cfg *Func, Variable *Dest, Operand *Source)
   2119         : InstX86BaseBinopGPRShift<InstX86Base::Shr>(Func, Dest, Source) {}
   2120   };
   2121 
   2122   class InstX86Sar : public InstX86BaseBinopGPRShift<InstX86Base::Sar> {
   2123   public:
   2124     static InstX86Sar *create(Cfg *Func, Variable *Dest, Operand *Source) {
   2125       return new (Func->allocate<InstX86Sar>()) InstX86Sar(Func, Dest, Source);
   2126     }
   2127 
   2128   private:
   2129     InstX86Sar(Cfg *Func, Variable *Dest, Operand *Source)
   2130         : InstX86BaseBinopGPRShift<InstX86Base::Sar>(Func, Dest, Source) {}
   2131   };
   2132 
   2133   class InstX86Psra : public InstX86BaseBinopXmmShift<InstX86Base::Psra> {
   2134   public:
   2135     static InstX86Psra *create(Cfg *Func, Variable *Dest, Operand *Source) {
   2136       assert(
   2137           Dest->getType() == IceType_v8i16 || Dest->getType() == IceType_v8i1 ||
   2138           Dest->getType() == IceType_v4i32 || Dest->getType() == IceType_v4i1);
   2139       return new (Func->allocate<InstX86Psra>())
   2140           InstX86Psra(Func, Dest, Source);
   2141     }
   2142 
   2143   private:
   2144     InstX86Psra(Cfg *Func, Variable *Dest, Operand *Source)
   2145         : InstX86BaseBinopXmmShift<InstX86Base::Psra>(Func, Dest, Source) {}
   2146   };
   2147 
   2148   class InstX86Pcmpeq
   2149       : public InstX86BaseBinopXmm<InstX86Base::Pcmpeq, true,
   2150                                    InstX86Base::SseSuffix::Integral> {
   2151   public:
   2152     static InstX86Pcmpeq *create(Cfg *Func, Variable *Dest, Operand *Source,
   2153                                  Type ArithmeticTypeOverride = IceType_void) {
   2154       const Type Ty = ArithmeticTypeOverride == IceType_void
   2155                           ? Dest->getType()
   2156                           : ArithmeticTypeOverride;
   2157       (void)Ty;
   2158       assert((Ty != IceType_f64 && Ty != IceType_i64) ||
   2159              InstX86Base::getTarget(Func)->getInstructionSet() >=
   2160                  Traits::SSE4_1);
   2161       return new (Func->allocate<InstX86Pcmpeq>())
   2162           InstX86Pcmpeq(Func, Dest, Source, ArithmeticTypeOverride);
   2163     }
   2164 
   2165   private:
   2166     InstX86Pcmpeq(Cfg *Func, Variable *Dest, Operand *Source,
   2167                   Type ArithmeticTypeOverride)
   2168         : InstX86BaseBinopXmm<InstX86Base::Pcmpeq, true,
   2169                               InstX86Base::SseSuffix::Integral>(
   2170               Func, Dest, Source, ArithmeticTypeOverride) {}
   2171   };
   2172 
   2173   class InstX86Pcmpgt
   2174       : public InstX86BaseBinopXmm<InstX86Base::Pcmpgt, true,
   2175                                    InstX86Base::SseSuffix::Integral> {
   2176   public:
   2177     static InstX86Pcmpgt *create(Cfg *Func, Variable *Dest, Operand *Source) {
   2178       assert(Dest->getType() != IceType_f64 ||
   2179              InstX86Base::getTarget(Func)->getInstructionSet() >=
   2180                  Traits::SSE4_1);
   2181       return new (Func->allocate<InstX86Pcmpgt>())
   2182           InstX86Pcmpgt(Func, Dest, Source);
   2183     }
   2184 
   2185   private:
   2186     InstX86Pcmpgt(Cfg *Func, Variable *Dest, Operand *Source)
   2187         : InstX86BaseBinopXmm<InstX86Base::Pcmpgt, true,
   2188                               InstX86Base::SseSuffix::Integral>(Func, Dest,
   2189                                                                 Source) {}
   2190   };
   2191 
   2192   /// movss is only a binary operation when the source and dest operands are
   2193   /// both registers (the high bits of dest are left untouched). In other cases,
   2194   /// it behaves like a copy (mov-like) operation (and the high bits of dest are
   2195   /// cleared). InstX86Movss will assert that both its source and dest operands
   2196   /// are registers, so the lowering code should use _mov instead of _movss in
   2197   /// cases where a copy operation is intended.
   2198   class InstX86MovssRegs
   2199       : public InstX86BaseBinopXmm<InstX86Base::MovssRegs, false,
   2200                                    InstX86Base::SseSuffix::None> {
   2201   public:
   2202     static InstX86MovssRegs *create(Cfg *Func, Variable *Dest,
   2203                                     Operand *Source) {
   2204       return new (Func->allocate<InstX86MovssRegs>())
   2205           InstX86MovssRegs(Func, Dest, Source);
   2206     }
   2207 
   2208     void emitIAS(const Cfg *Func) const override;
   2209 
   2210   private:
   2211     InstX86MovssRegs(Cfg *Func, Variable *Dest, Operand *Source)
   2212         : InstX86BaseBinopXmm<InstX86Base::MovssRegs, false,
   2213                               InstX86Base::SseSuffix::None>(Func, Dest,
   2214                                                             Source) {}
   2215   };
   2216 
   2217   class InstX86Idiv : public InstX86BaseTernop<InstX86Base::Idiv> {
   2218   public:
   2219     static InstX86Idiv *create(Cfg *Func, Variable *Dest, Operand *Source1,
   2220                                Operand *Source2) {
   2221       return new (Func->allocate<InstX86Idiv>())
   2222           InstX86Idiv(Func, Dest, Source1, Source2);
   2223     }
   2224 
   2225     void emit(const Cfg *Func) const override;
   2226     void emitIAS(const Cfg *Func) const override;
   2227 
   2228   private:
   2229     InstX86Idiv(Cfg *Func, Variable *Dest, Operand *Source1, Operand *Source2)
   2230         : InstX86BaseTernop<InstX86Base::Idiv>(Func, Dest, Source1, Source2) {}
   2231   };
   2232 
   2233   class InstX86Div : public InstX86BaseTernop<InstX86Base::Div> {
   2234   public:
   2235     static InstX86Div *create(Cfg *Func, Variable *Dest, Operand *Source1,
   2236                               Operand *Source2) {
   2237       return new (Func->allocate<InstX86Div>())
   2238           InstX86Div(Func, Dest, Source1, Source2);
   2239     }
   2240 
   2241     void emit(const Cfg *Func) const override;
   2242     void emitIAS(const Cfg *Func) const override;
   2243 
   2244   private:
   2245     InstX86Div(Cfg *Func, Variable *Dest, Operand *Source1, Operand *Source2)
   2246         : InstX86BaseTernop<InstX86Base::Div>(Func, Dest, Source1, Source2) {}
   2247   };
   2248 
   2249   class InstX86Insertps : public InstX86BaseTernop<InstX86Base::Insertps> {
   2250   public:
   2251     static InstX86Insertps *create(Cfg *Func, Variable *Dest, Operand *Source1,
   2252                                    Operand *Source2) {
   2253       return new (Func->allocate<InstX86Insertps>())
   2254           InstX86Insertps(Func, Dest, Source1, Source2);
   2255     }
   2256 
   2257     void emitIAS(const Cfg *Func) const override;
   2258 
   2259   private:
   2260     InstX86Insertps(Cfg *Func, Variable *Dest, Operand *Source1,
   2261                     Operand *Source2)
   2262         : InstX86BaseTernop<InstX86Base::Insertps>(Func, Dest, Source1,
   2263                                                    Source2) {}
   2264   };
   2265 
   2266   class InstX86Pinsr : public InstX86BaseTernop<InstX86Base::Pinsr> {
   2267   public:
   2268     static InstX86Pinsr *create(Cfg *Func, Variable *Dest, Operand *Source1,
   2269                                 Operand *Source2) {
   2270       // pinsrb and pinsrd are SSE4.1 instructions.
   2271       assert(
   2272           Dest->getType() == IceType_v8i16 || Dest->getType() == IceType_v8i1 ||
   2273           InstX86Base::getTarget(Func)->getInstructionSet() >= Traits::SSE4_1);
   2274       return new (Func->allocate<InstX86Pinsr>())
   2275           InstX86Pinsr(Func, Dest, Source1, Source2);
   2276     }
   2277 
   2278     void emit(const Cfg *Func) const override;
   2279     void emitIAS(const Cfg *Func) const override;
   2280 
   2281   private:
   2282     InstX86Pinsr(Cfg *Func, Variable *Dest, Operand *Source1, Operand *Source2)
   2283         : InstX86BaseTernop<InstX86Base::Pinsr>(Func, Dest, Source1, Source2) {}
   2284   };
   2285 
   2286   class InstX86Shufps : public InstX86BaseTernop<InstX86Base::Shufps> {
   2287   public:
   2288     static InstX86Shufps *create(Cfg *Func, Variable *Dest, Operand *Source1,
   2289                                  Operand *Source2) {
   2290       return new (Func->allocate<InstX86Shufps>())
   2291           InstX86Shufps(Func, Dest, Source1, Source2);
   2292     }
   2293 
   2294     void emitIAS(const Cfg *Func) const override;
   2295 
   2296   private:
   2297     InstX86Shufps(Cfg *Func, Variable *Dest, Operand *Source1, Operand *Source2)
   2298         : InstX86BaseTernop<InstX86Base::Shufps>(Func, Dest, Source1, Source2) {
   2299     }
   2300   };
   2301 
   2302   class InstX86Blendvps : public InstX86BaseTernop<InstX86Base::Blendvps> {
   2303   public:
   2304     static InstX86Blendvps *create(Cfg *Func, Variable *Dest, Operand *Source1,
   2305                                    Operand *Source2) {
   2306       assert(InstX86Base::getTarget(Func)->getInstructionSet() >=
   2307              Traits::SSE4_1);
   2308       return new (Func->allocate<InstX86Blendvps>())
   2309           InstX86Blendvps(Func, Dest, Source1, Source2);
   2310     }
   2311 
   2312     void emit(const Cfg *Func) const override;
   2313     void emitIAS(const Cfg *Fund) const override;
   2314 
   2315   private:
   2316     InstX86Blendvps(Cfg *Func, Variable *Dest, Operand *Source1,
   2317                     Operand *Source2)
   2318         : InstX86BaseTernop<InstX86Base::Blendvps>(Func, Dest, Source1,
   2319                                                    Source2) {}
   2320   };
   2321 
   2322   class InstX86Pblendvb : public InstX86BaseTernop<InstX86Base::Pblendvb> {
   2323   public:
   2324     static InstX86Pblendvb *create(Cfg *Func, Variable *Dest, Operand *Source1,
   2325                                    Operand *Source2) {
   2326       assert(InstX86Base::getTarget(Func)->getInstructionSet() >=
   2327              Traits::SSE4_1);
   2328       return new (Func->allocate<InstX86Pblendvb>())
   2329           InstX86Pblendvb(Func, Dest, Source1, Source2);
   2330     }
   2331 
   2332     void emit(const Cfg *Func) const override;
   2333     void emitIAS(const Cfg *Func) const override;
   2334 
   2335   private:
   2336     InstX86Pblendvb(Cfg *Func, Variable *Dest, Operand *Source1,
   2337                     Operand *Source2)
   2338         : InstX86BaseTernop<InstX86Base::Pblendvb>(Func, Dest, Source1,
   2339                                                    Source2) {}
   2340   };
   2341 
   2342   class InstX86Pextr : public InstX86BaseThreeAddressop<InstX86Base::Pextr> {
   2343   public:
   2344     static InstX86Pextr *create(Cfg *Func, Variable *Dest, Operand *Source0,
   2345                                 Operand *Source1) {
   2346       assert(Source0->getType() == IceType_v8i16 ||
   2347              Source0->getType() == IceType_v8i1 ||
   2348              InstX86Base::getTarget(Func)->getInstructionSet() >=
   2349                  Traits::SSE4_1);
   2350       return new (Func->allocate<InstX86Pextr>())
   2351           InstX86Pextr(Func, Dest, Source0, Source1);
   2352     }
   2353 
   2354     void emit(const Cfg *Func) const override;
   2355     void emitIAS(const Cfg *Func) const override;
   2356 
   2357   private:
   2358     InstX86Pextr(Cfg *Func, Variable *Dest, Operand *Source0, Operand *Source1)
   2359         : InstX86BaseThreeAddressop<InstX86Base::Pextr>(Func, Dest, Source0,
   2360                                                         Source1) {}
   2361   };
   2362 
   2363   class InstX86Pshufd : public InstX86BaseThreeAddressop<InstX86Base::Pshufd> {
   2364   public:
   2365     static InstX86Pshufd *create(Cfg *Func, Variable *Dest, Operand *Source0,
   2366                                  Operand *Source1) {
   2367       return new (Func->allocate<InstX86Pshufd>())
   2368           InstX86Pshufd(Func, Dest, Source0, Source1);
   2369     }
   2370 
   2371     void emitIAS(const Cfg *Func) const override;
   2372 
   2373   private:
   2374     InstX86Pshufd(Cfg *Func, Variable *Dest, Operand *Source0, Operand *Source1)
   2375         : InstX86BaseThreeAddressop<InstX86Base::Pshufd>(Func, Dest, Source0,
   2376                                                          Source1) {}
   2377   };
   2378 
   2379   /// Base class for a lockable x86-32 instruction (emits a locked prefix).
   2380   class InstX86BaseLockable : public InstX86Base {
   2381     InstX86BaseLockable() = delete;
   2382     InstX86BaseLockable(const InstX86BaseLockable &) = delete;
   2383     InstX86BaseLockable &operator=(const InstX86BaseLockable &) = delete;
   2384 
   2385   protected:
   2386     bool Locked;
   2387 
   2388     InstX86BaseLockable(Cfg *Func, typename InstX86Base::InstKindX86 Kind,
   2389                         SizeT Maxsrcs, Variable *Dest, bool Locked)
   2390         : InstX86Base(Func, Kind, Maxsrcs, Dest), Locked(Locked) {
   2391       // Assume that such instructions are used for Atomics and be careful with
   2392       // optimizations.
   2393       this->HasSideEffects = Locked;
   2394     }
   2395   };
   2396 
   2397   /// Mul instruction - unsigned multiply.
   2398   class InstX86Mul final : public InstX86Base {
   2399     InstX86Mul() = delete;
   2400     InstX86Mul(const InstX86Mul &) = delete;
   2401     InstX86Mul &operator=(const InstX86Mul &) = delete;
   2402 
   2403   public:
   2404     static InstX86Mul *create(Cfg *Func, Variable *Dest, Variable *Source1,
   2405                               Operand *Source2) {
   2406       return new (Func->allocate<InstX86Mul>())
   2407           InstX86Mul(Func, Dest, Source1, Source2);
   2408     }
   2409     void emit(const Cfg *Func) const override;
   2410     void emitIAS(const Cfg *Func) const override;
   2411     void dump(const Cfg *Func) const override;
   2412     static bool classof(const Inst *Instr) {
   2413       return InstX86Base::isClassof(Instr, InstX86Base::Mul);
   2414     }
   2415 
   2416   private:
   2417     InstX86Mul(Cfg *Func, Variable *Dest, Variable *Source1, Operand *Source2);
   2418   };
   2419 
   2420   /// Shld instruction - shift across a pair of operands.
   2421   class InstX86Shld final : public InstX86Base {
   2422     InstX86Shld() = delete;
   2423     InstX86Shld(const InstX86Shld &) = delete;
   2424     InstX86Shld &operator=(const InstX86Shld &) = delete;
   2425 
   2426   public:
   2427     static InstX86Shld *create(Cfg *Func, Variable *Dest, Variable *Source1,
   2428                                Operand *Source2) {
   2429       return new (Func->allocate<InstX86Shld>())
   2430           InstX86Shld(Func, Dest, Source1, Source2);
   2431     }
   2432     void emit(const Cfg *Func) const override;
   2433     void emitIAS(const Cfg *Func) const override;
   2434     void dump(const Cfg *Func) const override;
   2435     static bool classof(const Inst *Instr) {
   2436       return InstX86Base::isClassof(Instr, InstX86Base::Shld);
   2437     }
   2438 
   2439   private:
   2440     InstX86Shld(Cfg *Func, Variable *Dest, Variable *Source1, Operand *Source2);
   2441   };
   2442 
   2443   /// Shrd instruction - shift across a pair of operands.
   2444   class InstX86Shrd final : public InstX86Base {
   2445     InstX86Shrd() = delete;
   2446     InstX86Shrd(const InstX86Shrd &) = delete;
   2447     InstX86Shrd &operator=(const InstX86Shrd &) = delete;
   2448 
   2449   public:
   2450     static InstX86Shrd *create(Cfg *Func, Variable *Dest, Variable *Source1,
   2451                                Operand *Source2) {
   2452       return new (Func->allocate<InstX86Shrd>())
   2453           InstX86Shrd(Func, Dest, Source1, Source2);
   2454     }
   2455     void emit(const Cfg *Func) const override;
   2456     void emitIAS(const Cfg *Func) const override;
   2457     void dump(const Cfg *Func) const override;
   2458     static bool classof(const Inst *Instr) {
   2459       return InstX86Base::isClassof(Instr, InstX86Base::Shrd);
   2460     }
   2461 
   2462   private:
   2463     InstX86Shrd(Cfg *Func, Variable *Dest, Variable *Source1, Operand *Source2);
   2464   };
   2465 
   2466   /// Conditional move instruction.
   2467   class InstX86Cmov final : public InstX86Base {
   2468     InstX86Cmov() = delete;
   2469     InstX86Cmov(const InstX86Cmov &) = delete;
   2470     InstX86Cmov &operator=(const InstX86Cmov &) = delete;
   2471 
   2472   public:
   2473     static InstX86Cmov *create(Cfg *Func, Variable *Dest, Operand *Source,
   2474                                BrCond Cond) {
   2475       return new (Func->allocate<InstX86Cmov>())
   2476           InstX86Cmov(Func, Dest, Source, Cond);
   2477     }
   2478     void emit(const Cfg *Func) const override;
   2479     void emitIAS(const Cfg *Func) const override;
   2480     void dump(const Cfg *Func) const override;
   2481     static bool classof(const Inst *Instr) {
   2482       return InstX86Base::isClassof(Instr, InstX86Base::Cmov);
   2483     }
   2484 
   2485   private:
   2486     InstX86Cmov(Cfg *Func, Variable *Dest, Operand *Source, BrCond Cond);
   2487 
   2488     BrCond Condition;
   2489   };
   2490 
   2491   /// Cmpps instruction - compare packed singled-precision floating point values
   2492   class InstX86Cmpps final : public InstX86Base {
   2493     InstX86Cmpps() = delete;
   2494     InstX86Cmpps(const InstX86Cmpps &) = delete;
   2495     InstX86Cmpps &operator=(const InstX86Cmpps &) = delete;
   2496 
   2497   public:
   2498     static InstX86Cmpps *create(Cfg *Func, Variable *Dest, Operand *Source,
   2499                                 CmppsCond Condition) {
   2500       return new (Func->allocate<InstX86Cmpps>())
   2501           InstX86Cmpps(Func, Dest, Source, Condition);
   2502     }
   2503     void emit(const Cfg *Func) const override;
   2504     void emitIAS(const Cfg *Func) const override;
   2505     void dump(const Cfg *Func) const override;
   2506     static bool classof(const Inst *Instr) {
   2507       return InstX86Base::isClassof(Instr, InstX86Base::Cmpps);
   2508     }
   2509 
   2510   private:
   2511     InstX86Cmpps(Cfg *Func, Variable *Dest, Operand *Source, CmppsCond Cond);
   2512 
   2513     CmppsCond Condition;
   2514   };
   2515 
   2516   /// Cmpxchg instruction - cmpxchg <dest>, <desired> will compare if <dest>
   2517   /// equals eax. If so, the ZF is set and <desired> is stored in <dest>. If
   2518   /// not, ZF is cleared and <dest> is copied to eax (or subregister). <dest>
   2519   /// can be a register or memory, while <desired> must be a register. It is
   2520   /// the user's responsibility to mark eax with a FakeDef.
   2521   class InstX86Cmpxchg final : public InstX86BaseLockable {
   2522     InstX86Cmpxchg() = delete;
   2523     InstX86Cmpxchg(const InstX86Cmpxchg &) = delete;
   2524     InstX86Cmpxchg &operator=(const InstX86Cmpxchg &) = delete;
   2525 
   2526   public:
   2527     static InstX86Cmpxchg *create(Cfg *Func, Operand *DestOrAddr, Variable *Eax,
   2528                                   Variable *Desired, bool Locked) {
   2529       return new (Func->allocate<InstX86Cmpxchg>())
   2530           InstX86Cmpxchg(Func, DestOrAddr, Eax, Desired, Locked);
   2531     }
   2532     void emit(const Cfg *Func) const override;
   2533     void emitIAS(const Cfg *Func) const override;
   2534     void dump(const Cfg *Func) const override;
   2535     static bool classof(const Inst *Instr) {
   2536       return InstX86Base::isClassof(Instr, InstX86Base::Cmpxchg);
   2537     }
   2538 
   2539   private:
   2540     InstX86Cmpxchg(Cfg *Func, Operand *DestOrAddr, Variable *Eax,
   2541                    Variable *Desired, bool Locked);
   2542   };
   2543 
   2544   /// Cmpxchg8b instruction - cmpxchg8b <m64> will compare if <m64> equals
   2545   /// edx:eax. If so, the ZF is set and ecx:ebx is stored in <m64>. If not, ZF
   2546   /// is cleared and <m64> is copied to edx:eax. The caller is responsible for
   2547   /// inserting FakeDefs to mark edx and eax as modified. <m64> must be a memory
   2548   /// operand.
   2549   class InstX86Cmpxchg8b final : public InstX86BaseLockable {
   2550     InstX86Cmpxchg8b() = delete;
   2551     InstX86Cmpxchg8b(const InstX86Cmpxchg8b &) = delete;
   2552     InstX86Cmpxchg8b &operator=(const InstX86Cmpxchg8b &) = delete;
   2553 
   2554   public:
   2555     static InstX86Cmpxchg8b *create(Cfg *Func, X86OperandMem *Dest,
   2556                                     Variable *Edx, Variable *Eax, Variable *Ecx,
   2557                                     Variable *Ebx, bool Locked) {
   2558       return new (Func->allocate<InstX86Cmpxchg8b>())
   2559           InstX86Cmpxchg8b(Func, Dest, Edx, Eax, Ecx, Ebx, Locked);
   2560     }
   2561     void emit(const Cfg *Func) const override;
   2562     void emitIAS(const Cfg *Func) const override;
   2563     void dump(const Cfg *Func) const override;
   2564     static bool classof(const Inst *Instr) {
   2565       return InstX86Base::isClassof(Instr, InstX86Base::Cmpxchg8b);
   2566     }
   2567 
   2568   private:
   2569     InstX86Cmpxchg8b(Cfg *Func, X86OperandMem *Dest, Variable *Edx,
   2570                      Variable *Eax, Variable *Ecx, Variable *Ebx, bool Locked);
   2571   };
   2572 
   2573   /// Cvt instruction - wrapper for cvtsX2sY where X and Y are in {s,d,i} as
   2574   /// appropriate.  s=float, d=double, i=int. X and Y are determined from
   2575   /// dest/src types. Sign and zero extension on the integer operand needs to be
   2576   /// done separately.
   2577   class InstX86Cvt final : public InstX86Base {
   2578     InstX86Cvt() = delete;
   2579     InstX86Cvt(const InstX86Cvt &) = delete;
   2580     InstX86Cvt &operator=(const InstX86Cvt &) = delete;
   2581 
   2582   public:
   2583     enum CvtVariant { Si2ss, Tss2si, Ss2si, Float2float, Dq2ps, Tps2dq, Ps2dq };
   2584     static InstX86Cvt *create(Cfg *Func, Variable *Dest, Operand *Source,
   2585                               CvtVariant Variant) {
   2586       return new (Func->allocate<InstX86Cvt>())
   2587           InstX86Cvt(Func, Dest, Source, Variant);
   2588     }
   2589     void emit(const Cfg *Func) const override;
   2590     void emitIAS(const Cfg *Func) const override;
   2591     void dump(const Cfg *Func) const override;
   2592     static bool classof(const Inst *Instr) {
   2593       return InstX86Base::isClassof(Instr, InstX86Base::Cvt);
   2594     }
   2595     bool isTruncating() const { return Variant == Tss2si || Variant == Tps2dq; }
   2596 
   2597   private:
   2598     CvtVariant Variant;
   2599     InstX86Cvt(Cfg *Func, Variable *Dest, Operand *Source, CvtVariant Variant);
   2600   };
   2601 
   2602   /// Round instruction
   2603   class InstX86Round final
   2604       : public InstX86BaseThreeAddressop<InstX86Base::Round> {
   2605   public:
   2606     static InstX86Round *create(Cfg *Func, Variable *Dest, Operand *Source,
   2607                                 Operand *Imm) {
   2608       return new (Func->allocate<InstX86Round>())
   2609           InstX86Round(Func, Dest, Source, Imm);
   2610     }
   2611 
   2612     void emit(const Cfg *Func) const override;
   2613     void emitIAS(const Cfg *Func) const override;
   2614 
   2615   private:
   2616     InstX86Round(Cfg *Func, Variable *Dest, Operand *Source, Operand *Imm)
   2617         : InstX86BaseThreeAddressop<InstX86Base::Round>(Func, Dest, Source,
   2618                                                         Imm) {}
   2619   };
   2620 
   2621   /// cmp - Integer compare instruction.
   2622   class InstX86Icmp final : public InstX86Base {
   2623     InstX86Icmp() = delete;
   2624     InstX86Icmp(const InstX86Icmp &) = delete;
   2625     InstX86Icmp &operator=(const InstX86Icmp &) = delete;
   2626 
   2627   public:
   2628     static InstX86Icmp *create(Cfg *Func, Operand *Src1, Operand *Src2) {
   2629       return new (Func->allocate<InstX86Icmp>()) InstX86Icmp(Func, Src1, Src2);
   2630     }
   2631     void emit(const Cfg *Func) const override;
   2632     void emitIAS(const Cfg *Func) const override;
   2633     void dump(const Cfg *Func) const override;
   2634     static bool classof(const Inst *Instr) {
   2635       return InstX86Base::isClassof(Instr, InstX86Base::Icmp);
   2636     }
   2637 
   2638   private:
   2639     InstX86Icmp(Cfg *Func, Operand *Src1, Operand *Src2);
   2640   };
   2641 
   2642   /// ucomiss/ucomisd - floating-point compare instruction.
   2643   class InstX86Ucomiss final : public InstX86Base {
   2644     InstX86Ucomiss() = delete;
   2645     InstX86Ucomiss(const InstX86Ucomiss &) = delete;
   2646     InstX86Ucomiss &operator=(const InstX86Ucomiss &) = delete;
   2647 
   2648   public:
   2649     static InstX86Ucomiss *create(Cfg *Func, Operand *Src1, Operand *Src2) {
   2650       return new (Func->allocate<InstX86Ucomiss>())
   2651           InstX86Ucomiss(Func, Src1, Src2);
   2652     }
   2653     void emit(const Cfg *Func) const override;
   2654     void emitIAS(const Cfg *Func) const override;
   2655     void dump(const Cfg *Func) const override;
   2656     static bool classof(const Inst *Instr) {
   2657       return InstX86Base::isClassof(Instr, InstX86Base::Ucomiss);
   2658     }
   2659 
   2660   private:
   2661     InstX86Ucomiss(Cfg *Func, Operand *Src1, Operand *Src2);
   2662   };
   2663 
   2664   /// UD2 instruction.
   2665   class InstX86UD2 final : public InstX86Base {
   2666     InstX86UD2() = delete;
   2667     InstX86UD2(const InstX86UD2 &) = delete;
   2668     InstX86UD2 &operator=(const InstX86UD2 &) = delete;
   2669 
   2670   public:
   2671     static InstX86UD2 *create(Cfg *Func) {
   2672       return new (Func->allocate<InstX86UD2>()) InstX86UD2(Func);
   2673     }
   2674     void emit(const Cfg *Func) const override;
   2675     void emitIAS(const Cfg *Func) const override;
   2676     void dump(const Cfg *Func) const override;
   2677     static bool classof(const Inst *Instr) {
   2678       return InstX86Base::isClassof(Instr, InstX86Base::UD2);
   2679     }
   2680 
   2681   private:
   2682     explicit InstX86UD2(Cfg *Func);
   2683   };
   2684 
   2685   /// Int3 instruction.
   2686   class InstX86Int3 final : public InstX86Base {
   2687     InstX86Int3() = delete;
   2688     InstX86Int3(const InstX86Int3 &) = delete;
   2689     InstX86Int3 &operator=(const InstX86Int3 &) = delete;
   2690 
   2691   public:
   2692     static InstX86Int3 *create(Cfg *Func) {
   2693       return new (Func->allocate<InstX86Int3>()) InstX86Int3(Func);
   2694     }
   2695     void emit(const Cfg *Func) const override;
   2696     void emitIAS(const Cfg *Func) const override;
   2697     void dump(const Cfg *Func) const override;
   2698     static bool classof(const Inst *Instr) {
   2699       return InstX86Base::isClassof(Instr, InstX86Base::Int3);
   2700     }
   2701 
   2702   private:
   2703     explicit InstX86Int3(Cfg *Func);
   2704   };
   2705 
   2706   /// Test instruction.
   2707   class InstX86Test final : public InstX86Base {
   2708     InstX86Test() = delete;
   2709     InstX86Test(const InstX86Test &) = delete;
   2710     InstX86Test &operator=(const InstX86Test &) = delete;
   2711 
   2712   public:
   2713     static InstX86Test *create(Cfg *Func, Operand *Source1, Operand *Source2) {
   2714       return new (Func->allocate<InstX86Test>())
   2715           InstX86Test(Func, Source1, Source2);
   2716     }
   2717     void emit(const Cfg *Func) const override;
   2718     void emitIAS(const Cfg *Func) const override;
   2719     void dump(const Cfg *Func) const override;
   2720     static bool classof(const Inst *Instr) {
   2721       return InstX86Base::isClassof(Instr, InstX86Base::Test);
   2722     }
   2723 
   2724   private:
   2725     InstX86Test(Cfg *Func, Operand *Source1, Operand *Source2);
   2726   };
   2727 
   2728   /// Mfence instruction.
   2729   class InstX86Mfence final : public InstX86Base {
   2730     InstX86Mfence() = delete;
   2731     InstX86Mfence(const InstX86Mfence &) = delete;
   2732     InstX86Mfence &operator=(const InstX86Mfence &) = delete;
   2733 
   2734   public:
   2735     static InstX86Mfence *create(Cfg *Func) {
   2736       return new (Func->allocate<InstX86Mfence>()) InstX86Mfence(Func);
   2737     }
   2738     void emit(const Cfg *Func) const override;
   2739     void emitIAS(const Cfg *Func) const override;
   2740     void dump(const Cfg *Func) const override;
   2741     static bool classof(const Inst *Instr) {
   2742       return InstX86Base::isClassof(Instr, InstX86Base::Mfence);
   2743     }
   2744 
   2745   private:
   2746     explicit InstX86Mfence(Cfg *Func);
   2747   };
   2748 
   2749   /// This is essentially a "mov" instruction with anX86OperandMem operand
   2750   /// instead of Variable as the destination. It's important for liveness that
   2751   /// there is no Dest operand.
   2752   class InstX86Store final : public InstX86Base {
   2753     InstX86Store() = delete;
   2754     InstX86Store(const InstX86Store &) = delete;
   2755     InstX86Store &operator=(const InstX86Store &) = delete;
   2756 
   2757   public:
   2758     static InstX86Store *create(Cfg *Func, Operand *Value, X86Operand *Mem) {
   2759       return new (Func->allocate<InstX86Store>())
   2760           InstX86Store(Func, Value, Mem);
   2761     }
   2762     void emit(const Cfg *Func) const override;
   2763     void emitIAS(const Cfg *Func) const override;
   2764     void dump(const Cfg *Func) const override;
   2765     static bool classof(const Inst *Instr) {
   2766       return InstX86Base::isClassof(Instr, InstX86Base::Store);
   2767     }
   2768 
   2769   private:
   2770     InstX86Store(Cfg *Func, Operand *Value, X86Operand *Mem);
   2771   };
   2772 
   2773   /// This is essentially a vector "mov" instruction with an typename
   2774   /// X86OperandMem operand instead of Variable as the destination. It's
   2775   /// important for liveness that there is no Dest operand. The source must be
   2776   /// an Xmm register, since Dest is mem.
   2777   class InstX86StoreP final : public InstX86Base {
   2778     InstX86StoreP() = delete;
   2779     InstX86StoreP(const InstX86StoreP &) = delete;
   2780     InstX86StoreP &operator=(const InstX86StoreP &) = delete;
   2781 
   2782   public:
   2783     static InstX86StoreP *create(Cfg *Func, Variable *Value,
   2784                                  X86OperandMem *Mem) {
   2785       return new (Func->allocate<InstX86StoreP>())
   2786           InstX86StoreP(Func, Value, Mem);
   2787     }
   2788     void emit(const Cfg *Func) const override;
   2789     void emitIAS(const Cfg *Func) const override;
   2790     void dump(const Cfg *Func) const override;
   2791     static bool classof(const Inst *Instr) {
   2792       return InstX86Base::isClassof(Instr, InstX86Base::StoreP);
   2793     }
   2794 
   2795   private:
   2796     InstX86StoreP(Cfg *Func, Variable *Value, X86OperandMem *Mem);
   2797   };
   2798 
   2799   class InstX86StoreQ final : public InstX86Base {
   2800     InstX86StoreQ() = delete;
   2801     InstX86StoreQ(const InstX86StoreQ &) = delete;
   2802     InstX86StoreQ &operator=(const InstX86StoreQ &) = delete;
   2803 
   2804   public:
   2805     static InstX86StoreQ *create(Cfg *Func, Operand *Value,
   2806                                  X86OperandMem *Mem) {
   2807       return new (Func->allocate<InstX86StoreQ>())
   2808           InstX86StoreQ(Func, Value, Mem);
   2809     }
   2810     void emit(const Cfg *Func) const override;
   2811     void emitIAS(const Cfg *Func) const override;
   2812     void dump(const Cfg *Func) const override;
   2813     static bool classof(const Inst *Instr) {
   2814       return InstX86Base::isClassof(Instr, InstX86Base::StoreQ);
   2815     }
   2816 
   2817   private:
   2818     InstX86StoreQ(Cfg *Func, Operand *Value, X86OperandMem *Mem);
   2819   };
   2820 
   2821   class InstX86StoreD final : public InstX86Base {
   2822     InstX86StoreD() = delete;
   2823     InstX86StoreD(const InstX86StoreD &) = delete;
   2824     InstX86StoreD &operator=(const InstX86StoreD &) = delete;
   2825 
   2826   public:
   2827     static InstX86StoreD *create(Cfg *Func, Operand *Value,
   2828                                  X86OperandMem *Mem) {
   2829       return new (Func->allocate<InstX86StoreD>())
   2830           InstX86StoreD(Func, Value, Mem);
   2831     }
   2832     void emit(const Cfg *Func) const override;
   2833     void emitIAS(const Cfg *Func) const override;
   2834     void dump(const Cfg *Func) const override;
   2835     static bool classof(const Inst *Instr) {
   2836       return InstX86Base::isClassof(Instr, InstX86Base::StoreQ);
   2837     }
   2838 
   2839   private:
   2840     InstX86StoreD(Cfg *Func, Operand *Value, X86OperandMem *Mem);
   2841   };
   2842 
   2843   /// Nop instructions of varying length
   2844   class InstX86Nop final : public InstX86Base {
   2845     InstX86Nop() = delete;
   2846     InstX86Nop(const InstX86Nop &) = delete;
   2847     InstX86Nop &operator=(const InstX86Nop &) = delete;
   2848 
   2849   public:
   2850     // TODO: Replace with enum.
   2851     using NopVariant = unsigned;
   2852 
   2853     static InstX86Nop *create(Cfg *Func, NopVariant Variant) {
   2854       return new (Func->allocate<InstX86Nop>()) InstX86Nop(Func, Variant);
   2855     }
   2856     void emit(const Cfg *Func) const override;
   2857     void emitIAS(const Cfg *Func) const override;
   2858     void dump(const Cfg *Func) const override;
   2859     static bool classof(const Inst *Instr) {
   2860       return InstX86Base::isClassof(Instr, InstX86Base::Nop);
   2861     }
   2862 
   2863   private:
   2864     InstX86Nop(Cfg *Func, NopVariant Length);
   2865 
   2866     NopVariant Variant;
   2867   };
   2868 
   2869   /// Fld - load a value onto the x87 FP stack.
   2870   class InstX86Fld final : public InstX86Base {
   2871     InstX86Fld() = delete;
   2872     InstX86Fld(const InstX86Fld &) = delete;
   2873     InstX86Fld &operator=(const InstX86Fld &) = delete;
   2874 
   2875   public:
   2876     static InstX86Fld *create(Cfg *Func, Operand *Src) {
   2877       return new (Func->allocate<InstX86Fld>()) InstX86Fld(Func, Src);
   2878     }
   2879     void emit(const Cfg *Func) const override;
   2880     void emitIAS(const Cfg *Func) const override;
   2881     void dump(const Cfg *Func) const override;
   2882     static bool classof(const Inst *Instr) {
   2883       return InstX86Base::isClassof(Instr, InstX86Base::Fld);
   2884     }
   2885 
   2886   private:
   2887     InstX86Fld(Cfg *Func, Operand *Src);
   2888   };
   2889 
   2890   /// Fstp - store x87 st(0) into memory and pop st(0).
   2891   class InstX86Fstp final : public InstX86Base {
   2892     InstX86Fstp() = delete;
   2893     InstX86Fstp(const InstX86Fstp &) = delete;
   2894     InstX86Fstp &operator=(const InstX86Fstp &) = delete;
   2895 
   2896   public:
   2897     static InstX86Fstp *create(Cfg *Func, Variable *Dest) {
   2898       return new (Func->allocate<InstX86Fstp>()) InstX86Fstp(Func, Dest);
   2899     }
   2900     void emit(const Cfg *Func) const override;
   2901     void emitIAS(const Cfg *Func) const override;
   2902     void dump(const Cfg *Func) const override;
   2903     static bool classof(const Inst *Instr) {
   2904       return InstX86Base::isClassof(Instr, InstX86Base::Fstp);
   2905     }
   2906 
   2907   private:
   2908     InstX86Fstp(Cfg *Func, Variable *Dest);
   2909   };
   2910 
   2911   class InstX86Pop final : public InstX86Base {
   2912     InstX86Pop() = delete;
   2913     InstX86Pop(const InstX86Pop &) = delete;
   2914     InstX86Pop &operator=(const InstX86Pop &) = delete;
   2915 
   2916   public:
   2917     static InstX86Pop *create(Cfg *Func, Variable *Dest) {
   2918       return new (Func->allocate<InstX86Pop>()) InstX86Pop(Func, Dest);
   2919     }
   2920     void emit(const Cfg *Func) const override;
   2921     void emitIAS(const Cfg *Func) const override;
   2922     void dump(const Cfg *Func) const override;
   2923     static bool classof(const Inst *Instr) {
   2924       return InstX86Base::isClassof(Instr, InstX86Base::Pop);
   2925     }
   2926 
   2927   private:
   2928     InstX86Pop(Cfg *Func, Variable *Dest);
   2929   };
   2930 
   2931   class InstX86Push final : public InstX86Base {
   2932     InstX86Push() = delete;
   2933     InstX86Push(const InstX86Push &) = delete;
   2934     InstX86Push &operator=(const InstX86Push &) = delete;
   2935 
   2936   public:
   2937     static InstX86Push *create(Cfg *Func, InstX86Label *Label) {
   2938       return new (Func->allocate<InstX86Push>()) InstX86Push(Func, Label);
   2939     }
   2940     static InstX86Push *create(Cfg *Func, Operand *Source) {
   2941       return new (Func->allocate<InstX86Push>()) InstX86Push(Func, Source);
   2942     }
   2943     void emit(const Cfg *Func) const override;
   2944     void emitIAS(const Cfg *Func) const override;
   2945     void dump(const Cfg *Func) const override;
   2946     static bool classof(const Inst *Instr) {
   2947       return InstX86Base::isClassof(Instr, InstX86Base::Push);
   2948     }
   2949 
   2950   private:
   2951     InstX86Label *Label = nullptr;
   2952 
   2953     InstX86Push(Cfg *Func, Operand *Source);
   2954     InstX86Push(Cfg *Func, InstX86Label *Label);
   2955   };
   2956 
   2957   /// Ret instruction. Currently only supports the "ret" version that does not
   2958   /// pop arguments. This instruction takes a Source operand (for non-void
   2959   /// returning functions) for liveness analysis, though a FakeUse before the
   2960   /// ret would do just as well.
   2961   class InstX86Ret final : public InstX86Base {
   2962     InstX86Ret() = delete;
   2963     InstX86Ret(const InstX86Ret &) = delete;
   2964     InstX86Ret &operator=(const InstX86Ret &) = delete;
   2965 
   2966   public:
   2967     static InstX86Ret *create(Cfg *Func, Variable *Source = nullptr) {
   2968       return new (Func->allocate<InstX86Ret>()) InstX86Ret(Func, Source);
   2969     }
   2970     void emit(const Cfg *Func) const override;
   2971     void emitIAS(const Cfg *Func) const override;
   2972     void dump(const Cfg *Func) const override;
   2973     static bool classof(const Inst *Instr) {
   2974       return InstX86Base::isClassof(Instr, InstX86Base::Ret);
   2975     }
   2976 
   2977   private:
   2978     InstX86Ret(Cfg *Func, Variable *Source);
   2979   };
   2980 
   2981   /// Conditional set-byte instruction.
   2982   class InstX86Setcc final : public InstX86Base {
   2983     InstX86Setcc() = delete;
   2984     InstX86Setcc(const InstX86Cmov &) = delete;
   2985     InstX86Setcc &operator=(const InstX86Setcc &) = delete;
   2986 
   2987   public:
   2988     static InstX86Setcc *create(Cfg *Func, Variable *Dest, BrCond Cond) {
   2989       return new (Func->allocate<InstX86Setcc>())
   2990           InstX86Setcc(Func, Dest, Cond);
   2991     }
   2992     void emit(const Cfg *Func) const override;
   2993     void emitIAS(const Cfg *Func) const override;
   2994     void dump(const Cfg *Func) const override;
   2995     static bool classof(const Inst *Instr) {
   2996       return InstX86Base::isClassof(Instr, InstX86Base::Setcc);
   2997     }
   2998 
   2999   private:
   3000     InstX86Setcc(Cfg *Func, Variable *Dest, BrCond Cond);
   3001 
   3002     const BrCond Condition;
   3003   };
   3004 
   3005   /// Exchanging Add instruction. Exchanges the first operand (destination
   3006   /// operand) with the second operand (source operand), then loads the sum of
   3007   /// the two values into the destination operand. The destination may be a
   3008   /// register or memory, while the source must be a register.
   3009   ///
   3010   /// Both the dest and source are updated. The caller should then insert a
   3011   /// FakeDef to reflect the second udpate.
   3012   class InstX86Xadd final : public InstX86BaseLockable {
   3013     InstX86Xadd() = delete;
   3014     InstX86Xadd(const InstX86Xadd &) = delete;
   3015     InstX86Xadd &operator=(const InstX86Xadd &) = delete;
   3016 
   3017   public:
   3018     static InstX86Xadd *create(Cfg *Func, Operand *Dest, Variable *Source,
   3019                                bool Locked) {
   3020       return new (Func->allocate<InstX86Xadd>())
   3021           InstX86Xadd(Func, Dest, Source, Locked);
   3022     }
   3023     void emit(const Cfg *Func) const override;
   3024     void emitIAS(const Cfg *Func) const override;
   3025     void dump(const Cfg *Func) const override;
   3026     static bool classof(const Inst *Instr) {
   3027       return InstX86Base::isClassof(Instr, InstX86Base::Xadd);
   3028     }
   3029 
   3030   private:
   3031     InstX86Xadd(Cfg *Func, Operand *Dest, Variable *Source, bool Locked);
   3032   };
   3033 
   3034   /// Exchange instruction. Exchanges the first operand (destination operand)
   3035   /// with the second operand (source operand). At least one of the operands
   3036   /// must be a register (and the other can be reg or mem). Both the Dest and
   3037   /// Source are updated. If there is a memory operand, then the instruction is
   3038   /// automatically "locked" without the need for a lock prefix.
   3039   class InstX86Xchg final : public InstX86Base {
   3040     InstX86Xchg() = delete;
   3041     InstX86Xchg(const InstX86Xchg &) = delete;
   3042     InstX86Xchg &operator=(const InstX86Xchg &) = delete;
   3043 
   3044   public:
   3045     static InstX86Xchg *create(Cfg *Func, Operand *Dest, Variable *Source) {
   3046       return new (Func->allocate<InstX86Xchg>())
   3047           InstX86Xchg(Func, Dest, Source);
   3048     }
   3049     void emit(const Cfg *Func) const override;
   3050     void emitIAS(const Cfg *Func) const override;
   3051     void dump(const Cfg *Func) const override;
   3052     static bool classof(const Inst *Instr) {
   3053       return InstX86Base::isClassof(Instr, InstX86Base::Xchg);
   3054     }
   3055 
   3056   private:
   3057     InstX86Xchg(Cfg *Func, Operand *Dest, Variable *Source);
   3058   };
   3059 
   3060   /// Start marker for the Intel Architecture Code Analyzer. This is not an
   3061   /// executable instruction and must only be used for analysis.
   3062   class InstX86IacaStart final : public InstX86Base {
   3063     InstX86IacaStart() = delete;
   3064     InstX86IacaStart(const InstX86IacaStart &) = delete;
   3065     InstX86IacaStart &operator=(const InstX86IacaStart &) = delete;
   3066 
   3067   public:
   3068     static InstX86IacaStart *create(Cfg *Func) {
   3069       return new (Func->allocate<InstX86IacaStart>()) InstX86IacaStart(Func);
   3070     }
   3071     void emit(const Cfg *Func) const override;
   3072     void emitIAS(const Cfg *Func) const override;
   3073     void dump(const Cfg *Func) const override;
   3074     static bool classof(const Inst *Instr) {
   3075       return InstX86Base::isClassof(Instr, InstX86Base::IacaStart);
   3076     }
   3077 
   3078   private:
   3079     InstX86IacaStart(Cfg *Func);
   3080   };
   3081 
   3082   /// End marker for the Intel Architecture Code Analyzer. This is not an
   3083   /// executable instruction and must only be used for analysis.
   3084   class InstX86IacaEnd final : public InstX86Base {
   3085     InstX86IacaEnd() = delete;
   3086     InstX86IacaEnd(const InstX86IacaEnd &) = delete;
   3087     InstX86IacaEnd &operator=(const InstX86IacaEnd &) = delete;
   3088 
   3089   public:
   3090     static InstX86IacaEnd *create(Cfg *Func) {
   3091       return new (Func->allocate<InstX86IacaEnd>()) InstX86IacaEnd(Func);
   3092     }
   3093     void emit(const Cfg *Func) const override;
   3094     void emitIAS(const Cfg *Func) const override;
   3095     void dump(const Cfg *Func) const override;
   3096     static bool classof(const Inst *Instr) {
   3097       return InstX86Base::isClassof(Instr, InstX86Base::IacaEnd);
   3098     }
   3099 
   3100   private:
   3101     InstX86IacaEnd(Cfg *Func);
   3102   };
   3103 
   3104   class InstX86Pshufb
   3105       : public InstX86BaseBinopXmm<InstX86Base::Pshufb, false,
   3106                                    InstX86Base::SseSuffix::None> {
   3107   public:
   3108     static InstX86Pshufb *create(Cfg *Func, Variable *Dest, Operand *Source) {
   3109       return new (Func->allocate<InstX86Pshufb>())
   3110           InstX86Pshufb(Func, Dest, Source);
   3111     }
   3112 
   3113   private:
   3114     InstX86Pshufb(Cfg *Func, Variable *Dest, Operand *Source)
   3115         : InstX86BaseBinopXmm<InstX86Base::Pshufb, false,
   3116                               InstX86Base::SseSuffix::None>(Func, Dest,
   3117                                                             Source) {}
   3118   };
   3119 
   3120   class InstX86Punpckl
   3121       : public InstX86BaseBinopXmm<InstX86Base::Punpckl, false,
   3122                                    InstX86Base::SseSuffix::Unpack> {
   3123   public:
   3124     static InstX86Punpckl *create(Cfg *Func, Variable *Dest, Operand *Source) {
   3125       return new (Func->allocate<InstX86Punpckl>())
   3126           InstX86Punpckl(Func, Dest, Source);
   3127     }
   3128 
   3129   private:
   3130     InstX86Punpckl(Cfg *Func, Variable *Dest, Operand *Source)
   3131         : InstX86BaseBinopXmm<InstX86Base::Punpckl, false,
   3132                               InstX86Base::SseSuffix::Unpack>(Func, Dest,
   3133                                                               Source) {}
   3134   };
   3135 
   3136   class InstX86Punpckh
   3137       : public InstX86BaseBinopXmm<InstX86Base::Punpckh, false,
   3138                                    InstX86Base::SseSuffix::Unpack> {
   3139   public:
   3140     static InstX86Punpckh *create(Cfg *Func, Variable *Dest, Operand *Source) {
   3141       return new (Func->allocate<InstX86Punpckh>())
   3142           InstX86Punpckh(Func, Dest, Source);
   3143     }
   3144 
   3145   private:
   3146     InstX86Punpckh(Cfg *Func, Variable *Dest, Operand *Source)
   3147         : InstX86BaseBinopXmm<InstX86Base::Punpckh, false,
   3148                               InstX86Base::SseSuffix::Unpack>(Func, Dest,
   3149                                                               Source) {}
   3150   };
   3151 
   3152   class InstX86Packss
   3153       : public InstX86BaseBinopXmm<InstX86Base::Packss, false,
   3154                                    InstX86Base::SseSuffix::Pack> {
   3155   public:
   3156     static InstX86Packss *create(Cfg *Func, Variable *Dest, Operand *Source) {
   3157       return new (Func->allocate<InstX86Packss>())
   3158           InstX86Packss(Func, Dest, Source);
   3159     }
   3160 
   3161   private:
   3162     InstX86Packss(Cfg *Func, Variable *Dest, Operand *Source)
   3163         : InstX86BaseBinopXmm<InstX86Base::Packss, false,
   3164                               InstX86Base::SseSuffix::Pack>(Func, Dest,
   3165                                                             Source) {}
   3166   };
   3167 
   3168   class InstX86Packus
   3169       : public InstX86BaseBinopXmm<InstX86Base::Packus, false,
   3170                                    InstX86Base::SseSuffix::Pack> {
   3171   public:
   3172     static InstX86Packus *create(Cfg *Func, Variable *Dest, Operand *Source) {
   3173       return new (Func->allocate<InstX86Packus>())
   3174           InstX86Packus(Func, Dest, Source);
   3175     }
   3176 
   3177   private:
   3178     InstX86Packus(Cfg *Func, Variable *Dest, Operand *Source)
   3179         : InstX86BaseBinopXmm<InstX86Base::Packus, false,
   3180                               InstX86Base::SseSuffix::Pack>(Func, Dest,
   3181                                                             Source) {}
   3182   };
   3183 
   3184 }; // struct InstImpl
   3185 
   3186 /// struct Insts is a template that can be used to instantiate all the X86
   3187 /// instructions for a target with a simple
   3188 ///
   3189 /// using Insts = ::Ice::X86NAMESPACE::Insts<TraitsType>;
   3190 template <typename TraitsType> struct Insts {
   3191   using GetIP = typename InstImpl<TraitsType>::InstX86GetIP;
   3192   using FakeRMW = typename InstImpl<TraitsType>::InstX86FakeRMW;
   3193   using Label = typename InstImpl<TraitsType>::InstX86Label;
   3194 
   3195   using Call = typename InstImpl<TraitsType>::InstX86Call;
   3196 
   3197   using Br = typename InstImpl<TraitsType>::InstX86Br;
   3198   using Jmp = typename InstImpl<TraitsType>::InstX86Jmp;
   3199   using Bswap = typename InstImpl<TraitsType>::InstX86Bswap;
   3200   using Neg = typename InstImpl<TraitsType>::InstX86Neg;
   3201   using Bsf = typename InstImpl<TraitsType>::InstX86Bsf;
   3202   using Bsr = typename InstImpl<TraitsType>::InstX86Bsr;
   3203   using Lea = typename InstImpl<TraitsType>::InstX86Lea;
   3204   using Cbwdq = typename InstImpl<TraitsType>::InstX86Cbwdq;
   3205   using Movsx = typename InstImpl<TraitsType>::InstX86Movsx;
   3206   using Movzx = typename InstImpl<TraitsType>::InstX86Movzx;
   3207   using Movd = typename InstImpl<TraitsType>::InstX86Movd;
   3208   using Movmsk = typename InstImpl<TraitsType>::InstX86Movmsk;
   3209   using Sqrt = typename InstImpl<TraitsType>::InstX86Sqrt;
   3210   using Mov = typename InstImpl<TraitsType>::InstX86Mov;
   3211   using Movp = typename InstImpl<TraitsType>::InstX86Movp;
   3212   using Movq = typename InstImpl<TraitsType>::InstX86Movq;
   3213   using Add = typename InstImpl<TraitsType>::InstX86Add;
   3214   using AddRMW = typename InstImpl<TraitsType>::InstX86AddRMW;
   3215   using Addps = typename InstImpl<TraitsType>::InstX86Addps;
   3216   using Adc = typename InstImpl<TraitsType>::InstX86Adc;
   3217   using AdcRMW = typename InstImpl<TraitsType>::InstX86AdcRMW;
   3218   using Addss = typename InstImpl<TraitsType>::InstX86Addss;
   3219   using Andnps = typename InstImpl<TraitsType>::InstX86Andnps;
   3220   using Andps = typename InstImpl<TraitsType>::InstX86Andps;
   3221   using Padd = typename InstImpl<TraitsType>::InstX86Padd;
   3222   using Padds = typename InstImpl<TraitsType>::InstX86Padds;
   3223   using Paddus = typename InstImpl<TraitsType>::InstX86Paddus;
   3224   using Sub = typename InstImpl<TraitsType>::InstX86Sub;
   3225   using SubRMW = typename InstImpl<TraitsType>::InstX86SubRMW;
   3226   using Subps = typename InstImpl<TraitsType>::InstX86Subps;
   3227   using Subss = typename InstImpl<TraitsType>::InstX86Subss;
   3228   using Sbb = typename InstImpl<TraitsType>::InstX86Sbb;
   3229   using SbbRMW = typename InstImpl<TraitsType>::InstX86SbbRMW;
   3230   using Psub = typename InstImpl<TraitsType>::InstX86Psub;
   3231   using Psubs = typename InstImpl<TraitsType>::InstX86Psubs;
   3232   using Psubus = typename InstImpl<TraitsType>::InstX86Psubus;
   3233   using And = typename InstImpl<TraitsType>::InstX86And;
   3234   using AndRMW = typename InstImpl<TraitsType>::InstX86AndRMW;
   3235   using Pand = typename InstImpl<TraitsType>::InstX86Pand;
   3236   using Pandn = typename InstImpl<TraitsType>::InstX86Pandn;
   3237   using Or = typename InstImpl<TraitsType>::InstX86Or;
   3238   using Orps = typename InstImpl<TraitsType>::InstX86Orps;
   3239   using OrRMW = typename InstImpl<TraitsType>::InstX86OrRMW;
   3240   using Por = typename InstImpl<TraitsType>::InstX86Por;
   3241   using Xor = typename InstImpl<TraitsType>::InstX86Xor;
   3242   using Xorps = typename InstImpl<TraitsType>::InstX86Xorps;
   3243   using XorRMW = typename InstImpl<TraitsType>::InstX86XorRMW;
   3244   using Pxor = typename InstImpl<TraitsType>::InstX86Pxor;
   3245   using Maxss = typename InstImpl<TraitsType>::InstX86Maxss;
   3246   using Minss = typename InstImpl<TraitsType>::InstX86Minss;
   3247   using Maxps = typename InstImpl<TraitsType>::InstX86Maxps;
   3248   using Minps = typename InstImpl<TraitsType>::InstX86Minps;
   3249   using Imul = typename InstImpl<TraitsType>::InstX86Imul;
   3250   using ImulImm = typename InstImpl<TraitsType>::InstX86ImulImm;
   3251   using Mulps = typename InstImpl<TraitsType>::InstX86Mulps;
   3252   using Mulss = typename InstImpl<TraitsType>::InstX86Mulss;
   3253   using Pmull = typename InstImpl<TraitsType>::InstX86Pmull;
   3254   using Pmulhw = typename InstImpl<TraitsType>::InstX86Pmulhw;
   3255   using Pmulhuw = typename InstImpl<TraitsType>::InstX86Pmulhuw;
   3256   using Pmaddwd = typename InstImpl<TraitsType>::InstX86Pmaddwd;
   3257   using Pmuludq = typename InstImpl<TraitsType>::InstX86Pmuludq;
   3258   using Divps = typename InstImpl<TraitsType>::InstX86Divps;
   3259   using Divss = typename InstImpl<TraitsType>::InstX86Divss;
   3260   using Rol = typename InstImpl<TraitsType>::InstX86Rol;
   3261   using Shl = typename InstImpl<TraitsType>::InstX86Shl;
   3262   using Psll = typename InstImpl<TraitsType>::InstX86Psll;
   3263   using Psrl = typename InstImpl<TraitsType>::InstX86Psrl;
   3264   using Shr = typename InstImpl<TraitsType>::InstX86Shr;
   3265   using Sar = typename InstImpl<TraitsType>::InstX86Sar;
   3266   using Psra = typename InstImpl<TraitsType>::InstX86Psra;
   3267   using Pcmpeq = typename InstImpl<TraitsType>::InstX86Pcmpeq;
   3268   using Pcmpgt = typename InstImpl<TraitsType>::InstX86Pcmpgt;
   3269   using MovssRegs = typename InstImpl<TraitsType>::InstX86MovssRegs;
   3270   using Idiv = typename InstImpl<TraitsType>::InstX86Idiv;
   3271   using Div = typename InstImpl<TraitsType>::InstX86Div;
   3272   using Insertps = typename InstImpl<TraitsType>::InstX86Insertps;
   3273   using Pinsr = typename InstImpl<TraitsType>::InstX86Pinsr;
   3274   using Shufps = typename InstImpl<TraitsType>::InstX86Shufps;
   3275   using Blendvps = typename InstImpl<TraitsType>::InstX86Blendvps;
   3276   using Pblendvb = typename InstImpl<TraitsType>::InstX86Pblendvb;
   3277   using Pextr = typename InstImpl<TraitsType>::InstX86Pextr;
   3278   using Pshufd = typename InstImpl<TraitsType>::InstX86Pshufd;
   3279   using Lockable = typename InstImpl<TraitsType>::InstX86BaseLockable;
   3280   using Mul = typename InstImpl<TraitsType>::InstX86Mul;
   3281   using Shld = typename InstImpl<TraitsType>::InstX86Shld;
   3282   using Shrd = typename InstImpl<TraitsType>::InstX86Shrd;
   3283   using Cmov = typename InstImpl<TraitsType>::InstX86Cmov;
   3284   using Cmpps = typename InstImpl<TraitsType>::InstX86Cmpps;
   3285   using Cmpxchg = typename InstImpl<TraitsType>::InstX86Cmpxchg;
   3286   using Cmpxchg8b = typename InstImpl<TraitsType>::InstX86Cmpxchg8b;
   3287   using Cvt = typename InstImpl<TraitsType>::InstX86Cvt;
   3288   using Round = typename InstImpl<TraitsType>::InstX86Round;
   3289   using Icmp = typename InstImpl<TraitsType>::InstX86Icmp;
   3290   using Ucomiss = typename InstImpl<TraitsType>::InstX86Ucomiss;
   3291   using UD2 = typename InstImpl<TraitsType>::InstX86UD2;
   3292   using Int3 = typename InstImpl<TraitsType>::InstX86Int3;
   3293   using Test = typename InstImpl<TraitsType>::InstX86Test;
   3294   using Mfence = typename InstImpl<TraitsType>::InstX86Mfence;
   3295   using Store = typename InstImpl<TraitsType>::InstX86Store;
   3296   using StoreP = typename InstImpl<TraitsType>::InstX86StoreP;
   3297   using StoreQ = typename InstImpl<TraitsType>::InstX86StoreQ;
   3298   using StoreD = typename InstImpl<TraitsType>::InstX86StoreD;
   3299   using Nop = typename InstImpl<TraitsType>::InstX86Nop;
   3300   template <typename T = typename InstImpl<TraitsType>::Traits>
   3301   using Fld =
   3302       typename std::enable_if<T::UsesX87,
   3303                               typename InstImpl<TraitsType>::InstX86Fld>::type;
   3304   template <typename T = typename InstImpl<TraitsType>::Traits>
   3305   using Fstp =
   3306       typename std::enable_if<T::UsesX87,
   3307                               typename InstImpl<TraitsType>::InstX86Fstp>::type;
   3308   using Pop = typename InstImpl<TraitsType>::InstX86Pop;
   3309   using Push = typename InstImpl<TraitsType>::InstX86Push;
   3310   using Ret = typename InstImpl<TraitsType>::InstX86Ret;
   3311   using Setcc = typename InstImpl<TraitsType>::InstX86Setcc;
   3312   using Xadd = typename InstImpl<TraitsType>::InstX86Xadd;
   3313   using Xchg = typename InstImpl<TraitsType>::InstX86Xchg;
   3314 
   3315   using IacaStart = typename InstImpl<TraitsType>::InstX86IacaStart;
   3316   using IacaEnd = typename InstImpl<TraitsType>::InstX86IacaEnd;
   3317 
   3318   using Pshufb = typename InstImpl<TraitsType>::InstX86Pshufb;
   3319   using Punpckl = typename InstImpl<TraitsType>::InstX86Punpckl;
   3320   using Punpckh = typename InstImpl<TraitsType>::InstX86Punpckh;
   3321   using Packss = typename InstImpl<TraitsType>::InstX86Packss;
   3322   using Packus = typename InstImpl<TraitsType>::InstX86Packus;
   3323 };
   3324 
   3325 /// X86 Instructions have static data (particularly, opcodes and instruction
   3326 /// emitters). Each X86 target needs to define all of these, so this macro is
   3327 /// provided so that, if something changes, then all X86 targets will be updated
   3328 /// automatically.
   3329 #define X86INSTS_DEFINE_STATIC_DATA(X86NAMESPACE, TraitsType)                  \
   3330   namespace Ice {                                                              \
   3331   namespace X86NAMESPACE {                                                     \
   3332   /* In-place ops */                                                           \
   3333   template <>                                                                  \
   3334   template <>                                                                  \
   3335   const char *InstImpl<TraitsType>::InstX86Bswap::Base::Opcode = "bswap";      \
   3336   template <>                                                                  \
   3337   template <>                                                                  \
   3338   const char *InstImpl<TraitsType>::InstX86Neg::Base::Opcode = "neg";          \
   3339   /* Unary ops */                                                              \
   3340   template <>                                                                  \
   3341   template <>                                                                  \
   3342   const char *InstImpl<TraitsType>::InstX86Bsf::Base::Opcode = "bsf";          \
   3343   template <>                                                                  \
   3344   template <>                                                                  \
   3345   const char *InstImpl<TraitsType>::InstX86Bsr::Base::Opcode = "bsr";          \
   3346   template <>                                                                  \
   3347   template <>                                                                  \
   3348   const char *InstImpl<TraitsType>::InstX86Lea::Base::Opcode = "lea";          \
   3349   template <>                                                                  \
   3350   template <>                                                                  \
   3351   const char *InstImpl<TraitsType>::InstX86Movd::Base::Opcode = "movd";        \
   3352   template <>                                                                  \
   3353   template <>                                                                  \
   3354   const char *InstImpl<TraitsType>::InstX86Movsx::Base::Opcode = "movs";       \
   3355   template <>                                                                  \
   3356   template <>                                                                  \
   3357   const char *InstImpl<TraitsType>::InstX86Movzx::Base::Opcode = "movz";       \
   3358   template <>                                                                  \
   3359   template <>                                                                  \
   3360   const char *InstImpl<TraitsType>::InstX86Sqrt::Base::Opcode = "sqrt";        \
   3361   template <>                                                                  \
   3362   template <>                                                                  \
   3363   const char *InstImpl<TraitsType>::InstX86Cbwdq::Base::Opcode =               \
   3364       "cbw/cwd/cdq";                                                           \
   3365   /* Mov-like ops */                                                           \
   3366   template <>                                                                  \
   3367   template <>                                                                  \
   3368   const char *InstImpl<TraitsType>::InstX86Mov::Base::Opcode = "mov";          \
   3369   template <>                                                                  \
   3370   template <>                                                                  \
   3371   const char *InstImpl<TraitsType>::InstX86Movp::Base::Opcode = "movups";      \
   3372   template <>                                                                  \
   3373   template <>                                                                  \
   3374   const char *InstImpl<TraitsType>::InstX86Movq::Base::Opcode = "movq";        \
   3375   /* Binary ops */                                                             \
   3376   template <>                                                                  \
   3377   template <>                                                                  \
   3378   const char *InstImpl<TraitsType>::InstX86Add::Base::Opcode = "add";          \
   3379   template <>                                                                  \
   3380   template <>                                                                  \
   3381   const char *InstImpl<TraitsType>::InstX86AddRMW::Base::Opcode = "add";       \
   3382   template <>                                                                  \
   3383   template <>                                                                  \
   3384   const char *InstImpl<TraitsType>::InstX86Addps::Base::Opcode = "add";        \
   3385   template <>                                                                  \
   3386   template <>                                                                  \
   3387   const char *InstImpl<TraitsType>::InstX86Adc::Base::Opcode = "adc";          \
   3388   template <>                                                                  \
   3389   template <>                                                                  \
   3390   const char *InstImpl<TraitsType>::InstX86AdcRMW::Base::Opcode = "adc";       \
   3391   template <>                                                                  \
   3392   template <>                                                                  \
   3393   const char *InstImpl<TraitsType>::InstX86Addss::Base::Opcode = "add";        \
   3394   template <>                                                                  \
   3395   template <>                                                                  \
   3396   const char *InstImpl<TraitsType>::InstX86Andnps::Base::Opcode = "andn";      \
   3397   template <>                                                                  \
   3398   template <>                                                                  \
   3399   const char *InstImpl<TraitsType>::InstX86Andps::Base::Opcode = "and";        \
   3400   template <>                                                                  \
   3401   template <>                                                                  \
   3402   const char *InstImpl<TraitsType>::InstX86Maxss::Base::Opcode = "max";        \
   3403   template <>                                                                  \
   3404   template <>                                                                  \
   3405   const char *InstImpl<TraitsType>::InstX86Minss::Base::Opcode = "min";        \
   3406   template <>                                                                  \
   3407   template <>                                                                  \
   3408   const char *InstImpl<TraitsType>::InstX86Maxps::Base::Opcode = "max";        \
   3409   template <>                                                                  \
   3410   template <>                                                                  \
   3411   const char *InstImpl<TraitsType>::InstX86Minps::Base::Opcode = "min";        \
   3412   template <>                                                                  \
   3413   template <>                                                                  \
   3414   const char *InstImpl<TraitsType>::InstX86Padd::Base::Opcode = "padd";        \
   3415   template <>                                                                  \
   3416   template <>                                                                  \
   3417   const char *InstImpl<TraitsType>::InstX86Padds::Base::Opcode = "padds";      \
   3418   template <>                                                                  \
   3419   template <>                                                                  \
   3420   const char *InstImpl<TraitsType>::InstX86Paddus::Base::Opcode = "paddus";    \
   3421   template <>                                                                  \
   3422   template <>                                                                  \
   3423   const char *InstImpl<TraitsType>::InstX86Sub::Base::Opcode = "sub";          \
   3424   template <>                                                                  \
   3425   template <>                                                                  \
   3426   const char *InstImpl<TraitsType>::InstX86SubRMW::Base::Opcode = "sub";       \
   3427   template <>                                                                  \
   3428   template <>                                                                  \
   3429   const char *InstImpl<TraitsType>::InstX86Subps::Base::Opcode = "sub";        \
   3430   template <>                                                                  \
   3431   template <>                                                                  \
   3432   const char *InstImpl<TraitsType>::InstX86Subss::Base::Opcode = "sub";        \
   3433   template <>                                                                  \
   3434   template <>                                                                  \
   3435   const char *InstImpl<TraitsType>::InstX86Sbb::Base::Opcode = "sbb";          \
   3436   template <>                                                                  \
   3437   template <>                                                                  \
   3438   const char *InstImpl<TraitsType>::InstX86SbbRMW::Base::Opcode = "sbb";       \
   3439   template <>                                                                  \
   3440   template <>                                                                  \
   3441   const char *InstImpl<TraitsType>::InstX86Psub::Base::Opcode = "psub";        \
   3442   template <>                                                                  \
   3443   template <>                                                                  \
   3444   const char *InstImpl<TraitsType>::InstX86Psubs::Base::Opcode = "psubs";      \
   3445   template <>                                                                  \
   3446   template <>                                                                  \
   3447   const char *InstImpl<TraitsType>::InstX86Psubus::Base::Opcode = "psubus";    \
   3448   template <>                                                                  \
   3449   template <>                                                                  \
   3450   const char *InstImpl<TraitsType>::InstX86And::Base::Opcode = "and";          \
   3451   template <>                                                                  \
   3452   template <>                                                                  \
   3453   const char *InstImpl<TraitsType>::InstX86AndRMW::Base::Opcode = "and";       \
   3454   template <>                                                                  \
   3455   template <>                                                                  \
   3456   const char *InstImpl<TraitsType>::InstX86Pand::Base::Opcode = "pand";        \
   3457   template <>                                                                  \
   3458   template <>                                                                  \
   3459   const char *InstImpl<TraitsType>::InstX86Pandn::Base::Opcode = "pandn";      \
   3460   template <>                                                                  \
   3461   template <>                                                                  \
   3462   const char *InstImpl<TraitsType>::InstX86Or::Base::Opcode = "or";            \
   3463   template <>                                                                  \
   3464   template <>                                                                  \
   3465   const char *InstImpl<TraitsType>::InstX86Orps::Base::Opcode = "or";          \
   3466   template <>                                                                  \
   3467   template <>                                                                  \
   3468   const char *InstImpl<TraitsType>::InstX86OrRMW::Base::Opcode = "or";         \
   3469   template <>                                                                  \
   3470   template <>                                                                  \
   3471   const char *InstImpl<TraitsType>::InstX86Por::Base::Opcode = "por";          \
   3472   template <>                                                                  \
   3473   template <>                                                                  \
   3474   const char *InstImpl<TraitsType>::InstX86Xor::Base::Opcode = "xor";          \
   3475   template <>                                                                  \
   3476   template <>                                                                  \
   3477   const char *InstImpl<TraitsType>::InstX86Xorps::Base::Opcode = "xor";        \
   3478   template <>                                                                  \
   3479   template <>                                                                  \
   3480   const char *InstImpl<TraitsType>::InstX86XorRMW::Base::Opcode = "xor";       \
   3481   template <>                                                                  \
   3482   template <>                                                                  \
   3483   const char *InstImpl<TraitsType>::InstX86Pxor::Base::Opcode = "pxor";        \
   3484   template <>                                                                  \
   3485   template <>                                                                  \
   3486   const char *InstImpl<TraitsType>::InstX86Imul::Base::Opcode = "imul";        \
   3487   template <>                                                                  \
   3488   template <>                                                                  \
   3489   const char *InstImpl<TraitsType>::InstX86ImulImm::Base::Opcode = "imul";     \
   3490   template <>                                                                  \
   3491   template <>                                                                  \
   3492   const char *InstImpl<TraitsType>::InstX86Mulps::Base::Opcode = "mul";        \
   3493   template <>                                                                  \
   3494   template <>                                                                  \
   3495   const char *InstImpl<TraitsType>::InstX86Mulss::Base::Opcode = "mul";        \
   3496   template <>                                                                  \
   3497   template <>                                                                  \
   3498   const char *InstImpl<TraitsType>::InstX86Pmull::Base::Opcode = "pmull";      \
   3499   template <>                                                                  \
   3500   template <>                                                                  \
   3501   const char *InstImpl<TraitsType>::InstX86Pmulhw::Base::Opcode = "pmulhw";    \
   3502   template <>                                                                  \
   3503   template <>                                                                  \
   3504   const char *InstImpl<TraitsType>::InstX86Pmulhuw::Base::Opcode = "pmulhuw";  \
   3505   template <>                                                                  \
   3506   template <>                                                                  \
   3507   const char *InstImpl<TraitsType>::InstX86Pmaddwd::Base::Opcode = "pmaddwd";  \
   3508   template <>                                                                  \
   3509   template <>                                                                  \
   3510   const char *InstImpl<TraitsType>::InstX86Pmuludq::Base::Opcode = "pmuludq";  \
   3511   template <>                                                                  \
   3512   template <>                                                                  \
   3513   const char *InstImpl<TraitsType>::InstX86Div::Base::Opcode = "div";          \
   3514   template <>                                                                  \
   3515   template <>                                                                  \
   3516   const char *InstImpl<TraitsType>::InstX86Divps::Base::Opcode = "div";        \
   3517   template <>                                                                  \
   3518   template <>                                                                  \
   3519   const char *InstImpl<TraitsType>::InstX86Divss::Base::Opcode = "div";        \
   3520   template <>                                                                  \
   3521   template <>                                                                  \
   3522   const char *InstImpl<TraitsType>::InstX86Idiv::Base::Opcode = "idiv";        \
   3523   template <>                                                                  \
   3524   template <>                                                                  \
   3525   const char *InstImpl<TraitsType>::InstX86Rol::Base::Opcode = "rol";          \
   3526   template <>                                                                  \
   3527   template <>                                                                  \
   3528   const char *InstImpl<TraitsType>::InstX86Shl::Base::Opcode = "shl";          \
   3529   template <>                                                                  \
   3530   template <>                                                                  \
   3531   const char *InstImpl<TraitsType>::InstX86Psll::Base::Opcode = "psll";        \
   3532   template <>                                                                  \
   3533   template <>                                                                  \
   3534   const char *InstImpl<TraitsType>::InstX86Shr::Base::Opcode = "shr";          \
   3535   template <>                                                                  \
   3536   template <>                                                                  \
   3537   const char *InstImpl<TraitsType>::InstX86Sar::Base::Opcode = "sar";          \
   3538   template <>                                                                  \
   3539   template <>                                                                  \
   3540   const char *InstImpl<TraitsType>::InstX86Psra::Base::Opcode = "psra";        \
   3541   template <>                                                                  \
   3542   template <>                                                                  \
   3543   const char *InstImpl<TraitsType>::InstX86Psrl::Base::Opcode = "psrl";        \
   3544   template <>                                                                  \
   3545   template <>                                                                  \
   3546   const char *InstImpl<TraitsType>::InstX86Pcmpeq::Base::Opcode = "pcmpeq";    \
   3547   template <>                                                                  \
   3548   template <>                                                                  \
   3549   const char *InstImpl<TraitsType>::InstX86Pcmpgt::Base::Opcode = "pcmpgt";    \
   3550   template <>                                                                  \
   3551   template <>                                                                  \
   3552   const char *InstImpl<TraitsType>::InstX86MovssRegs::Base::Opcode = "movss";  \
   3553   /* Ternary ops */                                                            \
   3554   template <>                                                                  \
   3555   template <>                                                                  \
   3556   const char *InstImpl<TraitsType>::InstX86Insertps::Base::Opcode =            \
   3557       "insertps";                                                              \
   3558   template <>                                                                  \
   3559   template <>                                                                  \
   3560   const char *InstImpl<TraitsType>::InstX86Round::Base::Opcode = "round";      \
   3561   template <>                                                                  \
   3562   template <>                                                                  \
   3563   const char *InstImpl<TraitsType>::InstX86Shufps::Base::Opcode = "shufps";    \
   3564   template <>                                                                  \
   3565   template <>                                                                  \
   3566   const char *InstImpl<TraitsType>::InstX86Pinsr::Base::Opcode = "pinsr";      \
   3567   template <>                                                                  \
   3568   template <>                                                                  \
   3569   const char *InstImpl<TraitsType>::InstX86Blendvps::Base::Opcode =            \
   3570       "blendvps";                                                              \
   3571   template <>                                                                  \
   3572   template <>                                                                  \
   3573   const char *InstImpl<TraitsType>::InstX86Pblendvb::Base::Opcode =            \
   3574       "pblendvb";                                                              \
   3575   /* Three address ops */                                                      \
   3576   template <>                                                                  \
   3577   template <>                                                                  \
   3578   const char *InstImpl<TraitsType>::InstX86Pextr::Base::Opcode = "pextr";      \
   3579   template <>                                                                  \
   3580   template <>                                                                  \
   3581   const char *InstImpl<TraitsType>::InstX86Pshufd::Base::Opcode = "pshufd";    \
   3582   template <>                                                                  \
   3583   template <>                                                                  \
   3584   const char *InstImpl<TraitsType>::InstX86Pshufb::Base::Opcode = "pshufb";    \
   3585   template <>                                                                  \
   3586   template <>                                                                  \
   3587   const char *InstImpl<TraitsType>::InstX86Punpckl::Base::Opcode = "punpckl";  \
   3588   template <>                                                                  \
   3589   template <>                                                                  \
   3590   const char *InstImpl<TraitsType>::InstX86Punpckh::Base::Opcode = "punpckh";  \
   3591   template <>                                                                  \
   3592   template <>                                                                  \
   3593   const char *InstImpl<TraitsType>::InstX86Packss::Base::Opcode = "packss";    \
   3594   template <>                                                                  \
   3595   template <>                                                                  \
   3596   const char *InstImpl<TraitsType>::InstX86Packus::Base::Opcode = "packus";    \
   3597   /* Inplace GPR ops */                                                        \
   3598   template <>                                                                  \
   3599   template <>                                                                  \
   3600   const InstImpl<TraitsType>::Assembler::GPREmitterOneOp                       \
   3601       InstImpl<TraitsType>::InstX86Bswap::Base::Emitter = {                    \
   3602           &InstImpl<TraitsType>::Assembler::bswap,                             \
   3603           nullptr /* only a reg form exists */                                 \
   3604   };                                                                           \
   3605   template <>                                                                  \
   3606   template <>                                                                  \
   3607   const InstImpl<TraitsType>::Assembler::GPREmitterOneOp                       \
   3608       InstImpl<TraitsType>::InstX86Neg::Base::Emitter = {                      \
   3609           &InstImpl<TraitsType>::Assembler::neg,                               \
   3610           &InstImpl<TraitsType>::Assembler::neg};                              \
   3611                                                                                \
   3612   /* Unary GPR ops */                                                          \
   3613   template <>                                                                  \
   3614   template <> /* uses specialized emitter. */                                  \
   3615   const InstImpl<TraitsType>::Assembler::GPREmitterRegOp                       \
   3616       InstImpl<TraitsType>::InstX86Cbwdq::Base::Emitter = {nullptr, nullptr,   \
   3617                                                            nullptr};           \
   3618   template <>                                                                  \
   3619   template <>                                                                  \
   3620   const InstImpl<TraitsType>::Assembler::GPREmitterRegOp                       \
   3621       InstImpl<TraitsType>::InstX86Bsf::Base::Emitter = {                      \
   3622           &InstImpl<TraitsType>::Assembler::bsf,                               \
   3623           &InstImpl<TraitsType>::Assembler::bsf, nullptr};                     \
   3624   template <>                                                                  \
   3625   template <>                                                                  \
   3626   const InstImpl<TraitsType>::Assembler::GPREmitterRegOp                       \
   3627       InstImpl<TraitsType>::InstX86Bsr::Base::Emitter = {                      \
   3628           &InstImpl<TraitsType>::Assembler::bsr,                               \
   3629           &InstImpl<TraitsType>::Assembler::bsr, nullptr};                     \
   3630   template <>                                                                  \
   3631   template <>                                                                  \
   3632   const InstImpl<TraitsType>::Assembler::GPREmitterRegOp                       \
   3633       InstImpl<TraitsType>::InstX86Lea::Base::Emitter = {                      \
   3634           /* reg/reg and reg/imm are illegal */ nullptr,                       \
   3635           &InstImpl<TraitsType>::Assembler::lea, nullptr};                     \
   3636   template <>                                                                  \
   3637   template <>                                                                  \
   3638   const InstImpl<TraitsType>::Assembler::GPREmitterRegOp                       \
   3639       InstImpl<TraitsType>::InstX86Movsx::Base::Emitter = {                    \
   3640           &InstImpl<TraitsType>::Assembler::movsx,                             \
   3641           &InstImpl<TraitsType>::Assembler::movsx, nullptr};                   \
   3642   template <>                                                                  \
   3643   template <>                                                                  \
   3644   const InstImpl<TraitsType>::Assembler::GPREmitterRegOp                       \
   3645       InstImpl<TraitsType>::InstX86Movzx::Base::Emitter = {                    \
   3646           &InstImpl<TraitsType>::Assembler::movzx,                             \
   3647           &InstImpl<TraitsType>::Assembler::movzx, nullptr};                   \
   3648                                                                                \
   3649   /* Unary XMM ops */                                                          \
   3650   template <>                                                                  \
   3651   template <> /* uses specialized emitter. */                                  \
   3652   const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp                       \
   3653       InstImpl<TraitsType>::InstX86Movd::Base::Emitter = {nullptr, nullptr};   \
   3654   template <>                                                                  \
   3655   template <>                                                                  \
   3656   const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp                       \
   3657       InstImpl<TraitsType>::InstX86Sqrt::Base::Emitter = {                     \
   3658           &InstImpl<TraitsType>::Assembler::sqrt,                              \
   3659           &InstImpl<TraitsType>::Assembler::sqrt};                             \
   3660                                                                                \
   3661   /* Binary GPR ops */                                                         \
   3662   template <>                                                                  \
   3663   template <> /* uses specialized emitter. */                                  \
   3664   const InstImpl<TraitsType>::Assembler::GPREmitterRegOp                       \
   3665       InstImpl<TraitsType>::InstX86Imul::Base::Emitter = {nullptr, nullptr,    \
   3666                                                           nullptr};            \
   3667   template <>                                                                  \
   3668   template <>                                                                  \
   3669   const InstImpl<TraitsType>::Assembler::GPREmitterRegOp                       \
   3670       InstImpl<TraitsType>::InstX86Add::Base::Emitter = {                      \
   3671           &InstImpl<TraitsType>::Assembler::add,                               \
   3672           &InstImpl<TraitsType>::Assembler::add,                               \
   3673           &InstImpl<TraitsType>::Assembler::add};                              \
   3674   template <>                                                                  \
   3675   template <>                                                                  \
   3676   const InstImpl<TraitsType>::Assembler::GPREmitterAddrOp                      \
   3677       InstImpl<TraitsType>::InstX86AddRMW::Base::Emitter = {                   \
   3678           &InstImpl<TraitsType>::Assembler::add,                               \
   3679           &InstImpl<TraitsType>::Assembler::add};                              \
   3680   template <>                                                                  \
   3681   template <>                                                                  \
   3682   const InstImpl<TraitsType>::Assembler::GPREmitterRegOp                       \
   3683       InstImpl<TraitsType>::InstX86Adc::Base::Emitter = {                      \
   3684           &InstImpl<TraitsType>::Assembler::adc,                               \
   3685           &InstImpl<TraitsType>::Assembler::adc,                               \
   3686           &InstImpl<TraitsType>::Assembler::adc};                              \
   3687   template <>                                                                  \
   3688   template <>                                                                  \
   3689   const InstImpl<TraitsType>::Assembler::GPREmitterAddrOp                      \
   3690       InstImpl<TraitsType>::InstX86AdcRMW::Base::Emitter = {                   \
   3691           &InstImpl<TraitsType>::Assembler::adc,                               \
   3692           &InstImpl<TraitsType>::Assembler::adc};                              \
   3693   template <>                                                                  \
   3694   template <>                                                                  \
   3695   const InstImpl<TraitsType>::Assembler::GPREmitterRegOp                       \
   3696       InstImpl<TraitsType>::InstX86And::Base::Emitter = {                      \
   3697           &InstImpl<TraitsType>::Assembler::And,                               \
   3698           &InstImpl<TraitsType>::Assembler::And,                               \
   3699           &InstImpl<TraitsType>::Assembler::And};                              \
   3700   template <>                                                                  \
   3701   template <>                                                                  \
   3702   const InstImpl<TraitsType>::Assembler::GPREmitterAddrOp                      \
   3703       InstImpl<TraitsType>::InstX86AndRMW::Base::Emitter = {                   \
   3704           &InstImpl<TraitsType>::Assembler::And,                               \
   3705           &InstImpl<TraitsType>::Assembler::And};                              \
   3706   template <>                                                                  \
   3707   template <>                                                                  \
   3708   const InstImpl<TraitsType>::Assembler::GPREmitterRegOp                       \
   3709       InstImpl<TraitsType>::InstX86Or::Base::Emitter = {                       \
   3710           &InstImpl<TraitsType>::Assembler::Or,                                \
   3711           &InstImpl<TraitsType>::Assembler::Or,                                \
   3712           &InstImpl<TraitsType>::Assembler::Or};                               \
   3713   template <>                                                                  \
   3714   template <>                                                                  \
   3715   const InstImpl<TraitsType>::Assembler::GPREmitterAddrOp                      \
   3716       InstImpl<TraitsType>::InstX86OrRMW::Base::Emitter = {                    \
   3717           &InstImpl<TraitsType>::Assembler::Or,                                \
   3718           &InstImpl<TraitsType>::Assembler::Or};                               \
   3719   template <>                                                                  \
   3720   template <>                                                                  \
   3721   const InstImpl<TraitsType>::Assembler::GPREmitterRegOp                       \
   3722       InstImpl<TraitsType>::InstX86Sbb::Base::Emitter = {                      \
   3723           &InstImpl<TraitsType>::Assembler::sbb,                               \
   3724           &InstImpl<TraitsType>::Assembler::sbb,                               \
   3725           &InstImpl<TraitsType>::Assembler::sbb};                              \
   3726   template <>                                                                  \
   3727   template <>                                                                  \
   3728   const InstImpl<TraitsType>::Assembler::GPREmitterAddrOp                      \
   3729       InstImpl<TraitsType>::InstX86SbbRMW::Base::Emitter = {                   \
   3730           &InstImpl<TraitsType>::Assembler::sbb,                               \
   3731           &InstImpl<TraitsType>::Assembler::sbb};                              \
   3732   template <>                                                                  \
   3733   template <>                                                                  \
   3734   const InstImpl<TraitsType>::Assembler::GPREmitterRegOp                       \
   3735       InstImpl<TraitsType>::InstX86Sub::Base::Emitter = {                      \
   3736           &InstImpl<TraitsType>::Assembler::sub,                               \
   3737           &InstImpl<TraitsType>::Assembler::sub,                               \
   3738           &InstImpl<TraitsType>::Assembler::sub};                              \
   3739   template <>                                                                  \
   3740   template <>                                                                  \
   3741   const InstImpl<TraitsType>::Assembler::GPREmitterAddrOp                      \
   3742       InstImpl<TraitsType>::InstX86SubRMW::Base::Emitter = {                   \
   3743           &InstImpl<TraitsType>::Assembler::sub,                               \
   3744           &InstImpl<TraitsType>::Assembler::sub};                              \
   3745   template <>                                                                  \
   3746   template <>                                                                  \
   3747   const InstImpl<TraitsType>::Assembler::GPREmitterRegOp                       \
   3748       InstImpl<TraitsType>::InstX86Xor::Base::Emitter = {                      \
   3749           &InstImpl<TraitsType>::Assembler::Xor,                               \
   3750           &InstImpl<TraitsType>::Assembler::Xor,                               \
   3751           &InstImpl<TraitsType>::Assembler::Xor};                              \
   3752   template <>                                                                  \
   3753   template <>                                                                  \
   3754   const InstImpl<TraitsType>::Assembler::GPREmitterAddrOp                      \
   3755       InstImpl<TraitsType>::InstX86XorRMW::Base::Emitter = {                   \
   3756           &InstImpl<TraitsType>::Assembler::Xor,                               \
   3757           &InstImpl<TraitsType>::Assembler::Xor};                              \
   3758                                                                                \
   3759   /* Binary Shift GPR ops */                                                   \
   3760   template <>                                                                  \
   3761   template <>                                                                  \
   3762   const InstImpl<TraitsType>::Assembler::GPREmitterShiftOp                     \
   3763       InstImpl<TraitsType>::InstX86Rol::Base::Emitter = {                      \
   3764           &InstImpl<TraitsType>::Assembler::rol,                               \
   3765           &InstImpl<TraitsType>::Assembler::rol};                              \
   3766   template <>                                                                  \
   3767   template <>                                                                  \
   3768   const InstImpl<TraitsType>::Assembler::GPREmitterShiftOp                     \
   3769       InstImpl<TraitsType>::InstX86Sar::Base::Emitter = {                      \
   3770           &InstImpl<TraitsType>::Assembler::sar,                               \
   3771           &InstImpl<TraitsType>::Assembler::sar};                              \
   3772   template <>                                                                  \
   3773   template <>                                                                  \
   3774   const InstImpl<TraitsType>::Assembler::GPREmitterShiftOp                     \
   3775       InstImpl<TraitsType>::InstX86Shl::Base::Emitter = {                      \
   3776           &InstImpl<TraitsType>::Assembler::shl,                               \
   3777           &InstImpl<TraitsType>::Assembler::shl};                              \
   3778   template <>                                                                  \
   3779   template <>                                                                  \
   3780   const InstImpl<TraitsType>::Assembler::GPREmitterShiftOp                     \
   3781       InstImpl<TraitsType>::InstX86Shr::Base::Emitter = {                      \
   3782           &InstImpl<TraitsType>::Assembler::shr,                               \
   3783           &InstImpl<TraitsType>::Assembler::shr};                              \
   3784                                                                                \
   3785   /* Binary XMM ops */                                                         \
   3786   template <>                                                                  \
   3787   template <> /* uses specialized emitter. */                                  \
   3788   const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp                       \
   3789       InstImpl<TraitsType>::InstX86MovssRegs::Base::Emitter = {nullptr,        \
   3790                                                                nullptr};       \
   3791   template <>                                                                  \
   3792   template <>                                                                  \
   3793   const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp                       \
   3794       InstImpl<TraitsType>::InstX86Addss::Base::Emitter = {                    \
   3795           &InstImpl<TraitsType>::Assembler::addss,                             \
   3796           &InstImpl<TraitsType>::Assembler::addss};                            \
   3797   template <>                                                                  \
   3798   template <>                                                                  \
   3799   const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp                       \
   3800       InstImpl<TraitsType>::InstX86Addps::Base::Emitter = {                    \
   3801           &InstImpl<TraitsType>::Assembler::addps,                             \
   3802           &InstImpl<TraitsType>::Assembler::addps};                            \
   3803   template <>                                                                  \
   3804   template <>                                                                  \
   3805   const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp                       \
   3806       InstImpl<TraitsType>::InstX86Divss::Base::Emitter = {                    \
   3807           &InstImpl<TraitsType>::Assembler::divss,                             \
   3808           &InstImpl<TraitsType>::Assembler::divss};                            \
   3809   template <>                                                                  \
   3810   template <>                                                                  \
   3811   const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp                       \
   3812       InstImpl<TraitsType>::InstX86Divps::Base::Emitter = {                    \
   3813           &InstImpl<TraitsType>::Assembler::divps,                             \
   3814           &InstImpl<TraitsType>::Assembler::divps};                            \
   3815   template <>                                                                  \
   3816   template <>                                                                  \
   3817   const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp                       \
   3818       InstImpl<TraitsType>::InstX86Mulss::Base::Emitter = {                    \
   3819           &InstImpl<TraitsType>::Assembler::mulss,                             \
   3820           &InstImpl<TraitsType>::Assembler::mulss};                            \
   3821   template <>                                                                  \
   3822   template <>                                                                  \
   3823   const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp                       \
   3824       InstImpl<TraitsType>::InstX86Mulps::Base::Emitter = {                    \
   3825           &InstImpl<TraitsType>::Assembler::mulps,                             \
   3826           &InstImpl<TraitsType>::Assembler::mulps};                            \
   3827   template <>                                                                  \
   3828   template <>                                                                  \
   3829   const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp                       \
   3830       InstImpl<TraitsType>::InstX86Padd::Base::Emitter = {                     \
   3831           &InstImpl<TraitsType>::Assembler::padd,                              \
   3832           &InstImpl<TraitsType>::Assembler::padd};                             \
   3833   template <>                                                                  \
   3834   template <>                                                                  \
   3835   const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp                       \
   3836       InstImpl<TraitsType>::InstX86Padds::Base::Emitter = {                    \
   3837           &InstImpl<TraitsType>::Assembler::padds,                             \
   3838           &InstImpl<TraitsType>::Assembler::padds};                            \
   3839   template <>                                                                  \
   3840   template <>                                                                  \
   3841   const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp                       \
   3842       InstImpl<TraitsType>::InstX86Paddus::Base::Emitter = {                   \
   3843           &InstImpl<TraitsType>::Assembler::paddus,                            \
   3844           &InstImpl<TraitsType>::Assembler::paddus};                           \
   3845   template <>                                                                  \
   3846   template <>                                                                  \
   3847   const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp                       \
   3848       InstImpl<TraitsType>::InstX86Pand::Base::Emitter = {                     \
   3849           &InstImpl<TraitsType>::Assembler::pand,                              \
   3850           &InstImpl<TraitsType>::Assembler::pand};                             \
   3851   template <>                                                                  \
   3852   template <>                                                                  \
   3853   const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp                       \
   3854       InstImpl<TraitsType>::InstX86Pandn::Base::Emitter = {                    \
   3855           &InstImpl<TraitsType>::Assembler::pandn,                             \
   3856           &InstImpl<TraitsType>::Assembler::pandn};                            \
   3857   template <>                                                                  \
   3858   template <>                                                                  \
   3859   const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp                       \
   3860       InstImpl<TraitsType>::InstX86Pcmpeq::Base::Emitter = {                   \
   3861           &InstImpl<TraitsType>::Assembler::pcmpeq,                            \
   3862           &InstImpl<TraitsType>::Assembler::pcmpeq};                           \
   3863   template <>                                                                  \
   3864   template <>                                                                  \
   3865   const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp                       \
   3866       InstImpl<TraitsType>::InstX86Pcmpgt::Base::Emitter = {                   \
   3867           &InstImpl<TraitsType>::Assembler::pcmpgt,                            \
   3868           &InstImpl<TraitsType>::Assembler::pcmpgt};                           \
   3869   template <>                                                                  \
   3870   template <>                                                                  \
   3871   const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp                       \
   3872       InstImpl<TraitsType>::InstX86Pmull::Base::Emitter = {                    \
   3873           &InstImpl<TraitsType>::Assembler::pmull,                             \
   3874           &InstImpl<TraitsType>::Assembler::pmull};                            \
   3875   template <>                                                                  \
   3876   template <>                                                                  \
   3877   const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp                       \
   3878       InstImpl<TraitsType>::InstX86Pmulhw::Base::Emitter = {                   \
   3879           &InstImpl<TraitsType>::Assembler::pmulhw,                            \
   3880           &InstImpl<TraitsType>::Assembler::pmulhw};                           \
   3881   template <>                                                                  \
   3882   template <>                                                                  \
   3883   const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp                       \
   3884       InstImpl<TraitsType>::InstX86Pmulhuw::Base::Emitter = {                  \
   3885           &InstImpl<TraitsType>::Assembler::pmulhuw,                           \
   3886           &InstImpl<TraitsType>::Assembler::pmulhuw};                          \
   3887   template <>                                                                  \
   3888   template <>                                                                  \
   3889   const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp                       \
   3890       InstImpl<TraitsType>::InstX86Pmaddwd::Base::Emitter = {                  \
   3891           &InstImpl<TraitsType>::Assembler::pmaddwd,                           \
   3892           &InstImpl<TraitsType>::Assembler::pmaddwd};                          \
   3893   template <>                                                                  \
   3894   template <>                                                                  \
   3895   const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp                       \
   3896       InstImpl<TraitsType>::InstX86Pmuludq::Base::Emitter = {                  \
   3897           &InstImpl<TraitsType>::Assembler::pmuludq,                           \
   3898           &InstImpl<TraitsType>::Assembler::pmuludq};                          \
   3899   template <>                                                                  \
   3900   template <>                                                                  \
   3901   const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp                       \
   3902       InstImpl<TraitsType>::InstX86Por::Base::Emitter = {                      \
   3903           &InstImpl<TraitsType>::Assembler::por,                               \
   3904           &InstImpl<TraitsType>::Assembler::por};                              \
   3905   template <>                                                                  \
   3906   template <>                                                                  \
   3907   const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp                       \
   3908       InstImpl<TraitsType>::InstX86Psub::Base::Emitter = {                     \
   3909           &InstImpl<TraitsType>::Assembler::psub,                              \
   3910           &InstImpl<TraitsType>::Assembler::psub};                             \
   3911   template <>                                                                  \
   3912   template <>                                                                  \
   3913   const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp                       \
   3914       InstImpl<TraitsType>::InstX86Psubs::Base::Emitter = {                    \
   3915           &InstImpl<TraitsType>::Assembler::psubs,                             \
   3916           &InstImpl<TraitsType>::Assembler::psubs};                            \
   3917   template <>                                                                  \
   3918   template <>                                                                  \
   3919   const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp                       \
   3920       InstImpl<TraitsType>::InstX86Psubus::Base::Emitter = {                   \
   3921           &InstImpl<TraitsType>::Assembler::psubus,                            \
   3922           &InstImpl<TraitsType>::Assembler::psubus};                           \
   3923   template <>                                                                  \
   3924   template <>                                                                  \
   3925   const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp                       \
   3926       InstImpl<TraitsType>::InstX86Pxor::Base::Emitter = {                     \
   3927           &InstImpl<TraitsType>::Assembler::pxor,                              \
   3928           &InstImpl<TraitsType>::Assembler::pxor};                             \
   3929   template <>                                                                  \
   3930   template <>                                                                  \
   3931   const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp                       \
   3932       InstImpl<TraitsType>::InstX86Subss::Base::Emitter = {                    \
   3933           &InstImpl<TraitsType>::Assembler::subss,                             \
   3934           &InstImpl<TraitsType>::Assembler::subss};                            \
   3935   template <>                                                                  \
   3936   template <>                                                                  \
   3937   const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp                       \
   3938       InstImpl<TraitsType>::InstX86Subps::Base::Emitter = {                    \
   3939           &InstImpl<TraitsType>::Assembler::subps,                             \
   3940           &InstImpl<TraitsType>::Assembler::subps};                            \
   3941   template <>                                                                  \
   3942   template <>                                                                  \
   3943   const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp                       \
   3944       InstImpl<TraitsType>::InstX86Andnps::Base::Emitter = {                   \
   3945           &InstImpl<TraitsType>::Assembler::andnps,                            \
   3946           &InstImpl<TraitsType>::Assembler::andnps};                           \
   3947   template <>                                                                  \
   3948   template <>                                                                  \
   3949   const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp                       \
   3950       InstImpl<TraitsType>::InstX86Andps::Base::Emitter = {                    \
   3951           &InstImpl<TraitsType>::Assembler::andps,                             \
   3952           &InstImpl<TraitsType>::Assembler::andps};                            \
   3953   template <>                                                                  \
   3954   template <>                                                                  \
   3955   const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp                       \
   3956       InstImpl<TraitsType>::InstX86Maxss::Base::Emitter = {                    \
   3957           &InstImpl<TraitsType>::Assembler::maxss,                             \
   3958           &InstImpl<TraitsType>::Assembler::maxss};                            \
   3959   template <>                                                                  \
   3960   template <>                                                                  \
   3961   const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp                       \
   3962       InstImpl<TraitsType>::InstX86Minss::Base::Emitter = {                    \
   3963           &InstImpl<TraitsType>::Assembler::minss,                             \
   3964           &InstImpl<TraitsType>::Assembler::minss};                            \
   3965   template <>                                                                  \
   3966   template <>                                                                  \
   3967   const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp                       \
   3968       InstImpl<TraitsType>::InstX86Maxps::Base::Emitter = {                    \
   3969           &InstImpl<TraitsType>::Assembler::maxps,                             \
   3970           &InstImpl<TraitsType>::Assembler::maxps};                            \
   3971   template <>                                                                  \
   3972   template <>                                                                  \
   3973   const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp                       \
   3974       InstImpl<TraitsType>::InstX86Minps::Base::Emitter = {                    \
   3975           &InstImpl<TraitsType>::Assembler::minps,                             \
   3976           &InstImpl<TraitsType>::Assembler::minps};                            \
   3977   template <>                                                                  \
   3978   template <>                                                                  \
   3979   const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp                       \
   3980       InstImpl<TraitsType>::InstX86Orps::Base::Emitter = {                     \
   3981           &InstImpl<TraitsType>::Assembler::orps,                              \
   3982           &InstImpl<TraitsType>::Assembler::orps};                             \
   3983   template <>                                                                  \
   3984   template <>                                                                  \
   3985   const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp                       \
   3986       InstImpl<TraitsType>::InstX86Xorps::Base::Emitter = {                    \
   3987           &InstImpl<TraitsType>::Assembler::xorps,                             \
   3988           &InstImpl<TraitsType>::Assembler::xorps};                            \
   3989                                                                                \
   3990   /* Binary XMM Shift ops */                                                   \
   3991   template <>                                                                  \
   3992   template <>                                                                  \
   3993   const InstImpl<TraitsType>::Assembler::XmmEmitterShiftOp                     \
   3994       InstImpl<TraitsType>::InstX86Psll::Base::Emitter = {                     \
   3995           &InstImpl<TraitsType>::Assembler::psll,                              \
   3996           &InstImpl<TraitsType>::Assembler::psll,                              \
   3997           &InstImpl<TraitsType>::Assembler::psll};                             \
   3998   template <>                                                                  \
   3999   template <>                                                                  \
   4000   const InstImpl<TraitsType>::Assembler::XmmEmitterShiftOp                     \
   4001       InstImpl<TraitsType>::InstX86Psra::Base::Emitter = {                     \
   4002           &InstImpl<TraitsType>::Assembler::psra,                              \
   4003           &InstImpl<TraitsType>::Assembler::psra,                              \
   4004           &InstImpl<TraitsType>::Assembler::psra};                             \
   4005   template <>                                                                  \
   4006   template <>                                                                  \
   4007   const InstImpl<TraitsType>::Assembler::XmmEmitterShiftOp                     \
   4008       InstImpl<TraitsType>::InstX86Psrl::Base::Emitter = {                     \
   4009           &InstImpl<TraitsType>::Assembler::psrl,                              \
   4010           &InstImpl<TraitsType>::Assembler::psrl,                              \
   4011           &InstImpl<TraitsType>::Assembler::psrl};                             \
   4012   template <>                                                                  \
   4013   template <>                                                                  \
   4014   const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp                       \
   4015       InstImpl<TraitsType>::InstX86Pshufb::Base::Emitter = {                   \
   4016           &InstImpl<TraitsType>::Assembler::pshufb,                            \
   4017           &InstImpl<TraitsType>::Assembler::pshufb};                           \
   4018   template <>                                                                  \
   4019   template <>                                                                  \
   4020   const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp                       \
   4021       InstImpl<TraitsType>::InstX86Punpckl::Base::Emitter = {                  \
   4022           &InstImpl<TraitsType>::Assembler::punpckl,                           \
   4023           &InstImpl<TraitsType>::Assembler::punpckl};                          \
   4024   template <>                                                                  \
   4025   template <>                                                                  \
   4026   const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp                       \
   4027       InstImpl<TraitsType>::InstX86Punpckh::Base::Emitter = {                  \
   4028           &InstImpl<TraitsType>::Assembler::punpckh,                           \
   4029           &InstImpl<TraitsType>::Assembler::punpckh};                          \
   4030   template <>                                                                  \
   4031   template <>                                                                  \
   4032   const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp                       \
   4033       InstImpl<TraitsType>::InstX86Packss::Base::Emitter = {                   \
   4034           &InstImpl<TraitsType>::Assembler::packss,                            \
   4035           &InstImpl<TraitsType>::Assembler::packss};                           \
   4036   template <>                                                                  \
   4037   template <>                                                                  \
   4038   const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp                       \
   4039       InstImpl<TraitsType>::InstX86Packus::Base::Emitter = {                   \
   4040           &InstImpl<TraitsType>::Assembler::packus,                            \
   4041           &InstImpl<TraitsType>::Assembler::packus};                           \
   4042   }                                                                            \
   4043   }
   4044 
   4045 } // end of namespace X86NAMESPACE
   4046 } // end of namespace Ice
   4047 
   4048 #include "IceInstX86BaseImpl.h"
   4049 
   4050 #endif // SUBZERO_SRC_ICEINSTX86BASE_H
   4051