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