• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
getTargetInstImpl214     static TargetLowering *getTarget(const Cfg *Func) {
215       return static_cast<TargetLowering *>(Func->getTarget());
216     }
217 
218   protected:
InstX86BaseInstImpl219     InstX86Base(Cfg *Func, InstKindX86 Kind, SizeT Maxsrcs, Variable *Dest)
220         : InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {}
221 
isClassofInstImpl222     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).
validateVectorAddrModeInstImpl234     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:
validateVectorAddrModeOpndInstImpl243     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     }
getAddrInstImpl270     Operand *getAddr() const { return this->getSrc(1); }
getDataInstImpl271     Operand *getData() const { return this->getSrc(0); }
getOpInstImpl272     InstArithmetic::OpKind getOp() const { return Op; }
getBeaconInstImpl273     Variable *getBeacon() const {
274       return llvm::cast<Variable>(this->getSrc(2));
275     }
276     void dump(const Cfg *Func) const override;
classofInstImpl277     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:
createInstImpl293     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;
classofInstImpl299     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:
createInstImpl349     static InstX86Label *create(Cfg *Func, TargetLowering *Target) {
350       return new (Func->allocate<InstX86Label>()) InstX86Label(Func, Target);
351     }
getEmitInstCountInstImpl352     uint32_t getEmitInstCount() const override { return 0; }
getLabelNameInstImpl353     GlobalString getLabelName() const { return Name; }
getLabelNumberInstImpl354     SizeT getLabelNumber() const { return LabelNumber; }
isLabelInstImpl355     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;
setRelocOffsetInstImpl359     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.
createInstImpl379     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.
createInstImpl388     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.
createInstImpl397     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.
createInstImpl407     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     }
getTargetTrueInstImpl414     const CfgNode *getTargetTrue() const { return TargetTrue; }
getTargetFalseInstImpl415     const CfgNode *getTargetFalse() const { return TargetFalse; }
isNearInstImpl416     bool isNear() const { return Kind == Near; }
417     bool optimizeBranch(const CfgNode *NextNode);
getEmitInstCountInstImpl418     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     }
isUnconditionalBranchInstImpl428     bool isUnconditionalBranch() const override {
429       return !Label && Condition == Cond::Br_None;
430     }
getIntraBlockBranchTargetInstImpl431     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;
classofInstImpl436     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:
createInstImpl460     static InstX86Jmp *create(Cfg *Func, Operand *Target) {
461       return new (Func->allocate<InstX86Jmp>()) InstX86Jmp(Func, Target);
462     }
getJmpTargetInstImpl463     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;
classofInstImpl467     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:
createInstImpl482     static InstX86Call *create(Cfg *Func, Variable *Dest, Operand *CallTarget) {
483       return new (Func->allocate<InstX86Call>())
484           InstX86Call(Func, Dest, CallTarget);
485     }
getCallTargetInstImpl486     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;
classofInstImpl490     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 
emitInstImpl569     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     }
emitIASInstImpl577     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     }
dumpInstImpl583     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     }
classofInstImpl591     static bool classof(const Inst *Instr) {
592       return InstX86Base::isClassof(Instr, InstX86Base::K);
593     }
594 
595   protected:
InstX86BaseInplaceopGPRInstImpl596     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 
emitInstImpl616     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     }
emitIASInstImpl634     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     }
dumpInstImpl649     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 
classofInstImpl658     static bool classof(const Inst *Instr) {
659       return InstX86Base::isClassof(Instr, InstX86Base::K);
660     }
661 
662   protected:
InstX86BaseUnaryopGPRInstImpl663     InstX86BaseUnaryopGPR(Cfg *Func, Variable *Dest, Operand *Src)
664         : InstX86Base(Func, K, 1, Dest) {
665       this->addSource(Src);
666     }
667 
deoptLeaToAddOrNullInstImpl668     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 
emitInstImpl698     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     }
emitIASInstImpl708     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     }
dumpInstImpl713     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     }
classofInstImpl721     static bool classof(const Inst *Instr) {
722       return InstX86Base::isClassof(Instr, InstX86Base::K);
723     }
724 
725   protected:
InstX86BaseUnaryopXmmInstImpl726     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 
emitInstImpl745     void emit(const Cfg *Func) const override {
746       if (!BuildDefs::dump())
747         return;
748       this->emitTwoAddress(Func, Opcode);
749     }
emitIASInstImpl750     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     }
dumpInstImpl755     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     }
classofInstImpl763     static bool classof(const Inst *Instr) {
764       return InstX86Base::isClassof(Instr, InstX86Base::K);
765     }
766 
767   protected:
InstX86BaseBinopGPRShiftInstImpl768     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 
emitInstImpl787     void emit(const Cfg *Func) const override {
788       if (!BuildDefs::dump())
789         return;
790       this->emitTwoAddress(Func, Opcode);
791     }
emitIASInstImpl792     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     }
dumpInstImpl800     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     }
classofInstImpl808     static bool classof(const Inst *Instr) {
809       return InstX86Base::isClassof(Instr, InstX86Base::K);
810     }
811 
812   protected:
InstX86BaseBinopGPRInstImpl813     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 
emitInstImpl832     void emit(const Cfg *Func) const override {
833       if (!BuildDefs::dump())
834         return;
835       this->emitTwoAddress(Func, Opcode);
836     }
emitIASInstImpl837     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     }
dumpInstImpl842     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     }
classofInstImpl849     static bool classof(const Inst *Instr) {
850       return InstX86Base::isClassof(Instr, InstX86Base::K);
851     }
852 
853   protected:
InstX86BaseBinopRMWInstImpl854     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 
emitInstImpl874     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     }
emitIASInstImpl903     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     }
dumpInstImpl911     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     }
classofInstImpl919     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 
emitInstImpl947     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     }
emitIASInstImpl956     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     }
dumpInstImpl965     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     }
classofInstImpl973     static bool classof(const Inst *Instr) {
974       return InstX86Base::isClassof(Instr, InstX86Base::K);
975     }
976 
977   protected:
InstX86BaseBinopXmmShiftInstImpl978     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 
emitInstImpl997     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     }
dumpInstImpl1009     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     }
classofInstImpl1017     static bool classof(const Inst *Instr) {
1018       return InstX86Base::isClassof(Instr, InstX86Base::K);
1019     }
1020 
1021   protected:
InstX86BaseTernopInstImpl1022     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 
emitInstImpl1044     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     }
dumpInstImpl1056     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     }
classofInstImpl1064     static bool classof(const Inst *Instr) {
1065       return InstX86Base::isClassof(Instr, InstX86Base::K);
1066     }
1067 
1068   protected:
InstX86BaseThreeAddressopInstImpl1069     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 
isRedundantAssignInstImpl1089     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     }
isVarAssignInstImpl1109     bool isVarAssign() const override {
1110       return llvm::isa<Variable>(this->getSrc(0));
1111     }
dumpInstImpl1112     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     }
classofInstImpl1121     static bool classof(const Inst *Instr) {
1122       return InstX86Base::isClassof(Instr, InstX86Base::K);
1123     }
1124 
1125   protected:
InstX86BaseMovlikeInstImpl1126     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:
createInstImpl1141     static InstX86Bswap *create(Cfg *Func, Operand *SrcDest) {
1142       return new (Func->allocate<InstX86Bswap>()) InstX86Bswap(Func, SrcDest);
1143     }
1144 
1145   private:
InstX86BswapInstImpl1146     InstX86Bswap(Cfg *Func, Operand *SrcDest)
1147         : InstX86BaseInplaceopGPR<InstX86Base::Bswap>(Func, SrcDest) {}
1148   };
1149 
1150   class InstX86Neg : public InstX86BaseInplaceopGPR<InstX86Base::Neg> {
1151   public:
createInstImpl1152     static InstX86Neg *create(Cfg *Func, Operand *SrcDest) {
1153       return new (Func->allocate<InstX86Neg>()) InstX86Neg(Func, SrcDest);
1154     }
1155 
1156   private:
InstX86NegInstImpl1157     InstX86Neg(Cfg *Func, Operand *SrcDest)
1158         : InstX86BaseInplaceopGPR<InstX86Base::Neg>(Func, SrcDest) {}
1159   };
1160 
1161   class InstX86Bsf : public InstX86BaseUnaryopGPR<InstX86Base::Bsf> {
1162   public:
createInstImpl1163     static InstX86Bsf *create(Cfg *Func, Variable *Dest, Operand *Src) {
1164       return new (Func->allocate<InstX86Bsf>()) InstX86Bsf(Func, Dest, Src);
1165     }
1166 
1167   private:
InstX86BsfInstImpl1168     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:
createInstImpl1174     static InstX86Bsr *create(Cfg *Func, Variable *Dest, Operand *Src) {
1175       return new (Func->allocate<InstX86Bsr>()) InstX86Bsr(Func, Dest, Src);
1176     }
1177 
1178   private:
InstX86BsrInstImpl1179     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:
createInstImpl1185     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:
InstX86LeaInstImpl1192     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:
createInstImpl1199     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:
InstX86CbwdqInstImpl1207     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:
createInstImpl1213     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:
InstX86MovsxInstImpl1222     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:
createInstImpl1228     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 
setMustKeepInstImpl1238     void setMustKeep() { MustKeep = true; }
1239 
1240   private:
1241     bool MustKeep = false;
1242 
InstX86MovzxInstImpl1243     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:
createInstImpl1251     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:
InstX86MovdInstImpl1260     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:
createInstImpl1270     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;
classofInstImpl1277     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:
createInstImpl1287     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:
InstX86SqrtInstImpl1294     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:
createInstImpl1301     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:
InstX86MovInstImpl1312     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:
createInstImpl1320     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:
InstX86MovpInstImpl1329     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:
createInstImpl1336     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:
InstX86MovqInstImpl1345     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:
createInstImpl1351     static InstX86Add *create(Cfg *Func, Variable *Dest, Operand *Source) {
1352       return new (Func->allocate<InstX86Add>()) InstX86Add(Func, Dest, Source);
1353     }
1354 
1355   private:
InstX86AddInstImpl1356     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:
createInstImpl1362     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:
InstX86AddRMWInstImpl1369     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:
createInstImpl1377     static InstX86Addps *create(Cfg *Func, Variable *Dest, Operand *Source) {
1378       return new (Func->allocate<InstX86Addps>())
1379           InstX86Addps(Func, Dest, Source);
1380     }
1381 
1382   private:
InstX86AddpsInstImpl1383     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:
createInstImpl1391     static InstX86Adc *create(Cfg *Func, Variable *Dest, Operand *Source) {
1392       return new (Func->allocate<InstX86Adc>()) InstX86Adc(Func, Dest, Source);
1393     }
1394 
1395   private:
InstX86AdcInstImpl1396     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:
createInstImpl1402     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:
InstX86AdcRMWInstImpl1409     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:
createInstImpl1417     static InstX86Addss *create(Cfg *Func, Variable *Dest, Operand *Source) {
1418       return new (Func->allocate<InstX86Addss>())
1419           InstX86Addss(Func, Dest, Source);
1420     }
1421 
1422   private:
InstX86AddssInstImpl1423     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:
createInstImpl1433     static InstX86Padd *create(Cfg *Func, Variable *Dest, Operand *Source) {
1434       return new (Func->allocate<InstX86Padd>())
1435           InstX86Padd(Func, Dest, Source);
1436     }
1437 
1438   private:
InstX86PaddInstImpl1439     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:
createInstImpl1449     static InstX86Padds *create(Cfg *Func, Variable *Dest, Operand *Source) {
1450       return new (Func->allocate<InstX86Padds>())
1451           InstX86Padds(Func, Dest, Source);
1452     }
1453 
1454   private:
InstX86PaddsInstImpl1455     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:
createInstImpl1465     static InstX86Paddus *create(Cfg *Func, Variable *Dest, Operand *Source) {
1466       return new (Func->allocate<InstX86Paddus>())
1467           InstX86Paddus(Func, Dest, Source);
1468     }
1469 
1470   private:
InstX86PaddusInstImpl1471     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:
createInstImpl1479     static InstX86Sub *create(Cfg *Func, Variable *Dest, Operand *Source) {
1480       return new (Func->allocate<InstX86Sub>()) InstX86Sub(Func, Dest, Source);
1481     }
1482 
1483   private:
InstX86SubInstImpl1484     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:
createInstImpl1490     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:
InstX86SubRMWInstImpl1497     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:
createInstImpl1505     static InstX86Subps *create(Cfg *Func, Variable *Dest, Operand *Source) {
1506       return new (Func->allocate<InstX86Subps>())
1507           InstX86Subps(Func, Dest, Source);
1508     }
1509 
1510   private:
InstX86SubpsInstImpl1511     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:
createInstImpl1521     static InstX86Subss *create(Cfg *Func, Variable *Dest, Operand *Source) {
1522       return new (Func->allocate<InstX86Subss>())
1523           InstX86Subss(Func, Dest, Source);
1524     }
1525 
1526   private:
InstX86SubssInstImpl1527     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:
createInstImpl1535     static InstX86Sbb *create(Cfg *Func, Variable *Dest, Operand *Source) {
1536       return new (Func->allocate<InstX86Sbb>()) InstX86Sbb(Func, Dest, Source);
1537     }
1538 
1539   private:
InstX86SbbInstImpl1540     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:
createInstImpl1546     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:
InstX86SbbRMWInstImpl1553     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:
createInstImpl1561     static InstX86Psub *create(Cfg *Func, Variable *Dest, Operand *Source) {
1562       return new (Func->allocate<InstX86Psub>())
1563           InstX86Psub(Func, Dest, Source);
1564     }
1565 
1566   private:
InstX86PsubInstImpl1567     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:
createInstImpl1577     static InstX86Psubs *create(Cfg *Func, Variable *Dest, Operand *Source) {
1578       return new (Func->allocate<InstX86Psubs>())
1579           InstX86Psubs(Func, Dest, Source);
1580     }
1581 
1582   private:
InstX86PsubsInstImpl1583     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:
createInstImpl1593     static InstX86Psubus *create(Cfg *Func, Variable *Dest, Operand *Source) {
1594       return new (Func->allocate<InstX86Psubus>())
1595           InstX86Psubus(Func, Dest, Source);
1596     }
1597 
1598   private:
InstX86PsubusInstImpl1599     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:
createInstImpl1607     static InstX86And *create(Cfg *Func, Variable *Dest, Operand *Source) {
1608       return new (Func->allocate<InstX86And>()) InstX86And(Func, Dest, Source);
1609     }
1610 
1611   private:
InstX86AndInstImpl1612     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:
createInstImpl1620     static InstX86Andnps *create(Cfg *Func, Variable *Dest, Operand *Source) {
1621       return new (Func->allocate<InstX86Andnps>())
1622           InstX86Andnps(Func, Dest, Source);
1623     }
1624 
1625   private:
InstX86AndnpsInstImpl1626     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:
createInstImpl1636     static InstX86Andps *create(Cfg *Func, Variable *Dest, Operand *Source) {
1637       return new (Func->allocate<InstX86Andps>())
1638           InstX86Andps(Func, Dest, Source);
1639     }
1640 
1641   private:
InstX86AndpsInstImpl1642     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:
createInstImpl1650     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:
InstX86AndRMWInstImpl1657     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:
createInstImpl1664     static InstX86Pand *create(Cfg *Func, Variable *Dest, Operand *Source) {
1665       return new (Func->allocate<InstX86Pand>())
1666           InstX86Pand(Func, Dest, Source);
1667     }
1668 
1669   private:
InstX86PandInstImpl1670     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:
createInstImpl1680     static InstX86Pandn *create(Cfg *Func, Variable *Dest, Operand *Source) {
1681       return new (Func->allocate<InstX86Pandn>())
1682           InstX86Pandn(Func, Dest, Source);
1683     }
1684 
1685   private:
InstX86PandnInstImpl1686     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:
createInstImpl1696     static InstX86Maxss *create(Cfg *Func, Variable *Dest, Operand *Source) {
1697       return new (Func->allocate<InstX86Maxss>())
1698           InstX86Maxss(Func, Dest, Source);
1699     }
1700 
1701   private:
InstX86MaxssInstImpl1702     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:
createInstImpl1712     static InstX86Minss *create(Cfg *Func, Variable *Dest, Operand *Source) {
1713       return new (Func->allocate<InstX86Minss>())
1714           InstX86Minss(Func, Dest, Source);
1715     }
1716 
1717   private:
InstX86MinssInstImpl1718     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:
createInstImpl1728     static InstX86Maxps *create(Cfg *Func, Variable *Dest, Operand *Source) {
1729       return new (Func->allocate<InstX86Maxps>())
1730           InstX86Maxps(Func, Dest, Source);
1731     }
1732 
1733   private:
InstX86MaxpsInstImpl1734     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:
createInstImpl1744     static InstX86Minps *create(Cfg *Func, Variable *Dest, Operand *Source) {
1745       return new (Func->allocate<InstX86Minps>())
1746           InstX86Minps(Func, Dest, Source);
1747     }
1748 
1749   private:
InstX86MinpsInstImpl1750     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:
createInstImpl1758     static InstX86Or *create(Cfg *Func, Variable *Dest, Operand *Source) {
1759       return new (Func->allocate<InstX86Or>()) InstX86Or(Func, Dest, Source);
1760     }
1761 
1762   private:
InstX86OrInstImpl1763     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:
createInstImpl1771     static InstX86Orps *create(Cfg *Func, Variable *Dest, Operand *Source) {
1772       return new (Func->allocate<InstX86Orps>())
1773           InstX86Orps(Func, Dest, Source);
1774     }
1775 
1776   private:
InstX86OrpsInstImpl1777     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:
createInstImpl1785     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:
InstX86OrRMWInstImpl1792     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:
createInstImpl1799     static InstX86Por *create(Cfg *Func, Variable *Dest, Operand *Source) {
1800       return new (Func->allocate<InstX86Por>()) InstX86Por(Func, Dest, Source);
1801     }
1802 
1803   private:
InstX86PorInstImpl1804     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:
createInstImpl1812     static InstX86Xor *create(Cfg *Func, Variable *Dest, Operand *Source) {
1813       return new (Func->allocate<InstX86Xor>()) InstX86Xor(Func, Dest, Source);
1814     }
1815 
1816   private:
InstX86XorInstImpl1817     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:
createInstImpl1825     static InstX86Xorps *create(Cfg *Func, Variable *Dest, Operand *Source) {
1826       return new (Func->allocate<InstX86Xorps>())
1827           InstX86Xorps(Func, Dest, Source);
1828     }
1829 
1830   private:
InstX86XorpsInstImpl1831     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:
createInstImpl1839     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:
InstX86XorRMWInstImpl1846     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:
createInstImpl1853     static InstX86Pxor *create(Cfg *Func, Variable *Dest, Operand *Source) {
1854       return new (Func->allocate<InstX86Pxor>())
1855           InstX86Pxor(Func, Dest, Source);
1856     }
1857 
1858   private:
InstX86PxorInstImpl1859     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:
createInstImpl1867     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:
InstX86ImulInstImpl1876     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:
createInstImpl1883     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:
InstX86ImulImmInstImpl1893     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:
createInstImpl1903     static InstX86Mulps *create(Cfg *Func, Variable *Dest, Operand *Source) {
1904       return new (Func->allocate<InstX86Mulps>())
1905           InstX86Mulps(Func, Dest, Source);
1906     }
1907 
1908   private:
InstX86MulpsInstImpl1909     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:
createInstImpl1919     static InstX86Mulss *create(Cfg *Func, Variable *Dest, Operand *Source) {
1920       return new (Func->allocate<InstX86Mulss>())
1921           InstX86Mulss(Func, Dest, Source);
1922     }
1923 
1924   private:
InstX86MulssInstImpl1925     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:
createInstImpl1935     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:
InstX86PmullInstImpl1951     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:
createInstImpl1961     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:
InstX86PmulhwInstImpl1969     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:
createInstImpl1979     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:
InstX86PmulhuwInstImpl1987     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:
createInstImpl1997     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:
InstX86PmaddwdInstImpl2005     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:
createInstImpl2015     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:
InstX86PmuludqInstImpl2023     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:
createInstImpl2033     static InstX86Divps *create(Cfg *Func, Variable *Dest, Operand *Source) {
2034       return new (Func->allocate<InstX86Divps>())
2035           InstX86Divps(Func, Dest, Source);
2036     }
2037 
2038   private:
InstX86DivpsInstImpl2039     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:
createInstImpl2049     static InstX86Divss *create(Cfg *Func, Variable *Dest, Operand *Source) {
2050       return new (Func->allocate<InstX86Divss>())
2051           InstX86Divss(Func, Dest, Source);
2052     }
2053 
2054   private:
InstX86DivssInstImpl2055     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:
createInstImpl2063     static InstX86Rol *create(Cfg *Func, Variable *Dest, Operand *Source) {
2064       return new (Func->allocate<InstX86Rol>()) InstX86Rol(Func, Dest, Source);
2065     }
2066 
2067   private:
InstX86RolInstImpl2068     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:
createInstImpl2074     static InstX86Shl *create(Cfg *Func, Variable *Dest, Operand *Source) {
2075       return new (Func->allocate<InstX86Shl>()) InstX86Shl(Func, Dest, Source);
2076     }
2077 
2078   private:
InstX86ShlInstImpl2079     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:
createInstImpl2085     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:
InstX86PsllInstImpl2094     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:
createInstImpl2100     static InstX86Psrl *create(Cfg *Func, Variable *Dest, Operand *Source) {
2101       return new (Func->allocate<InstX86Psrl>())
2102           InstX86Psrl(Func, Dest, Source);
2103     }
2104 
2105   private:
InstX86PsrlInstImpl2106     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:
createInstImpl2113     static InstX86Shr *create(Cfg *Func, Variable *Dest, Operand *Source) {
2114       return new (Func->allocate<InstX86Shr>()) InstX86Shr(Func, Dest, Source);
2115     }
2116 
2117   private:
InstX86ShrInstImpl2118     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:
createInstImpl2124     static InstX86Sar *create(Cfg *Func, Variable *Dest, Operand *Source) {
2125       return new (Func->allocate<InstX86Sar>()) InstX86Sar(Func, Dest, Source);
2126     }
2127 
2128   private:
InstX86SarInstImpl2129     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:
createInstImpl2135     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:
InstX86PsraInstImpl2144     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:
InstX86PcmpeqInstImpl2166     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:
createInstImpl2177     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:
InstX86PcmpgtInstImpl2186     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:
createInstImpl2202     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:
InstX86MovssRegsInstImpl2211     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:
createInstImpl2219     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:
InstX86IdivInstImpl2229     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:
createInstImpl2235     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:
InstX86DivInstImpl2245     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:
createInstImpl2251     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:
InstX86InsertpsInstImpl2260     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:
createInstImpl2268     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:
InstX86PinsrInstImpl2282     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:
createInstImpl2288     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:
InstX86ShufpsInstImpl2297     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:
createInstImpl2304     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:
InstX86BlendvpsInstImpl2316     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:
createInstImpl2324     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:
InstX86PblendvbInstImpl2336     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:
createInstImpl2344     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:
InstX86PextrInstImpl2358     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:
createInstImpl2365     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:
InstX86PshufdInstImpl2374     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 
InstX86BaseLockableInstImpl2388     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:
createInstImpl2404     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;
classofInstImpl2412     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:
createInstImpl2427     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;
classofInstImpl2435     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:
createInstImpl2450     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;
classofInstImpl2458     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:
createInstImpl2473     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;
classofInstImpl2481     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:
createInstImpl2498     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;
classofInstImpl2506     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:
createInstImpl2527     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;
classofInstImpl2535     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:
createInstImpl2555     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;
classofInstImpl2564     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 };
createInstImpl2584     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;
classofInstImpl2592     static bool classof(const Inst *Instr) {
2593       return InstX86Base::isClassof(Instr, InstX86Base::Cvt);
2594     }
isTruncatingInstImpl2595     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:
createInstImpl2606     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:
InstX86RoundInstImpl2616     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:
createInstImpl2628     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;
classofInstImpl2634     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:
createInstImpl2649     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;
classofInstImpl2656     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:
createInstImpl2671     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;
classofInstImpl2677     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:
createInstImpl2692     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;
classofInstImpl2698     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:
createInstImpl2713     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;
classofInstImpl2720     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:
createInstImpl2735     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;
classofInstImpl2741     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:
createInstImpl2758     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;
classofInstImpl2765     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:
createInstImpl2783     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;
classofInstImpl2791     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:
createInstImpl2805     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;
classofInstImpl2813     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:
createInstImpl2827     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;
classofInstImpl2835     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 
createInstImpl2853     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;
classofInstImpl2859     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:
createInstImpl2876     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;
classofInstImpl2882     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:
createInstImpl2897     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;
classofInstImpl2903     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:
createInstImpl2917     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;
classofInstImpl2923     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:
createInstImpl2937     static InstX86Push *create(Cfg *Func, InstX86Label *Label) {
2938       return new (Func->allocate<InstX86Push>()) InstX86Push(Func, Label);
2939     }
createInstImpl2940     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;
classofInstImpl2946     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;
classofInstImpl2973     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:
createInstImpl2988     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;
classofInstImpl2995     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:
createInstImpl3018     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;
classofInstImpl3026     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:
createInstImpl3045     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;
classofInstImpl3052     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:
createInstImpl3068     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;
classofInstImpl3074     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:
createInstImpl3090     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;
classofInstImpl3096     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:
createInstImpl3108     static InstX86Pshufb *create(Cfg *Func, Variable *Dest, Operand *Source) {
3109       return new (Func->allocate<InstX86Pshufb>())
3110           InstX86Pshufb(Func, Dest, Source);
3111     }
3112 
3113   private:
InstX86PshufbInstImpl3114     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:
createInstImpl3124     static InstX86Punpckl *create(Cfg *Func, Variable *Dest, Operand *Source) {
3125       return new (Func->allocate<InstX86Punpckl>())
3126           InstX86Punpckl(Func, Dest, Source);
3127     }
3128 
3129   private:
InstX86PunpcklInstImpl3130     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:
createInstImpl3140     static InstX86Punpckh *create(Cfg *Func, Variable *Dest, Operand *Source) {
3141       return new (Func->allocate<InstX86Punpckh>())
3142           InstX86Punpckh(Func, Dest, Source);
3143     }
3144 
3145   private:
InstX86PunpckhInstImpl3146     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:
createInstImpl3156     static InstX86Packss *create(Cfg *Func, Variable *Dest, Operand *Source) {
3157       return new (Func->allocate<InstX86Packss>())
3158           InstX86Packss(Func, Dest, Source);
3159     }
3160 
3161   private:
InstX86PackssInstImpl3162     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:
createInstImpl3172     static InstX86Packus *create(Cfg *Func, Variable *Dest, Operand *Source) {
3173       return new (Func->allocate<InstX86Packus>())
3174           InstX86Packus(Func, Dest, Source);
3175     }
3176 
3177   private:
InstX86PackusInstImpl3178     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