blob: 4c628540d75beba045dba31ea68dc0c116508bdc [file] [log] [blame]
John Porto921856d2015-07-07 11:56:26 -07001//===- subzero/src/IceInstX86Base.h - Generic x86 instructions -*- C++ -*--===//
2//
3// The Subzero Code Generator
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9///
10/// \file
Jim Stichnoth92a6e5b2015-12-02 16:52:44 -080011/// \brief This file defines the InstX86Base template class, as well as the
12/// generic X86 Instruction class hierarchy.
13///
14/// Only X86 instructions common across all/most X86 targets should be defined
15/// here, with target-specific instructions declared in the target's traits.
John Porto921856d2015-07-07 11:56:26 -070016///
17//===----------------------------------------------------------------------===//
18
19#ifndef SUBZERO_SRC_ICEINSTX86BASE_H
20#define SUBZERO_SRC_ICEINSTX86BASE_H
21
22#include "IceDefs.h"
23#include "IceInst.h"
24#include "IceOperand.h"
25
26namespace Ice {
27
John Porto4a566862016-01-04 09:33:41 -080028#ifndef X86NAMESPACE
29#error "You must define the X86 Target namespace."
30#endif
John Porto921856d2015-07-07 11:56:26 -070031
John Porto4a566862016-01-04 09:33:41 -080032namespace X86NAMESPACE {
John Porto921856d2015-07-07 11:56:26 -070033
John Porto4a566862016-01-04 09:33:41 -080034template <typename TraitsType> struct InstImpl {
35 using Traits = TraitsType;
36 using Assembler = typename Traits::Assembler;
37 using AssemblerLabel = typename Assembler::Label;
38 using AssemblerImmediate = typename Assembler::Immediate;
39 using TargetLowering = typename Traits::TargetLowering;
40 using Address = typename Traits::Address;
41 using X86Operand = typename Traits::X86Operand;
42 using X86OperandMem = typename Traits::X86OperandMem;
43 using VariableSplit = typename Traits::VariableSplit;
John Porto921856d2015-07-07 11:56:26 -070044
John Porto4a566862016-01-04 09:33:41 -080045 using GPRRegister = typename Traits::RegisterSet::GPRRegister;
46 using RegisterSet = typename Traits::RegisterSet;
47 using XmmRegister = typename Traits::RegisterSet::XmmRegister;
John Porto921856d2015-07-07 11:56:26 -070048
John Porto4a566862016-01-04 09:33:41 -080049 using Cond = typename Traits::Cond;
50 using BrCond = typename Traits::Cond::BrCond;
51 using CmppsCond = typename Traits::Cond::CmppsCond;
Andrew Scull2c862522015-08-06 08:41:53 -070052
John Porto4a566862016-01-04 09:33:41 -080053 template <typename SReg_t, typename DReg_t>
54 using CastEmitterRegOp =
55 typename Traits::Assembler::template CastEmitterRegOp<SReg_t, DReg_t>;
56 template <typename SReg_t, typename DReg_t>
57 using ThreeOpImmEmitter =
58 typename Traits::Assembler::template ThreeOpImmEmitter<SReg_t, DReg_t>;
59 using GPREmitterAddrOp = typename Traits::Assembler::GPREmitterAddrOp;
60 using GPREmitterRegOp = typename Traits::Assembler::GPREmitterRegOp;
61 using GPREmitterShiftD = typename Traits::Assembler::GPREmitterShiftD;
62 using GPREmitterShiftOp = typename Traits::Assembler::GPREmitterShiftOp;
63 using GPREmitterOneOp = typename Traits::Assembler::GPREmitterOneOp;
64 using XmmEmitterRegOp = typename Traits::Assembler::XmmEmitterRegOp;
65 using XmmEmitterShiftOp = typename Traits::Assembler::XmmEmitterShiftOp;
66 using XmmEmitterMovOps = typename Traits::Assembler::XmmEmitterMovOps;
John Porto921856d2015-07-07 11:56:26 -070067
John Porto4a566862016-01-04 09:33:41 -080068 class InstX86Base : public InstTarget {
69 InstX86Base() = delete;
70 InstX86Base(const InstX86Base &) = delete;
71 InstX86Base &operator=(const InstX86Base &) = delete;
David Sehr6da7ae22015-12-17 15:01:30 -080072
John Porto4a566862016-01-04 09:33:41 -080073 public:
74 enum InstKindX86 {
75 k__Start = Inst::Target,
76 Adc,
77 AdcRMW,
78 Add,
79 AddRMW,
80 Addps,
81 Addss,
82 And,
83 Andnps,
84 Andps,
85 AndRMW,
86 Blendvps,
87 Br,
88 Bsf,
89 Bsr,
90 Bswap,
91 Call,
92 Cbwdq,
93 Cmov,
94 Cmpps,
95 Cmpxchg,
96 Cmpxchg8b,
97 Cvt,
98 Div,
99 Divps,
100 Divss,
101 FakeRMW,
102 Fld,
103 Fstp,
Jim Stichnoth8ff4b282016-01-04 15:39:06 -0800104 GetIP,
John Porto4a566862016-01-04 09:33:41 -0800105 Icmp,
106 Idiv,
107 Imul,
108 ImulImm,
109 Insertps,
Eric Holk67c7c412016-04-15 13:05:37 -0700110 Int3,
John Porto4a566862016-01-04 09:33:41 -0800111 Jmp,
112 Label,
113 Lea,
114 Load,
115 Mfence,
Nicolas Capenseb568f52017-02-13 09:49:43 -0500116 Minps,
117 Maxps,
John Porto4a566862016-01-04 09:33:41 -0800118 Minss,
119 Maxss,
120 Mov,
121 Movd,
Nicolas Capense3cabda2016-10-18 16:27:27 -0400122 Movmsk,
John Porto4a566862016-01-04 09:33:41 -0800123 Movp,
124 Movq,
125 MovssRegs,
126 Movsx,
127 Movzx,
128 Mul,
129 Mulps,
130 Mulss,
131 Neg,
132 Nop,
133 Or,
134 Orps,
135 OrRMW,
136 Padd,
Nicolas Capens67a49b52016-10-26 13:18:35 -0400137 Padds,
138 Paddus,
John Porto4a566862016-01-04 09:33:41 -0800139 Pand,
140 Pandn,
141 Pblendvb,
142 Pcmpeq,
143 Pcmpgt,
144 Pextr,
145 Pinsr,
146 Pmull,
Nicolas Capens13cde0f2016-10-26 10:36:11 -0400147 Pmulhw,
148 Pmulhuw,
149 Pmaddwd,
John Porto4a566862016-01-04 09:33:41 -0800150 Pmuludq,
151 Pop,
152 Por,
John Portode29f122016-04-26 19:16:07 -0700153 Pshufb,
John Porto4a566862016-01-04 09:33:41 -0800154 Pshufd,
John Portoae15f0f2016-04-26 04:26:33 -0700155 Punpckl,
Nicolas Capens1448d952016-10-14 16:37:09 -0400156 Punpckh,
Nicolas Capens7638e272016-10-06 11:33:55 -0400157 Packss,
158 Packus,
John Porto4a566862016-01-04 09:33:41 -0800159 Psll,
160 Psra,
161 Psrl,
162 Psub,
Nicolas Capens67a49b52016-10-26 13:18:35 -0400163 Psubs,
164 Psubus,
John Porto4a566862016-01-04 09:33:41 -0800165 Push,
166 Pxor,
167 Ret,
168 Rol,
Nicolas Capensf0d12c32016-10-27 15:17:41 -0400169 Round,
John Porto4a566862016-01-04 09:33:41 -0800170 Sar,
171 Sbb,
172 SbbRMW,
173 Setcc,
174 Shl,
175 Shld,
176 Shr,
177 Shrd,
178 Shufps,
Nicolas Capens956cfd62016-10-31 14:28:09 -0400179 Sqrt,
John Porto4a566862016-01-04 09:33:41 -0800180 Store,
181 StoreP,
182 StoreQ,
Nicolas Capensacfb3df2016-10-03 10:46:30 -0400183 StoreD,
John Porto4a566862016-01-04 09:33:41 -0800184 Sub,
185 SubRMW,
186 Subps,
187 Subss,
188 Test,
189 Ucomiss,
190 UD2,
191 Xadd,
192 Xchg,
193 Xor,
194 Xorps,
195 XorRMW,
John Porto921856d2015-07-07 11:56:26 -0700196
John Porto4a566862016-01-04 09:33:41 -0800197 /// Intel Architecture Code Analyzer markers. These are not executable so
198 /// must only be used for analysis.
199 IacaStart,
200 IacaEnd
201 };
John Porto921856d2015-07-07 11:56:26 -0700202
Nicolas Capens7638e272016-10-06 11:33:55 -0400203 enum SseSuffix { None, Packed, Unpack, Scalar, Integral, Pack };
John Porto921856d2015-07-07 11:56:26 -0700204
John Porto4a566862016-01-04 09:33:41 -0800205 static const char *getWidthString(Type Ty);
206 static const char *getFldString(Type Ty);
207 static BrCond getOppositeCondition(BrCond Cond);
208 void dump(const Cfg *Func) const override;
David Sehrb8e49c12015-11-12 14:41:22 -0800209
John Porto4a566862016-01-04 09:33:41 -0800210 // Shared emit routines for common forms of instructions.
211 void emitTwoAddress(const Cfg *Func, const char *Opcode,
212 const char *Suffix = "") const;
John Porto921856d2015-07-07 11:56:26 -0700213
John Porto4a566862016-01-04 09:33:41 -0800214 static TargetLowering *getTarget(const Cfg *Func) {
215 return static_cast<TargetLowering *>(Func->getTarget());
John Porto921856d2015-07-07 11:56:26 -0700216 }
John Porto921856d2015-07-07 11:56:26 -0700217
John Porto4a566862016-01-04 09:33:41 -0800218 protected:
219 InstX86Base(Cfg *Func, InstKindX86 Kind, SizeT Maxsrcs, Variable *Dest)
220 : InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {}
221
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800222 static bool isClassof(const Inst *Instr, InstKindX86 MyKind) {
223 return Instr->getKind() == static_cast<InstKind>(MyKind);
John Porto921856d2015-07-07 11:56:26 -0700224 }
John Porto4a566862016-01-04 09:33:41 -0800225 // Most instructions that operate on vector arguments require vector memory
226 // operands to be fully aligned (16-byte alignment for PNaCl vector types).
227 // The stack frame layout and call ABI ensure proper alignment for stack
228 // operands, but memory operands (originating from load/store bitcode
229 // instructions) only have element-size alignment guarantees. This function
230 // validates that none of the operands is a memory operand of vector type,
231 // calling report_fatal_error() if one is found. This function should be
232 // called during emission, and maybe also in the ctor (as long as that fits
233 // the lowering style).
234 void validateVectorAddrMode() const {
235 if (this->getDest())
236 this->validateVectorAddrModeOpnd(this->getDest());
237 for (SizeT i = 0; i < this->getSrcSize(); ++i) {
238 this->validateVectorAddrModeOpnd(this->getSrc(i));
Jim Stichnoth5bff61c2015-10-28 09:26:00 -0700239 }
240 }
John Porto921856d2015-07-07 11:56:26 -0700241
John Porto4a566862016-01-04 09:33:41 -0800242 private:
243 static void validateVectorAddrModeOpnd(const Operand *Opnd) {
244 if (llvm::isa<X86OperandMem>(Opnd) && isVectorType(Opnd->getType())) {
245 llvm::report_fatal_error("Possible misaligned vector memory operation");
246 }
247 }
248 };
John Porto921856d2015-07-07 11:56:26 -0700249
John Porto4a566862016-01-04 09:33:41 -0800250 /// InstX86FakeRMW represents a non-atomic read-modify-write operation on a
251 /// memory location. An InstX86FakeRMW is a "fake" instruction in that it
252 /// still needs to be lowered to some actual RMW instruction.
253 ///
254 /// If A is some memory address, D is some data value to apply, and OP is an
255 /// arithmetic operator, the instruction operates as: (*A) = (*A) OP D
256 class InstX86FakeRMW final : public InstX86Base {
257 InstX86FakeRMW() = delete;
258 InstX86FakeRMW(const InstX86FakeRMW &) = delete;
259 InstX86FakeRMW &operator=(const InstX86FakeRMW &) = delete;
John Porto921856d2015-07-07 11:56:26 -0700260
John Porto4a566862016-01-04 09:33:41 -0800261 public:
262 static InstX86FakeRMW *create(Cfg *Func, Operand *Data, Operand *Addr,
263 Variable *Beacon, InstArithmetic::OpKind Op,
264 uint32_t Align = 1) {
265 // TODO(stichnot): Stop ignoring alignment specification.
266 (void)Align;
267 return new (Func->allocate<InstX86FakeRMW>())
268 InstX86FakeRMW(Func, Data, Addr, Op, Beacon);
269 }
270 Operand *getAddr() const { return this->getSrc(1); }
271 Operand *getData() const { return this->getSrc(0); }
272 InstArithmetic::OpKind getOp() const { return Op; }
273 Variable *getBeacon() const {
274 return llvm::cast<Variable>(this->getSrc(2));
275 }
276 void dump(const Cfg *Func) const override;
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800277 static bool classof(const Inst *Instr) {
278 return InstX86Base::isClassof(Instr, InstX86Base::FakeRMW);
John Porto4a566862016-01-04 09:33:41 -0800279 }
John Porto921856d2015-07-07 11:56:26 -0700280
John Porto4a566862016-01-04 09:33:41 -0800281 private:
282 InstArithmetic::OpKind Op;
283 InstX86FakeRMW(Cfg *Func, Operand *Data, Operand *Addr,
284 InstArithmetic::OpKind Op, Variable *Beacon);
285 };
John Porto921856d2015-07-07 11:56:26 -0700286
Jim Stichnoth8ff4b282016-01-04 15:39:06 -0800287 class InstX86GetIP final : public InstX86Base {
288 InstX86GetIP() = delete;
289 InstX86GetIP(const InstX86GetIP &) = delete;
290 InstX86GetIP &operator=(const InstX86GetIP &) = delete;
291
292 public:
293 static InstX86GetIP *create(Cfg *Func, Variable *Dest) {
294 return new (Func->allocate<InstX86GetIP>()) InstX86GetIP(Func, Dest);
295 }
296 void emit(const Cfg *Func) const override;
297 void emitIAS(const Cfg *Func) const override;
298 void dump(const Cfg *Func) const override;
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800299 static bool classof(const Inst *Instr) {
300 return InstX86Base::isClassof(Instr, InstX86Base::GetIP);
Jim Stichnoth8ff4b282016-01-04 15:39:06 -0800301 }
302
303 private:
304 InstX86GetIP(Cfg *Func, Variable *Dest);
305 };
306
John Porto4a566862016-01-04 09:33:41 -0800307 /// InstX86Label represents an intra-block label that is the target of an
308 /// intra-block branch. The offset between the label and the branch must be
309 /// fit into one byte (considered "near"). These are used for lowering i1
310 /// calculations, Select instructions, and 64-bit compares on a 32-bit
311 /// architecture, without basic block splitting. Basic block splitting is not
312 /// so desirable for several reasons, one of which is the impact on decisions
313 /// based on whether a variable's live range spans multiple basic blocks.
314 ///
315 /// Intra-block control flow must be used with caution. Consider the sequence
316 /// for "c = (a >= b ? x : y)".
317 /// cmp a, b
318 /// br lt, L1
319 /// mov c, x
320 /// jmp L2
321 /// L1:
322 /// mov c, y
323 /// L2:
324 ///
325 /// Labels L1 and L2 are intra-block labels. Without knowledge of the
326 /// intra-block control flow, liveness analysis will determine the "mov c, x"
327 /// instruction to be dead. One way to prevent this is to insert a
328 /// "FakeUse(c)" instruction anywhere between the two "mov c, ..."
329 /// instructions, e.g.:
330 ///
331 /// cmp a, b
332 /// br lt, L1
333 /// mov c, x
334 /// jmp L2
335 /// FakeUse(c)
336 /// L1:
337 /// mov c, y
338 /// L2:
339 ///
340 /// The down-side is that "mov c, x" can never be dead-code eliminated even if
341 /// there are no uses of c. As unlikely as this situation is, it may be
342 /// prevented by running dead code elimination before lowering.
343 class InstX86Label final : public InstX86Base {
344 InstX86Label() = delete;
345 InstX86Label(const InstX86Label &) = delete;
346 InstX86Label &operator=(const InstX86Label &) = delete;
John Porto921856d2015-07-07 11:56:26 -0700347
John Porto4a566862016-01-04 09:33:41 -0800348 public:
349 static InstX86Label *create(Cfg *Func, TargetLowering *Target) {
350 return new (Func->allocate<InstX86Label>()) InstX86Label(Func, Target);
351 }
352 uint32_t getEmitInstCount() const override { return 0; }
Jim Stichnoth467ffe52016-03-29 15:01:06 -0700353 GlobalString getLabelName() const { return Name; }
354 SizeT getLabelNumber() const { return LabelNumber; }
Jim Stichnothb9a84722016-08-01 13:18:36 -0700355 bool isLabel() const override { return true; }
John Porto4a566862016-01-04 09:33:41 -0800356 void emit(const Cfg *Func) const override;
357 void emitIAS(const Cfg *Func) const override;
358 void dump(const Cfg *Func) const override;
John Porto27fddcc2016-02-02 15:06:09 -0800359 void setRelocOffset(RelocOffset *Value) { OffsetReloc = Value; }
John Porto921856d2015-07-07 11:56:26 -0700360
John Porto4a566862016-01-04 09:33:41 -0800361 private:
362 InstX86Label(Cfg *Func, TargetLowering *Target);
John Porto921856d2015-07-07 11:56:26 -0700363
Jim Stichnoth467ffe52016-03-29 15:01:06 -0700364 SizeT LabelNumber; // used for unique label generation.
John Porto27fddcc2016-02-02 15:06:09 -0800365 RelocOffset *OffsetReloc = nullptr;
Jim Stichnoth467ffe52016-03-29 15:01:06 -0700366 GlobalString Name;
John Porto4a566862016-01-04 09:33:41 -0800367 };
John Porto921856d2015-07-07 11:56:26 -0700368
John Porto4a566862016-01-04 09:33:41 -0800369 /// Conditional and unconditional branch instruction.
370 class InstX86Br final : public InstX86Base {
371 InstX86Br() = delete;
372 InstX86Br(const InstX86Br &) = delete;
373 InstX86Br &operator=(const InstX86Br &) = delete;
John Porto921856d2015-07-07 11:56:26 -0700374
John Porto4a566862016-01-04 09:33:41 -0800375 public:
376 enum Mode { Near, Far };
John Porto921856d2015-07-07 11:56:26 -0700377
John Porto4a566862016-01-04 09:33:41 -0800378 /// Create a conditional branch to a node.
379 static InstX86Br *create(Cfg *Func, CfgNode *TargetTrue,
380 CfgNode *TargetFalse, BrCond Condition,
381 Mode Kind) {
382 assert(Condition != Cond::Br_None);
383 constexpr InstX86Label *NoLabel = nullptr;
384 return new (Func->allocate<InstX86Br>())
385 InstX86Br(Func, TargetTrue, TargetFalse, NoLabel, Condition, Kind);
386 }
387 /// Create an unconditional branch to a node.
388 static InstX86Br *create(Cfg *Func, CfgNode *Target, Mode Kind) {
389 constexpr CfgNode *NoCondTarget = nullptr;
390 constexpr InstX86Label *NoLabel = nullptr;
391 return new (Func->allocate<InstX86Br>())
392 InstX86Br(Func, NoCondTarget, Target, NoLabel, Cond::Br_None, Kind);
393 }
394 /// Create a non-terminator conditional branch to a node, with a fallthrough
395 /// to the next instruction in the current node. This is used for switch
396 /// lowering.
397 static InstX86Br *create(Cfg *Func, CfgNode *Target, BrCond Condition,
398 Mode Kind) {
399 assert(Condition != Cond::Br_None);
400 constexpr CfgNode *NoUncondTarget = nullptr;
401 constexpr InstX86Label *NoLabel = nullptr;
402 return new (Func->allocate<InstX86Br>())
403 InstX86Br(Func, Target, NoUncondTarget, NoLabel, Condition, Kind);
404 }
405 /// Create a conditional intra-block branch (or unconditional, if
406 /// Condition==Br_None) to a label in the current block.
407 static InstX86Br *create(Cfg *Func, InstX86Label *Label, BrCond Condition,
408 Mode Kind) {
409 constexpr CfgNode *NoCondTarget = nullptr;
410 constexpr CfgNode *NoUncondTarget = nullptr;
411 return new (Func->allocate<InstX86Br>())
412 InstX86Br(Func, NoCondTarget, NoUncondTarget, Label, Condition, Kind);
413 }
414 const CfgNode *getTargetTrue() const { return TargetTrue; }
415 const CfgNode *getTargetFalse() const { return TargetFalse; }
416 bool isNear() const { return Kind == Near; }
417 bool optimizeBranch(const CfgNode *NextNode);
418 uint32_t getEmitInstCount() const override {
419 uint32_t Sum = 0;
420 if (Label)
421 ++Sum;
422 if (getTargetTrue())
423 ++Sum;
424 if (getTargetFalse())
425 ++Sum;
426 return Sum;
427 }
428 bool isUnconditionalBranch() const override {
429 return !Label && Condition == Cond::Br_None;
430 }
Jim Stichnothb9a84722016-08-01 13:18:36 -0700431 const Inst *getIntraBlockBranchTarget() const override { return Label; }
John Porto4a566862016-01-04 09:33:41 -0800432 bool repointEdges(CfgNode *OldNode, CfgNode *NewNode) override;
433 void emit(const Cfg *Func) const override;
434 void emitIAS(const Cfg *Func) const override;
435 void dump(const Cfg *Func) const override;
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800436 static bool classof(const Inst *Instr) {
437 return InstX86Base::isClassof(Instr, InstX86Base::Br);
John Porto4a566862016-01-04 09:33:41 -0800438 }
John Porto921856d2015-07-07 11:56:26 -0700439
John Porto4a566862016-01-04 09:33:41 -0800440 private:
441 InstX86Br(Cfg *Func, const CfgNode *TargetTrue, const CfgNode *TargetFalse,
442 const InstX86Label *Label, BrCond Condition, Mode Kind);
John Porto921856d2015-07-07 11:56:26 -0700443
John Porto4a566862016-01-04 09:33:41 -0800444 BrCond Condition;
445 const CfgNode *TargetTrue;
446 const CfgNode *TargetFalse;
447 const InstX86Label *Label; // Intra-block branch target
448 const Mode Kind;
449 };
John Porto921856d2015-07-07 11:56:26 -0700450
John Porto4a566862016-01-04 09:33:41 -0800451 /// Jump to a target outside this function, such as tailcall, nacljump,
452 /// naclret, unreachable. This is different from a Branch instruction in that
453 /// there is no intra-function control flow to represent.
454 class InstX86Jmp final : public InstX86Base {
455 InstX86Jmp() = delete;
456 InstX86Jmp(const InstX86Jmp &) = delete;
457 InstX86Jmp &operator=(const InstX86Jmp &) = delete;
John Porto921856d2015-07-07 11:56:26 -0700458
John Porto4a566862016-01-04 09:33:41 -0800459 public:
460 static InstX86Jmp *create(Cfg *Func, Operand *Target) {
461 return new (Func->allocate<InstX86Jmp>()) InstX86Jmp(Func, Target);
462 }
463 Operand *getJmpTarget() const { return this->getSrc(0); }
464 void emit(const Cfg *Func) const override;
465 void emitIAS(const Cfg *Func) const override;
466 void dump(const Cfg *Func) const override;
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800467 static bool classof(const Inst *Instr) {
468 return InstX86Base::isClassof(Instr, InstX86Base::Jmp);
John Porto4a566862016-01-04 09:33:41 -0800469 }
John Porto921856d2015-07-07 11:56:26 -0700470
John Porto4a566862016-01-04 09:33:41 -0800471 private:
472 InstX86Jmp(Cfg *Func, Operand *Target);
473 };
John Porto921856d2015-07-07 11:56:26 -0700474
John Porto4a566862016-01-04 09:33:41 -0800475 /// Call instruction. Arguments should have already been pushed.
476 class InstX86Call final : public InstX86Base {
477 InstX86Call() = delete;
478 InstX86Call(const InstX86Call &) = delete;
479 InstX86Call &operator=(const InstX86Call &) = delete;
John Porto921856d2015-07-07 11:56:26 -0700480
John Porto4a566862016-01-04 09:33:41 -0800481 public:
482 static InstX86Call *create(Cfg *Func, Variable *Dest, Operand *CallTarget) {
483 return new (Func->allocate<InstX86Call>())
484 InstX86Call(Func, Dest, CallTarget);
485 }
486 Operand *getCallTarget() const { return this->getSrc(0); }
487 void emit(const Cfg *Func) const override;
488 void emitIAS(const Cfg *Func) const override;
489 void dump(const Cfg *Func) const override;
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800490 static bool classof(const Inst *Instr) {
491 return InstX86Base::isClassof(Instr, InstX86Base::Call);
John Porto4a566862016-01-04 09:33:41 -0800492 }
John Porto921856d2015-07-07 11:56:26 -0700493
John Porto4a566862016-01-04 09:33:41 -0800494 private:
495 InstX86Call(Cfg *Func, Variable *Dest, Operand *CallTarget);
496 };
John Porto921856d2015-07-07 11:56:26 -0700497
John Porto4a566862016-01-04 09:33:41 -0800498 /// Emit a one-operand (GPR) instruction.
499 static void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Var,
500 const GPREmitterOneOp &Emitter);
John Porto921856d2015-07-07 11:56:26 -0700501
John Porto4a566862016-01-04 09:33:41 -0800502 static void emitIASAsAddrOpTyGPR(const Cfg *Func, Type Ty, const Operand *Op0,
503 const Operand *Op1,
504 const GPREmitterAddrOp &Emitter);
John Porto008f4ce2015-12-24 13:22:18 -0800505
John Porto4a566862016-01-04 09:33:41 -0800506 static void emitIASGPRShift(const Cfg *Func, Type Ty, const Variable *Var,
507 const Operand *Src,
508 const GPREmitterShiftOp &Emitter);
John Porto921856d2015-07-07 11:56:26 -0700509
John Porto4a566862016-01-04 09:33:41 -0800510 static void emitIASAddrOpTyGPR(const Cfg *Func, Type Ty, const Address &Addr,
511 const Operand *Src,
512 const GPREmitterAddrOp &Emitter);
John Porto921856d2015-07-07 11:56:26 -0700513
John Porto4a566862016-01-04 09:33:41 -0800514 static void emitIASRegOpTyXMM(const Cfg *Func, Type Ty, const Variable *Var,
515 const Operand *Src,
516 const XmmEmitterRegOp &Emitter);
John Porto921856d2015-07-07 11:56:26 -0700517
John Porto4a566862016-01-04 09:33:41 -0800518 static void emitIASGPRShiftDouble(const Cfg *Func, const Variable *Dest,
519 const Operand *Src1Op,
520 const Operand *Src2Op,
521 const GPREmitterShiftD &Emitter);
John Porto008f4ce2015-12-24 13:22:18 -0800522
Jim Stichnoth8aa39662016-02-10 11:20:30 -0800523 template <typename DReg_t, typename SReg_t, DReg_t (*destEnc)(RegNumT),
524 SReg_t (*srcEnc)(RegNumT)>
John Porto4a566862016-01-04 09:33:41 -0800525 static void emitIASCastRegOp(const Cfg *Func, Type DestTy,
526 const Variable *Dest, Type SrcTy,
527 const Operand *Src,
528 const CastEmitterRegOp<DReg_t, SReg_t> &Emitter);
John Porto921856d2015-07-07 11:56:26 -0700529
Jim Stichnoth8aa39662016-02-10 11:20:30 -0800530 template <typename DReg_t, typename SReg_t, DReg_t (*destEnc)(RegNumT),
531 SReg_t (*srcEnc)(RegNumT)>
John Porto4a566862016-01-04 09:33:41 -0800532 static void
533 emitIASThreeOpImmOps(const Cfg *Func, Type DispatchTy, const Variable *Dest,
534 const Operand *Src0, const Operand *Src1,
535 const ThreeOpImmEmitter<DReg_t, SReg_t> Emitter);
John Porto921856d2015-07-07 11:56:26 -0700536
John Porto4a566862016-01-04 09:33:41 -0800537 static void emitIASMovlikeXMM(const Cfg *Func, const Variable *Dest,
538 const Operand *Src,
539 const XmmEmitterMovOps Emitter);
John Porto921856d2015-07-07 11:56:26 -0700540
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800541 static void emitVariableBlendInst(const char *Opcode, const Inst *Instr,
John Porto4a566862016-01-04 09:33:41 -0800542 const Cfg *Func);
John Porto921856d2015-07-07 11:56:26 -0700543
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800544 static void emitIASVariableBlendInst(const Inst *Instr, const Cfg *Func,
John Porto4a566862016-01-04 09:33:41 -0800545 const XmmEmitterRegOp &Emitter);
John Porto921856d2015-07-07 11:56:26 -0700546
John Porto4a566862016-01-04 09:33:41 -0800547 static void emitIASXmmShift(const Cfg *Func, Type Ty, const Variable *Var,
548 const Operand *Src,
549 const XmmEmitterShiftOp &Emitter);
John Porto921856d2015-07-07 11:56:26 -0700550
John Porto4a566862016-01-04 09:33:41 -0800551 /// Emit a two-operand (GPR) instruction, where the dest operand is a Variable
552 /// that's guaranteed to be a register.
553 template <bool VarCanBeByte = true, bool SrcCanBeByte = true>
John Porto56958cb2016-01-14 09:18:18 -0800554 static void emitIASRegOpTyGPR(const Cfg *Func, bool IsLea, Type Ty,
555 const Variable *Dst, const Operand *Src,
John Porto4a566862016-01-04 09:33:41 -0800556 const GPREmitterRegOp &Emitter);
John Porto921856d2015-07-07 11:56:26 -0700557
John Porto4a566862016-01-04 09:33:41 -0800558 /// Instructions of the form x := op(x).
559 template <typename InstX86Base::InstKindX86 K>
560 class InstX86BaseInplaceopGPR : public InstX86Base {
561 InstX86BaseInplaceopGPR() = delete;
562 InstX86BaseInplaceopGPR(const InstX86BaseInplaceopGPR &) = delete;
563 InstX86BaseInplaceopGPR &
564 operator=(const InstX86BaseInplaceopGPR &) = delete;
John Porto921856d2015-07-07 11:56:26 -0700565
John Porto4a566862016-01-04 09:33:41 -0800566 public:
567 using Base = InstX86BaseInplaceopGPR<K>;
John Porto921856d2015-07-07 11:56:26 -0700568
John Porto4a566862016-01-04 09:33:41 -0800569 void emit(const Cfg *Func) const override {
570 if (!BuildDefs::dump())
571 return;
572 Ostream &Str = Func->getContext()->getStrEmit();
573 assert(this->getSrcSize() == 1);
574 Str << "\t" << Opcode << "\t";
575 this->getSrc(0)->emit(Func);
576 }
577 void emitIAS(const Cfg *Func) const override {
578 assert(this->getSrcSize() == 1);
579 const Variable *Var = this->getDest();
580 Type Ty = Var->getType();
581 emitIASOpTyGPR(Func, Ty, Var, Emitter);
582 }
583 void dump(const Cfg *Func) const override {
584 if (!BuildDefs::dump())
585 return;
586 Ostream &Str = Func->getContext()->getStrDump();
587 this->dumpDest(Func);
588 Str << " = " << Opcode << "." << this->getDest()->getType() << " ";
589 this->dumpSources(Func);
590 }
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800591 static bool classof(const Inst *Instr) {
592 return InstX86Base::isClassof(Instr, InstX86Base::K);
John Porto4a566862016-01-04 09:33:41 -0800593 }
John Porto921856d2015-07-07 11:56:26 -0700594
John Porto4a566862016-01-04 09:33:41 -0800595 protected:
596 InstX86BaseInplaceopGPR(Cfg *Func, Operand *SrcDest)
597 : InstX86Base(Func, K, 1, llvm::dyn_cast<Variable>(SrcDest)) {
598 this->addSource(SrcDest);
599 }
600
601 private:
602 static const char *Opcode;
603 static const GPREmitterOneOp Emitter;
604 };
605
606 /// Instructions of the form x := op(y).
607 template <typename InstX86Base::InstKindX86 K>
608 class InstX86BaseUnaryopGPR : public InstX86Base {
609 InstX86BaseUnaryopGPR() = delete;
610 InstX86BaseUnaryopGPR(const InstX86BaseUnaryopGPR &) = delete;
611 InstX86BaseUnaryopGPR &operator=(const InstX86BaseUnaryopGPR &) = delete;
612
613 public:
614 using Base = InstX86BaseUnaryopGPR<K>;
615
616 void emit(const Cfg *Func) const override {
617 if (!BuildDefs::dump())
618 return;
619 Ostream &Str = Func->getContext()->getStrEmit();
620 assert(this->getSrcSize() == 1);
621 Type SrcTy = this->getSrc(0)->getType();
622 Type DestTy = this->getDest()->getType();
623 Str << "\t" << Opcode << this->getWidthString(SrcTy);
624 // Movsx and movzx need both the source and dest type width letter to
625 // define the operation. The other unary operations have the same source
626 // and dest type and as a result need only one letter.
627 if (SrcTy != DestTy)
628 Str << this->getWidthString(DestTy);
629 Str << "\t";
630 this->getSrc(0)->emit(Func);
631 Str << ", ";
632 this->getDest()->emit(Func);
633 }
634 void emitIAS(const Cfg *Func) const override {
635 assert(this->getSrcSize() == 1);
636 const Variable *Var = this->getDest();
637 Type Ty = Var->getType();
638 const Operand *Src = this->getSrc(0);
John Porto56958cb2016-01-14 09:18:18 -0800639 constexpr bool IsLea = K == InstX86Base::Lea;
Manasij Mukherjee5b7e1c02016-08-04 14:28:37 -0700640
641 if (IsLea) {
642 if (auto *Add = deoptLeaToAddOrNull(Func)) {
643 Add->emitIAS(Func);
644 return;
645 }
646 }
John Porto56958cb2016-01-14 09:18:18 -0800647 emitIASRegOpTyGPR(Func, IsLea, Ty, Var, Src, Emitter);
John Porto4a566862016-01-04 09:33:41 -0800648 }
649 void dump(const Cfg *Func) const override {
650 if (!BuildDefs::dump())
651 return;
652 Ostream &Str = Func->getContext()->getStrDump();
653 this->dumpDest(Func);
654 Str << " = " << Opcode << "." << this->getSrc(0)->getType() << " ";
655 this->dumpSources(Func);
656 }
Manasij Mukherjee5b7e1c02016-08-04 14:28:37 -0700657
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800658 static bool classof(const Inst *Instr) {
659 return InstX86Base::isClassof(Instr, InstX86Base::K);
John Porto4a566862016-01-04 09:33:41 -0800660 }
661
662 protected:
663 InstX86BaseUnaryopGPR(Cfg *Func, Variable *Dest, Operand *Src)
664 : InstX86Base(Func, K, 1, Dest) {
665 this->addSource(Src);
666 }
667
Manasij Mukherjee5b7e1c02016-08-04 14:28:37 -0700668 Inst *deoptLeaToAddOrNull(const Cfg *Func) const {
669 // Revert back to Add when the Lea is a 2-address instruction.
670 // Caller has to emit, this just produces the add instruction.
671 if (auto *MemOp = llvm::dyn_cast<X86OperandMem>(this->getSrc(0))) {
672 if (getFlags().getAggressiveLea() &&
673 MemOp->getBase()->getRegNum() == this->getDest()->getRegNum() &&
674 MemOp->getIndex() == nullptr && MemOp->getShift() == 0) {
675 auto *Add = InstImpl<TraitsType>::InstX86Add::create(
676 const_cast<Cfg *>(Func), this->getDest(), MemOp->getOffset());
677 // TODO(manasijm): Remove const_cast by emitting code for add
678 // directly.
679 return Add;
680 }
681 }
682 return nullptr;
683 }
684
John Porto4a566862016-01-04 09:33:41 -0800685 static const char *Opcode;
686 static const GPREmitterRegOp Emitter;
687 };
688
689 template <typename InstX86Base::InstKindX86 K>
690 class InstX86BaseUnaryopXmm : public InstX86Base {
691 InstX86BaseUnaryopXmm() = delete;
692 InstX86BaseUnaryopXmm(const InstX86BaseUnaryopXmm &) = delete;
693 InstX86BaseUnaryopXmm &operator=(const InstX86BaseUnaryopXmm &) = delete;
694
695 public:
696 using Base = InstX86BaseUnaryopXmm<K>;
697
698 void emit(const Cfg *Func) const override {
699 if (!BuildDefs::dump())
700 return;
701 Ostream &Str = Func->getContext()->getStrEmit();
702 assert(this->getSrcSize() == 1);
703 Str << "\t" << Opcode << "\t";
704 this->getSrc(0)->emit(Func);
705 Str << ", ";
706 this->getDest()->emit(Func);
707 }
708 void emitIAS(const Cfg *Func) const override {
709 Type Ty = this->getDest()->getType();
710 assert(this->getSrcSize() == 1);
711 emitIASRegOpTyXMM(Func, Ty, this->getDest(), this->getSrc(0), Emitter);
712 }
713 void dump(const Cfg *Func) const override {
714 if (!BuildDefs::dump())
715 return;
716 Ostream &Str = Func->getContext()->getStrDump();
717 this->dumpDest(Func);
718 Str << " = " << Opcode << "." << this->getDest()->getType() << " ";
719 this->dumpSources(Func);
720 }
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800721 static bool classof(const Inst *Instr) {
722 return InstX86Base::isClassof(Instr, InstX86Base::K);
John Porto4a566862016-01-04 09:33:41 -0800723 }
724
725 protected:
726 InstX86BaseUnaryopXmm(Cfg *Func, Variable *Dest, Operand *Src)
727 : InstX86Base(Func, K, 1, Dest) {
728 this->addSource(Src);
729 }
730
731 static const char *Opcode;
732 static const XmmEmitterRegOp Emitter;
733 };
734
735 template <typename InstX86Base::InstKindX86 K>
736 class InstX86BaseBinopGPRShift : public InstX86Base {
737 InstX86BaseBinopGPRShift() = delete;
738 InstX86BaseBinopGPRShift(const InstX86BaseBinopGPRShift &) = delete;
739 InstX86BaseBinopGPRShift &
740 operator=(const InstX86BaseBinopGPRShift &) = delete;
741
742 public:
743 using Base = InstX86BaseBinopGPRShift<K>;
744
745 void emit(const Cfg *Func) const override {
746 if (!BuildDefs::dump())
747 return;
748 this->emitTwoAddress(Func, Opcode);
749 }
750 void emitIAS(const Cfg *Func) const override {
751 Type Ty = this->getDest()->getType();
752 assert(this->getSrcSize() == 2);
753 emitIASGPRShift(Func, Ty, this->getDest(), this->getSrc(1), Emitter);
754 }
755 void dump(const Cfg *Func) const override {
756 if (!BuildDefs::dump())
757 return;
758 Ostream &Str = Func->getContext()->getStrDump();
759 this->dumpDest(Func);
760 Str << " = " << Opcode << "." << this->getDest()->getType() << " ";
761 this->dumpSources(Func);
762 }
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800763 static bool classof(const Inst *Instr) {
764 return InstX86Base::isClassof(Instr, InstX86Base::K);
John Porto4a566862016-01-04 09:33:41 -0800765 }
766
767 protected:
768 InstX86BaseBinopGPRShift(Cfg *Func, Variable *Dest, Operand *Source)
769 : InstX86Base(Func, K, 2, Dest) {
770 this->addSource(Dest);
771 this->addSource(Source);
772 }
773
774 static const char *Opcode;
775 static const GPREmitterShiftOp Emitter;
776 };
777
778 template <typename InstX86Base::InstKindX86 K>
779 class InstX86BaseBinopGPR : public InstX86Base {
780 InstX86BaseBinopGPR() = delete;
781 InstX86BaseBinopGPR(const InstX86BaseBinopGPR &) = delete;
782 InstX86BaseBinopGPR &operator=(const InstX86BaseBinopGPR &) = delete;
783
784 public:
785 using Base = InstX86BaseBinopGPR<K>;
786
787 void emit(const Cfg *Func) const override {
788 if (!BuildDefs::dump())
789 return;
790 this->emitTwoAddress(Func, Opcode);
791 }
792 void emitIAS(const Cfg *Func) const override {
793 Type Ty = this->getDest()->getType();
794 assert(this->getSrcSize() == 2);
John Porto56958cb2016-01-14 09:18:18 -0800795 constexpr bool ThisIsLEA = K == InstX86Base::Lea;
796 static_assert(!ThisIsLEA, "Lea should be a unaryop.");
797 emitIASRegOpTyGPR(Func, !ThisIsLEA, Ty, this->getDest(), this->getSrc(1),
798 Emitter);
John Porto4a566862016-01-04 09:33:41 -0800799 }
800 void dump(const Cfg *Func) const override {
801 if (!BuildDefs::dump())
802 return;
803 Ostream &Str = Func->getContext()->getStrDump();
804 this->dumpDest(Func);
805 Str << " = " << Opcode << "." << this->getDest()->getType() << " ";
806 this->dumpSources(Func);
807 }
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800808 static bool classof(const Inst *Instr) {
809 return InstX86Base::isClassof(Instr, InstX86Base::K);
John Porto4a566862016-01-04 09:33:41 -0800810 }
811
812 protected:
813 InstX86BaseBinopGPR(Cfg *Func, Variable *Dest, Operand *Source)
814 : InstX86Base(Func, K, 2, Dest) {
815 this->addSource(Dest);
816 this->addSource(Source);
817 }
818
819 static const char *Opcode;
820 static const GPREmitterRegOp Emitter;
821 };
822
823 template <typename InstX86Base::InstKindX86 K>
824 class InstX86BaseBinopRMW : public InstX86Base {
825 InstX86BaseBinopRMW() = delete;
826 InstX86BaseBinopRMW(const InstX86BaseBinopRMW &) = delete;
827 InstX86BaseBinopRMW &operator=(const InstX86BaseBinopRMW &) = delete;
828
829 public:
830 using Base = InstX86BaseBinopRMW<K>;
831
832 void emit(const Cfg *Func) const override {
833 if (!BuildDefs::dump())
834 return;
835 this->emitTwoAddress(Func, Opcode);
836 }
837 void emitIAS(const Cfg *Func) const override {
838 Type Ty = this->getSrc(0)->getType();
839 assert(this->getSrcSize() == 2);
840 emitIASAsAddrOpTyGPR(Func, Ty, this->getSrc(0), this->getSrc(1), Emitter);
841 }
842 void dump(const Cfg *Func) const override {
843 if (!BuildDefs::dump())
844 return;
845 Ostream &Str = Func->getContext()->getStrDump();
846 Str << Opcode << "." << this->getSrc(0)->getType() << " ";
847 this->dumpSources(Func);
848 }
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800849 static bool classof(const Inst *Instr) {
850 return InstX86Base::isClassof(Instr, InstX86Base::K);
John Porto4a566862016-01-04 09:33:41 -0800851 }
852
853 protected:
854 InstX86BaseBinopRMW(Cfg *Func, X86OperandMem *DestSrc0, Operand *Src1)
855 : InstX86Base(Func, K, 2, nullptr) {
856 this->addSource(DestSrc0);
857 this->addSource(Src1);
858 }
859
860 static const char *Opcode;
861 static const GPREmitterAddrOp Emitter;
862 };
863
864 template <typename InstX86Base::InstKindX86 K, bool NeedsElementType,
865 typename InstX86Base::SseSuffix Suffix>
866 class InstX86BaseBinopXmm : public InstX86Base {
867 InstX86BaseBinopXmm() = delete;
868 InstX86BaseBinopXmm(const InstX86BaseBinopXmm &) = delete;
869 InstX86BaseBinopXmm &operator=(const InstX86BaseBinopXmm &) = delete;
870
871 public:
872 using Base = InstX86BaseBinopXmm<K, NeedsElementType, Suffix>;
873
874 void emit(const Cfg *Func) const override {
875 if (!BuildDefs::dump())
876 return;
877 this->validateVectorAddrMode();
David Sehrb19d39c2016-01-13 14:17:37 -0800878 const Type DestTy = ArithmeticTypeOverride == IceType_void
879 ? this->getDest()->getType()
880 : ArithmeticTypeOverride;
881 const char *SuffixString = "";
John Porto4a566862016-01-04 09:33:41 -0800882 switch (Suffix) {
883 case InstX86Base::SseSuffix::None:
John Porto4a566862016-01-04 09:33:41 -0800884 break;
David Sehrb19d39c2016-01-13 14:17:37 -0800885 case InstX86Base::SseSuffix::Packed:
886 SuffixString = Traits::TypeAttributes[DestTy].PdPsString;
887 break;
John Portoae15f0f2016-04-26 04:26:33 -0700888 case InstX86Base::SseSuffix::Unpack:
889 SuffixString = Traits::TypeAttributes[DestTy].UnpackString;
890 break;
David Sehrb19d39c2016-01-13 14:17:37 -0800891 case InstX86Base::SseSuffix::Scalar:
892 SuffixString = Traits::TypeAttributes[DestTy].SdSsString;
893 break;
894 case InstX86Base::SseSuffix::Integral:
Nicolas Capens7638e272016-10-06 11:33:55 -0400895 SuffixString = Traits::TypeAttributes[DestTy].IntegralString;
896 break;
897 case InstX86Base::SseSuffix::Pack:
David Sehrb19d39c2016-01-13 14:17:37 -0800898 SuffixString = Traits::TypeAttributes[DestTy].PackString;
899 break;
John Porto4a566862016-01-04 09:33:41 -0800900 }
David Sehrb19d39c2016-01-13 14:17:37 -0800901 this->emitTwoAddress(Func, Opcode, SuffixString);
John Porto4a566862016-01-04 09:33:41 -0800902 }
903 void emitIAS(const Cfg *Func) const override {
904 this->validateVectorAddrMode();
905 Type Ty = this->getDest()->getType();
906 if (NeedsElementType)
907 Ty = typeElementType(Ty);
908 assert(this->getSrcSize() == 2);
909 emitIASRegOpTyXMM(Func, Ty, this->getDest(), this->getSrc(1), Emitter);
910 }
911 void dump(const Cfg *Func) const override {
912 if (!BuildDefs::dump())
913 return;
914 Ostream &Str = Func->getContext()->getStrDump();
915 this->dumpDest(Func);
916 Str << " = " << Opcode << "." << this->getDest()->getType() << " ";
917 this->dumpSources(Func);
918 }
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800919 static bool classof(const Inst *Instr) {
920 return InstX86Base::isClassof(Instr, InstX86Base::K);
John Porto4a566862016-01-04 09:33:41 -0800921 }
922
923 protected:
David Sehrb19d39c2016-01-13 14:17:37 -0800924 InstX86BaseBinopXmm(Cfg *Func, Variable *Dest, Operand *Source,
925 Type ArithmeticTypeOverride = IceType_void)
926 : InstX86Base(Func, K, 2, Dest),
927 ArithmeticTypeOverride(ArithmeticTypeOverride) {
John Porto4a566862016-01-04 09:33:41 -0800928 this->addSource(Dest);
929 this->addSource(Source);
930 }
931
David Sehrb19d39c2016-01-13 14:17:37 -0800932 const Type ArithmeticTypeOverride;
John Porto4a566862016-01-04 09:33:41 -0800933 static const char *Opcode;
934 static const XmmEmitterRegOp Emitter;
935 };
936
937 template <typename InstX86Base::InstKindX86 K, bool AllowAllTypes = false>
938 class InstX86BaseBinopXmmShift : public InstX86Base {
939 InstX86BaseBinopXmmShift() = delete;
940 InstX86BaseBinopXmmShift(const InstX86BaseBinopXmmShift &) = delete;
941 InstX86BaseBinopXmmShift &
942 operator=(const InstX86BaseBinopXmmShift &) = delete;
943
944 public:
945 using Base = InstX86BaseBinopXmmShift<K, AllowAllTypes>;
946
947 void emit(const Cfg *Func) const override {
948 if (!BuildDefs::dump())
949 return;
950 this->validateVectorAddrMode();
951 // Shift operations are always integral, and hence always need a suffix.
952 const Type DestTy = this->getDest()->getType();
953 this->emitTwoAddress(Func, this->Opcode,
Nicolas Capens7638e272016-10-06 11:33:55 -0400954 Traits::TypeAttributes[DestTy].IntegralString);
John Porto4a566862016-01-04 09:33:41 -0800955 }
956 void emitIAS(const Cfg *Func) const override {
957 this->validateVectorAddrMode();
958 Type Ty = this->getDest()->getType();
959 assert(AllowAllTypes || isVectorType(Ty));
960 Type ElementTy = typeElementType(Ty);
961 assert(this->getSrcSize() == 2);
962 emitIASXmmShift(Func, ElementTy, this->getDest(), this->getSrc(1),
963 Emitter);
964 }
965 void dump(const Cfg *Func) const override {
966 if (!BuildDefs::dump())
967 return;
968 Ostream &Str = Func->getContext()->getStrDump();
969 this->dumpDest(Func);
970 Str << " = " << Opcode << "." << this->getDest()->getType() << " ";
971 this->dumpSources(Func);
972 }
Jim Stichnoth8cfeb692016-02-05 09:50:02 -0800973 static bool classof(const Inst *Instr) {
974 return InstX86Base::isClassof(Instr, InstX86Base::K);
John Porto4a566862016-01-04 09:33:41 -0800975 }
976
977 protected:
978 InstX86BaseBinopXmmShift(Cfg *Func, Variable *Dest, Operand *Source)
979 : InstX86Base(Func, K, 2, Dest) {
980 this->addSource(Dest);
981 this->addSource(Source);
982 }
983
984 static const char *Opcode;
985 static const XmmEmitterShiftOp Emitter;
986 };
987
988 template <typename InstX86Base::InstKindX86 K>
989 class InstX86BaseTernop : public InstX86Base {
990 InstX86BaseTernop() = delete;
991 InstX86BaseTernop(const InstX86BaseTernop &) = delete;
992 InstX86BaseTernop &operator=(const InstX86BaseTernop &) = delete;
993
994 public:
995 using Base = InstX86BaseTernop<K>;
996
997 void emit(const Cfg *Func) const override {
998 if (!BuildDefs::dump())
999 return;
1000 Ostream &Str = Func->getContext()->getStrEmit();
1001 assert(this->getSrcSize() == 3);
1002 Str << "\t" << Opcode << "\t";
1003 this->getSrc(2)->emit(Func);
1004 Str << ", ";
1005 this->getSrc(1)->emit(Func);
1006 Str << ", ";
1007 this->getDest()->emit(Func);
1008 }
1009 void dump(const Cfg *Func) const override {
1010 if (!BuildDefs::dump())
1011 return;
1012 Ostream &Str = Func->getContext()->getStrDump();
1013 this->dumpDest(Func);
1014 Str << " = " << Opcode << "." << this->getDest()->getType() << " ";
1015 this->dumpSources(Func);
1016 }
Jim Stichnoth8cfeb692016-02-05 09:50:02 -08001017 static bool classof(const Inst *Instr) {
1018 return InstX86Base::isClassof(Instr, InstX86Base::K);
John Porto4a566862016-01-04 09:33:41 -08001019 }
1020
1021 protected:
1022 InstX86BaseTernop(Cfg *Func, Variable *Dest, Operand *Source1,
1023 Operand *Source2)
1024 : InstX86Base(Func, K, 3, Dest) {
1025 this->addSource(Dest);
1026 this->addSource(Source1);
1027 this->addSource(Source2);
1028 }
1029
1030 static const char *Opcode;
1031 };
1032
1033 // Instructions of the form x := y op z
1034 template <typename InstX86Base::InstKindX86 K>
1035 class InstX86BaseThreeAddressop : public InstX86Base {
1036 InstX86BaseThreeAddressop() = delete;
1037 InstX86BaseThreeAddressop(const InstX86BaseThreeAddressop &) = delete;
1038 InstX86BaseThreeAddressop &
1039 operator=(const InstX86BaseThreeAddressop &) = delete;
1040
1041 public:
1042 using Base = InstX86BaseThreeAddressop<K>;
1043
1044 void emit(const Cfg *Func) const override {
1045 if (!BuildDefs::dump())
1046 return;
1047 Ostream &Str = Func->getContext()->getStrEmit();
1048 assert(this->getSrcSize() == 2);
1049 Str << "\t" << Opcode << "\t";
1050 this->getSrc(1)->emit(Func);
1051 Str << ", ";
1052 this->getSrc(0)->emit(Func);
1053 Str << ", ";
1054 this->getDest()->emit(Func);
1055 }
1056 void dump(const Cfg *Func) const override {
1057 if (!BuildDefs::dump())
1058 return;
1059 Ostream &Str = Func->getContext()->getStrDump();
1060 this->dumpDest(Func);
1061 Str << " = " << Opcode << "." << this->getDest()->getType() << " ";
1062 this->dumpSources(Func);
1063 }
Jim Stichnoth8cfeb692016-02-05 09:50:02 -08001064 static bool classof(const Inst *Instr) {
1065 return InstX86Base::isClassof(Instr, InstX86Base::K);
John Porto4a566862016-01-04 09:33:41 -08001066 }
1067
1068 protected:
1069 InstX86BaseThreeAddressop(Cfg *Func, Variable *Dest, Operand *Source0,
1070 Operand *Source1)
1071 : InstX86Base(Func, K, 2, Dest) {
1072 this->addSource(Source0);
1073 this->addSource(Source1);
1074 }
1075
1076 static const char *Opcode;
1077 };
1078
1079 /// Base class for assignment instructions
1080 template <typename InstX86Base::InstKindX86 K>
1081 class InstX86BaseMovlike : public InstX86Base {
1082 InstX86BaseMovlike() = delete;
1083 InstX86BaseMovlike(const InstX86BaseMovlike &) = delete;
1084 InstX86BaseMovlike &operator=(const InstX86BaseMovlike &) = delete;
1085
1086 public:
1087 using Base = InstX86BaseMovlike<K>;
1088
1089 bool isRedundantAssign() const override {
1090 if (const auto *SrcVar =
1091 llvm::dyn_cast<const Variable>(this->getSrc(0))) {
1092 if (SrcVar->hasReg() && this->Dest->hasReg()) {
1093 // An assignment between physical registers is considered redundant if
1094 // they have the same base register and the same encoding. E.g.:
1095 // mov cl, ecx ==> redundant
1096 // mov ch, ecx ==> not redundant due to different encodings
1097 // mov ch, ebp ==> not redundant due to different base registers
1098 // mov ecx, ecx ==> redundant, and dangerous in x86-64. i64 zexting
1099 // is handled by Inst86Zext.
Jim Stichnoth8aa39662016-02-10 11:20:30 -08001100 const auto SrcReg = SrcVar->getRegNum();
1101 const auto DestReg = this->Dest->getRegNum();
John Porto4a566862016-01-04 09:33:41 -08001102 return (Traits::getEncoding(SrcReg) ==
1103 Traits::getEncoding(DestReg)) &&
1104 (Traits::getBaseReg(SrcReg) == Traits::getBaseReg(DestReg));
1105 }
1106 }
1107 return checkForRedundantAssign(this->getDest(), this->getSrc(0));
1108 }
1109 bool isVarAssign() const override {
1110 return llvm::isa<Variable>(this->getSrc(0));
1111 }
1112 void dump(const Cfg *Func) const override {
1113 if (!BuildDefs::dump())
1114 return;
1115 Ostream &Str = Func->getContext()->getStrDump();
1116 Str << Opcode << "." << this->getDest()->getType() << " ";
1117 this->dumpDest(Func);
1118 Str << ", ";
1119 this->dumpSources(Func);
1120 }
Jim Stichnoth8cfeb692016-02-05 09:50:02 -08001121 static bool classof(const Inst *Instr) {
1122 return InstX86Base::isClassof(Instr, InstX86Base::K);
John Porto4a566862016-01-04 09:33:41 -08001123 }
1124
1125 protected:
1126 InstX86BaseMovlike(Cfg *Func, Variable *Dest, Operand *Source)
1127 : InstX86Base(Func, K, 1, Dest) {
1128 this->addSource(Source);
1129 // For an integer assignment, make sure it's either a same-type assignment
1130 // or a truncation.
1131 assert(!isScalarIntegerType(Dest->getType()) ||
1132 (typeWidthInBytes(Dest->getType()) <=
1133 typeWidthInBytes(Source->getType())));
1134 }
1135
1136 static const char *Opcode;
1137 };
1138
1139 class InstX86Bswap : public InstX86BaseInplaceopGPR<InstX86Base::Bswap> {
1140 public:
1141 static InstX86Bswap *create(Cfg *Func, Operand *SrcDest) {
1142 return new (Func->allocate<InstX86Bswap>()) InstX86Bswap(Func, SrcDest);
1143 }
1144
1145 private:
1146 InstX86Bswap(Cfg *Func, Operand *SrcDest)
1147 : InstX86BaseInplaceopGPR<InstX86Base::Bswap>(Func, SrcDest) {}
1148 };
1149
1150 class InstX86Neg : public InstX86BaseInplaceopGPR<InstX86Base::Neg> {
1151 public:
1152 static InstX86Neg *create(Cfg *Func, Operand *SrcDest) {
1153 return new (Func->allocate<InstX86Neg>()) InstX86Neg(Func, SrcDest);
1154 }
1155
1156 private:
1157 InstX86Neg(Cfg *Func, Operand *SrcDest)
1158 : InstX86BaseInplaceopGPR<InstX86Base::Neg>(Func, SrcDest) {}
1159 };
1160
1161 class InstX86Bsf : public InstX86BaseUnaryopGPR<InstX86Base::Bsf> {
1162 public:
1163 static InstX86Bsf *create(Cfg *Func, Variable *Dest, Operand *Src) {
1164 return new (Func->allocate<InstX86Bsf>()) InstX86Bsf(Func, Dest, Src);
1165 }
1166
1167 private:
1168 InstX86Bsf(Cfg *Func, Variable *Dest, Operand *Src)
1169 : InstX86BaseUnaryopGPR<InstX86Base::Bsf>(Func, Dest, Src) {}
1170 };
1171
1172 class InstX86Bsr : public InstX86BaseUnaryopGPR<InstX86Base::Bsr> {
1173 public:
1174 static InstX86Bsr *create(Cfg *Func, Variable *Dest, Operand *Src) {
1175 return new (Func->allocate<InstX86Bsr>()) InstX86Bsr(Func, Dest, Src);
1176 }
1177
1178 private:
1179 InstX86Bsr(Cfg *Func, Variable *Dest, Operand *Src)
1180 : InstX86BaseUnaryopGPR<InstX86Base::Bsr>(Func, Dest, Src) {}
1181 };
1182
1183 class InstX86Lea : public InstX86BaseUnaryopGPR<InstX86Base::Lea> {
1184 public:
1185 static InstX86Lea *create(Cfg *Func, Variable *Dest, Operand *Src) {
1186 return new (Func->allocate<InstX86Lea>()) InstX86Lea(Func, Dest, Src);
1187 }
1188
1189 void emit(const Cfg *Func) const override;
1190
1191 private:
1192 InstX86Lea(Cfg *Func, Variable *Dest, Operand *Src)
1193 : InstX86BaseUnaryopGPR<InstX86Base::Lea>(Func, Dest, Src) {}
1194 };
1195
1196 // Cbwdq instruction - wrapper for cbw, cwd, and cdq
1197 class InstX86Cbwdq : public InstX86BaseUnaryopGPR<InstX86Base::Cbwdq> {
1198 public:
1199 static InstX86Cbwdq *create(Cfg *Func, Variable *Dest, Operand *Src) {
1200 return new (Func->allocate<InstX86Cbwdq>()) InstX86Cbwdq(Func, Dest, Src);
1201 }
1202
1203 void emit(const Cfg *Func) const override;
1204 void emitIAS(const Cfg *Func) const override;
1205
1206 private:
1207 InstX86Cbwdq(Cfg *Func, Variable *Dest, Operand *Src)
1208 : InstX86BaseUnaryopGPR<InstX86Base::Cbwdq>(Func, Dest, Src) {}
1209 };
1210
1211 class InstX86Movsx : public InstX86BaseUnaryopGPR<InstX86Base::Movsx> {
1212 public:
1213 static InstX86Movsx *create(Cfg *Func, Variable *Dest, Operand *Src) {
1214 assert(typeWidthInBytes(Dest->getType()) >
1215 typeWidthInBytes(Src->getType()));
1216 return new (Func->allocate<InstX86Movsx>()) InstX86Movsx(Func, Dest, Src);
1217 }
1218
1219 void emitIAS(const Cfg *Func) const override;
1220
1221 private:
1222 InstX86Movsx(Cfg *Func, Variable *Dest, Operand *Src)
1223 : InstX86BaseUnaryopGPR<InstX86Base::Movsx>(Func, Dest, Src) {}
1224 };
1225
1226 class InstX86Movzx : public InstX86BaseUnaryopGPR<InstX86Base::Movzx> {
1227 public:
1228 static InstX86Movzx *create(Cfg *Func, Variable *Dest, Operand *Src) {
1229 assert(typeWidthInBytes(Dest->getType()) >
1230 typeWidthInBytes(Src->getType()));
1231 return new (Func->allocate<InstX86Movzx>()) InstX86Movzx(Func, Dest, Src);
1232 }
1233
1234 void emit(const Cfg *Func) const override;
1235
1236 void emitIAS(const Cfg *Func) const override;
1237
John Porto56958cb2016-01-14 09:18:18 -08001238 void setMustKeep() { MustKeep = true; }
1239
John Porto4a566862016-01-04 09:33:41 -08001240 private:
John Porto56958cb2016-01-14 09:18:18 -08001241 bool MustKeep = false;
1242
John Porto4a566862016-01-04 09:33:41 -08001243 InstX86Movzx(Cfg *Func, Variable *Dest, Operand *Src)
1244 : InstX86BaseUnaryopGPR<InstX86Base::Movzx>(Func, Dest, Src) {}
John Porto56958cb2016-01-14 09:18:18 -08001245
1246 bool mayBeElided(const Variable *Dest, const Operand *Src) const;
John Porto4a566862016-01-04 09:33:41 -08001247 };
1248
1249 class InstX86Movd : public InstX86BaseUnaryopXmm<InstX86Base::Movd> {
1250 public:
1251 static InstX86Movd *create(Cfg *Func, Variable *Dest, Operand *Src) {
1252 return new (Func->allocate<InstX86Movd>()) InstX86Movd(Func, Dest, Src);
1253 }
1254
1255 void emit(const Cfg *Func) const override;
1256
1257 void emitIAS(const Cfg *Func) const override;
1258
1259 private:
1260 InstX86Movd(Cfg *Func, Variable *Dest, Operand *Src)
1261 : InstX86BaseUnaryopXmm<InstX86Base::Movd>(Func, Dest, Src) {}
1262 };
1263
Nicolas Capense3cabda2016-10-18 16:27:27 -04001264 class InstX86Movmsk final : public InstX86Base {
1265 InstX86Movmsk() = delete;
1266 InstX86Movmsk(const InstX86Movmsk &) = delete;
1267 InstX86Movmsk &operator=(const InstX86Movmsk &) = delete;
1268
1269 public:
1270 static InstX86Movmsk *create(Cfg *Func, Variable *Dest, Operand *Source) {
1271 return new (Func->allocate<InstX86Movmsk>())
1272 InstX86Movmsk(Func, Dest, Source);
1273 }
1274 void emit(const Cfg *Func) const override;
1275 void emitIAS(const Cfg *Func) const override;
1276 void dump(const Cfg *Func) const override;
1277 static bool classof(const Inst *Instr) {
1278 return InstX86Base::isClassof(Instr, InstX86Base::InstX86Movmsk);
1279 }
1280
1281 private:
1282 InstX86Movmsk(Cfg *Func, Variable *Dest, Operand *Source);
1283 };
1284
Nicolas Capens956cfd62016-10-31 14:28:09 -04001285 class InstX86Sqrt : public InstX86BaseUnaryopXmm<InstX86Base::Sqrt> {
John Porto4a566862016-01-04 09:33:41 -08001286 public:
Nicolas Capens956cfd62016-10-31 14:28:09 -04001287 static InstX86Sqrt *create(Cfg *Func, Variable *Dest, Operand *Src) {
1288 return new (Func->allocate<InstX86Sqrt>()) InstX86Sqrt(Func, Dest, Src);
John Porto4a566862016-01-04 09:33:41 -08001289 }
1290
1291 virtual void emit(const Cfg *Func) const override;
1292
1293 private:
Nicolas Capens956cfd62016-10-31 14:28:09 -04001294 InstX86Sqrt(Cfg *Func, Variable *Dest, Operand *Src)
1295 : InstX86BaseUnaryopXmm<InstX86Base::Sqrt>(Func, Dest, Src) {}
John Porto4a566862016-01-04 09:33:41 -08001296 };
1297
1298 /// Move/assignment instruction - wrapper for mov/movss/movsd.
1299 class InstX86Mov : public InstX86BaseMovlike<InstX86Base::Mov> {
1300 public:
1301 static InstX86Mov *create(Cfg *Func, Variable *Dest, Operand *Source) {
1302 assert(!isScalarIntegerType(Dest->getType()) ||
1303 (typeWidthInBytes(Dest->getType()) <=
1304 typeWidthInBytes(Source->getType())));
1305 return new (Func->allocate<InstX86Mov>()) InstX86Mov(Func, Dest, Source);
1306 }
1307
1308 void emit(const Cfg *Func) const override;
1309 void emitIAS(const Cfg *Func) const override;
1310
1311 private:
1312 InstX86Mov(Cfg *Func, Variable *Dest, Operand *Source)
1313 : InstX86BaseMovlike<InstX86Base::Mov>(Func, Dest, Source) {}
1314 };
1315
1316 /// Move packed - copy 128 bit values between XMM registers, or mem128 and XMM
1317 /// registers.
1318 class InstX86Movp : public InstX86BaseMovlike<InstX86Base::Movp> {
1319 public:
1320 static InstX86Movp *create(Cfg *Func, Variable *Dest, Operand *Source) {
1321 return new (Func->allocate<InstX86Movp>())
1322 InstX86Movp(Func, Dest, Source);
1323 }
1324
1325 void emit(const Cfg *Func) const override;
1326 void emitIAS(const Cfg *Func) const override;
1327
1328 private:
1329 InstX86Movp(Cfg *Func, Variable *Dest, Operand *Source)
1330 : InstX86BaseMovlike<InstX86Base::Movp>(Func, Dest, Source) {}
1331 };
1332
1333 /// Movq - copy between XMM registers, or mem64 and XMM registers.
1334 class InstX86Movq : public InstX86BaseMovlike<InstX86Base::Movq> {
1335 public:
1336 static InstX86Movq *create(Cfg *Func, Variable *Dest, Operand *Source) {
1337 return new (Func->allocate<InstX86Movq>())
1338 InstX86Movq(Func, Dest, Source);
1339 }
1340
1341 void emit(const Cfg *Func) const override;
1342 void emitIAS(const Cfg *Func) const override;
1343
1344 private:
1345 InstX86Movq(Cfg *Func, Variable *Dest, Operand *Source)
1346 : InstX86BaseMovlike<InstX86Base::Movq>(Func, Dest, Source) {}
1347 };
1348
1349 class InstX86Add : public InstX86BaseBinopGPR<InstX86Base::Add> {
1350 public:
1351 static InstX86Add *create(Cfg *Func, Variable *Dest, Operand *Source) {
1352 return new (Func->allocate<InstX86Add>()) InstX86Add(Func, Dest, Source);
1353 }
1354
1355 private:
1356 InstX86Add(Cfg *Func, Variable *Dest, Operand *Source)
1357 : InstX86BaseBinopGPR<InstX86Base::Add>(Func, Dest, Source) {}
1358 };
1359
1360 class InstX86AddRMW : public InstX86BaseBinopRMW<InstX86Base::AddRMW> {
1361 public:
1362 static InstX86AddRMW *create(Cfg *Func, X86OperandMem *DestSrc0,
1363 Operand *Src1) {
1364 return new (Func->allocate<InstX86AddRMW>())
1365 InstX86AddRMW(Func, DestSrc0, Src1);
1366 }
1367
1368 private:
1369 InstX86AddRMW(Cfg *Func, X86OperandMem *DestSrc0, Operand *Src1)
1370 : InstX86BaseBinopRMW<InstX86Base::AddRMW>(Func, DestSrc0, Src1) {}
1371 };
1372
1373 class InstX86Addps
1374 : public InstX86BaseBinopXmm<InstX86Base::Addps, true,
1375 InstX86Base::SseSuffix::Packed> {
1376 public:
1377 static InstX86Addps *create(Cfg *Func, Variable *Dest, Operand *Source) {
1378 return new (Func->allocate<InstX86Addps>())
1379 InstX86Addps(Func, Dest, Source);
1380 }
1381
1382 private:
1383 InstX86Addps(Cfg *Func, Variable *Dest, Operand *Source)
1384 : InstX86BaseBinopXmm<InstX86Base::Addps, true,
1385 InstX86Base::SseSuffix::Packed>(Func, Dest,
1386 Source) {}
1387 };
1388
1389 class InstX86Adc : public InstX86BaseBinopGPR<InstX86Base::Adc> {
1390 public:
1391 static InstX86Adc *create(Cfg *Func, Variable *Dest, Operand *Source) {
1392 return new (Func->allocate<InstX86Adc>()) InstX86Adc(Func, Dest, Source);
1393 }
1394
1395 private:
1396 InstX86Adc(Cfg *Func, Variable *Dest, Operand *Source)
1397 : InstX86BaseBinopGPR<InstX86Base::Adc>(Func, Dest, Source) {}
1398 };
1399
1400 class InstX86AdcRMW : public InstX86BaseBinopRMW<InstX86Base::AdcRMW> {
1401 public:
1402 static InstX86AdcRMW *create(Cfg *Func, X86OperandMem *DestSrc0,
1403 Operand *Src1) {
1404 return new (Func->allocate<InstX86AdcRMW>())
1405 InstX86AdcRMW(Func, DestSrc0, Src1);
1406 }
1407
1408 private:
1409 InstX86AdcRMW(Cfg *Func, X86OperandMem *DestSrc0, Operand *Src1)
1410 : InstX86BaseBinopRMW<InstX86Base::AdcRMW>(Func, DestSrc0, Src1) {}
1411 };
1412
1413 class InstX86Addss
1414 : public InstX86BaseBinopXmm<InstX86Base::Addss, false,
1415 InstX86Base::SseSuffix::Scalar> {
1416 public:
1417 static InstX86Addss *create(Cfg *Func, Variable *Dest, Operand *Source) {
1418 return new (Func->allocate<InstX86Addss>())
1419 InstX86Addss(Func, Dest, Source);
1420 }
1421
1422 private:
1423 InstX86Addss(Cfg *Func, Variable *Dest, Operand *Source)
1424 : InstX86BaseBinopXmm<InstX86Base::Addss, false,
1425 InstX86Base::SseSuffix::Scalar>(Func, Dest,
1426 Source) {}
1427 };
1428
1429 class InstX86Padd
1430 : public InstX86BaseBinopXmm<InstX86Base::Padd, true,
1431 InstX86Base::SseSuffix::Integral> {
1432 public:
1433 static InstX86Padd *create(Cfg *Func, Variable *Dest, Operand *Source) {
1434 return new (Func->allocate<InstX86Padd>())
1435 InstX86Padd(Func, Dest, Source);
1436 }
1437
1438 private:
1439 InstX86Padd(Cfg *Func, Variable *Dest, Operand *Source)
1440 : InstX86BaseBinopXmm<InstX86Base::Padd, true,
1441 InstX86Base::SseSuffix::Integral>(Func, Dest,
John Porto921856d2015-07-07 11:56:26 -07001442 Source) {}
John Porto4a566862016-01-04 09:33:41 -08001443 };
John Porto921856d2015-07-07 11:56:26 -07001444
Nicolas Capens67a49b52016-10-26 13:18:35 -04001445 class InstX86Padds
1446 : public InstX86BaseBinopXmm<InstX86Base::Padds, true,
1447 InstX86Base::SseSuffix::Integral> {
1448 public:
1449 static InstX86Padds *create(Cfg *Func, Variable *Dest, Operand *Source) {
1450 return new (Func->allocate<InstX86Padds>())
1451 InstX86Padds(Func, Dest, Source);
1452 }
1453
1454 private:
1455 InstX86Padds(Cfg *Func, Variable *Dest, Operand *Source)
1456 : InstX86BaseBinopXmm<InstX86Base::Padds, true,
1457 InstX86Base::SseSuffix::Integral>(Func, Dest,
1458 Source) {}
1459 };
1460
1461 class InstX86Paddus
1462 : public InstX86BaseBinopXmm<InstX86Base::Paddus, true,
1463 InstX86Base::SseSuffix::Integral> {
1464 public:
1465 static InstX86Paddus *create(Cfg *Func, Variable *Dest, Operand *Source) {
1466 return new (Func->allocate<InstX86Paddus>())
1467 InstX86Paddus(Func, Dest, Source);
1468 }
1469
1470 private:
1471 InstX86Paddus(Cfg *Func, Variable *Dest, Operand *Source)
1472 : InstX86BaseBinopXmm<InstX86Base::Paddus, true,
1473 InstX86Base::SseSuffix::Integral>(Func, Dest,
1474 Source) {}
1475 };
1476
John Porto4a566862016-01-04 09:33:41 -08001477 class InstX86Sub : public InstX86BaseBinopGPR<InstX86Base::Sub> {
1478 public:
1479 static InstX86Sub *create(Cfg *Func, Variable *Dest, Operand *Source) {
1480 return new (Func->allocate<InstX86Sub>()) InstX86Sub(Func, Dest, Source);
1481 }
John Porto921856d2015-07-07 11:56:26 -07001482
John Porto4a566862016-01-04 09:33:41 -08001483 private:
1484 InstX86Sub(Cfg *Func, Variable *Dest, Operand *Source)
1485 : InstX86BaseBinopGPR<InstX86Base::Sub>(Func, Dest, Source) {}
1486 };
John Porto921856d2015-07-07 11:56:26 -07001487
John Porto4a566862016-01-04 09:33:41 -08001488 class InstX86SubRMW : public InstX86BaseBinopRMW<InstX86Base::SubRMW> {
1489 public:
1490 static InstX86SubRMW *create(Cfg *Func, X86OperandMem *DestSrc0,
1491 Operand *Src1) {
1492 return new (Func->allocate<InstX86SubRMW>())
1493 InstX86SubRMW(Func, DestSrc0, Src1);
1494 }
1495
1496 private:
1497 InstX86SubRMW(Cfg *Func, X86OperandMem *DestSrc0, Operand *Src1)
1498 : InstX86BaseBinopRMW<InstX86Base::SubRMW>(Func, DestSrc0, Src1) {}
1499 };
1500
1501 class InstX86Subps
1502 : public InstX86BaseBinopXmm<InstX86Base::Subps, true,
1503 InstX86Base::SseSuffix::Packed> {
1504 public:
1505 static InstX86Subps *create(Cfg *Func, Variable *Dest, Operand *Source) {
1506 return new (Func->allocate<InstX86Subps>())
1507 InstX86Subps(Func, Dest, Source);
1508 }
1509
1510 private:
1511 InstX86Subps(Cfg *Func, Variable *Dest, Operand *Source)
1512 : InstX86BaseBinopXmm<InstX86Base::Subps, true,
1513 InstX86Base::SseSuffix::Packed>(Func, Dest,
1514 Source) {}
1515 };
1516
1517 class InstX86Subss
1518 : public InstX86BaseBinopXmm<InstX86Base::Subss, false,
1519 InstX86Base::SseSuffix::Scalar> {
1520 public:
1521 static InstX86Subss *create(Cfg *Func, Variable *Dest, Operand *Source) {
1522 return new (Func->allocate<InstX86Subss>())
1523 InstX86Subss(Func, Dest, Source);
1524 }
1525
1526 private:
1527 InstX86Subss(Cfg *Func, Variable *Dest, Operand *Source)
1528 : InstX86BaseBinopXmm<InstX86Base::Subss, false,
1529 InstX86Base::SseSuffix::Scalar>(Func, Dest,
1530 Source) {}
1531 };
1532
1533 class InstX86Sbb : public InstX86BaseBinopGPR<InstX86Base::Sbb> {
1534 public:
1535 static InstX86Sbb *create(Cfg *Func, Variable *Dest, Operand *Source) {
1536 return new (Func->allocate<InstX86Sbb>()) InstX86Sbb(Func, Dest, Source);
1537 }
1538
1539 private:
1540 InstX86Sbb(Cfg *Func, Variable *Dest, Operand *Source)
1541 : InstX86BaseBinopGPR<InstX86Base::Sbb>(Func, Dest, Source) {}
1542 };
1543
1544 class InstX86SbbRMW : public InstX86BaseBinopRMW<InstX86Base::SbbRMW> {
1545 public:
1546 static InstX86SbbRMW *create(Cfg *Func, X86OperandMem *DestSrc0,
1547 Operand *Src1) {
1548 return new (Func->allocate<InstX86SbbRMW>())
1549 InstX86SbbRMW(Func, DestSrc0, Src1);
1550 }
1551
1552 private:
1553 InstX86SbbRMW(Cfg *Func, X86OperandMem *DestSrc0, Operand *Src1)
1554 : InstX86BaseBinopRMW<InstX86Base::SbbRMW>(Func, DestSrc0, Src1) {}
1555 };
1556
1557 class InstX86Psub
1558 : public InstX86BaseBinopXmm<InstX86Base::Psub, true,
1559 InstX86Base::SseSuffix::Integral> {
1560 public:
1561 static InstX86Psub *create(Cfg *Func, Variable *Dest, Operand *Source) {
1562 return new (Func->allocate<InstX86Psub>())
1563 InstX86Psub(Func, Dest, Source);
1564 }
1565
1566 private:
1567 InstX86Psub(Cfg *Func, Variable *Dest, Operand *Source)
1568 : InstX86BaseBinopXmm<InstX86Base::Psub, true,
1569 InstX86Base::SseSuffix::Integral>(Func, Dest,
John Porto921856d2015-07-07 11:56:26 -07001570 Source) {}
John Porto4a566862016-01-04 09:33:41 -08001571 };
John Porto921856d2015-07-07 11:56:26 -07001572
Nicolas Capens67a49b52016-10-26 13:18:35 -04001573 class InstX86Psubs
1574 : public InstX86BaseBinopXmm<InstX86Base::Psubs, true,
1575 InstX86Base::SseSuffix::Integral> {
1576 public:
1577 static InstX86Psubs *create(Cfg *Func, Variable *Dest, Operand *Source) {
1578 return new (Func->allocate<InstX86Psubs>())
1579 InstX86Psubs(Func, Dest, Source);
1580 }
1581
1582 private:
1583 InstX86Psubs(Cfg *Func, Variable *Dest, Operand *Source)
1584 : InstX86BaseBinopXmm<InstX86Base::Psubs, true,
1585 InstX86Base::SseSuffix::Integral>(Func, Dest,
1586 Source) {}
1587 };
1588
1589 class InstX86Psubus
1590 : public InstX86BaseBinopXmm<InstX86Base::Psubus, true,
1591 InstX86Base::SseSuffix::Integral> {
1592 public:
1593 static InstX86Psubus *create(Cfg *Func, Variable *Dest, Operand *Source) {
1594 return new (Func->allocate<InstX86Psubus>())
1595 InstX86Psubus(Func, Dest, Source);
1596 }
1597
1598 private:
1599 InstX86Psubus(Cfg *Func, Variable *Dest, Operand *Source)
1600 : InstX86BaseBinopXmm<InstX86Base::Psubus, true,
1601 InstX86Base::SseSuffix::Integral>(Func, Dest,
1602 Source) {}
1603 };
1604
John Porto4a566862016-01-04 09:33:41 -08001605 class InstX86And : public InstX86BaseBinopGPR<InstX86Base::And> {
1606 public:
1607 static InstX86And *create(Cfg *Func, Variable *Dest, Operand *Source) {
1608 return new (Func->allocate<InstX86And>()) InstX86And(Func, Dest, Source);
1609 }
John Porto921856d2015-07-07 11:56:26 -07001610
John Porto4a566862016-01-04 09:33:41 -08001611 private:
1612 InstX86And(Cfg *Func, Variable *Dest, Operand *Source)
1613 : InstX86BaseBinopGPR<InstX86Base::And>(Func, Dest, Source) {}
1614 };
1615
1616 class InstX86Andnps
1617 : public InstX86BaseBinopXmm<InstX86Base::Andnps, true,
1618 InstX86Base::SseSuffix::Packed> {
1619 public:
1620 static InstX86Andnps *create(Cfg *Func, Variable *Dest, Operand *Source) {
1621 return new (Func->allocate<InstX86Andnps>())
1622 InstX86Andnps(Func, Dest, Source);
1623 }
1624
1625 private:
1626 InstX86Andnps(Cfg *Func, Variable *Dest, Operand *Source)
1627 : InstX86BaseBinopXmm<InstX86Base::Andnps, true,
1628 InstX86Base::SseSuffix::Packed>(Func, Dest,
1629 Source) {}
1630 };
1631
1632 class InstX86Andps
1633 : public InstX86BaseBinopXmm<InstX86Base::Andps, true,
1634 InstX86Base::SseSuffix::Packed> {
1635 public:
1636 static InstX86Andps *create(Cfg *Func, Variable *Dest, Operand *Source) {
1637 return new (Func->allocate<InstX86Andps>())
1638 InstX86Andps(Func, Dest, Source);
1639 }
1640
1641 private:
1642 InstX86Andps(Cfg *Func, Variable *Dest, Operand *Source)
1643 : InstX86BaseBinopXmm<InstX86Base::Andps, true,
1644 InstX86Base::SseSuffix::Packed>(Func, Dest,
1645 Source) {}
1646 };
1647
1648 class InstX86AndRMW : public InstX86BaseBinopRMW<InstX86Base::AndRMW> {
1649 public:
1650 static InstX86AndRMW *create(Cfg *Func, X86OperandMem *DestSrc0,
1651 Operand *Src1) {
1652 return new (Func->allocate<InstX86AndRMW>())
1653 InstX86AndRMW(Func, DestSrc0, Src1);
1654 }
1655
1656 private:
1657 InstX86AndRMW(Cfg *Func, X86OperandMem *DestSrc0, Operand *Src1)
1658 : InstX86BaseBinopRMW<InstX86Base::AndRMW>(Func, DestSrc0, Src1) {}
1659 };
1660
1661 class InstX86Pand : public InstX86BaseBinopXmm<InstX86Base::Pand, false,
1662 InstX86Base::SseSuffix::None> {
1663 public:
1664 static InstX86Pand *create(Cfg *Func, Variable *Dest, Operand *Source) {
1665 return new (Func->allocate<InstX86Pand>())
1666 InstX86Pand(Func, Dest, Source);
1667 }
1668
1669 private:
1670 InstX86Pand(Cfg *Func, Variable *Dest, Operand *Source)
1671 : InstX86BaseBinopXmm<InstX86Base::Pand, false,
1672 InstX86Base::SseSuffix::None>(Func, Dest,
1673 Source) {}
1674 };
1675
1676 class InstX86Pandn
1677 : public InstX86BaseBinopXmm<InstX86Base::Pandn, false,
1678 InstX86Base::SseSuffix::None> {
1679 public:
1680 static InstX86Pandn *create(Cfg *Func, Variable *Dest, Operand *Source) {
1681 return new (Func->allocate<InstX86Pandn>())
1682 InstX86Pandn(Func, Dest, Source);
1683 }
1684
1685 private:
1686 InstX86Pandn(Cfg *Func, Variable *Dest, Operand *Source)
1687 : InstX86BaseBinopXmm<InstX86Base::Pandn, false,
1688 InstX86Base::SseSuffix::None>(Func, Dest,
1689 Source) {}
1690 };
1691
1692 class InstX86Maxss
1693 : public InstX86BaseBinopXmm<InstX86Base::Maxss, true,
1694 InstX86Base::SseSuffix::Scalar> {
1695 public:
1696 static InstX86Maxss *create(Cfg *Func, Variable *Dest, Operand *Source) {
1697 return new (Func->allocate<InstX86Maxss>())
1698 InstX86Maxss(Func, Dest, Source);
1699 }
1700
1701 private:
1702 InstX86Maxss(Cfg *Func, Variable *Dest, Operand *Source)
1703 : InstX86BaseBinopXmm<InstX86Base::Maxss, true,
1704 InstX86Base::SseSuffix::Scalar>(Func, Dest,
1705 Source) {}
1706 };
1707
1708 class InstX86Minss
1709 : public InstX86BaseBinopXmm<InstX86Base::Minss, true,
1710 InstX86Base::SseSuffix::Scalar> {
1711 public:
1712 static InstX86Minss *create(Cfg *Func, Variable *Dest, Operand *Source) {
1713 return new (Func->allocate<InstX86Minss>())
1714 InstX86Minss(Func, Dest, Source);
1715 }
1716
1717 private:
1718 InstX86Minss(Cfg *Func, Variable *Dest, Operand *Source)
1719 : InstX86BaseBinopXmm<InstX86Base::Minss, true,
1720 InstX86Base::SseSuffix::Scalar>(Func, Dest,
1721 Source) {}
1722 };
1723
Nicolas Capenseb568f52017-02-13 09:49:43 -05001724 class InstX86Maxps
1725 : public InstX86BaseBinopXmm<InstX86Base::Maxps, true,
1726 InstX86Base::SseSuffix::None> {
1727 public:
1728 static InstX86Maxps *create(Cfg *Func, Variable *Dest, Operand *Source) {
1729 return new (Func->allocate<InstX86Maxps>())
1730 InstX86Maxps(Func, Dest, Source);
1731 }
1732
1733 private:
1734 InstX86Maxps(Cfg *Func, Variable *Dest, Operand *Source)
1735 : InstX86BaseBinopXmm<InstX86Base::Maxps, true,
1736 InstX86Base::SseSuffix::None>(Func, Dest,
1737 Source) {}
1738 };
1739
1740 class InstX86Minps
1741 : public InstX86BaseBinopXmm<InstX86Base::Minps, true,
1742 InstX86Base::SseSuffix::None> {
1743 public:
1744 static InstX86Minps *create(Cfg *Func, Variable *Dest, Operand *Source) {
1745 return new (Func->allocate<InstX86Minps>())
1746 InstX86Minps(Func, Dest, Source);
1747 }
1748
1749 private:
1750 InstX86Minps(Cfg *Func, Variable *Dest, Operand *Source)
1751 : InstX86BaseBinopXmm<InstX86Base::Minps, true,
1752 InstX86Base::SseSuffix::None>(Func, Dest,
1753 Source) {}
1754 };
1755
John Porto4a566862016-01-04 09:33:41 -08001756 class InstX86Or : public InstX86BaseBinopGPR<InstX86Base::Or> {
1757 public:
1758 static InstX86Or *create(Cfg *Func, Variable *Dest, Operand *Source) {
1759 return new (Func->allocate<InstX86Or>()) InstX86Or(Func, Dest, Source);
1760 }
1761
1762 private:
1763 InstX86Or(Cfg *Func, Variable *Dest, Operand *Source)
1764 : InstX86BaseBinopGPR<InstX86Base::Or>(Func, Dest, Source) {}
1765 };
1766
1767 class InstX86Orps
1768 : public InstX86BaseBinopXmm<InstX86Base::Orps, true,
1769 InstX86Base::SseSuffix::Packed> {
1770 public:
1771 static InstX86Orps *create(Cfg *Func, Variable *Dest, Operand *Source) {
1772 return new (Func->allocate<InstX86Orps>())
1773 InstX86Orps(Func, Dest, Source);
1774 }
1775
1776 private:
1777 InstX86Orps(Cfg *Func, Variable *Dest, Operand *Source)
1778 : InstX86BaseBinopXmm<InstX86Base::Orps, true,
1779 InstX86Base::SseSuffix::Packed>(Func, Dest,
1780 Source) {}
1781 };
1782
1783 class InstX86OrRMW : public InstX86BaseBinopRMW<InstX86Base::OrRMW> {
1784 public:
1785 static InstX86OrRMW *create(Cfg *Func, X86OperandMem *DestSrc0,
1786 Operand *Src1) {
1787 return new (Func->allocate<InstX86OrRMW>())
1788 InstX86OrRMW(Func, DestSrc0, Src1);
1789 }
1790
1791 private:
1792 InstX86OrRMW(Cfg *Func, X86OperandMem *DestSrc0, Operand *Src1)
1793 : InstX86BaseBinopRMW<InstX86Base::OrRMW>(Func, DestSrc0, Src1) {}
1794 };
1795
1796 class InstX86Por : public InstX86BaseBinopXmm<InstX86Base::Por, false,
1797 InstX86Base::SseSuffix::None> {
1798 public:
1799 static InstX86Por *create(Cfg *Func, Variable *Dest, Operand *Source) {
1800 return new (Func->allocate<InstX86Por>()) InstX86Por(Func, Dest, Source);
1801 }
1802
1803 private:
1804 InstX86Por(Cfg *Func, Variable *Dest, Operand *Source)
1805 : InstX86BaseBinopXmm<InstX86Base::Por, false,
1806 InstX86Base::SseSuffix::None>(Func, Dest,
1807 Source) {}
1808 };
1809
1810 class InstX86Xor : public InstX86BaseBinopGPR<InstX86Base::Xor> {
1811 public:
1812 static InstX86Xor *create(Cfg *Func, Variable *Dest, Operand *Source) {
1813 return new (Func->allocate<InstX86Xor>()) InstX86Xor(Func, Dest, Source);
1814 }
1815
1816 private:
1817 InstX86Xor(Cfg *Func, Variable *Dest, Operand *Source)
1818 : InstX86BaseBinopGPR<InstX86Base::Xor>(Func, Dest, Source) {}
1819 };
1820
1821 class InstX86Xorps
1822 : public InstX86BaseBinopXmm<InstX86Base::Xorps, true,
1823 InstX86Base::SseSuffix::Packed> {
1824 public:
1825 static InstX86Xorps *create(Cfg *Func, Variable *Dest, Operand *Source) {
1826 return new (Func->allocate<InstX86Xorps>())
1827 InstX86Xorps(Func, Dest, Source);
1828 }
1829
1830 private:
1831 InstX86Xorps(Cfg *Func, Variable *Dest, Operand *Source)
1832 : InstX86BaseBinopXmm<InstX86Base::Xorps, true,
1833 InstX86Base::SseSuffix::Packed>(Func, Dest,
1834 Source) {}
1835 };
1836
1837 class InstX86XorRMW : public InstX86BaseBinopRMW<InstX86Base::XorRMW> {
1838 public:
1839 static InstX86XorRMW *create(Cfg *Func, X86OperandMem *DestSrc0,
1840 Operand *Src1) {
1841 return new (Func->allocate<InstX86XorRMW>())
1842 InstX86XorRMW(Func, DestSrc0, Src1);
1843 }
1844
1845 private:
1846 InstX86XorRMW(Cfg *Func, X86OperandMem *DestSrc0, Operand *Src1)
1847 : InstX86BaseBinopRMW<InstX86Base::XorRMW>(Func, DestSrc0, Src1) {}
1848 };
1849
1850 class InstX86Pxor : public InstX86BaseBinopXmm<InstX86Base::Pxor, false,
1851 InstX86Base::SseSuffix::None> {
1852 public:
1853 static InstX86Pxor *create(Cfg *Func, Variable *Dest, Operand *Source) {
1854 return new (Func->allocate<InstX86Pxor>())
1855 InstX86Pxor(Func, Dest, Source);
1856 }
1857
1858 private:
1859 InstX86Pxor(Cfg *Func, Variable *Dest, Operand *Source)
1860 : InstX86BaseBinopXmm<InstX86Base::Pxor, false,
1861 InstX86Base::SseSuffix::None>(Func, Dest,
1862 Source) {}
1863 };
1864
1865 class InstX86Imul : public InstX86BaseBinopGPR<InstX86Base::Imul> {
1866 public:
1867 static InstX86Imul *create(Cfg *Func, Variable *Dest, Operand *Source) {
1868 return new (Func->allocate<InstX86Imul>())
1869 InstX86Imul(Func, Dest, Source);
1870 }
1871
1872 void emit(const Cfg *Func) const override;
1873 void emitIAS(const Cfg *Func) const override;
1874
1875 private:
1876 InstX86Imul(Cfg *Func, Variable *Dest, Operand *Source)
1877 : InstX86BaseBinopGPR<InstX86Base::Imul>(Func, Dest, Source) {}
1878 };
1879
1880 class InstX86ImulImm
1881 : public InstX86BaseThreeAddressop<InstX86Base::ImulImm> {
1882 public:
1883 static InstX86ImulImm *create(Cfg *Func, Variable *Dest, Operand *Source0,
1884 Operand *Source1) {
1885 return new (Func->allocate<InstX86ImulImm>())
1886 InstX86ImulImm(Func, Dest, Source0, Source1);
1887 }
1888
1889 void emit(const Cfg *Func) const override;
1890 void emitIAS(const Cfg *Func) const override;
1891
1892 private:
1893 InstX86ImulImm(Cfg *Func, Variable *Dest, Operand *Source0,
1894 Operand *Source1)
1895 : InstX86BaseThreeAddressop<InstX86Base::ImulImm>(Func, Dest, Source0,
1896 Source1) {}
1897 };
1898
1899 class InstX86Mulps
1900 : public InstX86BaseBinopXmm<InstX86Base::Mulps, true,
1901 InstX86Base::SseSuffix::Packed> {
1902 public:
1903 static InstX86Mulps *create(Cfg *Func, Variable *Dest, Operand *Source) {
1904 return new (Func->allocate<InstX86Mulps>())
1905 InstX86Mulps(Func, Dest, Source);
1906 }
1907
1908 private:
1909 InstX86Mulps(Cfg *Func, Variable *Dest, Operand *Source)
1910 : InstX86BaseBinopXmm<InstX86Base::Mulps, true,
1911 InstX86Base::SseSuffix::Packed>(Func, Dest,
1912 Source) {}
1913 };
1914
1915 class InstX86Mulss
1916 : public InstX86BaseBinopXmm<InstX86Base::Mulss, false,
1917 InstX86Base::SseSuffix::Scalar> {
1918 public:
1919 static InstX86Mulss *create(Cfg *Func, Variable *Dest, Operand *Source) {
1920 return new (Func->allocate<InstX86Mulss>())
1921 InstX86Mulss(Func, Dest, Source);
1922 }
1923
1924 private:
1925 InstX86Mulss(Cfg *Func, Variable *Dest, Operand *Source)
1926 : InstX86BaseBinopXmm<InstX86Base::Mulss, false,
1927 InstX86Base::SseSuffix::Scalar>(Func, Dest,
1928 Source) {}
1929 };
1930
1931 class InstX86Pmull
1932 : public InstX86BaseBinopXmm<InstX86Base::Pmull, true,
1933 InstX86Base::SseSuffix::Integral> {
1934 public:
1935 static InstX86Pmull *create(Cfg *Func, Variable *Dest, Operand *Source) {
1936 bool TypesAreValid =
1937 Dest->getType() == IceType_v4i32 || Dest->getType() == IceType_v8i16;
1938 auto *Target = InstX86Base::getTarget(Func);
1939 bool InstructionSetIsValid =
1940 Dest->getType() == IceType_v8i16 ||
1941 Target->getInstructionSet() >= Traits::SSE4_1;
1942 (void)TypesAreValid;
1943 (void)InstructionSetIsValid;
1944 assert(TypesAreValid);
1945 assert(InstructionSetIsValid);
1946 return new (Func->allocate<InstX86Pmull>())
1947 InstX86Pmull(Func, Dest, Source);
1948 }
1949
1950 private:
1951 InstX86Pmull(Cfg *Func, Variable *Dest, Operand *Source)
1952 : InstX86BaseBinopXmm<InstX86Base::Pmull, true,
1953 InstX86Base::SseSuffix::Integral>(Func, Dest,
John Porto921856d2015-07-07 11:56:26 -07001954 Source) {}
John Porto4a566862016-01-04 09:33:41 -08001955 };
John Porto921856d2015-07-07 11:56:26 -07001956
Nicolas Capens13cde0f2016-10-26 10:36:11 -04001957 class InstX86Pmulhw
1958 : public InstX86BaseBinopXmm<InstX86Base::Pmulhw, false,
1959 InstX86Base::SseSuffix::None> {
1960 public:
1961 static InstX86Pmulhw *create(Cfg *Func, Variable *Dest, Operand *Source) {
1962 assert(Dest->getType() == IceType_v8i16 &&
1963 Source->getType() == IceType_v8i16);
1964 return new (Func->allocate<InstX86Pmulhw>())
1965 InstX86Pmulhw(Func, Dest, Source);
1966 }
1967
1968 private:
1969 InstX86Pmulhw(Cfg *Func, Variable *Dest, Operand *Source)
1970 : InstX86BaseBinopXmm<InstX86Base::Pmulhw, false,
1971 InstX86Base::SseSuffix::None>(Func, Dest,
1972 Source) {}
1973 };
1974
1975 class InstX86Pmulhuw
1976 : public InstX86BaseBinopXmm<InstX86Base::Pmulhuw, false,
1977 InstX86Base::SseSuffix::None> {
1978 public:
1979 static InstX86Pmulhuw *create(Cfg *Func, Variable *Dest, Operand *Source) {
1980 assert(Dest->getType() == IceType_v8i16 &&
1981 Source->getType() == IceType_v8i16);
1982 return new (Func->allocate<InstX86Pmulhuw>())
1983 InstX86Pmulhuw(Func, Dest, Source);
1984 }
1985
1986 private:
1987 InstX86Pmulhuw(Cfg *Func, Variable *Dest, Operand *Source)
1988 : InstX86BaseBinopXmm<InstX86Base::Pmulhuw, false,
1989 InstX86Base::SseSuffix::None>(Func, Dest,
1990 Source) {}
1991 };
1992
1993 class InstX86Pmaddwd
1994 : public InstX86BaseBinopXmm<InstX86Base::Pmaddwd, false,
1995 InstX86Base::SseSuffix::None> {
1996 public:
1997 static InstX86Pmaddwd *create(Cfg *Func, Variable *Dest, Operand *Source) {
1998 assert(Dest->getType() == IceType_v8i16 &&
1999 Source->getType() == IceType_v8i16);
2000 return new (Func->allocate<InstX86Pmaddwd>())
2001 InstX86Pmaddwd(Func, Dest, Source);
2002 }
2003
2004 private:
2005 InstX86Pmaddwd(Cfg *Func, Variable *Dest, Operand *Source)
2006 : InstX86BaseBinopXmm<InstX86Base::Pmaddwd, false,
2007 InstX86Base::SseSuffix::None>(Func, Dest,
2008 Source) {}
2009 };
2010
John Porto4a566862016-01-04 09:33:41 -08002011 class InstX86Pmuludq
2012 : public InstX86BaseBinopXmm<InstX86Base::Pmuludq, false,
2013 InstX86Base::SseSuffix::None> {
2014 public:
2015 static InstX86Pmuludq *create(Cfg *Func, Variable *Dest, Operand *Source) {
2016 assert(Dest->getType() == IceType_v4i32 &&
2017 Source->getType() == IceType_v4i32);
2018 return new (Func->allocate<InstX86Pmuludq>())
2019 InstX86Pmuludq(Func, Dest, Source);
2020 }
John Porto921856d2015-07-07 11:56:26 -07002021
John Porto4a566862016-01-04 09:33:41 -08002022 private:
2023 InstX86Pmuludq(Cfg *Func, Variable *Dest, Operand *Source)
2024 : InstX86BaseBinopXmm<InstX86Base::Pmuludq, false,
2025 InstX86Base::SseSuffix::None>(Func, Dest,
2026 Source) {}
2027 };
John Porto921856d2015-07-07 11:56:26 -07002028
John Porto4a566862016-01-04 09:33:41 -08002029 class InstX86Divps
2030 : public InstX86BaseBinopXmm<InstX86Base::Divps, true,
2031 InstX86Base::SseSuffix::Packed> {
2032 public:
2033 static InstX86Divps *create(Cfg *Func, Variable *Dest, Operand *Source) {
2034 return new (Func->allocate<InstX86Divps>())
2035 InstX86Divps(Func, Dest, Source);
2036 }
John Porto921856d2015-07-07 11:56:26 -07002037
John Porto4a566862016-01-04 09:33:41 -08002038 private:
2039 InstX86Divps(Cfg *Func, Variable *Dest, Operand *Source)
2040 : InstX86BaseBinopXmm<InstX86Base::Divps, true,
2041 InstX86Base::SseSuffix::Packed>(Func, Dest,
2042 Source) {}
2043 };
John Porto921856d2015-07-07 11:56:26 -07002044
John Porto4a566862016-01-04 09:33:41 -08002045 class InstX86Divss
2046 : public InstX86BaseBinopXmm<InstX86Base::Divss, false,
2047 InstX86Base::SseSuffix::Scalar> {
2048 public:
2049 static InstX86Divss *create(Cfg *Func, Variable *Dest, Operand *Source) {
2050 return new (Func->allocate<InstX86Divss>())
2051 InstX86Divss(Func, Dest, Source);
2052 }
John Porto921856d2015-07-07 11:56:26 -07002053
John Porto4a566862016-01-04 09:33:41 -08002054 private:
2055 InstX86Divss(Cfg *Func, Variable *Dest, Operand *Source)
2056 : InstX86BaseBinopXmm<InstX86Base::Divss, false,
2057 InstX86Base::SseSuffix::Scalar>(Func, Dest,
2058 Source) {}
2059 };
2060
2061 class InstX86Rol : public InstX86BaseBinopGPRShift<InstX86Base::Rol> {
2062 public:
2063 static InstX86Rol *create(Cfg *Func, Variable *Dest, Operand *Source) {
2064 return new (Func->allocate<InstX86Rol>()) InstX86Rol(Func, Dest, Source);
2065 }
2066
2067 private:
2068 InstX86Rol(Cfg *Func, Variable *Dest, Operand *Source)
2069 : InstX86BaseBinopGPRShift<InstX86Base::Rol>(Func, Dest, Source) {}
2070 };
2071
2072 class InstX86Shl : public InstX86BaseBinopGPRShift<InstX86Base::Shl> {
2073 public:
2074 static InstX86Shl *create(Cfg *Func, Variable *Dest, Operand *Source) {
2075 return new (Func->allocate<InstX86Shl>()) InstX86Shl(Func, Dest, Source);
2076 }
2077
2078 private:
2079 InstX86Shl(Cfg *Func, Variable *Dest, Operand *Source)
2080 : InstX86BaseBinopGPRShift<InstX86Base::Shl>(Func, Dest, Source) {}
2081 };
2082
2083 class InstX86Psll : public InstX86BaseBinopXmmShift<InstX86Base::Psll> {
2084 public:
2085 static InstX86Psll *create(Cfg *Func, Variable *Dest, Operand *Source) {
2086 assert(
2087 Dest->getType() == IceType_v8i16 || Dest->getType() == IceType_v8i1 ||
2088 Dest->getType() == IceType_v4i32 || Dest->getType() == IceType_v4i1);
2089 return new (Func->allocate<InstX86Psll>())
2090 InstX86Psll(Func, Dest, Source);
2091 }
2092
2093 private:
2094 InstX86Psll(Cfg *Func, Variable *Dest, Operand *Source)
2095 : InstX86BaseBinopXmmShift<InstX86Base::Psll>(Func, Dest, Source) {}
2096 };
2097
2098 class InstX86Psrl : public InstX86BaseBinopXmmShift<InstX86Base::Psrl, true> {
2099 public:
2100 static InstX86Psrl *create(Cfg *Func, Variable *Dest, Operand *Source) {
2101 return new (Func->allocate<InstX86Psrl>())
2102 InstX86Psrl(Func, Dest, Source);
2103 }
2104
2105 private:
2106 InstX86Psrl(Cfg *Func, Variable *Dest, Operand *Source)
2107 : InstX86BaseBinopXmmShift<InstX86Base::Psrl, true>(Func, Dest,
2108 Source) {}
2109 };
2110
2111 class InstX86Shr : public InstX86BaseBinopGPRShift<InstX86Base::Shr> {
2112 public:
2113 static InstX86Shr *create(Cfg *Func, Variable *Dest, Operand *Source) {
2114 return new (Func->allocate<InstX86Shr>()) InstX86Shr(Func, Dest, Source);
2115 }
2116
2117 private:
2118 InstX86Shr(Cfg *Func, Variable *Dest, Operand *Source)
2119 : InstX86BaseBinopGPRShift<InstX86Base::Shr>(Func, Dest, Source) {}
2120 };
2121
2122 class InstX86Sar : public InstX86BaseBinopGPRShift<InstX86Base::Sar> {
2123 public:
2124 static InstX86Sar *create(Cfg *Func, Variable *Dest, Operand *Source) {
2125 return new (Func->allocate<InstX86Sar>()) InstX86Sar(Func, Dest, Source);
2126 }
2127
2128 private:
2129 InstX86Sar(Cfg *Func, Variable *Dest, Operand *Source)
2130 : InstX86BaseBinopGPRShift<InstX86Base::Sar>(Func, Dest, Source) {}
2131 };
2132
2133 class InstX86Psra : public InstX86BaseBinopXmmShift<InstX86Base::Psra> {
2134 public:
2135 static InstX86Psra *create(Cfg *Func, Variable *Dest, Operand *Source) {
2136 assert(
2137 Dest->getType() == IceType_v8i16 || Dest->getType() == IceType_v8i1 ||
2138 Dest->getType() == IceType_v4i32 || Dest->getType() == IceType_v4i1);
2139 return new (Func->allocate<InstX86Psra>())
2140 InstX86Psra(Func, Dest, Source);
2141 }
2142
2143 private:
2144 InstX86Psra(Cfg *Func, Variable *Dest, Operand *Source)
2145 : InstX86BaseBinopXmmShift<InstX86Base::Psra>(Func, Dest, Source) {}
2146 };
2147
2148 class InstX86Pcmpeq
2149 : public InstX86BaseBinopXmm<InstX86Base::Pcmpeq, true,
2150 InstX86Base::SseSuffix::Integral> {
2151 public:
David Sehrb19d39c2016-01-13 14:17:37 -08002152 static InstX86Pcmpeq *create(Cfg *Func, Variable *Dest, Operand *Source,
2153 Type ArithmeticTypeOverride = IceType_void) {
2154 const Type Ty = ArithmeticTypeOverride == IceType_void
2155 ? Dest->getType()
2156 : ArithmeticTypeOverride;
2157 (void)Ty;
2158 assert((Ty != IceType_f64 && Ty != IceType_i64) ||
2159 InstX86Base::getTarget(Func)->getInstructionSet() >=
2160 Traits::SSE4_1);
John Porto4a566862016-01-04 09:33:41 -08002161 return new (Func->allocate<InstX86Pcmpeq>())
David Sehrb19d39c2016-01-13 14:17:37 -08002162 InstX86Pcmpeq(Func, Dest, Source, ArithmeticTypeOverride);
John Porto4a566862016-01-04 09:33:41 -08002163 }
2164
2165 private:
David Sehrb19d39c2016-01-13 14:17:37 -08002166 InstX86Pcmpeq(Cfg *Func, Variable *Dest, Operand *Source,
2167 Type ArithmeticTypeOverride)
John Porto4a566862016-01-04 09:33:41 -08002168 : InstX86BaseBinopXmm<InstX86Base::Pcmpeq, true,
David Sehrb19d39c2016-01-13 14:17:37 -08002169 InstX86Base::SseSuffix::Integral>(
2170 Func, Dest, Source, ArithmeticTypeOverride) {}
John Porto4a566862016-01-04 09:33:41 -08002171 };
John Porto921856d2015-07-07 11:56:26 -07002172
John Porto4a566862016-01-04 09:33:41 -08002173 class InstX86Pcmpgt
2174 : public InstX86BaseBinopXmm<InstX86Base::Pcmpgt, true,
2175 InstX86Base::SseSuffix::Integral> {
2176 public:
2177 static InstX86Pcmpgt *create(Cfg *Func, Variable *Dest, Operand *Source) {
David Sehrb19d39c2016-01-13 14:17:37 -08002178 assert(Dest->getType() != IceType_f64 ||
2179 InstX86Base::getTarget(Func)->getInstructionSet() >=
2180 Traits::SSE4_1);
John Porto4a566862016-01-04 09:33:41 -08002181 return new (Func->allocate<InstX86Pcmpgt>())
2182 InstX86Pcmpgt(Func, Dest, Source);
2183 }
John Porto921856d2015-07-07 11:56:26 -07002184
John Porto4a566862016-01-04 09:33:41 -08002185 private:
2186 InstX86Pcmpgt(Cfg *Func, Variable *Dest, Operand *Source)
2187 : InstX86BaseBinopXmm<InstX86Base::Pcmpgt, true,
2188 InstX86Base::SseSuffix::Integral>(Func, Dest,
John Porto921856d2015-07-07 11:56:26 -07002189 Source) {}
John Porto4a566862016-01-04 09:33:41 -08002190 };
John Porto921856d2015-07-07 11:56:26 -07002191
John Porto4a566862016-01-04 09:33:41 -08002192 /// movss is only a binary operation when the source and dest operands are
2193 /// both registers (the high bits of dest are left untouched). In other cases,
2194 /// it behaves like a copy (mov-like) operation (and the high bits of dest are
2195 /// cleared). InstX86Movss will assert that both its source and dest operands
2196 /// are registers, so the lowering code should use _mov instead of _movss in
2197 /// cases where a copy operation is intended.
2198 class InstX86MovssRegs
2199 : public InstX86BaseBinopXmm<InstX86Base::MovssRegs, false,
2200 InstX86Base::SseSuffix::None> {
2201 public:
2202 static InstX86MovssRegs *create(Cfg *Func, Variable *Dest,
2203 Operand *Source) {
2204 return new (Func->allocate<InstX86MovssRegs>())
2205 InstX86MovssRegs(Func, Dest, Source);
2206 }
John Porto921856d2015-07-07 11:56:26 -07002207
John Porto4a566862016-01-04 09:33:41 -08002208 void emitIAS(const Cfg *Func) const override;
John Porto921856d2015-07-07 11:56:26 -07002209
John Porto4a566862016-01-04 09:33:41 -08002210 private:
2211 InstX86MovssRegs(Cfg *Func, Variable *Dest, Operand *Source)
2212 : InstX86BaseBinopXmm<InstX86Base::MovssRegs, false,
2213 InstX86Base::SseSuffix::None>(Func, Dest,
2214 Source) {}
2215 };
John Porto921856d2015-07-07 11:56:26 -07002216
John Porto4a566862016-01-04 09:33:41 -08002217 class InstX86Idiv : public InstX86BaseTernop<InstX86Base::Idiv> {
2218 public:
2219 static InstX86Idiv *create(Cfg *Func, Variable *Dest, Operand *Source1,
John Porto921856d2015-07-07 11:56:26 -07002220 Operand *Source2) {
John Porto4a566862016-01-04 09:33:41 -08002221 return new (Func->allocate<InstX86Idiv>())
2222 InstX86Idiv(Func, Dest, Source1, Source2);
2223 }
John Porto921856d2015-07-07 11:56:26 -07002224
John Porto4a566862016-01-04 09:33:41 -08002225 void emit(const Cfg *Func) const override;
2226 void emitIAS(const Cfg *Func) const override;
John Porto921856d2015-07-07 11:56:26 -07002227
John Porto4a566862016-01-04 09:33:41 -08002228 private:
2229 InstX86Idiv(Cfg *Func, Variable *Dest, Operand *Source1, Operand *Source2)
2230 : InstX86BaseTernop<InstX86Base::Idiv>(Func, Dest, Source1, Source2) {}
2231 };
John Porto921856d2015-07-07 11:56:26 -07002232
John Porto4a566862016-01-04 09:33:41 -08002233 class InstX86Div : public InstX86BaseTernop<InstX86Base::Div> {
2234 public:
2235 static InstX86Div *create(Cfg *Func, Variable *Dest, Operand *Source1,
2236 Operand *Source2) {
2237 return new (Func->allocate<InstX86Div>())
2238 InstX86Div(Func, Dest, Source1, Source2);
2239 }
2240
2241 void emit(const Cfg *Func) const override;
2242 void emitIAS(const Cfg *Func) const override;
2243
2244 private:
2245 InstX86Div(Cfg *Func, Variable *Dest, Operand *Source1, Operand *Source2)
2246 : InstX86BaseTernop<InstX86Base::Div>(Func, Dest, Source1, Source2) {}
2247 };
2248
2249 class InstX86Insertps : public InstX86BaseTernop<InstX86Base::Insertps> {
2250 public:
2251 static InstX86Insertps *create(Cfg *Func, Variable *Dest, Operand *Source1,
2252 Operand *Source2) {
2253 return new (Func->allocate<InstX86Insertps>())
2254 InstX86Insertps(Func, Dest, Source1, Source2);
2255 }
2256
2257 void emitIAS(const Cfg *Func) const override;
2258
2259 private:
2260 InstX86Insertps(Cfg *Func, Variable *Dest, Operand *Source1,
2261 Operand *Source2)
2262 : InstX86BaseTernop<InstX86Base::Insertps>(Func, Dest, Source1,
2263 Source2) {}
2264 };
2265
2266 class InstX86Pinsr : public InstX86BaseTernop<InstX86Base::Pinsr> {
2267 public:
2268 static InstX86Pinsr *create(Cfg *Func, Variable *Dest, Operand *Source1,
2269 Operand *Source2) {
2270 // pinsrb and pinsrd are SSE4.1 instructions.
2271 assert(
2272 Dest->getType() == IceType_v8i16 || Dest->getType() == IceType_v8i1 ||
2273 InstX86Base::getTarget(Func)->getInstructionSet() >= Traits::SSE4_1);
2274 return new (Func->allocate<InstX86Pinsr>())
2275 InstX86Pinsr(Func, Dest, Source1, Source2);
2276 }
2277
2278 void emit(const Cfg *Func) const override;
2279 void emitIAS(const Cfg *Func) const override;
2280
2281 private:
2282 InstX86Pinsr(Cfg *Func, Variable *Dest, Operand *Source1, Operand *Source2)
2283 : InstX86BaseTernop<InstX86Base::Pinsr>(Func, Dest, Source1, Source2) {}
2284 };
2285
2286 class InstX86Shufps : public InstX86BaseTernop<InstX86Base::Shufps> {
2287 public:
2288 static InstX86Shufps *create(Cfg *Func, Variable *Dest, Operand *Source1,
John Porto921856d2015-07-07 11:56:26 -07002289 Operand *Source2) {
John Porto4a566862016-01-04 09:33:41 -08002290 return new (Func->allocate<InstX86Shufps>())
2291 InstX86Shufps(Func, Dest, Source1, Source2);
2292 }
John Porto921856d2015-07-07 11:56:26 -07002293
John Porto4a566862016-01-04 09:33:41 -08002294 void emitIAS(const Cfg *Func) const override;
John Porto921856d2015-07-07 11:56:26 -07002295
John Porto4a566862016-01-04 09:33:41 -08002296 private:
2297 InstX86Shufps(Cfg *Func, Variable *Dest, Operand *Source1, Operand *Source2)
2298 : InstX86BaseTernop<InstX86Base::Shufps>(Func, Dest, Source1, Source2) {
2299 }
2300 };
John Porto921856d2015-07-07 11:56:26 -07002301
John Porto4a566862016-01-04 09:33:41 -08002302 class InstX86Blendvps : public InstX86BaseTernop<InstX86Base::Blendvps> {
2303 public:
2304 static InstX86Blendvps *create(Cfg *Func, Variable *Dest, Operand *Source1,
2305 Operand *Source2) {
2306 assert(InstX86Base::getTarget(Func)->getInstructionSet() >=
2307 Traits::SSE4_1);
2308 return new (Func->allocate<InstX86Blendvps>())
2309 InstX86Blendvps(Func, Dest, Source1, Source2);
2310 }
John Porto921856d2015-07-07 11:56:26 -07002311
John Porto4a566862016-01-04 09:33:41 -08002312 void emit(const Cfg *Func) const override;
2313 void emitIAS(const Cfg *Fund) const override;
John Porto921856d2015-07-07 11:56:26 -07002314
John Porto4a566862016-01-04 09:33:41 -08002315 private:
2316 InstX86Blendvps(Cfg *Func, Variable *Dest, Operand *Source1,
2317 Operand *Source2)
2318 : InstX86BaseTernop<InstX86Base::Blendvps>(Func, Dest, Source1,
2319 Source2) {}
2320 };
John Porto921856d2015-07-07 11:56:26 -07002321
John Porto4a566862016-01-04 09:33:41 -08002322 class InstX86Pblendvb : public InstX86BaseTernop<InstX86Base::Pblendvb> {
2323 public:
2324 static InstX86Pblendvb *create(Cfg *Func, Variable *Dest, Operand *Source1,
2325 Operand *Source2) {
2326 assert(InstX86Base::getTarget(Func)->getInstructionSet() >=
2327 Traits::SSE4_1);
2328 return new (Func->allocate<InstX86Pblendvb>())
2329 InstX86Pblendvb(Func, Dest, Source1, Source2);
2330 }
John Porto921856d2015-07-07 11:56:26 -07002331
John Porto4a566862016-01-04 09:33:41 -08002332 void emit(const Cfg *Func) const override;
2333 void emitIAS(const Cfg *Func) const override;
John Porto921856d2015-07-07 11:56:26 -07002334
John Porto4a566862016-01-04 09:33:41 -08002335 private:
2336 InstX86Pblendvb(Cfg *Func, Variable *Dest, Operand *Source1,
2337 Operand *Source2)
2338 : InstX86BaseTernop<InstX86Base::Pblendvb>(Func, Dest, Source1,
2339 Source2) {}
2340 };
John Porto921856d2015-07-07 11:56:26 -07002341
John Porto4a566862016-01-04 09:33:41 -08002342 class InstX86Pextr : public InstX86BaseThreeAddressop<InstX86Base::Pextr> {
2343 public:
2344 static InstX86Pextr *create(Cfg *Func, Variable *Dest, Operand *Source0,
2345 Operand *Source1) {
2346 assert(Source0->getType() == IceType_v8i16 ||
2347 Source0->getType() == IceType_v8i1 ||
2348 InstX86Base::getTarget(Func)->getInstructionSet() >=
2349 Traits::SSE4_1);
2350 return new (Func->allocate<InstX86Pextr>())
2351 InstX86Pextr(Func, Dest, Source0, Source1);
2352 }
John Porto921856d2015-07-07 11:56:26 -07002353
John Porto4a566862016-01-04 09:33:41 -08002354 void emit(const Cfg *Func) const override;
2355 void emitIAS(const Cfg *Func) const override;
John Porto921856d2015-07-07 11:56:26 -07002356
John Porto4a566862016-01-04 09:33:41 -08002357 private:
2358 InstX86Pextr(Cfg *Func, Variable *Dest, Operand *Source0, Operand *Source1)
2359 : InstX86BaseThreeAddressop<InstX86Base::Pextr>(Func, Dest, Source0,
2360 Source1) {}
2361 };
John Porto921856d2015-07-07 11:56:26 -07002362
John Porto4a566862016-01-04 09:33:41 -08002363 class InstX86Pshufd : public InstX86BaseThreeAddressop<InstX86Base::Pshufd> {
2364 public:
2365 static InstX86Pshufd *create(Cfg *Func, Variable *Dest, Operand *Source0,
2366 Operand *Source1) {
2367 return new (Func->allocate<InstX86Pshufd>())
2368 InstX86Pshufd(Func, Dest, Source0, Source1);
2369 }
John Porto921856d2015-07-07 11:56:26 -07002370
John Porto4a566862016-01-04 09:33:41 -08002371 void emitIAS(const Cfg *Func) const override;
John Porto921856d2015-07-07 11:56:26 -07002372
John Porto4a566862016-01-04 09:33:41 -08002373 private:
2374 InstX86Pshufd(Cfg *Func, Variable *Dest, Operand *Source0, Operand *Source1)
2375 : InstX86BaseThreeAddressop<InstX86Base::Pshufd>(Func, Dest, Source0,
2376 Source1) {}
2377 };
John Porto921856d2015-07-07 11:56:26 -07002378
John Porto4a566862016-01-04 09:33:41 -08002379 /// Base class for a lockable x86-32 instruction (emits a locked prefix).
2380 class InstX86BaseLockable : public InstX86Base {
2381 InstX86BaseLockable() = delete;
2382 InstX86BaseLockable(const InstX86BaseLockable &) = delete;
2383 InstX86BaseLockable &operator=(const InstX86BaseLockable &) = delete;
John Porto921856d2015-07-07 11:56:26 -07002384
John Porto4a566862016-01-04 09:33:41 -08002385 protected:
2386 bool Locked;
John Porto921856d2015-07-07 11:56:26 -07002387
John Porto4a566862016-01-04 09:33:41 -08002388 InstX86BaseLockable(Cfg *Func, typename InstX86Base::InstKindX86 Kind,
2389 SizeT Maxsrcs, Variable *Dest, bool Locked)
2390 : InstX86Base(Func, Kind, Maxsrcs, Dest), Locked(Locked) {
2391 // Assume that such instructions are used for Atomics and be careful with
2392 // optimizations.
2393 this->HasSideEffects = Locked;
2394 }
2395 };
John Porto921856d2015-07-07 11:56:26 -07002396
John Porto4a566862016-01-04 09:33:41 -08002397 /// Mul instruction - unsigned multiply.
2398 class InstX86Mul final : public InstX86Base {
2399 InstX86Mul() = delete;
2400 InstX86Mul(const InstX86Mul &) = delete;
2401 InstX86Mul &operator=(const InstX86Mul &) = delete;
John Porto921856d2015-07-07 11:56:26 -07002402
John Porto4a566862016-01-04 09:33:41 -08002403 public:
2404 static InstX86Mul *create(Cfg *Func, Variable *Dest, Variable *Source1,
2405 Operand *Source2) {
2406 return new (Func->allocate<InstX86Mul>())
2407 InstX86Mul(Func, Dest, Source1, Source2);
2408 }
2409 void emit(const Cfg *Func) const override;
2410 void emitIAS(const Cfg *Func) const override;
2411 void dump(const Cfg *Func) const override;
Jim Stichnoth8cfeb692016-02-05 09:50:02 -08002412 static bool classof(const Inst *Instr) {
2413 return InstX86Base::isClassof(Instr, InstX86Base::Mul);
John Porto4a566862016-01-04 09:33:41 -08002414 }
John Porto921856d2015-07-07 11:56:26 -07002415
John Porto4a566862016-01-04 09:33:41 -08002416 private:
2417 InstX86Mul(Cfg *Func, Variable *Dest, Variable *Source1, Operand *Source2);
2418 };
John Porto921856d2015-07-07 11:56:26 -07002419
John Porto4a566862016-01-04 09:33:41 -08002420 /// Shld instruction - shift across a pair of operands.
2421 class InstX86Shld final : public InstX86Base {
2422 InstX86Shld() = delete;
2423 InstX86Shld(const InstX86Shld &) = delete;
2424 InstX86Shld &operator=(const InstX86Shld &) = delete;
John Porto921856d2015-07-07 11:56:26 -07002425
John Porto4a566862016-01-04 09:33:41 -08002426 public:
2427 static InstX86Shld *create(Cfg *Func, Variable *Dest, Variable *Source1,
2428 Operand *Source2) {
2429 return new (Func->allocate<InstX86Shld>())
2430 InstX86Shld(Func, Dest, Source1, Source2);
2431 }
2432 void emit(const Cfg *Func) const override;
2433 void emitIAS(const Cfg *Func) const override;
2434 void dump(const Cfg *Func) const override;
Jim Stichnoth8cfeb692016-02-05 09:50:02 -08002435 static bool classof(const Inst *Instr) {
2436 return InstX86Base::isClassof(Instr, InstX86Base::Shld);
John Porto4a566862016-01-04 09:33:41 -08002437 }
John Porto921856d2015-07-07 11:56:26 -07002438
John Porto4a566862016-01-04 09:33:41 -08002439 private:
2440 InstX86Shld(Cfg *Func, Variable *Dest, Variable *Source1, Operand *Source2);
2441 };
John Porto921856d2015-07-07 11:56:26 -07002442
John Porto4a566862016-01-04 09:33:41 -08002443 /// Shrd instruction - shift across a pair of operands.
2444 class InstX86Shrd final : public InstX86Base {
2445 InstX86Shrd() = delete;
2446 InstX86Shrd(const InstX86Shrd &) = delete;
2447 InstX86Shrd &operator=(const InstX86Shrd &) = delete;
John Porto921856d2015-07-07 11:56:26 -07002448
John Porto4a566862016-01-04 09:33:41 -08002449 public:
2450 static InstX86Shrd *create(Cfg *Func, Variable *Dest, Variable *Source1,
2451 Operand *Source2) {
2452 return new (Func->allocate<InstX86Shrd>())
2453 InstX86Shrd(Func, Dest, Source1, Source2);
2454 }
2455 void emit(const Cfg *Func) const override;
2456 void emitIAS(const Cfg *Func) const override;
2457 void dump(const Cfg *Func) const override;
Jim Stichnoth8cfeb692016-02-05 09:50:02 -08002458 static bool classof(const Inst *Instr) {
2459 return InstX86Base::isClassof(Instr, InstX86Base::Shrd);
John Porto4a566862016-01-04 09:33:41 -08002460 }
John Porto921856d2015-07-07 11:56:26 -07002461
John Porto4a566862016-01-04 09:33:41 -08002462 private:
2463 InstX86Shrd(Cfg *Func, Variable *Dest, Variable *Source1, Operand *Source2);
2464 };
John Porto921856d2015-07-07 11:56:26 -07002465
John Porto4a566862016-01-04 09:33:41 -08002466 /// Conditional move instruction.
2467 class InstX86Cmov final : public InstX86Base {
2468 InstX86Cmov() = delete;
2469 InstX86Cmov(const InstX86Cmov &) = delete;
2470 InstX86Cmov &operator=(const InstX86Cmov &) = delete;
John Porto921856d2015-07-07 11:56:26 -07002471
John Porto4a566862016-01-04 09:33:41 -08002472 public:
2473 static InstX86Cmov *create(Cfg *Func, Variable *Dest, Operand *Source,
2474 BrCond Cond) {
2475 return new (Func->allocate<InstX86Cmov>())
2476 InstX86Cmov(Func, Dest, Source, Cond);
2477 }
2478 void emit(const Cfg *Func) const override;
2479 void emitIAS(const Cfg *Func) const override;
2480 void dump(const Cfg *Func) const override;
Jim Stichnoth8cfeb692016-02-05 09:50:02 -08002481 static bool classof(const Inst *Instr) {
2482 return InstX86Base::isClassof(Instr, InstX86Base::Cmov);
John Porto4a566862016-01-04 09:33:41 -08002483 }
John Porto921856d2015-07-07 11:56:26 -07002484
John Porto4a566862016-01-04 09:33:41 -08002485 private:
2486 InstX86Cmov(Cfg *Func, Variable *Dest, Operand *Source, BrCond Cond);
John Porto921856d2015-07-07 11:56:26 -07002487
John Porto4a566862016-01-04 09:33:41 -08002488 BrCond Condition;
2489 };
John Porto921856d2015-07-07 11:56:26 -07002490
John Porto4a566862016-01-04 09:33:41 -08002491 /// Cmpps instruction - compare packed singled-precision floating point values
2492 class InstX86Cmpps final : public InstX86Base {
2493 InstX86Cmpps() = delete;
2494 InstX86Cmpps(const InstX86Cmpps &) = delete;
2495 InstX86Cmpps &operator=(const InstX86Cmpps &) = delete;
John Porto921856d2015-07-07 11:56:26 -07002496
John Porto4a566862016-01-04 09:33:41 -08002497 public:
2498 static InstX86Cmpps *create(Cfg *Func, Variable *Dest, Operand *Source,
2499 CmppsCond Condition) {
2500 return new (Func->allocate<InstX86Cmpps>())
2501 InstX86Cmpps(Func, Dest, Source, Condition);
2502 }
2503 void emit(const Cfg *Func) const override;
2504 void emitIAS(const Cfg *Func) const override;
2505 void dump(const Cfg *Func) const override;
Jim Stichnoth8cfeb692016-02-05 09:50:02 -08002506 static bool classof(const Inst *Instr) {
2507 return InstX86Base::isClassof(Instr, InstX86Base::Cmpps);
John Porto4a566862016-01-04 09:33:41 -08002508 }
John Porto921856d2015-07-07 11:56:26 -07002509
John Porto4a566862016-01-04 09:33:41 -08002510 private:
2511 InstX86Cmpps(Cfg *Func, Variable *Dest, Operand *Source, CmppsCond Cond);
John Porto921856d2015-07-07 11:56:26 -07002512
John Porto4a566862016-01-04 09:33:41 -08002513 CmppsCond Condition;
2514 };
John Porto921856d2015-07-07 11:56:26 -07002515
John Porto4a566862016-01-04 09:33:41 -08002516 /// Cmpxchg instruction - cmpxchg <dest>, <desired> will compare if <dest>
2517 /// equals eax. If so, the ZF is set and <desired> is stored in <dest>. If
2518 /// not, ZF is cleared and <dest> is copied to eax (or subregister). <dest>
2519 /// can be a register or memory, while <desired> must be a register. It is
2520 /// the user's responsibility to mark eax with a FakeDef.
2521 class InstX86Cmpxchg final : public InstX86BaseLockable {
2522 InstX86Cmpxchg() = delete;
2523 InstX86Cmpxchg(const InstX86Cmpxchg &) = delete;
2524 InstX86Cmpxchg &operator=(const InstX86Cmpxchg &) = delete;
John Porto921856d2015-07-07 11:56:26 -07002525
John Porto4a566862016-01-04 09:33:41 -08002526 public:
2527 static InstX86Cmpxchg *create(Cfg *Func, Operand *DestOrAddr, Variable *Eax,
2528 Variable *Desired, bool Locked) {
2529 return new (Func->allocate<InstX86Cmpxchg>())
2530 InstX86Cmpxchg(Func, DestOrAddr, Eax, Desired, Locked);
2531 }
2532 void emit(const Cfg *Func) const override;
2533 void emitIAS(const Cfg *Func) const override;
2534 void dump(const Cfg *Func) const override;
Jim Stichnoth8cfeb692016-02-05 09:50:02 -08002535 static bool classof(const Inst *Instr) {
2536 return InstX86Base::isClassof(Instr, InstX86Base::Cmpxchg);
John Porto4a566862016-01-04 09:33:41 -08002537 }
John Porto921856d2015-07-07 11:56:26 -07002538
John Porto4a566862016-01-04 09:33:41 -08002539 private:
2540 InstX86Cmpxchg(Cfg *Func, Operand *DestOrAddr, Variable *Eax,
2541 Variable *Desired, bool Locked);
2542 };
John Porto921856d2015-07-07 11:56:26 -07002543
John Porto4a566862016-01-04 09:33:41 -08002544 /// Cmpxchg8b instruction - cmpxchg8b <m64> will compare if <m64> equals
2545 /// edx:eax. If so, the ZF is set and ecx:ebx is stored in <m64>. If not, ZF
2546 /// is cleared and <m64> is copied to edx:eax. The caller is responsible for
2547 /// inserting FakeDefs to mark edx and eax as modified. <m64> must be a memory
2548 /// operand.
2549 class InstX86Cmpxchg8b final : public InstX86BaseLockable {
2550 InstX86Cmpxchg8b() = delete;
2551 InstX86Cmpxchg8b(const InstX86Cmpxchg8b &) = delete;
2552 InstX86Cmpxchg8b &operator=(const InstX86Cmpxchg8b &) = delete;
John Porto921856d2015-07-07 11:56:26 -07002553
John Porto4a566862016-01-04 09:33:41 -08002554 public:
2555 static InstX86Cmpxchg8b *create(Cfg *Func, X86OperandMem *Dest,
2556 Variable *Edx, Variable *Eax, Variable *Ecx,
2557 Variable *Ebx, bool Locked) {
2558 return new (Func->allocate<InstX86Cmpxchg8b>())
2559 InstX86Cmpxchg8b(Func, Dest, Edx, Eax, Ecx, Ebx, Locked);
2560 }
2561 void emit(const Cfg *Func) const override;
2562 void emitIAS(const Cfg *Func) const override;
2563 void dump(const Cfg *Func) const override;
Jim Stichnoth8cfeb692016-02-05 09:50:02 -08002564 static bool classof(const Inst *Instr) {
2565 return InstX86Base::isClassof(Instr, InstX86Base::Cmpxchg8b);
John Porto4a566862016-01-04 09:33:41 -08002566 }
John Porto921856d2015-07-07 11:56:26 -07002567
John Porto4a566862016-01-04 09:33:41 -08002568 private:
2569 InstX86Cmpxchg8b(Cfg *Func, X86OperandMem *Dest, Variable *Edx,
2570 Variable *Eax, Variable *Ecx, Variable *Ebx, bool Locked);
2571 };
John Porto921856d2015-07-07 11:56:26 -07002572
John Porto4a566862016-01-04 09:33:41 -08002573 /// Cvt instruction - wrapper for cvtsX2sY where X and Y are in {s,d,i} as
2574 /// appropriate. s=float, d=double, i=int. X and Y are determined from
2575 /// dest/src types. Sign and zero extension on the integer operand needs to be
2576 /// done separately.
2577 class InstX86Cvt final : public InstX86Base {
2578 InstX86Cvt() = delete;
2579 InstX86Cvt(const InstX86Cvt &) = delete;
2580 InstX86Cvt &operator=(const InstX86Cvt &) = delete;
John Porto921856d2015-07-07 11:56:26 -07002581
John Porto4a566862016-01-04 09:33:41 -08002582 public:
Nicolas Capensdbf81e02017-01-14 12:53:55 -05002583 enum CvtVariant { Si2ss, Tss2si, Ss2si, Float2float, Dq2ps, Tps2dq, Ps2dq };
John Porto4a566862016-01-04 09:33:41 -08002584 static InstX86Cvt *create(Cfg *Func, Variable *Dest, Operand *Source,
2585 CvtVariant Variant) {
2586 return new (Func->allocate<InstX86Cvt>())
2587 InstX86Cvt(Func, Dest, Source, Variant);
2588 }
2589 void emit(const Cfg *Func) const override;
2590 void emitIAS(const Cfg *Func) const override;
2591 void dump(const Cfg *Func) const override;
Jim Stichnoth8cfeb692016-02-05 09:50:02 -08002592 static bool classof(const Inst *Instr) {
2593 return InstX86Base::isClassof(Instr, InstX86Base::Cvt);
John Porto4a566862016-01-04 09:33:41 -08002594 }
2595 bool isTruncating() const { return Variant == Tss2si || Variant == Tps2dq; }
John Porto921856d2015-07-07 11:56:26 -07002596
John Porto4a566862016-01-04 09:33:41 -08002597 private:
2598 CvtVariant Variant;
2599 InstX86Cvt(Cfg *Func, Variable *Dest, Operand *Source, CvtVariant Variant);
2600 };
John Porto921856d2015-07-07 11:56:26 -07002601
Nicolas Capensf0d12c32016-10-27 15:17:41 -04002602 /// Round instruction
2603 class InstX86Round final
2604 : public InstX86BaseThreeAddressop<InstX86Base::Round> {
2605 public:
2606 static InstX86Round *create(Cfg *Func, Variable *Dest, Operand *Source,
2607 Operand *Imm) {
2608 return new (Func->allocate<InstX86Round>())
2609 InstX86Round(Func, Dest, Source, Imm);
2610 }
2611
2612 void emit(const Cfg *Func) const override;
2613 void emitIAS(const Cfg *Func) const override;
2614
2615 private:
2616 InstX86Round(Cfg *Func, Variable *Dest, Operand *Source, Operand *Imm)
2617 : InstX86BaseThreeAddressop<InstX86Base::Round>(Func, Dest, Source,
2618 Imm) {}
2619 };
2620
John Porto4a566862016-01-04 09:33:41 -08002621 /// cmp - Integer compare instruction.
2622 class InstX86Icmp final : public InstX86Base {
2623 InstX86Icmp() = delete;
2624 InstX86Icmp(const InstX86Icmp &) = delete;
2625 InstX86Icmp &operator=(const InstX86Icmp &) = delete;
John Porto921856d2015-07-07 11:56:26 -07002626
John Porto4a566862016-01-04 09:33:41 -08002627 public:
2628 static InstX86Icmp *create(Cfg *Func, Operand *Src1, Operand *Src2) {
2629 return new (Func->allocate<InstX86Icmp>()) InstX86Icmp(Func, Src1, Src2);
2630 }
2631 void emit(const Cfg *Func) const override;
2632 void emitIAS(const Cfg *Func) const override;
2633 void dump(const Cfg *Func) const override;
Jim Stichnoth8cfeb692016-02-05 09:50:02 -08002634 static bool classof(const Inst *Instr) {
2635 return InstX86Base::isClassof(Instr, InstX86Base::Icmp);
John Porto4a566862016-01-04 09:33:41 -08002636 }
John Porto921856d2015-07-07 11:56:26 -07002637
John Porto4a566862016-01-04 09:33:41 -08002638 private:
2639 InstX86Icmp(Cfg *Func, Operand *Src1, Operand *Src2);
2640 };
John Porto921856d2015-07-07 11:56:26 -07002641
John Porto4a566862016-01-04 09:33:41 -08002642 /// ucomiss/ucomisd - floating-point compare instruction.
2643 class InstX86Ucomiss final : public InstX86Base {
2644 InstX86Ucomiss() = delete;
2645 InstX86Ucomiss(const InstX86Ucomiss &) = delete;
2646 InstX86Ucomiss &operator=(const InstX86Ucomiss &) = delete;
John Porto921856d2015-07-07 11:56:26 -07002647
John Porto4a566862016-01-04 09:33:41 -08002648 public:
2649 static InstX86Ucomiss *create(Cfg *Func, Operand *Src1, Operand *Src2) {
2650 return new (Func->allocate<InstX86Ucomiss>())
2651 InstX86Ucomiss(Func, Src1, Src2);
2652 }
2653 void emit(const Cfg *Func) const override;
2654 void emitIAS(const Cfg *Func) const override;
2655 void dump(const Cfg *Func) const override;
Jim Stichnoth8cfeb692016-02-05 09:50:02 -08002656 static bool classof(const Inst *Instr) {
2657 return InstX86Base::isClassof(Instr, InstX86Base::Ucomiss);
John Porto4a566862016-01-04 09:33:41 -08002658 }
John Porto921856d2015-07-07 11:56:26 -07002659
John Porto4a566862016-01-04 09:33:41 -08002660 private:
2661 InstX86Ucomiss(Cfg *Func, Operand *Src1, Operand *Src2);
2662 };
John Porto921856d2015-07-07 11:56:26 -07002663
John Porto4a566862016-01-04 09:33:41 -08002664 /// UD2 instruction.
2665 class InstX86UD2 final : public InstX86Base {
2666 InstX86UD2() = delete;
2667 InstX86UD2(const InstX86UD2 &) = delete;
2668 InstX86UD2 &operator=(const InstX86UD2 &) = delete;
2669
2670 public:
2671 static InstX86UD2 *create(Cfg *Func) {
2672 return new (Func->allocate<InstX86UD2>()) InstX86UD2(Func);
2673 }
2674 void emit(const Cfg *Func) const override;
2675 void emitIAS(const Cfg *Func) const override;
2676 void dump(const Cfg *Func) const override;
Jim Stichnoth8cfeb692016-02-05 09:50:02 -08002677 static bool classof(const Inst *Instr) {
2678 return InstX86Base::isClassof(Instr, InstX86Base::UD2);
John Porto4a566862016-01-04 09:33:41 -08002679 }
2680
2681 private:
2682 explicit InstX86UD2(Cfg *Func);
2683 };
2684
Eric Holk67c7c412016-04-15 13:05:37 -07002685 /// Int3 instruction.
2686 class InstX86Int3 final : public InstX86Base {
2687 InstX86Int3() = delete;
2688 InstX86Int3(const InstX86Int3 &) = delete;
2689 InstX86Int3 &operator=(const InstX86Int3 &) = delete;
2690
2691 public:
2692 static InstX86Int3 *create(Cfg *Func) {
2693 return new (Func->allocate<InstX86Int3>()) InstX86Int3(Func);
2694 }
2695 void emit(const Cfg *Func) const override;
2696 void emitIAS(const Cfg *Func) const override;
2697 void dump(const Cfg *Func) const override;
2698 static bool classof(const Inst *Instr) {
2699 return InstX86Base::isClassof(Instr, InstX86Base::Int3);
2700 }
2701
2702 private:
2703 explicit InstX86Int3(Cfg *Func);
2704 };
2705
John Porto4a566862016-01-04 09:33:41 -08002706 /// Test instruction.
2707 class InstX86Test final : public InstX86Base {
2708 InstX86Test() = delete;
2709 InstX86Test(const InstX86Test &) = delete;
2710 InstX86Test &operator=(const InstX86Test &) = delete;
John Porto921856d2015-07-07 11:56:26 -07002711
John Porto4a566862016-01-04 09:33:41 -08002712 public:
2713 static InstX86Test *create(Cfg *Func, Operand *Source1, Operand *Source2) {
2714 return new (Func->allocate<InstX86Test>())
2715 InstX86Test(Func, Source1, Source2);
2716 }
2717 void emit(const Cfg *Func) const override;
2718 void emitIAS(const Cfg *Func) const override;
2719 void dump(const Cfg *Func) const override;
Jim Stichnoth8cfeb692016-02-05 09:50:02 -08002720 static bool classof(const Inst *Instr) {
2721 return InstX86Base::isClassof(Instr, InstX86Base::Test);
John Porto4a566862016-01-04 09:33:41 -08002722 }
John Porto921856d2015-07-07 11:56:26 -07002723
John Porto4a566862016-01-04 09:33:41 -08002724 private:
2725 InstX86Test(Cfg *Func, Operand *Source1, Operand *Source2);
2726 };
John Porto921856d2015-07-07 11:56:26 -07002727
John Porto4a566862016-01-04 09:33:41 -08002728 /// Mfence instruction.
2729 class InstX86Mfence final : public InstX86Base {
2730 InstX86Mfence() = delete;
2731 InstX86Mfence(const InstX86Mfence &) = delete;
2732 InstX86Mfence &operator=(const InstX86Mfence &) = delete;
John Porto921856d2015-07-07 11:56:26 -07002733
John Porto4a566862016-01-04 09:33:41 -08002734 public:
2735 static InstX86Mfence *create(Cfg *Func) {
2736 return new (Func->allocate<InstX86Mfence>()) InstX86Mfence(Func);
2737 }
2738 void emit(const Cfg *Func) const override;
2739 void emitIAS(const Cfg *Func) const override;
2740 void dump(const Cfg *Func) const override;
Jim Stichnoth8cfeb692016-02-05 09:50:02 -08002741 static bool classof(const Inst *Instr) {
2742 return InstX86Base::isClassof(Instr, InstX86Base::Mfence);
John Porto4a566862016-01-04 09:33:41 -08002743 }
John Porto921856d2015-07-07 11:56:26 -07002744
John Porto4a566862016-01-04 09:33:41 -08002745 private:
2746 explicit InstX86Mfence(Cfg *Func);
2747 };
John Porto921856d2015-07-07 11:56:26 -07002748
John Porto4a566862016-01-04 09:33:41 -08002749 /// This is essentially a "mov" instruction with anX86OperandMem operand
2750 /// instead of Variable as the destination. It's important for liveness that
2751 /// there is no Dest operand.
2752 class InstX86Store final : public InstX86Base {
2753 InstX86Store() = delete;
2754 InstX86Store(const InstX86Store &) = delete;
2755 InstX86Store &operator=(const InstX86Store &) = delete;
John Porto921856d2015-07-07 11:56:26 -07002756
John Porto4a566862016-01-04 09:33:41 -08002757 public:
2758 static InstX86Store *create(Cfg *Func, Operand *Value, X86Operand *Mem) {
2759 return new (Func->allocate<InstX86Store>())
2760 InstX86Store(Func, Value, Mem);
2761 }
2762 void emit(const Cfg *Func) const override;
2763 void emitIAS(const Cfg *Func) const override;
2764 void dump(const Cfg *Func) const override;
Jim Stichnoth8cfeb692016-02-05 09:50:02 -08002765 static bool classof(const Inst *Instr) {
2766 return InstX86Base::isClassof(Instr, InstX86Base::Store);
John Porto4a566862016-01-04 09:33:41 -08002767 }
John Porto921856d2015-07-07 11:56:26 -07002768
John Porto4a566862016-01-04 09:33:41 -08002769 private:
2770 InstX86Store(Cfg *Func, Operand *Value, X86Operand *Mem);
2771 };
John Porto921856d2015-07-07 11:56:26 -07002772
John Porto4a566862016-01-04 09:33:41 -08002773 /// This is essentially a vector "mov" instruction with an typename
2774 /// X86OperandMem operand instead of Variable as the destination. It's
2775 /// important for liveness that there is no Dest operand. The source must be
2776 /// an Xmm register, since Dest is mem.
2777 class InstX86StoreP final : public InstX86Base {
2778 InstX86StoreP() = delete;
2779 InstX86StoreP(const InstX86StoreP &) = delete;
2780 InstX86StoreP &operator=(const InstX86StoreP &) = delete;
John Porto921856d2015-07-07 11:56:26 -07002781
John Porto4a566862016-01-04 09:33:41 -08002782 public:
2783 static InstX86StoreP *create(Cfg *Func, Variable *Value,
2784 X86OperandMem *Mem) {
2785 return new (Func->allocate<InstX86StoreP>())
2786 InstX86StoreP(Func, Value, Mem);
2787 }
2788 void emit(const Cfg *Func) const override;
2789 void emitIAS(const Cfg *Func) const override;
2790 void dump(const Cfg *Func) const override;
Jim Stichnoth8cfeb692016-02-05 09:50:02 -08002791 static bool classof(const Inst *Instr) {
2792 return InstX86Base::isClassof(Instr, InstX86Base::StoreP);
John Porto4a566862016-01-04 09:33:41 -08002793 }
John Porto921856d2015-07-07 11:56:26 -07002794
John Porto4a566862016-01-04 09:33:41 -08002795 private:
2796 InstX86StoreP(Cfg *Func, Variable *Value, X86OperandMem *Mem);
2797 };
John Porto921856d2015-07-07 11:56:26 -07002798
John Porto4a566862016-01-04 09:33:41 -08002799 class InstX86StoreQ final : public InstX86Base {
2800 InstX86StoreQ() = delete;
2801 InstX86StoreQ(const InstX86StoreQ &) = delete;
2802 InstX86StoreQ &operator=(const InstX86StoreQ &) = delete;
John Porto921856d2015-07-07 11:56:26 -07002803
John Porto4a566862016-01-04 09:33:41 -08002804 public:
Nicolas Capensacfb3df2016-10-03 10:46:30 -04002805 static InstX86StoreQ *create(Cfg *Func, Operand *Value,
John Porto4a566862016-01-04 09:33:41 -08002806 X86OperandMem *Mem) {
2807 return new (Func->allocate<InstX86StoreQ>())
2808 InstX86StoreQ(Func, Value, Mem);
2809 }
2810 void emit(const Cfg *Func) const override;
2811 void emitIAS(const Cfg *Func) const override;
2812 void dump(const Cfg *Func) const override;
Jim Stichnoth8cfeb692016-02-05 09:50:02 -08002813 static bool classof(const Inst *Instr) {
2814 return InstX86Base::isClassof(Instr, InstX86Base::StoreQ);
John Porto4a566862016-01-04 09:33:41 -08002815 }
John Porto921856d2015-07-07 11:56:26 -07002816
John Porto4a566862016-01-04 09:33:41 -08002817 private:
Nicolas Capensacfb3df2016-10-03 10:46:30 -04002818 InstX86StoreQ(Cfg *Func, Operand *Value, X86OperandMem *Mem);
2819 };
2820
2821 class InstX86StoreD final : public InstX86Base {
2822 InstX86StoreD() = delete;
2823 InstX86StoreD(const InstX86StoreD &) = delete;
2824 InstX86StoreD &operator=(const InstX86StoreD &) = delete;
2825
2826 public:
2827 static InstX86StoreD *create(Cfg *Func, Operand *Value,
2828 X86OperandMem *Mem) {
2829 return new (Func->allocate<InstX86StoreD>())
2830 InstX86StoreD(Func, Value, Mem);
2831 }
2832 void emit(const Cfg *Func) const override;
2833 void emitIAS(const Cfg *Func) const override;
2834 void dump(const Cfg *Func) const override;
2835 static bool classof(const Inst *Instr) {
2836 return InstX86Base::isClassof(Instr, InstX86Base::StoreQ);
2837 }
2838
2839 private:
2840 InstX86StoreD(Cfg *Func, Operand *Value, X86OperandMem *Mem);
John Porto4a566862016-01-04 09:33:41 -08002841 };
John Porto921856d2015-07-07 11:56:26 -07002842
John Porto4a566862016-01-04 09:33:41 -08002843 /// Nop instructions of varying length
2844 class InstX86Nop final : public InstX86Base {
2845 InstX86Nop() = delete;
2846 InstX86Nop(const InstX86Nop &) = delete;
2847 InstX86Nop &operator=(const InstX86Nop &) = delete;
John Porto921856d2015-07-07 11:56:26 -07002848
John Porto4a566862016-01-04 09:33:41 -08002849 public:
2850 // TODO: Replace with enum.
2851 using NopVariant = unsigned;
John Porto921856d2015-07-07 11:56:26 -07002852
John Porto4a566862016-01-04 09:33:41 -08002853 static InstX86Nop *create(Cfg *Func, NopVariant Variant) {
2854 return new (Func->allocate<InstX86Nop>()) InstX86Nop(Func, Variant);
2855 }
2856 void emit(const Cfg *Func) const override;
2857 void emitIAS(const Cfg *Func) const override;
2858 void dump(const Cfg *Func) const override;
Jim Stichnoth8cfeb692016-02-05 09:50:02 -08002859 static bool classof(const Inst *Instr) {
2860 return InstX86Base::isClassof(Instr, InstX86Base::Nop);
John Porto4a566862016-01-04 09:33:41 -08002861 }
John Porto921856d2015-07-07 11:56:26 -07002862
John Porto4a566862016-01-04 09:33:41 -08002863 private:
Nicolas Capensd7396142016-09-02 10:22:57 -04002864 InstX86Nop(Cfg *Func, NopVariant Length);
John Porto921856d2015-07-07 11:56:26 -07002865
John Porto4a566862016-01-04 09:33:41 -08002866 NopVariant Variant;
2867 };
John Porto921856d2015-07-07 11:56:26 -07002868
John Porto4a566862016-01-04 09:33:41 -08002869 /// Fld - load a value onto the x87 FP stack.
2870 class InstX86Fld final : public InstX86Base {
2871 InstX86Fld() = delete;
2872 InstX86Fld(const InstX86Fld &) = delete;
2873 InstX86Fld &operator=(const InstX86Fld &) = delete;
John Porto921856d2015-07-07 11:56:26 -07002874
John Porto4a566862016-01-04 09:33:41 -08002875 public:
2876 static InstX86Fld *create(Cfg *Func, Operand *Src) {
2877 return new (Func->allocate<InstX86Fld>()) InstX86Fld(Func, Src);
2878 }
2879 void emit(const Cfg *Func) const override;
2880 void emitIAS(const Cfg *Func) const override;
2881 void dump(const Cfg *Func) const override;
Jim Stichnoth8cfeb692016-02-05 09:50:02 -08002882 static bool classof(const Inst *Instr) {
2883 return InstX86Base::isClassof(Instr, InstX86Base::Fld);
John Porto4a566862016-01-04 09:33:41 -08002884 }
John Porto921856d2015-07-07 11:56:26 -07002885
John Porto4a566862016-01-04 09:33:41 -08002886 private:
2887 InstX86Fld(Cfg *Func, Operand *Src);
2888 };
John Porto921856d2015-07-07 11:56:26 -07002889
John Porto4a566862016-01-04 09:33:41 -08002890 /// Fstp - store x87 st(0) into memory and pop st(0).
2891 class InstX86Fstp final : public InstX86Base {
2892 InstX86Fstp() = delete;
2893 InstX86Fstp(const InstX86Fstp &) = delete;
2894 InstX86Fstp &operator=(const InstX86Fstp &) = delete;
John Porto921856d2015-07-07 11:56:26 -07002895
John Porto4a566862016-01-04 09:33:41 -08002896 public:
2897 static InstX86Fstp *create(Cfg *Func, Variable *Dest) {
2898 return new (Func->allocate<InstX86Fstp>()) InstX86Fstp(Func, Dest);
2899 }
2900 void emit(const Cfg *Func) const override;
2901 void emitIAS(const Cfg *Func) const override;
2902 void dump(const Cfg *Func) const override;
Jim Stichnoth8cfeb692016-02-05 09:50:02 -08002903 static bool classof(const Inst *Instr) {
2904 return InstX86Base::isClassof(Instr, InstX86Base::Fstp);
John Porto4a566862016-01-04 09:33:41 -08002905 }
John Porto921856d2015-07-07 11:56:26 -07002906
John Porto4a566862016-01-04 09:33:41 -08002907 private:
2908 InstX86Fstp(Cfg *Func, Variable *Dest);
2909 };
John Porto921856d2015-07-07 11:56:26 -07002910
John Porto4a566862016-01-04 09:33:41 -08002911 class InstX86Pop final : public InstX86Base {
2912 InstX86Pop() = delete;
2913 InstX86Pop(const InstX86Pop &) = delete;
2914 InstX86Pop &operator=(const InstX86Pop &) = delete;
John Porto921856d2015-07-07 11:56:26 -07002915
John Porto4a566862016-01-04 09:33:41 -08002916 public:
2917 static InstX86Pop *create(Cfg *Func, Variable *Dest) {
2918 return new (Func->allocate<InstX86Pop>()) InstX86Pop(Func, Dest);
2919 }
2920 void emit(const Cfg *Func) const override;
2921 void emitIAS(const Cfg *Func) const override;
2922 void dump(const Cfg *Func) const override;
Jim Stichnoth8cfeb692016-02-05 09:50:02 -08002923 static bool classof(const Inst *Instr) {
2924 return InstX86Base::isClassof(Instr, InstX86Base::Pop);
John Porto4a566862016-01-04 09:33:41 -08002925 }
John Porto921856d2015-07-07 11:56:26 -07002926
John Porto4a566862016-01-04 09:33:41 -08002927 private:
2928 InstX86Pop(Cfg *Func, Variable *Dest);
2929 };
John Porto921856d2015-07-07 11:56:26 -07002930
John Porto4a566862016-01-04 09:33:41 -08002931 class InstX86Push final : public InstX86Base {
2932 InstX86Push() = delete;
2933 InstX86Push(const InstX86Push &) = delete;
2934 InstX86Push &operator=(const InstX86Push &) = delete;
John Porto921856d2015-07-07 11:56:26 -07002935
John Porto4a566862016-01-04 09:33:41 -08002936 public:
John Porto56958cb2016-01-14 09:18:18 -08002937 static InstX86Push *create(Cfg *Func, InstX86Label *Label) {
2938 return new (Func->allocate<InstX86Push>()) InstX86Push(Func, Label);
2939 }
2940 static InstX86Push *create(Cfg *Func, Operand *Source) {
John Porto4a566862016-01-04 09:33:41 -08002941 return new (Func->allocate<InstX86Push>()) InstX86Push(Func, Source);
2942 }
2943 void emit(const Cfg *Func) const override;
2944 void emitIAS(const Cfg *Func) const override;
2945 void dump(const Cfg *Func) const override;
Jim Stichnoth8cfeb692016-02-05 09:50:02 -08002946 static bool classof(const Inst *Instr) {
2947 return InstX86Base::isClassof(Instr, InstX86Base::Push);
John Porto4a566862016-01-04 09:33:41 -08002948 }
John Porto921856d2015-07-07 11:56:26 -07002949
John Porto4a566862016-01-04 09:33:41 -08002950 private:
John Porto56958cb2016-01-14 09:18:18 -08002951 InstX86Label *Label = nullptr;
2952
2953 InstX86Push(Cfg *Func, Operand *Source);
2954 InstX86Push(Cfg *Func, InstX86Label *Label);
John Porto4a566862016-01-04 09:33:41 -08002955 };
John Porto921856d2015-07-07 11:56:26 -07002956
John Porto4a566862016-01-04 09:33:41 -08002957 /// Ret instruction. Currently only supports the "ret" version that does not
2958 /// pop arguments. This instruction takes a Source operand (for non-void
2959 /// returning functions) for liveness analysis, though a FakeUse before the
2960 /// ret would do just as well.
2961 class InstX86Ret final : public InstX86Base {
2962 InstX86Ret() = delete;
2963 InstX86Ret(const InstX86Ret &) = delete;
2964 InstX86Ret &operator=(const InstX86Ret &) = delete;
John Porto921856d2015-07-07 11:56:26 -07002965
John Porto4a566862016-01-04 09:33:41 -08002966 public:
2967 static InstX86Ret *create(Cfg *Func, Variable *Source = nullptr) {
2968 return new (Func->allocate<InstX86Ret>()) InstX86Ret(Func, Source);
2969 }
2970 void emit(const Cfg *Func) const override;
2971 void emitIAS(const Cfg *Func) const override;
2972 void dump(const Cfg *Func) const override;
Jim Stichnoth8cfeb692016-02-05 09:50:02 -08002973 static bool classof(const Inst *Instr) {
2974 return InstX86Base::isClassof(Instr, InstX86Base::Ret);
John Porto4a566862016-01-04 09:33:41 -08002975 }
John Porto921856d2015-07-07 11:56:26 -07002976
John Porto4a566862016-01-04 09:33:41 -08002977 private:
2978 InstX86Ret(Cfg *Func, Variable *Source);
2979 };
John Porto921856d2015-07-07 11:56:26 -07002980
John Porto4a566862016-01-04 09:33:41 -08002981 /// Conditional set-byte instruction.
2982 class InstX86Setcc final : public InstX86Base {
2983 InstX86Setcc() = delete;
2984 InstX86Setcc(const InstX86Cmov &) = delete;
2985 InstX86Setcc &operator=(const InstX86Setcc &) = delete;
John Porto921856d2015-07-07 11:56:26 -07002986
John Porto4a566862016-01-04 09:33:41 -08002987 public:
2988 static InstX86Setcc *create(Cfg *Func, Variable *Dest, BrCond Cond) {
2989 return new (Func->allocate<InstX86Setcc>())
2990 InstX86Setcc(Func, Dest, Cond);
2991 }
2992 void emit(const Cfg *Func) const override;
2993 void emitIAS(const Cfg *Func) const override;
2994 void dump(const Cfg *Func) const override;
Jim Stichnoth8cfeb692016-02-05 09:50:02 -08002995 static bool classof(const Inst *Instr) {
2996 return InstX86Base::isClassof(Instr, InstX86Base::Setcc);
John Porto4a566862016-01-04 09:33:41 -08002997 }
John Porto921856d2015-07-07 11:56:26 -07002998
John Porto4a566862016-01-04 09:33:41 -08002999 private:
3000 InstX86Setcc(Cfg *Func, Variable *Dest, BrCond Cond);
John Porto921856d2015-07-07 11:56:26 -07003001
John Porto4a566862016-01-04 09:33:41 -08003002 const BrCond Condition;
3003 };
John Porto921856d2015-07-07 11:56:26 -07003004
John Porto4a566862016-01-04 09:33:41 -08003005 /// Exchanging Add instruction. Exchanges the first operand (destination
3006 /// operand) with the second operand (source operand), then loads the sum of
3007 /// the two values into the destination operand. The destination may be a
3008 /// register or memory, while the source must be a register.
3009 ///
3010 /// Both the dest and source are updated. The caller should then insert a
3011 /// FakeDef to reflect the second udpate.
3012 class InstX86Xadd final : public InstX86BaseLockable {
3013 InstX86Xadd() = delete;
3014 InstX86Xadd(const InstX86Xadd &) = delete;
3015 InstX86Xadd &operator=(const InstX86Xadd &) = delete;
John Porto921856d2015-07-07 11:56:26 -07003016
John Porto4a566862016-01-04 09:33:41 -08003017 public:
3018 static InstX86Xadd *create(Cfg *Func, Operand *Dest, Variable *Source,
3019 bool Locked) {
3020 return new (Func->allocate<InstX86Xadd>())
3021 InstX86Xadd(Func, Dest, Source, Locked);
3022 }
3023 void emit(const Cfg *Func) const override;
3024 void emitIAS(const Cfg *Func) const override;
3025 void dump(const Cfg *Func) const override;
Jim Stichnoth8cfeb692016-02-05 09:50:02 -08003026 static bool classof(const Inst *Instr) {
3027 return InstX86Base::isClassof(Instr, InstX86Base::Xadd);
John Porto4a566862016-01-04 09:33:41 -08003028 }
John Porto921856d2015-07-07 11:56:26 -07003029
John Porto4a566862016-01-04 09:33:41 -08003030 private:
3031 InstX86Xadd(Cfg *Func, Operand *Dest, Variable *Source, bool Locked);
3032 };
John Porto921856d2015-07-07 11:56:26 -07003033
John Porto4a566862016-01-04 09:33:41 -08003034 /// Exchange instruction. Exchanges the first operand (destination operand)
3035 /// with the second operand (source operand). At least one of the operands
3036 /// must be a register (and the other can be reg or mem). Both the Dest and
3037 /// Source are updated. If there is a memory operand, then the instruction is
3038 /// automatically "locked" without the need for a lock prefix.
3039 class InstX86Xchg final : public InstX86Base {
3040 InstX86Xchg() = delete;
3041 InstX86Xchg(const InstX86Xchg &) = delete;
3042 InstX86Xchg &operator=(const InstX86Xchg &) = delete;
John Porto921856d2015-07-07 11:56:26 -07003043
John Porto4a566862016-01-04 09:33:41 -08003044 public:
3045 static InstX86Xchg *create(Cfg *Func, Operand *Dest, Variable *Source) {
3046 return new (Func->allocate<InstX86Xchg>())
3047 InstX86Xchg(Func, Dest, Source);
3048 }
3049 void emit(const Cfg *Func) const override;
3050 void emitIAS(const Cfg *Func) const override;
3051 void dump(const Cfg *Func) const override;
Jim Stichnoth8cfeb692016-02-05 09:50:02 -08003052 static bool classof(const Inst *Instr) {
3053 return InstX86Base::isClassof(Instr, InstX86Base::Xchg);
John Porto4a566862016-01-04 09:33:41 -08003054 }
John Porto921856d2015-07-07 11:56:26 -07003055
John Porto4a566862016-01-04 09:33:41 -08003056 private:
3057 InstX86Xchg(Cfg *Func, Operand *Dest, Variable *Source);
3058 };
John Porto921856d2015-07-07 11:56:26 -07003059
John Porto4a566862016-01-04 09:33:41 -08003060 /// Start marker for the Intel Architecture Code Analyzer. This is not an
3061 /// executable instruction and must only be used for analysis.
3062 class InstX86IacaStart final : public InstX86Base {
3063 InstX86IacaStart() = delete;
3064 InstX86IacaStart(const InstX86IacaStart &) = delete;
3065 InstX86IacaStart &operator=(const InstX86IacaStart &) = delete;
Andrew Scull2c862522015-08-06 08:41:53 -07003066
John Porto4a566862016-01-04 09:33:41 -08003067 public:
3068 static InstX86IacaStart *create(Cfg *Func) {
3069 return new (Func->allocate<InstX86IacaStart>()) InstX86IacaStart(Func);
3070 }
3071 void emit(const Cfg *Func) const override;
3072 void emitIAS(const Cfg *Func) const override;
3073 void dump(const Cfg *Func) const override;
Jim Stichnoth8cfeb692016-02-05 09:50:02 -08003074 static bool classof(const Inst *Instr) {
3075 return InstX86Base::isClassof(Instr, InstX86Base::IacaStart);
John Porto4a566862016-01-04 09:33:41 -08003076 }
Andrew Scull2c862522015-08-06 08:41:53 -07003077
John Porto4a566862016-01-04 09:33:41 -08003078 private:
3079 InstX86IacaStart(Cfg *Func);
3080 };
Andrew Scull2c862522015-08-06 08:41:53 -07003081
John Porto4a566862016-01-04 09:33:41 -08003082 /// End marker for the Intel Architecture Code Analyzer. This is not an
3083 /// executable instruction and must only be used for analysis.
3084 class InstX86IacaEnd final : public InstX86Base {
3085 InstX86IacaEnd() = delete;
3086 InstX86IacaEnd(const InstX86IacaEnd &) = delete;
3087 InstX86IacaEnd &operator=(const InstX86IacaEnd &) = delete;
Andrew Scull2c862522015-08-06 08:41:53 -07003088
John Porto4a566862016-01-04 09:33:41 -08003089 public:
3090 static InstX86IacaEnd *create(Cfg *Func) {
3091 return new (Func->allocate<InstX86IacaEnd>()) InstX86IacaEnd(Func);
3092 }
3093 void emit(const Cfg *Func) const override;
3094 void emitIAS(const Cfg *Func) const override;
3095 void dump(const Cfg *Func) const override;
Jim Stichnoth8cfeb692016-02-05 09:50:02 -08003096 static bool classof(const Inst *Instr) {
3097 return InstX86Base::isClassof(Instr, InstX86Base::IacaEnd);
John Porto4a566862016-01-04 09:33:41 -08003098 }
Andrew Scull2c862522015-08-06 08:41:53 -07003099
John Porto4a566862016-01-04 09:33:41 -08003100 private:
3101 InstX86IacaEnd(Cfg *Func);
3102 };
John Portoae15f0f2016-04-26 04:26:33 -07003103
John Portode29f122016-04-26 19:16:07 -07003104 class InstX86Pshufb
3105 : public InstX86BaseBinopXmm<InstX86Base::Pshufb, false,
3106 InstX86Base::SseSuffix::None> {
3107 public:
3108 static InstX86Pshufb *create(Cfg *Func, Variable *Dest, Operand *Source) {
3109 return new (Func->allocate<InstX86Pshufb>())
3110 InstX86Pshufb(Func, Dest, Source);
3111 }
3112
3113 private:
3114 InstX86Pshufb(Cfg *Func, Variable *Dest, Operand *Source)
3115 : InstX86BaseBinopXmm<InstX86Base::Pshufb, false,
3116 InstX86Base::SseSuffix::None>(Func, Dest,
3117 Source) {}
3118 };
3119
John Portoae15f0f2016-04-26 04:26:33 -07003120 class InstX86Punpckl
3121 : public InstX86BaseBinopXmm<InstX86Base::Punpckl, false,
3122 InstX86Base::SseSuffix::Unpack> {
3123 public:
3124 static InstX86Punpckl *create(Cfg *Func, Variable *Dest, Operand *Source) {
3125 return new (Func->allocate<InstX86Punpckl>())
3126 InstX86Punpckl(Func, Dest, Source);
3127 }
3128
3129 private:
3130 InstX86Punpckl(Cfg *Func, Variable *Dest, Operand *Source)
3131 : InstX86BaseBinopXmm<InstX86Base::Punpckl, false,
3132 InstX86Base::SseSuffix::Unpack>(Func, Dest,
3133 Source) {}
3134 };
3135
Nicolas Capens1448d952016-10-14 16:37:09 -04003136 class InstX86Punpckh
3137 : public InstX86BaseBinopXmm<InstX86Base::Punpckh, false,
3138 InstX86Base::SseSuffix::Unpack> {
3139 public:
3140 static InstX86Punpckh *create(Cfg *Func, Variable *Dest, Operand *Source) {
3141 return new (Func->allocate<InstX86Punpckh>())
3142 InstX86Punpckh(Func, Dest, Source);
3143 }
3144
3145 private:
3146 InstX86Punpckh(Cfg *Func, Variable *Dest, Operand *Source)
3147 : InstX86BaseBinopXmm<InstX86Base::Punpckh, false,
3148 InstX86Base::SseSuffix::Unpack>(Func, Dest,
3149 Source) {}
3150 };
3151
Nicolas Capens7638e272016-10-06 11:33:55 -04003152 class InstX86Packss
3153 : public InstX86BaseBinopXmm<InstX86Base::Packss, false,
3154 InstX86Base::SseSuffix::Pack> {
3155 public:
3156 static InstX86Packss *create(Cfg *Func, Variable *Dest, Operand *Source) {
3157 return new (Func->allocate<InstX86Packss>())
3158 InstX86Packss(Func, Dest, Source);
3159 }
3160
3161 private:
3162 InstX86Packss(Cfg *Func, Variable *Dest, Operand *Source)
3163 : InstX86BaseBinopXmm<InstX86Base::Packss, false,
3164 InstX86Base::SseSuffix::Pack>(Func, Dest,
3165 Source) {}
3166 };
3167
3168 class InstX86Packus
3169 : public InstX86BaseBinopXmm<InstX86Base::Packus, false,
3170 InstX86Base::SseSuffix::Pack> {
3171 public:
3172 static InstX86Packus *create(Cfg *Func, Variable *Dest, Operand *Source) {
3173 return new (Func->allocate<InstX86Packus>())
3174 InstX86Packus(Func, Dest, Source);
3175 }
3176
3177 private:
3178 InstX86Packus(Cfg *Func, Variable *Dest, Operand *Source)
3179 : InstX86BaseBinopXmm<InstX86Base::Packus, false,
3180 InstX86Base::SseSuffix::Pack>(Func, Dest,
3181 Source) {}
3182 };
3183
John Porto4a566862016-01-04 09:33:41 -08003184}; // struct InstImpl
Andrew Scull2c862522015-08-06 08:41:53 -07003185
John Porto921856d2015-07-07 11:56:26 -07003186/// struct Insts is a template that can be used to instantiate all the X86
3187/// instructions for a target with a simple
3188///
John Porto4a566862016-01-04 09:33:41 -08003189/// using Insts = ::Ice::X86NAMESPACE::Insts<TraitsType>;
3190template <typename TraitsType> struct Insts {
Jim Stichnoth8ff4b282016-01-04 15:39:06 -08003191 using GetIP = typename InstImpl<TraitsType>::InstX86GetIP;
John Porto4a566862016-01-04 09:33:41 -08003192 using FakeRMW = typename InstImpl<TraitsType>::InstX86FakeRMW;
3193 using Label = typename InstImpl<TraitsType>::InstX86Label;
John Porto921856d2015-07-07 11:56:26 -07003194
John Porto4a566862016-01-04 09:33:41 -08003195 using Call = typename InstImpl<TraitsType>::InstX86Call;
John Porto921856d2015-07-07 11:56:26 -07003196
John Porto4a566862016-01-04 09:33:41 -08003197 using Br = typename InstImpl<TraitsType>::InstX86Br;
3198 using Jmp = typename InstImpl<TraitsType>::InstX86Jmp;
3199 using Bswap = typename InstImpl<TraitsType>::InstX86Bswap;
3200 using Neg = typename InstImpl<TraitsType>::InstX86Neg;
3201 using Bsf = typename InstImpl<TraitsType>::InstX86Bsf;
3202 using Bsr = typename InstImpl<TraitsType>::InstX86Bsr;
3203 using Lea = typename InstImpl<TraitsType>::InstX86Lea;
3204 using Cbwdq = typename InstImpl<TraitsType>::InstX86Cbwdq;
3205 using Movsx = typename InstImpl<TraitsType>::InstX86Movsx;
3206 using Movzx = typename InstImpl<TraitsType>::InstX86Movzx;
3207 using Movd = typename InstImpl<TraitsType>::InstX86Movd;
Nicolas Capense3cabda2016-10-18 16:27:27 -04003208 using Movmsk = typename InstImpl<TraitsType>::InstX86Movmsk;
Nicolas Capens956cfd62016-10-31 14:28:09 -04003209 using Sqrt = typename InstImpl<TraitsType>::InstX86Sqrt;
John Porto4a566862016-01-04 09:33:41 -08003210 using Mov = typename InstImpl<TraitsType>::InstX86Mov;
3211 using Movp = typename InstImpl<TraitsType>::InstX86Movp;
3212 using Movq = typename InstImpl<TraitsType>::InstX86Movq;
3213 using Add = typename InstImpl<TraitsType>::InstX86Add;
3214 using AddRMW = typename InstImpl<TraitsType>::InstX86AddRMW;
3215 using Addps = typename InstImpl<TraitsType>::InstX86Addps;
3216 using Adc = typename InstImpl<TraitsType>::InstX86Adc;
3217 using AdcRMW = typename InstImpl<TraitsType>::InstX86AdcRMW;
3218 using Addss = typename InstImpl<TraitsType>::InstX86Addss;
3219 using Andnps = typename InstImpl<TraitsType>::InstX86Andnps;
3220 using Andps = typename InstImpl<TraitsType>::InstX86Andps;
3221 using Padd = typename InstImpl<TraitsType>::InstX86Padd;
Nicolas Capens67a49b52016-10-26 13:18:35 -04003222 using Padds = typename InstImpl<TraitsType>::InstX86Padds;
3223 using Paddus = typename InstImpl<TraitsType>::InstX86Paddus;
John Porto4a566862016-01-04 09:33:41 -08003224 using Sub = typename InstImpl<TraitsType>::InstX86Sub;
3225 using SubRMW = typename InstImpl<TraitsType>::InstX86SubRMW;
3226 using Subps = typename InstImpl<TraitsType>::InstX86Subps;
3227 using Subss = typename InstImpl<TraitsType>::InstX86Subss;
3228 using Sbb = typename InstImpl<TraitsType>::InstX86Sbb;
3229 using SbbRMW = typename InstImpl<TraitsType>::InstX86SbbRMW;
3230 using Psub = typename InstImpl<TraitsType>::InstX86Psub;
Nicolas Capens67a49b52016-10-26 13:18:35 -04003231 using Psubs = typename InstImpl<TraitsType>::InstX86Psubs;
3232 using Psubus = typename InstImpl<TraitsType>::InstX86Psubus;
John Porto4a566862016-01-04 09:33:41 -08003233 using And = typename InstImpl<TraitsType>::InstX86And;
3234 using AndRMW = typename InstImpl<TraitsType>::InstX86AndRMW;
3235 using Pand = typename InstImpl<TraitsType>::InstX86Pand;
3236 using Pandn = typename InstImpl<TraitsType>::InstX86Pandn;
3237 using Or = typename InstImpl<TraitsType>::InstX86Or;
3238 using Orps = typename InstImpl<TraitsType>::InstX86Orps;
3239 using OrRMW = typename InstImpl<TraitsType>::InstX86OrRMW;
3240 using Por = typename InstImpl<TraitsType>::InstX86Por;
3241 using Xor = typename InstImpl<TraitsType>::InstX86Xor;
3242 using Xorps = typename InstImpl<TraitsType>::InstX86Xorps;
3243 using XorRMW = typename InstImpl<TraitsType>::InstX86XorRMW;
3244 using Pxor = typename InstImpl<TraitsType>::InstX86Pxor;
3245 using Maxss = typename InstImpl<TraitsType>::InstX86Maxss;
3246 using Minss = typename InstImpl<TraitsType>::InstX86Minss;
Nicolas Capenseb568f52017-02-13 09:49:43 -05003247 using Maxps = typename InstImpl<TraitsType>::InstX86Maxps;
3248 using Minps = typename InstImpl<TraitsType>::InstX86Minps;
John Porto4a566862016-01-04 09:33:41 -08003249 using Imul = typename InstImpl<TraitsType>::InstX86Imul;
3250 using ImulImm = typename InstImpl<TraitsType>::InstX86ImulImm;
3251 using Mulps = typename InstImpl<TraitsType>::InstX86Mulps;
3252 using Mulss = typename InstImpl<TraitsType>::InstX86Mulss;
3253 using Pmull = typename InstImpl<TraitsType>::InstX86Pmull;
Nicolas Capens13cde0f2016-10-26 10:36:11 -04003254 using Pmulhw = typename InstImpl<TraitsType>::InstX86Pmulhw;
3255 using Pmulhuw = typename InstImpl<TraitsType>::InstX86Pmulhuw;
3256 using Pmaddwd = typename InstImpl<TraitsType>::InstX86Pmaddwd;
John Porto4a566862016-01-04 09:33:41 -08003257 using Pmuludq = typename InstImpl<TraitsType>::InstX86Pmuludq;
3258 using Divps = typename InstImpl<TraitsType>::InstX86Divps;
3259 using Divss = typename InstImpl<TraitsType>::InstX86Divss;
3260 using Rol = typename InstImpl<TraitsType>::InstX86Rol;
3261 using Shl = typename InstImpl<TraitsType>::InstX86Shl;
3262 using Psll = typename InstImpl<TraitsType>::InstX86Psll;
3263 using Psrl = typename InstImpl<TraitsType>::InstX86Psrl;
3264 using Shr = typename InstImpl<TraitsType>::InstX86Shr;
3265 using Sar = typename InstImpl<TraitsType>::InstX86Sar;
3266 using Psra = typename InstImpl<TraitsType>::InstX86Psra;
3267 using Pcmpeq = typename InstImpl<TraitsType>::InstX86Pcmpeq;
3268 using Pcmpgt = typename InstImpl<TraitsType>::InstX86Pcmpgt;
3269 using MovssRegs = typename InstImpl<TraitsType>::InstX86MovssRegs;
3270 using Idiv = typename InstImpl<TraitsType>::InstX86Idiv;
3271 using Div = typename InstImpl<TraitsType>::InstX86Div;
3272 using Insertps = typename InstImpl<TraitsType>::InstX86Insertps;
3273 using Pinsr = typename InstImpl<TraitsType>::InstX86Pinsr;
3274 using Shufps = typename InstImpl<TraitsType>::InstX86Shufps;
3275 using Blendvps = typename InstImpl<TraitsType>::InstX86Blendvps;
3276 using Pblendvb = typename InstImpl<TraitsType>::InstX86Pblendvb;
3277 using Pextr = typename InstImpl<TraitsType>::InstX86Pextr;
3278 using Pshufd = typename InstImpl<TraitsType>::InstX86Pshufd;
3279 using Lockable = typename InstImpl<TraitsType>::InstX86BaseLockable;
3280 using Mul = typename InstImpl<TraitsType>::InstX86Mul;
3281 using Shld = typename InstImpl<TraitsType>::InstX86Shld;
3282 using Shrd = typename InstImpl<TraitsType>::InstX86Shrd;
3283 using Cmov = typename InstImpl<TraitsType>::InstX86Cmov;
3284 using Cmpps = typename InstImpl<TraitsType>::InstX86Cmpps;
3285 using Cmpxchg = typename InstImpl<TraitsType>::InstX86Cmpxchg;
3286 using Cmpxchg8b = typename InstImpl<TraitsType>::InstX86Cmpxchg8b;
3287 using Cvt = typename InstImpl<TraitsType>::InstX86Cvt;
Nicolas Capensf0d12c32016-10-27 15:17:41 -04003288 using Round = typename InstImpl<TraitsType>::InstX86Round;
John Porto4a566862016-01-04 09:33:41 -08003289 using Icmp = typename InstImpl<TraitsType>::InstX86Icmp;
3290 using Ucomiss = typename InstImpl<TraitsType>::InstX86Ucomiss;
3291 using UD2 = typename InstImpl<TraitsType>::InstX86UD2;
Eric Holk67c7c412016-04-15 13:05:37 -07003292 using Int3 = typename InstImpl<TraitsType>::InstX86Int3;
John Porto4a566862016-01-04 09:33:41 -08003293 using Test = typename InstImpl<TraitsType>::InstX86Test;
3294 using Mfence = typename InstImpl<TraitsType>::InstX86Mfence;
3295 using Store = typename InstImpl<TraitsType>::InstX86Store;
3296 using StoreP = typename InstImpl<TraitsType>::InstX86StoreP;
3297 using StoreQ = typename InstImpl<TraitsType>::InstX86StoreQ;
Nicolas Capensacfb3df2016-10-03 10:46:30 -04003298 using StoreD = typename InstImpl<TraitsType>::InstX86StoreD;
John Porto4a566862016-01-04 09:33:41 -08003299 using Nop = typename InstImpl<TraitsType>::InstX86Nop;
3300 template <typename T = typename InstImpl<TraitsType>::Traits>
3301 using Fld =
3302 typename std::enable_if<T::UsesX87,
3303 typename InstImpl<TraitsType>::InstX86Fld>::type;
3304 template <typename T = typename InstImpl<TraitsType>::Traits>
3305 using Fstp =
3306 typename std::enable_if<T::UsesX87,
3307 typename InstImpl<TraitsType>::InstX86Fstp>::type;
3308 using Pop = typename InstImpl<TraitsType>::InstX86Pop;
3309 using Push = typename InstImpl<TraitsType>::InstX86Push;
3310 using Ret = typename InstImpl<TraitsType>::InstX86Ret;
3311 using Setcc = typename InstImpl<TraitsType>::InstX86Setcc;
3312 using Xadd = typename InstImpl<TraitsType>::InstX86Xadd;
3313 using Xchg = typename InstImpl<TraitsType>::InstX86Xchg;
Andrew Scull2c862522015-08-06 08:41:53 -07003314
John Porto4a566862016-01-04 09:33:41 -08003315 using IacaStart = typename InstImpl<TraitsType>::InstX86IacaStart;
3316 using IacaEnd = typename InstImpl<TraitsType>::InstX86IacaEnd;
John Portoae15f0f2016-04-26 04:26:33 -07003317
John Portode29f122016-04-26 19:16:07 -07003318 using Pshufb = typename InstImpl<TraitsType>::InstX86Pshufb;
John Portoae15f0f2016-04-26 04:26:33 -07003319 using Punpckl = typename InstImpl<TraitsType>::InstX86Punpckl;
Nicolas Capens1448d952016-10-14 16:37:09 -04003320 using Punpckh = typename InstImpl<TraitsType>::InstX86Punpckh;
Nicolas Capens7638e272016-10-06 11:33:55 -04003321 using Packss = typename InstImpl<TraitsType>::InstX86Packss;
3322 using Packus = typename InstImpl<TraitsType>::InstX86Packus;
John Porto921856d2015-07-07 11:56:26 -07003323};
3324
3325/// X86 Instructions have static data (particularly, opcodes and instruction
3326/// emitters). Each X86 target needs to define all of these, so this macro is
3327/// provided so that, if something changes, then all X86 targets will be updated
3328/// automatically.
John Porto4a566862016-01-04 09:33:41 -08003329#define X86INSTS_DEFINE_STATIC_DATA(X86NAMESPACE, TraitsType) \
John Porto921856d2015-07-07 11:56:26 -07003330 namespace Ice { \
John Porto4a566862016-01-04 09:33:41 -08003331 namespace X86NAMESPACE { \
John Porto921856d2015-07-07 11:56:26 -07003332 /* In-place ops */ \
John Porto4a566862016-01-04 09:33:41 -08003333 template <> \
3334 template <> \
3335 const char *InstImpl<TraitsType>::InstX86Bswap::Base::Opcode = "bswap"; \
3336 template <> \
3337 template <> \
3338 const char *InstImpl<TraitsType>::InstX86Neg::Base::Opcode = "neg"; \
John Porto921856d2015-07-07 11:56:26 -07003339 /* Unary ops */ \
John Porto4a566862016-01-04 09:33:41 -08003340 template <> \
3341 template <> \
3342 const char *InstImpl<TraitsType>::InstX86Bsf::Base::Opcode = "bsf"; \
3343 template <> \
3344 template <> \
3345 const char *InstImpl<TraitsType>::InstX86Bsr::Base::Opcode = "bsr"; \
3346 template <> \
3347 template <> \
3348 const char *InstImpl<TraitsType>::InstX86Lea::Base::Opcode = "lea"; \
3349 template <> \
3350 template <> \
3351 const char *InstImpl<TraitsType>::InstX86Movd::Base::Opcode = "movd"; \
3352 template <> \
3353 template <> \
3354 const char *InstImpl<TraitsType>::InstX86Movsx::Base::Opcode = "movs"; \
3355 template <> \
3356 template <> \
3357 const char *InstImpl<TraitsType>::InstX86Movzx::Base::Opcode = "movz"; \
3358 template <> \
3359 template <> \
Nicolas Capens956cfd62016-10-31 14:28:09 -04003360 const char *InstImpl<TraitsType>::InstX86Sqrt::Base::Opcode = "sqrt"; \
John Porto4a566862016-01-04 09:33:41 -08003361 template <> \
3362 template <> \
3363 const char *InstImpl<TraitsType>::InstX86Cbwdq::Base::Opcode = \
3364 "cbw/cwd/cdq"; \
John Porto921856d2015-07-07 11:56:26 -07003365 /* Mov-like ops */ \
John Porto4a566862016-01-04 09:33:41 -08003366 template <> \
3367 template <> \
3368 const char *InstImpl<TraitsType>::InstX86Mov::Base::Opcode = "mov"; \
3369 template <> \
3370 template <> \
3371 const char *InstImpl<TraitsType>::InstX86Movp::Base::Opcode = "movups"; \
3372 template <> \
3373 template <> \
3374 const char *InstImpl<TraitsType>::InstX86Movq::Base::Opcode = "movq"; \
John Porto921856d2015-07-07 11:56:26 -07003375 /* Binary ops */ \
John Porto4a566862016-01-04 09:33:41 -08003376 template <> \
3377 template <> \
3378 const char *InstImpl<TraitsType>::InstX86Add::Base::Opcode = "add"; \
3379 template <> \
3380 template <> \
3381 const char *InstImpl<TraitsType>::InstX86AddRMW::Base::Opcode = "add"; \
3382 template <> \
3383 template <> \
3384 const char *InstImpl<TraitsType>::InstX86Addps::Base::Opcode = "add"; \
3385 template <> \
3386 template <> \
3387 const char *InstImpl<TraitsType>::InstX86Adc::Base::Opcode = "adc"; \
3388 template <> \
3389 template <> \
3390 const char *InstImpl<TraitsType>::InstX86AdcRMW::Base::Opcode = "adc"; \
3391 template <> \
3392 template <> \
3393 const char *InstImpl<TraitsType>::InstX86Addss::Base::Opcode = "add"; \
3394 template <> \
3395 template <> \
3396 const char *InstImpl<TraitsType>::InstX86Andnps::Base::Opcode = "andn"; \
3397 template <> \
3398 template <> \
3399 const char *InstImpl<TraitsType>::InstX86Andps::Base::Opcode = "and"; \
3400 template <> \
3401 template <> \
3402 const char *InstImpl<TraitsType>::InstX86Maxss::Base::Opcode = "max"; \
3403 template <> \
3404 template <> \
3405 const char *InstImpl<TraitsType>::InstX86Minss::Base::Opcode = "min"; \
3406 template <> \
3407 template <> \
Nicolas Capenseb568f52017-02-13 09:49:43 -05003408 const char *InstImpl<TraitsType>::InstX86Maxps::Base::Opcode = "max"; \
3409 template <> \
3410 template <> \
3411 const char *InstImpl<TraitsType>::InstX86Minps::Base::Opcode = "min"; \
3412 template <> \
3413 template <> \
John Porto4a566862016-01-04 09:33:41 -08003414 const char *InstImpl<TraitsType>::InstX86Padd::Base::Opcode = "padd"; \
3415 template <> \
3416 template <> \
Nicolas Capens67a49b52016-10-26 13:18:35 -04003417 const char *InstImpl<TraitsType>::InstX86Padds::Base::Opcode = "padds"; \
3418 template <> \
3419 template <> \
3420 const char *InstImpl<TraitsType>::InstX86Paddus::Base::Opcode = "paddus"; \
3421 template <> \
3422 template <> \
John Porto4a566862016-01-04 09:33:41 -08003423 const char *InstImpl<TraitsType>::InstX86Sub::Base::Opcode = "sub"; \
3424 template <> \
3425 template <> \
3426 const char *InstImpl<TraitsType>::InstX86SubRMW::Base::Opcode = "sub"; \
3427 template <> \
3428 template <> \
3429 const char *InstImpl<TraitsType>::InstX86Subps::Base::Opcode = "sub"; \
3430 template <> \
3431 template <> \
3432 const char *InstImpl<TraitsType>::InstX86Subss::Base::Opcode = "sub"; \
3433 template <> \
3434 template <> \
3435 const char *InstImpl<TraitsType>::InstX86Sbb::Base::Opcode = "sbb"; \
3436 template <> \
3437 template <> \
3438 const char *InstImpl<TraitsType>::InstX86SbbRMW::Base::Opcode = "sbb"; \
3439 template <> \
3440 template <> \
3441 const char *InstImpl<TraitsType>::InstX86Psub::Base::Opcode = "psub"; \
3442 template <> \
3443 template <> \
Nicolas Capens67a49b52016-10-26 13:18:35 -04003444 const char *InstImpl<TraitsType>::InstX86Psubs::Base::Opcode = "psubs"; \
3445 template <> \
3446 template <> \
3447 const char *InstImpl<TraitsType>::InstX86Psubus::Base::Opcode = "psubus"; \
3448 template <> \
3449 template <> \
John Porto4a566862016-01-04 09:33:41 -08003450 const char *InstImpl<TraitsType>::InstX86And::Base::Opcode = "and"; \
3451 template <> \
3452 template <> \
3453 const char *InstImpl<TraitsType>::InstX86AndRMW::Base::Opcode = "and"; \
3454 template <> \
3455 template <> \
3456 const char *InstImpl<TraitsType>::InstX86Pand::Base::Opcode = "pand"; \
3457 template <> \
3458 template <> \
3459 const char *InstImpl<TraitsType>::InstX86Pandn::Base::Opcode = "pandn"; \
3460 template <> \
3461 template <> \
3462 const char *InstImpl<TraitsType>::InstX86Or::Base::Opcode = "or"; \
3463 template <> \
3464 template <> \
3465 const char *InstImpl<TraitsType>::InstX86Orps::Base::Opcode = "or"; \
3466 template <> \
3467 template <> \
3468 const char *InstImpl<TraitsType>::InstX86OrRMW::Base::Opcode = "or"; \
3469 template <> \
3470 template <> \
3471 const char *InstImpl<TraitsType>::InstX86Por::Base::Opcode = "por"; \
3472 template <> \
3473 template <> \
3474 const char *InstImpl<TraitsType>::InstX86Xor::Base::Opcode = "xor"; \
3475 template <> \
3476 template <> \
3477 const char *InstImpl<TraitsType>::InstX86Xorps::Base::Opcode = "xor"; \
3478 template <> \
3479 template <> \
3480 const char *InstImpl<TraitsType>::InstX86XorRMW::Base::Opcode = "xor"; \
3481 template <> \
3482 template <> \
3483 const char *InstImpl<TraitsType>::InstX86Pxor::Base::Opcode = "pxor"; \
3484 template <> \
3485 template <> \
3486 const char *InstImpl<TraitsType>::InstX86Imul::Base::Opcode = "imul"; \
3487 template <> \
3488 template <> \
3489 const char *InstImpl<TraitsType>::InstX86ImulImm::Base::Opcode = "imul"; \
3490 template <> \
3491 template <> \
3492 const char *InstImpl<TraitsType>::InstX86Mulps::Base::Opcode = "mul"; \
3493 template <> \
3494 template <> \
3495 const char *InstImpl<TraitsType>::InstX86Mulss::Base::Opcode = "mul"; \
3496 template <> \
3497 template <> \
3498 const char *InstImpl<TraitsType>::InstX86Pmull::Base::Opcode = "pmull"; \
3499 template <> \
3500 template <> \
Nicolas Capens13cde0f2016-10-26 10:36:11 -04003501 const char *InstImpl<TraitsType>::InstX86Pmulhw::Base::Opcode = "pmulhw"; \
3502 template <> \
3503 template <> \
3504 const char *InstImpl<TraitsType>::InstX86Pmulhuw::Base::Opcode = "pmulhuw"; \
3505 template <> \
3506 template <> \
3507 const char *InstImpl<TraitsType>::InstX86Pmaddwd::Base::Opcode = "pmaddwd"; \
3508 template <> \
3509 template <> \
John Porto4a566862016-01-04 09:33:41 -08003510 const char *InstImpl<TraitsType>::InstX86Pmuludq::Base::Opcode = "pmuludq"; \
3511 template <> \
3512 template <> \
3513 const char *InstImpl<TraitsType>::InstX86Div::Base::Opcode = "div"; \
3514 template <> \
3515 template <> \
3516 const char *InstImpl<TraitsType>::InstX86Divps::Base::Opcode = "div"; \
3517 template <> \
3518 template <> \
3519 const char *InstImpl<TraitsType>::InstX86Divss::Base::Opcode = "div"; \
3520 template <> \
3521 template <> \
3522 const char *InstImpl<TraitsType>::InstX86Idiv::Base::Opcode = "idiv"; \
3523 template <> \
3524 template <> \
3525 const char *InstImpl<TraitsType>::InstX86Rol::Base::Opcode = "rol"; \
3526 template <> \
3527 template <> \
3528 const char *InstImpl<TraitsType>::InstX86Shl::Base::Opcode = "shl"; \
3529 template <> \
3530 template <> \
3531 const char *InstImpl<TraitsType>::InstX86Psll::Base::Opcode = "psll"; \
3532 template <> \
3533 template <> \
3534 const char *InstImpl<TraitsType>::InstX86Shr::Base::Opcode = "shr"; \
3535 template <> \
3536 template <> \
3537 const char *InstImpl<TraitsType>::InstX86Sar::Base::Opcode = "sar"; \
3538 template <> \
3539 template <> \
3540 const char *InstImpl<TraitsType>::InstX86Psra::Base::Opcode = "psra"; \
3541 template <> \
3542 template <> \
3543 const char *InstImpl<TraitsType>::InstX86Psrl::Base::Opcode = "psrl"; \
3544 template <> \
3545 template <> \
3546 const char *InstImpl<TraitsType>::InstX86Pcmpeq::Base::Opcode = "pcmpeq"; \
3547 template <> \
3548 template <> \
3549 const char *InstImpl<TraitsType>::InstX86Pcmpgt::Base::Opcode = "pcmpgt"; \
3550 template <> \
3551 template <> \
3552 const char *InstImpl<TraitsType>::InstX86MovssRegs::Base::Opcode = "movss"; \
John Porto921856d2015-07-07 11:56:26 -07003553 /* Ternary ops */ \
John Porto4a566862016-01-04 09:33:41 -08003554 template <> \
3555 template <> \
3556 const char *InstImpl<TraitsType>::InstX86Insertps::Base::Opcode = \
3557 "insertps"; \
3558 template <> \
3559 template <> \
Nicolas Capensf0d12c32016-10-27 15:17:41 -04003560 const char *InstImpl<TraitsType>::InstX86Round::Base::Opcode = "round"; \
3561 template <> \
3562 template <> \
John Porto4a566862016-01-04 09:33:41 -08003563 const char *InstImpl<TraitsType>::InstX86Shufps::Base::Opcode = "shufps"; \
3564 template <> \
3565 template <> \
3566 const char *InstImpl<TraitsType>::InstX86Pinsr::Base::Opcode = "pinsr"; \
3567 template <> \
3568 template <> \
3569 const char *InstImpl<TraitsType>::InstX86Blendvps::Base::Opcode = \
3570 "blendvps"; \
3571 template <> \
3572 template <> \
3573 const char *InstImpl<TraitsType>::InstX86Pblendvb::Base::Opcode = \
3574 "pblendvb"; \
John Porto921856d2015-07-07 11:56:26 -07003575 /* Three address ops */ \
John Porto4a566862016-01-04 09:33:41 -08003576 template <> \
3577 template <> \
3578 const char *InstImpl<TraitsType>::InstX86Pextr::Base::Opcode = "pextr"; \
3579 template <> \
3580 template <> \
3581 const char *InstImpl<TraitsType>::InstX86Pshufd::Base::Opcode = "pshufd"; \
John Portoae15f0f2016-04-26 04:26:33 -07003582 template <> \
3583 template <> \
John Portode29f122016-04-26 19:16:07 -07003584 const char *InstImpl<TraitsType>::InstX86Pshufb::Base::Opcode = "pshufb"; \
3585 template <> \
3586 template <> \
John Portoae15f0f2016-04-26 04:26:33 -07003587 const char *InstImpl<TraitsType>::InstX86Punpckl::Base::Opcode = "punpckl"; \
Nicolas Capens7638e272016-10-06 11:33:55 -04003588 template <> \
3589 template <> \
Nicolas Capens1448d952016-10-14 16:37:09 -04003590 const char *InstImpl<TraitsType>::InstX86Punpckh::Base::Opcode = "punpckh"; \
3591 template <> \
3592 template <> \
Nicolas Capens7638e272016-10-06 11:33:55 -04003593 const char *InstImpl<TraitsType>::InstX86Packss::Base::Opcode = "packss"; \
3594 template <> \
3595 template <> \
3596 const char *InstImpl<TraitsType>::InstX86Packus::Base::Opcode = "packus"; \
John Porto921856d2015-07-07 11:56:26 -07003597 /* Inplace GPR ops */ \
3598 template <> \
John Porto4a566862016-01-04 09:33:41 -08003599 template <> \
3600 const InstImpl<TraitsType>::Assembler::GPREmitterOneOp \
3601 InstImpl<TraitsType>::InstX86Bswap::Base::Emitter = { \
3602 &InstImpl<TraitsType>::Assembler::bswap, \
John Porto921856d2015-07-07 11:56:26 -07003603 nullptr /* only a reg form exists */ \
3604 }; \
3605 template <> \
John Porto4a566862016-01-04 09:33:41 -08003606 template <> \
3607 const InstImpl<TraitsType>::Assembler::GPREmitterOneOp \
3608 InstImpl<TraitsType>::InstX86Neg::Base::Emitter = { \
3609 &InstImpl<TraitsType>::Assembler::neg, \
3610 &InstImpl<TraitsType>::Assembler::neg}; \
John Porto921856d2015-07-07 11:56:26 -07003611 \
3612 /* Unary GPR ops */ \
John Porto4a566862016-01-04 09:33:41 -08003613 template <> \
John Porto921856d2015-07-07 11:56:26 -07003614 template <> /* uses specialized emitter. */ \
John Porto4a566862016-01-04 09:33:41 -08003615 const InstImpl<TraitsType>::Assembler::GPREmitterRegOp \
3616 InstImpl<TraitsType>::InstX86Cbwdq::Base::Emitter = {nullptr, nullptr, \
3617 nullptr}; \
John Porto921856d2015-07-07 11:56:26 -07003618 template <> \
John Porto921856d2015-07-07 11:56:26 -07003619 template <> \
John Porto4a566862016-01-04 09:33:41 -08003620 const InstImpl<TraitsType>::Assembler::GPREmitterRegOp \
3621 InstImpl<TraitsType>::InstX86Bsf::Base::Emitter = { \
3622 &InstImpl<TraitsType>::Assembler::bsf, \
3623 &InstImpl<TraitsType>::Assembler::bsf, nullptr}; \
John Porto921856d2015-07-07 11:56:26 -07003624 template <> \
John Porto4a566862016-01-04 09:33:41 -08003625 template <> \
3626 const InstImpl<TraitsType>::Assembler::GPREmitterRegOp \
3627 InstImpl<TraitsType>::InstX86Bsr::Base::Emitter = { \
3628 &InstImpl<TraitsType>::Assembler::bsr, \
3629 &InstImpl<TraitsType>::Assembler::bsr, nullptr}; \
3630 template <> \
3631 template <> \
3632 const InstImpl<TraitsType>::Assembler::GPREmitterRegOp \
3633 InstImpl<TraitsType>::InstX86Lea::Base::Emitter = { \
John Porto921856d2015-07-07 11:56:26 -07003634 /* reg/reg and reg/imm are illegal */ nullptr, \
John Porto4a566862016-01-04 09:33:41 -08003635 &InstImpl<TraitsType>::Assembler::lea, nullptr}; \
John Porto921856d2015-07-07 11:56:26 -07003636 template <> \
John Porto921856d2015-07-07 11:56:26 -07003637 template <> \
John Porto4a566862016-01-04 09:33:41 -08003638 const InstImpl<TraitsType>::Assembler::GPREmitterRegOp \
3639 InstImpl<TraitsType>::InstX86Movsx::Base::Emitter = { \
3640 &InstImpl<TraitsType>::Assembler::movsx, \
3641 &InstImpl<TraitsType>::Assembler::movsx, nullptr}; \
3642 template <> \
3643 template <> \
3644 const InstImpl<TraitsType>::Assembler::GPREmitterRegOp \
3645 InstImpl<TraitsType>::InstX86Movzx::Base::Emitter = { \
3646 &InstImpl<TraitsType>::Assembler::movzx, \
3647 &InstImpl<TraitsType>::Assembler::movzx, nullptr}; \
John Porto921856d2015-07-07 11:56:26 -07003648 \
3649 /* Unary XMM ops */ \
John Porto921856d2015-07-07 11:56:26 -07003650 template <> \
John Porto4a566862016-01-04 09:33:41 -08003651 template <> /* uses specialized emitter. */ \
3652 const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp \
3653 InstImpl<TraitsType>::InstX86Movd::Base::Emitter = {nullptr, nullptr}; \
3654 template <> \
3655 template <> \
3656 const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp \
Nicolas Capens956cfd62016-10-31 14:28:09 -04003657 InstImpl<TraitsType>::InstX86Sqrt::Base::Emitter = { \
3658 &InstImpl<TraitsType>::Assembler::sqrt, \
3659 &InstImpl<TraitsType>::Assembler::sqrt}; \
John Porto921856d2015-07-07 11:56:26 -07003660 \
3661 /* Binary GPR ops */ \
John Porto4a566862016-01-04 09:33:41 -08003662 template <> \
John Porto921856d2015-07-07 11:56:26 -07003663 template <> /* uses specialized emitter. */ \
John Porto4a566862016-01-04 09:33:41 -08003664 const InstImpl<TraitsType>::Assembler::GPREmitterRegOp \
3665 InstImpl<TraitsType>::InstX86Imul::Base::Emitter = {nullptr, nullptr, \
3666 nullptr}; \
John Porto921856d2015-07-07 11:56:26 -07003667 template <> \
John Porto921856d2015-07-07 11:56:26 -07003668 template <> \
John Porto4a566862016-01-04 09:33:41 -08003669 const InstImpl<TraitsType>::Assembler::GPREmitterRegOp \
3670 InstImpl<TraitsType>::InstX86Add::Base::Emitter = { \
3671 &InstImpl<TraitsType>::Assembler::add, \
3672 &InstImpl<TraitsType>::Assembler::add, \
3673 &InstImpl<TraitsType>::Assembler::add}; \
John Porto921856d2015-07-07 11:56:26 -07003674 template <> \
John Porto921856d2015-07-07 11:56:26 -07003675 template <> \
John Porto4a566862016-01-04 09:33:41 -08003676 const InstImpl<TraitsType>::Assembler::GPREmitterAddrOp \
3677 InstImpl<TraitsType>::InstX86AddRMW::Base::Emitter = { \
3678 &InstImpl<TraitsType>::Assembler::add, \
3679 &InstImpl<TraitsType>::Assembler::add}; \
John Porto921856d2015-07-07 11:56:26 -07003680 template <> \
John Porto921856d2015-07-07 11:56:26 -07003681 template <> \
John Porto4a566862016-01-04 09:33:41 -08003682 const InstImpl<TraitsType>::Assembler::GPREmitterRegOp \
3683 InstImpl<TraitsType>::InstX86Adc::Base::Emitter = { \
3684 &InstImpl<TraitsType>::Assembler::adc, \
3685 &InstImpl<TraitsType>::Assembler::adc, \
3686 &InstImpl<TraitsType>::Assembler::adc}; \
John Porto921856d2015-07-07 11:56:26 -07003687 template <> \
John Porto921856d2015-07-07 11:56:26 -07003688 template <> \
John Porto4a566862016-01-04 09:33:41 -08003689 const InstImpl<TraitsType>::Assembler::GPREmitterAddrOp \
3690 InstImpl<TraitsType>::InstX86AdcRMW::Base::Emitter = { \
3691 &InstImpl<TraitsType>::Assembler::adc, \
3692 &InstImpl<TraitsType>::Assembler::adc}; \
John Porto921856d2015-07-07 11:56:26 -07003693 template <> \
John Porto921856d2015-07-07 11:56:26 -07003694 template <> \
John Porto4a566862016-01-04 09:33:41 -08003695 const InstImpl<TraitsType>::Assembler::GPREmitterRegOp \
3696 InstImpl<TraitsType>::InstX86And::Base::Emitter = { \
3697 &InstImpl<TraitsType>::Assembler::And, \
3698 &InstImpl<TraitsType>::Assembler::And, \
3699 &InstImpl<TraitsType>::Assembler::And}; \
John Porto921856d2015-07-07 11:56:26 -07003700 template <> \
John Porto921856d2015-07-07 11:56:26 -07003701 template <> \
John Porto4a566862016-01-04 09:33:41 -08003702 const InstImpl<TraitsType>::Assembler::GPREmitterAddrOp \
3703 InstImpl<TraitsType>::InstX86AndRMW::Base::Emitter = { \
3704 &InstImpl<TraitsType>::Assembler::And, \
3705 &InstImpl<TraitsType>::Assembler::And}; \
John Porto921856d2015-07-07 11:56:26 -07003706 template <> \
John Porto921856d2015-07-07 11:56:26 -07003707 template <> \
John Porto4a566862016-01-04 09:33:41 -08003708 const InstImpl<TraitsType>::Assembler::GPREmitterRegOp \
3709 InstImpl<TraitsType>::InstX86Or::Base::Emitter = { \
3710 &InstImpl<TraitsType>::Assembler::Or, \
3711 &InstImpl<TraitsType>::Assembler::Or, \
3712 &InstImpl<TraitsType>::Assembler::Or}; \
3713 template <> \
3714 template <> \
3715 const InstImpl<TraitsType>::Assembler::GPREmitterAddrOp \
3716 InstImpl<TraitsType>::InstX86OrRMW::Base::Emitter = { \
3717 &InstImpl<TraitsType>::Assembler::Or, \
3718 &InstImpl<TraitsType>::Assembler::Or}; \
3719 template <> \
3720 template <> \
3721 const InstImpl<TraitsType>::Assembler::GPREmitterRegOp \
3722 InstImpl<TraitsType>::InstX86Sbb::Base::Emitter = { \
3723 &InstImpl<TraitsType>::Assembler::sbb, \
3724 &InstImpl<TraitsType>::Assembler::sbb, \
3725 &InstImpl<TraitsType>::Assembler::sbb}; \
3726 template <> \
3727 template <> \
3728 const InstImpl<TraitsType>::Assembler::GPREmitterAddrOp \
3729 InstImpl<TraitsType>::InstX86SbbRMW::Base::Emitter = { \
3730 &InstImpl<TraitsType>::Assembler::sbb, \
3731 &InstImpl<TraitsType>::Assembler::sbb}; \
3732 template <> \
3733 template <> \
3734 const InstImpl<TraitsType>::Assembler::GPREmitterRegOp \
3735 InstImpl<TraitsType>::InstX86Sub::Base::Emitter = { \
3736 &InstImpl<TraitsType>::Assembler::sub, \
3737 &InstImpl<TraitsType>::Assembler::sub, \
3738 &InstImpl<TraitsType>::Assembler::sub}; \
3739 template <> \
3740 template <> \
3741 const InstImpl<TraitsType>::Assembler::GPREmitterAddrOp \
3742 InstImpl<TraitsType>::InstX86SubRMW::Base::Emitter = { \
3743 &InstImpl<TraitsType>::Assembler::sub, \
3744 &InstImpl<TraitsType>::Assembler::sub}; \
3745 template <> \
3746 template <> \
3747 const InstImpl<TraitsType>::Assembler::GPREmitterRegOp \
3748 InstImpl<TraitsType>::InstX86Xor::Base::Emitter = { \
3749 &InstImpl<TraitsType>::Assembler::Xor, \
3750 &InstImpl<TraitsType>::Assembler::Xor, \
3751 &InstImpl<TraitsType>::Assembler::Xor}; \
3752 template <> \
3753 template <> \
3754 const InstImpl<TraitsType>::Assembler::GPREmitterAddrOp \
3755 InstImpl<TraitsType>::InstX86XorRMW::Base::Emitter = { \
3756 &InstImpl<TraitsType>::Assembler::Xor, \
3757 &InstImpl<TraitsType>::Assembler::Xor}; \
John Porto921856d2015-07-07 11:56:26 -07003758 \
3759 /* Binary Shift GPR ops */ \
3760 template <> \
John Porto921856d2015-07-07 11:56:26 -07003761 template <> \
John Porto4a566862016-01-04 09:33:41 -08003762 const InstImpl<TraitsType>::Assembler::GPREmitterShiftOp \
3763 InstImpl<TraitsType>::InstX86Rol::Base::Emitter = { \
3764 &InstImpl<TraitsType>::Assembler::rol, \
3765 &InstImpl<TraitsType>::Assembler::rol}; \
John Porto921856d2015-07-07 11:56:26 -07003766 template <> \
John Porto921856d2015-07-07 11:56:26 -07003767 template <> \
John Porto4a566862016-01-04 09:33:41 -08003768 const InstImpl<TraitsType>::Assembler::GPREmitterShiftOp \
3769 InstImpl<TraitsType>::InstX86Sar::Base::Emitter = { \
3770 &InstImpl<TraitsType>::Assembler::sar, \
3771 &InstImpl<TraitsType>::Assembler::sar}; \
3772 template <> \
3773 template <> \
3774 const InstImpl<TraitsType>::Assembler::GPREmitterShiftOp \
3775 InstImpl<TraitsType>::InstX86Shl::Base::Emitter = { \
3776 &InstImpl<TraitsType>::Assembler::shl, \
3777 &InstImpl<TraitsType>::Assembler::shl}; \
3778 template <> \
3779 template <> \
3780 const InstImpl<TraitsType>::Assembler::GPREmitterShiftOp \
3781 InstImpl<TraitsType>::InstX86Shr::Base::Emitter = { \
3782 &InstImpl<TraitsType>::Assembler::shr, \
3783 &InstImpl<TraitsType>::Assembler::shr}; \
John Porto921856d2015-07-07 11:56:26 -07003784 \
3785 /* Binary XMM ops */ \
John Porto4a566862016-01-04 09:33:41 -08003786 template <> \
John Porto921856d2015-07-07 11:56:26 -07003787 template <> /* uses specialized emitter. */ \
John Porto4a566862016-01-04 09:33:41 -08003788 const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp \
3789 InstImpl<TraitsType>::InstX86MovssRegs::Base::Emitter = {nullptr, \
3790 nullptr}; \
John Porto921856d2015-07-07 11:56:26 -07003791 template <> \
John Porto921856d2015-07-07 11:56:26 -07003792 template <> \
John Porto4a566862016-01-04 09:33:41 -08003793 const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp \
3794 InstImpl<TraitsType>::InstX86Addss::Base::Emitter = { \
3795 &InstImpl<TraitsType>::Assembler::addss, \
3796 &InstImpl<TraitsType>::Assembler::addss}; \
John Porto921856d2015-07-07 11:56:26 -07003797 template <> \
John Porto921856d2015-07-07 11:56:26 -07003798 template <> \
John Porto4a566862016-01-04 09:33:41 -08003799 const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp \
3800 InstImpl<TraitsType>::InstX86Addps::Base::Emitter = { \
3801 &InstImpl<TraitsType>::Assembler::addps, \
3802 &InstImpl<TraitsType>::Assembler::addps}; \
John Porto921856d2015-07-07 11:56:26 -07003803 template <> \
John Porto921856d2015-07-07 11:56:26 -07003804 template <> \
John Porto4a566862016-01-04 09:33:41 -08003805 const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp \
3806 InstImpl<TraitsType>::InstX86Divss::Base::Emitter = { \
3807 &InstImpl<TraitsType>::Assembler::divss, \
3808 &InstImpl<TraitsType>::Assembler::divss}; \
John Porto921856d2015-07-07 11:56:26 -07003809 template <> \
John Porto921856d2015-07-07 11:56:26 -07003810 template <> \
John Porto4a566862016-01-04 09:33:41 -08003811 const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp \
3812 InstImpl<TraitsType>::InstX86Divps::Base::Emitter = { \
3813 &InstImpl<TraitsType>::Assembler::divps, \
3814 &InstImpl<TraitsType>::Assembler::divps}; \
John Porto921856d2015-07-07 11:56:26 -07003815 template <> \
John Porto921856d2015-07-07 11:56:26 -07003816 template <> \
John Porto4a566862016-01-04 09:33:41 -08003817 const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp \
3818 InstImpl<TraitsType>::InstX86Mulss::Base::Emitter = { \
3819 &InstImpl<TraitsType>::Assembler::mulss, \
3820 &InstImpl<TraitsType>::Assembler::mulss}; \
John Porto921856d2015-07-07 11:56:26 -07003821 template <> \
John Porto921856d2015-07-07 11:56:26 -07003822 template <> \
John Porto4a566862016-01-04 09:33:41 -08003823 const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp \
3824 InstImpl<TraitsType>::InstX86Mulps::Base::Emitter = { \
3825 &InstImpl<TraitsType>::Assembler::mulps, \
3826 &InstImpl<TraitsType>::Assembler::mulps}; \
John Porto921856d2015-07-07 11:56:26 -07003827 template <> \
John Porto921856d2015-07-07 11:56:26 -07003828 template <> \
John Porto4a566862016-01-04 09:33:41 -08003829 const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp \
3830 InstImpl<TraitsType>::InstX86Padd::Base::Emitter = { \
3831 &InstImpl<TraitsType>::Assembler::padd, \
3832 &InstImpl<TraitsType>::Assembler::padd}; \
John Porto921856d2015-07-07 11:56:26 -07003833 template <> \
John Porto921856d2015-07-07 11:56:26 -07003834 template <> \
John Porto4a566862016-01-04 09:33:41 -08003835 const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp \
Nicolas Capens67a49b52016-10-26 13:18:35 -04003836 InstImpl<TraitsType>::InstX86Padds::Base::Emitter = { \
3837 &InstImpl<TraitsType>::Assembler::padds, \
3838 &InstImpl<TraitsType>::Assembler::padds}; \
3839 template <> \
3840 template <> \
3841 const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp \
3842 InstImpl<TraitsType>::InstX86Paddus::Base::Emitter = { \
3843 &InstImpl<TraitsType>::Assembler::paddus, \
3844 &InstImpl<TraitsType>::Assembler::paddus}; \
3845 template <> \
3846 template <> \
3847 const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp \
John Porto4a566862016-01-04 09:33:41 -08003848 InstImpl<TraitsType>::InstX86Pand::Base::Emitter = { \
3849 &InstImpl<TraitsType>::Assembler::pand, \
3850 &InstImpl<TraitsType>::Assembler::pand}; \
John Porto921856d2015-07-07 11:56:26 -07003851 template <> \
John Porto921856d2015-07-07 11:56:26 -07003852 template <> \
John Porto4a566862016-01-04 09:33:41 -08003853 const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp \
3854 InstImpl<TraitsType>::InstX86Pandn::Base::Emitter = { \
3855 &InstImpl<TraitsType>::Assembler::pandn, \
3856 &InstImpl<TraitsType>::Assembler::pandn}; \
David Sehre3984282015-12-15 17:34:55 -08003857 template <> \
David Sehre3984282015-12-15 17:34:55 -08003858 template <> \
John Porto4a566862016-01-04 09:33:41 -08003859 const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp \
3860 InstImpl<TraitsType>::InstX86Pcmpeq::Base::Emitter = { \
3861 &InstImpl<TraitsType>::Assembler::pcmpeq, \
3862 &InstImpl<TraitsType>::Assembler::pcmpeq}; \
David Sehre3984282015-12-15 17:34:55 -08003863 template <> \
David Sehre3984282015-12-15 17:34:55 -08003864 template <> \
John Porto4a566862016-01-04 09:33:41 -08003865 const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp \
3866 InstImpl<TraitsType>::InstX86Pcmpgt::Base::Emitter = { \
3867 &InstImpl<TraitsType>::Assembler::pcmpgt, \
3868 &InstImpl<TraitsType>::Assembler::pcmpgt}; \
David Sehre3984282015-12-15 17:34:55 -08003869 template <> \
David Sehre3984282015-12-15 17:34:55 -08003870 template <> \
John Porto4a566862016-01-04 09:33:41 -08003871 const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp \
3872 InstImpl<TraitsType>::InstX86Pmull::Base::Emitter = { \
3873 &InstImpl<TraitsType>::Assembler::pmull, \
3874 &InstImpl<TraitsType>::Assembler::pmull}; \
3875 template <> \
3876 template <> \
3877 const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp \
Nicolas Capens13cde0f2016-10-26 10:36:11 -04003878 InstImpl<TraitsType>::InstX86Pmulhw::Base::Emitter = { \
3879 &InstImpl<TraitsType>::Assembler::pmulhw, \
3880 &InstImpl<TraitsType>::Assembler::pmulhw}; \
3881 template <> \
3882 template <> \
3883 const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp \
3884 InstImpl<TraitsType>::InstX86Pmulhuw::Base::Emitter = { \
3885 &InstImpl<TraitsType>::Assembler::pmulhuw, \
3886 &InstImpl<TraitsType>::Assembler::pmulhuw}; \
3887 template <> \
3888 template <> \
3889 const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp \
3890 InstImpl<TraitsType>::InstX86Pmaddwd::Base::Emitter = { \
3891 &InstImpl<TraitsType>::Assembler::pmaddwd, \
3892 &InstImpl<TraitsType>::Assembler::pmaddwd}; \
3893 template <> \
3894 template <> \
3895 const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp \
John Porto4a566862016-01-04 09:33:41 -08003896 InstImpl<TraitsType>::InstX86Pmuludq::Base::Emitter = { \
3897 &InstImpl<TraitsType>::Assembler::pmuludq, \
3898 &InstImpl<TraitsType>::Assembler::pmuludq}; \
3899 template <> \
3900 template <> \
3901 const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp \
3902 InstImpl<TraitsType>::InstX86Por::Base::Emitter = { \
3903 &InstImpl<TraitsType>::Assembler::por, \
3904 &InstImpl<TraitsType>::Assembler::por}; \
3905 template <> \
3906 template <> \
3907 const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp \
3908 InstImpl<TraitsType>::InstX86Psub::Base::Emitter = { \
3909 &InstImpl<TraitsType>::Assembler::psub, \
3910 &InstImpl<TraitsType>::Assembler::psub}; \
3911 template <> \
3912 template <> \
3913 const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp \
Nicolas Capens67a49b52016-10-26 13:18:35 -04003914 InstImpl<TraitsType>::InstX86Psubs::Base::Emitter = { \
3915 &InstImpl<TraitsType>::Assembler::psubs, \
3916 &InstImpl<TraitsType>::Assembler::psubs}; \
3917 template <> \
3918 template <> \
3919 const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp \
3920 InstImpl<TraitsType>::InstX86Psubus::Base::Emitter = { \
3921 &InstImpl<TraitsType>::Assembler::psubus, \
3922 &InstImpl<TraitsType>::Assembler::psubus}; \
3923 template <> \
3924 template <> \
3925 const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp \
John Porto4a566862016-01-04 09:33:41 -08003926 InstImpl<TraitsType>::InstX86Pxor::Base::Emitter = { \
3927 &InstImpl<TraitsType>::Assembler::pxor, \
3928 &InstImpl<TraitsType>::Assembler::pxor}; \
3929 template <> \
3930 template <> \
3931 const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp \
3932 InstImpl<TraitsType>::InstX86Subss::Base::Emitter = { \
3933 &InstImpl<TraitsType>::Assembler::subss, \
3934 &InstImpl<TraitsType>::Assembler::subss}; \
3935 template <> \
3936 template <> \
3937 const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp \
3938 InstImpl<TraitsType>::InstX86Subps::Base::Emitter = { \
3939 &InstImpl<TraitsType>::Assembler::subps, \
3940 &InstImpl<TraitsType>::Assembler::subps}; \
3941 template <> \
3942 template <> \
3943 const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp \
3944 InstImpl<TraitsType>::InstX86Andnps::Base::Emitter = { \
3945 &InstImpl<TraitsType>::Assembler::andnps, \
3946 &InstImpl<TraitsType>::Assembler::andnps}; \
3947 template <> \
3948 template <> \
3949 const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp \
3950 InstImpl<TraitsType>::InstX86Andps::Base::Emitter = { \
3951 &InstImpl<TraitsType>::Assembler::andps, \
3952 &InstImpl<TraitsType>::Assembler::andps}; \
3953 template <> \
3954 template <> \
3955 const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp \
3956 InstImpl<TraitsType>::InstX86Maxss::Base::Emitter = { \
3957 &InstImpl<TraitsType>::Assembler::maxss, \
3958 &InstImpl<TraitsType>::Assembler::maxss}; \
3959 template <> \
3960 template <> \
3961 const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp \
3962 InstImpl<TraitsType>::InstX86Minss::Base::Emitter = { \
3963 &InstImpl<TraitsType>::Assembler::minss, \
3964 &InstImpl<TraitsType>::Assembler::minss}; \
3965 template <> \
3966 template <> \
3967 const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp \
Nicolas Capenseb568f52017-02-13 09:49:43 -05003968 InstImpl<TraitsType>::InstX86Maxps::Base::Emitter = { \
3969 &InstImpl<TraitsType>::Assembler::maxps, \
3970 &InstImpl<TraitsType>::Assembler::maxps}; \
3971 template <> \
3972 template <> \
3973 const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp \
3974 InstImpl<TraitsType>::InstX86Minps::Base::Emitter = { \
3975 &InstImpl<TraitsType>::Assembler::minps, \
3976 &InstImpl<TraitsType>::Assembler::minps}; \
3977 template <> \
3978 template <> \
3979 const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp \
John Porto4a566862016-01-04 09:33:41 -08003980 InstImpl<TraitsType>::InstX86Orps::Base::Emitter = { \
3981 &InstImpl<TraitsType>::Assembler::orps, \
3982 &InstImpl<TraitsType>::Assembler::orps}; \
3983 template <> \
3984 template <> \
3985 const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp \
3986 InstImpl<TraitsType>::InstX86Xorps::Base::Emitter = { \
3987 &InstImpl<TraitsType>::Assembler::xorps, \
3988 &InstImpl<TraitsType>::Assembler::xorps}; \
John Porto921856d2015-07-07 11:56:26 -07003989 \
3990 /* Binary XMM Shift ops */ \
3991 template <> \
John Porto921856d2015-07-07 11:56:26 -07003992 template <> \
John Porto4a566862016-01-04 09:33:41 -08003993 const InstImpl<TraitsType>::Assembler::XmmEmitterShiftOp \
3994 InstImpl<TraitsType>::InstX86Psll::Base::Emitter = { \
3995 &InstImpl<TraitsType>::Assembler::psll, \
3996 &InstImpl<TraitsType>::Assembler::psll, \
3997 &InstImpl<TraitsType>::Assembler::psll}; \
John Porto921856d2015-07-07 11:56:26 -07003998 template <> \
John Porto4a566862016-01-04 09:33:41 -08003999 template <> \
4000 const InstImpl<TraitsType>::Assembler::XmmEmitterShiftOp \
4001 InstImpl<TraitsType>::InstX86Psra::Base::Emitter = { \
4002 &InstImpl<TraitsType>::Assembler::psra, \
4003 &InstImpl<TraitsType>::Assembler::psra, \
4004 &InstImpl<TraitsType>::Assembler::psra}; \
4005 template <> \
4006 template <> \
4007 const InstImpl<TraitsType>::Assembler::XmmEmitterShiftOp \
4008 InstImpl<TraitsType>::InstX86Psrl::Base::Emitter = { \
4009 &InstImpl<TraitsType>::Assembler::psrl, \
4010 &InstImpl<TraitsType>::Assembler::psrl, \
4011 &InstImpl<TraitsType>::Assembler::psrl}; \
John Portoae15f0f2016-04-26 04:26:33 -07004012 template <> \
4013 template <> \
4014 const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp \
John Portode29f122016-04-26 19:16:07 -07004015 InstImpl<TraitsType>::InstX86Pshufb::Base::Emitter = { \
4016 &InstImpl<TraitsType>::Assembler::pshufb, \
4017 &InstImpl<TraitsType>::Assembler::pshufb}; \
4018 template <> \
4019 template <> \
4020 const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp \
John Portoae15f0f2016-04-26 04:26:33 -07004021 InstImpl<TraitsType>::InstX86Punpckl::Base::Emitter = { \
Nicolas Capens71c69372016-10-04 00:07:21 -04004022 &InstImpl<TraitsType>::Assembler::punpckl, \
4023 &InstImpl<TraitsType>::Assembler::punpckl}; \
Nicolas Capens7638e272016-10-06 11:33:55 -04004024 template <> \
4025 template <> \
4026 const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp \
Nicolas Capens1448d952016-10-14 16:37:09 -04004027 InstImpl<TraitsType>::InstX86Punpckh::Base::Emitter = { \
4028 &InstImpl<TraitsType>::Assembler::punpckh, \
4029 &InstImpl<TraitsType>::Assembler::punpckh}; \
4030 template <> \
4031 template <> \
4032 const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp \
Nicolas Capens7638e272016-10-06 11:33:55 -04004033 InstImpl<TraitsType>::InstX86Packss::Base::Emitter = { \
4034 &InstImpl<TraitsType>::Assembler::packss, \
4035 &InstImpl<TraitsType>::Assembler::packss}; \
4036 template <> \
4037 template <> \
4038 const InstImpl<TraitsType>::Assembler::XmmEmitterRegOp \
4039 InstImpl<TraitsType>::InstX86Packus::Base::Emitter = { \
4040 &InstImpl<TraitsType>::Assembler::packus, \
4041 &InstImpl<TraitsType>::Assembler::packus}; \
John Porto921856d2015-07-07 11:56:26 -07004042 } \
4043 }
4044
John Porto4a566862016-01-04 09:33:41 -08004045} // end of namespace X86NAMESPACE
John Porto921856d2015-07-07 11:56:26 -07004046} // end of namespace Ice
4047
4048#include "IceInstX86BaseImpl.h"
4049
4050#endif // SUBZERO_SRC_ICEINSTX86BASE_H