Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(87)

Side by Side Diff: src/IceInstX86Base.h

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

Powered by Google App Engine
This is Rietveld 408576698