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