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

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: Eliminates all references to X8632 from Impl files. 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
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 // This file defines the InstX86Base and OperandX86Base template classes that
jvoung (off chromium) 2015/07/06 18:58:45 Is there a OperandX86Base template class? I see so
John 2015/07/06 22:30:09 There's an X86Operand class defined in the X8632 T
11 // are shared accross all x86 targets.
jvoung (off chromium) 2015/07/06 18:58:45 accross -> across
John 2015/07/06 22:30:09 Done.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #ifndef SUBZERO_SRC_ICEINSTX86BASE_H
16 #define SUBZERO_SRC_ICEINSTX86BASE_H
17
18 #include "IceDefs.h"
19 #include "IceInst.h"
20 #include "IceOperand.h"
21
22 namespace Ice {
23
24 namespace X86Internal {
25
26 template <class Machine> struct MachineTraits;
27
28 template <class Machine> class InstX86Base : public InstTarget {
29 InstX86Base<Machine>() = delete;
30 InstX86Base<Machine>(const InstX86Base &) = delete;
31 InstX86Base &operator=(const InstX86Base &) = delete;
32
33 public:
34 using Traits = MachineTraits<Machine>;
35
36 enum InstKindX86 {
37 k__Start = Inst::Target,
38 Adc,
39 AdcRMW,
40 Add,
41 AddRMW,
42 Addps,
43 Addss,
44 Adjuststack,
45 And,
46 AndRMW,
47 Blendvps,
48 Br,
49 Bsf,
50 Bsr,
51 Bswap,
52 Call,
53 Cbwdq,
54 Cmov,
55 Cmpps,
56 Cmpxchg,
57 Cmpxchg8b,
58 Cvt,
59 Div,
60 Divps,
61 Divss,
62 FakeRMW,
63 Fld,
64 Fstp,
65 Icmp,
66 Idiv,
67 Imul,
68 Insertps,
69 Jmp,
70 Label,
71 Lea,
72 Load,
73 Mfence,
74 Mov,
75 Movd,
76 Movp,
77 Movq,
78 MovssRegs,
79 Movsx,
80 Movzx,
81 Mul,
82 Mulps,
83 Mulss,
84 Neg,
85 Nop,
86 Or,
87 OrRMW,
88 Padd,
89 Pand,
90 Pandn,
91 Pblendvb,
92 Pcmpeq,
93 Pcmpgt,
94 Pextr,
95 Pinsr,
96 Pmull,
97 Pmuludq,
98 Pop,
99 Por,
100 Pshufd,
101 Psll,
102 Psra,
103 Psrl,
104 Psub,
105 Push,
106 Pxor,
107 Ret,
108 Rol,
109 Sar,
110 Sbb,
111 SbbRMW,
112 Setcc,
113 Shl,
114 Shld,
115 Shr,
116 Shrd,
117 Shufps,
118 Sqrtss,
119 Store,
120 StoreP,
121 StoreQ,
122 Sub,
123 SubRMW,
124 Subps,
125 Subss,
126 Test,
127 Ucomiss,
128 UD2,
129 Xadd,
130 Xchg,
131 Xor,
132 XorRMW
133 };
134
135 static const char *getWidthString(Type Ty);
136 static const char *getFldString(Type Ty);
137 static typename Traits::Cond::BrCond
138 getOppositeCondition(typename Traits::Cond::BrCond Cond);
139 void dump(const Cfg *Func) const override;
140
141 // Shared emit routines for common forms of instructions.
142 // See the definition of emitTwoAddress() for a description of
143 // ShiftHack.
144 static void emitTwoAddress(const char *Opcode, const Inst *Inst,
145 const Cfg *Func, bool ShiftHack = false);
146
147 static void
148 emitIASGPRShift(const Cfg *Func, Type Ty, const Variable *Var,
149 const Operand *Src,
150 const typename Traits::Assembler::GPREmitterShiftOp &Emitter);
151
152 protected:
153 InstX86Base<Machine>(Cfg *Func, InstKindX86 Kind, SizeT Maxsrcs,
154 Variable *Dest)
155 : InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {}
156
157 static bool isClassof(const Inst *Inst, InstKindX86 MyKind) {
158 return Inst->getKind() == static_cast<InstKind>(MyKind);
159 }
160 // Most instructions that operate on vector arguments require vector
161 // memory operands to be fully aligned (16-byte alignment for PNaCl
162 // vector types). The stack frame layout and call ABI ensure proper
163 // alignment for stack operands, but memory operands (originating
164 // from load/store bitcode instructions) only have element-size
165 // alignment guarantees. This function validates that none of the
166 // operands is a memory operand of vector type, calling
167 // report_fatal_error() if one is found. This function should be
168 // called during emission, and maybe also in the ctor (as long as
169 // that fits the lowering style).
170 void validateVectorAddrMode() const {
171 if (this->getDest())
172 this->validateVectorAddrModeOpnd(this->getDest());
173 for (SizeT i = 0; i < this->getSrcSize(); ++i) {
174 this->validateVectorAddrModeOpnd(this->getSrc(i));
175 }
176 }
177
178 private:
179 static void validateVectorAddrModeOpnd(const Operand *Opnd) {
180 if (llvm::isa<typename InstX86Base<Machine>::Traits::X86OperandMem>(Opnd) &&
181 isVectorType(Opnd->getType())) {
182 llvm::report_fatal_error("Possible misaligned vector memory operation");
183 }
184 }
185 };
186
187 // InstX86BaseFakeRMW represents a non-atomic read-modify-write operation on a
188 // memory location. An InstX86BaseFakeRMW is a "fake" instruction in that it
189 // still needs to be lowered to some actual RMW instruction.
190 //
191 // If A is some memory address, D is some data value to apply, and OP is an
192 // arithmetic operator, the instruction operates as: (*A) = (*A) OP D
193 template <class Machine>
194 class InstX86BaseFakeRMW : public InstX86Base<Machine> {
195 InstX86BaseFakeRMW() = delete;
196 InstX86BaseFakeRMW(const InstX86BaseFakeRMW &) = delete;
197 InstX86BaseFakeRMW &operator=(const InstX86BaseFakeRMW &) = delete;
198
199 public:
200 static InstX86BaseFakeRMW *create(Cfg *Func, Operand *Data, Operand *Addr,
201 Variable *Beacon, InstArithmetic::OpKind Op,
202 uint32_t Align = 1) {
203 // TODO(stichnot): Stop ignoring alignment specification.
204 (void)Align;
205 return new (Func->allocate<InstX86BaseFakeRMW>())
206 InstX86BaseFakeRMW(Func, Data, Addr, Op, Beacon);
207 }
208 Operand *getAddr() const { return this->getSrc(1); }
209 Operand *getData() const { return this->getSrc(0); }
210 InstArithmetic::OpKind getOp() const { return Op; }
211 Variable *getBeacon() const { return llvm::cast<Variable>(this->getSrc(2)); }
212 void dump(const Cfg *Func) const override;
213 static bool classof(const Inst *Inst) {
214 return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::FakeRMW);
215 }
216
217 private:
218 InstArithmetic::OpKind Op;
219 InstX86BaseFakeRMW(Cfg *Func, Operand *Data, Operand *Addr,
220 InstArithmetic::OpKind Op, Variable *Beacon);
221 };
222
223 // InstX86BaseLabel represents an intra-block label that is the target
224 // of an intra-block branch. The offset between the label and the
225 // branch must be fit into one byte (considered "near"). These are
226 // used for lowering i1 calculations, Select instructions, and 64-bit
227 // compares on a 32-bit architecture, without basic block splitting.
228 // Basic block splitting is not so desirable for several reasons, one
229 // of which is the impact on decisions based on whether a variable's
230 // live range spans multiple basic blocks.
231 //
232 // Intra-block control flow must be used with caution. Consider the
233 // sequence for "c = (a >= b ? x : y)".
234 // cmp a, b
235 // br lt, L1
236 // mov c, x
237 // jmp L2
238 // L1:
239 // mov c, y
240 // L2:
241 //
242 // Labels L1 and L2 are intra-block labels. Without knowledge of the
243 // intra-block control flow, liveness analysis will determine the "mov
244 // c, x" instruction to be dead. One way to prevent this is to insert
245 // a "FakeUse(c)" instruction anywhere between the two "mov c, ..."
246 // instructions, e.g.:
247 //
248 // cmp a, b
249 // br lt, L1
250 // mov c, x
251 // jmp L2
252 // FakeUse(c)
253 // L1:
254 // mov c, y
255 // L2:
256 //
257 // The down-side is that "mov c, x" can never be dead-code eliminated
258 // even if there are no uses of c. As unlikely as this situation is,
259 // it may be prevented by running dead code elimination before
260 // lowering.
261 template <class Machine> class InstX86BaseLabel : public InstX86Base<Machine> {
262 InstX86BaseLabel() = delete;
263 InstX86BaseLabel(const InstX86BaseLabel &) = delete;
264 InstX86BaseLabel &operator=(const InstX86BaseLabel &) = delete;
265
266 public:
267 static InstX86BaseLabel *
268 create(Cfg *Func,
269 typename InstX86Base<Machine>::Traits::TargetLowering *Target) {
270 return new (Func->allocate<InstX86BaseLabel>())
271 InstX86BaseLabel(Func, Target);
272 }
273 uint32_t getEmitInstCount() const override { return 0; }
274 IceString getName(const Cfg *Func) const;
275 SizeT getNumber() const { return Number; }
276 void emit(const Cfg *Func) const override;
277 void emitIAS(const Cfg *Func) const override;
278 void dump(const Cfg *Func) const override;
279
280 private:
281 InstX86BaseLabel(
282 Cfg *Func, typename InstX86Base<Machine>::Traits::TargetLowering *Target);
283
284 SizeT Number; // used for unique label generation.
285 };
286
287 // Conditional and unconditional branch instruction.
288 template <class Machine> class InstX86BaseBr : public InstX86Base<Machine> {
289 InstX86BaseBr() = delete;
290 InstX86BaseBr(const InstX86BaseBr &) = delete;
291 InstX86BaseBr &operator=(const InstX86BaseBr &) = delete;
292
293 public:
294 // Create a conditional branch to a node.
295 static InstX86BaseBr *
296 create(Cfg *Func, CfgNode *TargetTrue, CfgNode *TargetFalse,
297 typename InstX86Base<Machine>::Traits::Cond::BrCond Condition) {
298 assert(Condition != InstX86Base<Machine>::Traits::Cond::Br_None);
299 const InstX86BaseLabel<Machine> *NoLabel = nullptr;
300 return new (Func->allocate<InstX86BaseBr>())
301 InstX86BaseBr(Func, TargetTrue, TargetFalse, NoLabel, Condition);
302 }
303 // Create an unconditional branch to a node.
304 static InstX86BaseBr *create(Cfg *Func, CfgNode *Target) {
305 const CfgNode *NoCondTarget = nullptr;
306 const InstX86BaseLabel<Machine> *NoLabel = nullptr;
307 return new (Func->allocate<InstX86BaseBr>())
308 InstX86BaseBr(Func, NoCondTarget, Target, NoLabel,
309 InstX86Base<Machine>::Traits::Cond::Br_None);
310 }
311 // Create a non-terminator conditional branch to a node, with a
312 // fallthrough to the next instruction in the current node. This is
313 // used for switch lowering.
314 static InstX86BaseBr *
315 create(Cfg *Func, CfgNode *Target,
316 typename InstX86Base<Machine>::Traits::Cond::BrCond Condition) {
317 assert(Condition != InstX86Base<Machine>::Traits::Cond::Br_None);
318 const CfgNode *NoUncondTarget = nullptr;
319 const InstX86BaseLabel<Machine> *NoLabel = nullptr;
320 return new (Func->allocate<InstX86BaseBr>())
321 InstX86BaseBr(Func, Target, NoUncondTarget, NoLabel, Condition);
322 }
323 // Create a conditional intra-block branch (or unconditional, if
324 // Condition==Br_None) to a label in the current block.
325 static InstX86BaseBr *
326 create(Cfg *Func, InstX86BaseLabel<Machine> *Label,
327 typename InstX86Base<Machine>::Traits::Cond::BrCond Condition) {
328 const CfgNode *NoCondTarget = nullptr;
329 const CfgNode *NoUncondTarget = nullptr;
330 return new (Func->allocate<InstX86BaseBr>())
331 InstX86BaseBr(Func, NoCondTarget, NoUncondTarget, Label, Condition);
332 }
333 const CfgNode *getTargetTrue() const { return TargetTrue; }
334 const CfgNode *getTargetFalse() const { return TargetFalse; }
335 bool optimizeBranch(const CfgNode *NextNode);
336 uint32_t getEmitInstCount() const override {
337 uint32_t Sum = 0;
338 if (Label)
339 ++Sum;
340 if (getTargetTrue())
341 ++Sum;
342 if (getTargetFalse())
343 ++Sum;
344 return Sum;
345 }
346 bool isUnconditionalBranch() const override {
347 return !Label && Condition == InstX86Base<Machine>::Traits::Cond::Br_None;
348 }
349 bool repointEdge(CfgNode *OldNode, CfgNode *NewNode) override;
350 void emit(const Cfg *Func) const override;
351 void emitIAS(const Cfg *Func) const override;
352 void dump(const Cfg *Func) const override;
353 static bool classof(const Inst *Inst) {
354 return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Br);
355 }
356
357 private:
358 InstX86BaseBr(Cfg *Func, const CfgNode *TargetTrue,
359 const CfgNode *TargetFalse,
360 const InstX86BaseLabel<Machine> *Label,
361 typename InstX86Base<Machine>::Traits::Cond::BrCond Condition);
362
363 typename InstX86Base<Machine>::Traits::Cond::BrCond Condition;
364 const CfgNode *TargetTrue;
365 const CfgNode *TargetFalse;
366 const InstX86BaseLabel<Machine> *Label; // Intra-block branch target
367 };
368
369 // Jump to a target outside this function, such as tailcall, nacljump,
370 // naclret, unreachable. This is different from a Branch instruction
371 // in that there is no intra-function control flow to represent.
372 template <class Machine> class InstX86BaseJmp : public InstX86Base<Machine> {
373 InstX86BaseJmp() = delete;
374 InstX86BaseJmp(const InstX86BaseJmp &) = delete;
375 InstX86BaseJmp &operator=(const InstX86BaseJmp &) = delete;
376
377 public:
378 static InstX86BaseJmp *create(Cfg *Func, Operand *Target) {
379 return new (Func->allocate<InstX86BaseJmp>()) InstX86BaseJmp(Func, Target);
380 }
381 Operand *getJmpTarget() const { return this->getSrc(0); }
382 void emit(const Cfg *Func) const override;
383 void emitIAS(const Cfg *Func) const override;
384 void dump(const Cfg *Func) const override;
385 static bool classof(const Inst *Inst) {
386 return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Jmp);
387 }
388
389 private:
390 InstX86BaseJmp(Cfg *Func, Operand *Target);
391 };
392
393 // AdjustStack instruction - subtracts esp by the given amount and
394 // updates the stack offset during code emission.
395 template <class Machine>
396 class InstX86BaseAdjustStack : public InstX86Base<Machine> {
397 InstX86BaseAdjustStack() = delete;
398 InstX86BaseAdjustStack(const InstX86BaseAdjustStack &) = delete;
399 InstX86BaseAdjustStack &operator=(const InstX86BaseAdjustStack &) = delete;
400
401 public:
402 static InstX86BaseAdjustStack *create(Cfg *Func, SizeT Amount,
403 Variable *Esp) {
404 return new (Func->allocate<InstX86BaseAdjustStack>())
405 InstX86BaseAdjustStack(Func, Amount, Esp);
406 }
407 void emit(const Cfg *Func) const override;
408 void emitIAS(const Cfg *Func) const override;
409 void dump(const Cfg *Func) const override;
410 static bool classof(const Inst *Inst) {
411 return InstX86Base<Machine>::isClassof(Inst,
412 InstX86Base<Machine>::Adjuststack);
413 }
414
415 private:
416 InstX86BaseAdjustStack(Cfg *Func, SizeT Amount, Variable *Esp);
417 SizeT Amount;
418 };
419
420 // Call instruction. Arguments should have already been pushed.
421 template <class Machine> class InstX86BaseCall : public InstX86Base<Machine> {
422 InstX86BaseCall() = delete;
423 InstX86BaseCall(const InstX86BaseCall &) = delete;
424 InstX86BaseCall &operator=(const InstX86BaseCall &) = delete;
425
426 public:
427 static InstX86BaseCall *create(Cfg *Func, Variable *Dest,
428 Operand *CallTarget) {
429 return new (Func->allocate<InstX86BaseCall>())
430 InstX86BaseCall(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 InstX86BaseCall(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 InstX86BaseBswap
996 : public InstX86BaseInplaceopGPR<Machine, InstX86Base<Machine>::Bswap> {
997 public:
998 static InstX86BaseBswap *create(Cfg *Func, Operand *SrcDest) {
999 return new (Func->allocate<InstX86BaseBswap>())
1000 InstX86BaseBswap(Func, SrcDest);
1001 }
1002
1003 private:
1004 InstX86BaseBswap(Cfg *Func, Operand *SrcDest)
1005 : InstX86BaseInplaceopGPR<Machine, InstX86Base<Machine>::Bswap>(Func,
1006 SrcDest) {
1007 }
1008 };
1009
1010 template <class Machine>
1011 class InstX86BaseNeg
1012 : public InstX86BaseInplaceopGPR<Machine, InstX86Base<Machine>::Neg> {
1013 public:
1014 static InstX86BaseNeg *create(Cfg *Func, Operand *SrcDest) {
1015 return new (Func->allocate<InstX86BaseNeg>()) InstX86BaseNeg(Func, SrcDest);
1016 }
1017
1018 private:
1019 InstX86BaseNeg(Cfg *Func, Operand *SrcDest)
1020 : InstX86BaseInplaceopGPR<Machine, InstX86Base<Machine>::Neg>(Func,
1021 SrcDest) {}
1022 };
1023
1024 template <class Machine>
1025 class InstX86BaseBsf
1026 : public InstX86BaseUnaryopGPR<Machine, InstX86Base<Machine>::Bsf> {
1027 public:
1028 static InstX86BaseBsf *create(Cfg *Func, Variable *Dest, Operand *Src) {
1029 return new (Func->allocate<InstX86BaseBsf>())
1030 InstX86BaseBsf(Func, Dest, Src);
1031 }
1032
1033 private:
1034 InstX86BaseBsf(Cfg *Func, Variable *Dest, Operand *Src)
1035 : InstX86BaseUnaryopGPR<Machine, InstX86Base<Machine>::Bsf>(Func, Dest,
1036 Src) {}
1037 };
1038
1039 template <class Machine>
1040 class InstX86BaseBsr
1041 : public InstX86BaseUnaryopGPR<Machine, InstX86Base<Machine>::Bsr> {
1042 public:
1043 static InstX86BaseBsr *create(Cfg *Func, Variable *Dest, Operand *Src) {
1044 return new (Func->allocate<InstX86BaseBsr>())
1045 InstX86BaseBsr(Func, Dest, Src);
1046 }
1047
1048 private:
1049 InstX86BaseBsr(Cfg *Func, Variable *Dest, Operand *Src)
1050 : InstX86BaseUnaryopGPR<Machine, InstX86Base<Machine>::Bsr>(Func, Dest,
1051 Src) {}
1052 };
1053
1054 template <class Machine>
1055 class InstX86BaseLea
1056 : public InstX86BaseUnaryopGPR<Machine, InstX86Base<Machine>::Lea> {
1057 public:
1058 static InstX86BaseLea *create(Cfg *Func, Variable *Dest, Operand *Src) {
1059 return new (Func->allocate<InstX86BaseLea>())
1060 InstX86BaseLea(Func, Dest, Src);
1061 }
1062
1063 void emit(const Cfg *Func) const override;
1064
1065 private:
1066 InstX86BaseLea(Cfg *Func, Variable *Dest, Operand *Src)
1067 : InstX86BaseUnaryopGPR<Machine, InstX86Base<Machine>::Lea>(Func, Dest,
1068 Src) {}
1069 };
1070
1071 // Cbwdq instruction - wrapper for cbw, cwd, and cdq
1072 template <class Machine>
1073 class InstX86BaseCbwdq
1074 : public InstX86BaseUnaryopGPR<Machine, InstX86Base<Machine>::Cbwdq> {
1075 public:
1076 static InstX86BaseCbwdq *create(Cfg *Func, Variable *Dest, Operand *Src) {
1077 return new (Func->allocate<InstX86BaseCbwdq>())
1078 InstX86BaseCbwdq(Func, Dest, Src);
1079 }
1080
1081 void emit(const Cfg *Func) const override;
1082 void emitIAS(const Cfg *Func) const override;
1083
1084 private:
1085 InstX86BaseCbwdq(Cfg *Func, Variable *Dest, Operand *Src)
1086 : InstX86BaseUnaryopGPR<Machine, InstX86Base<Machine>::Cbwdq>(Func, Dest,
1087 Src) {}
1088 };
1089
1090 template <class Machine>
1091 class InstX86BaseMovsx
1092 : public InstX86BaseUnaryopGPR<Machine, InstX86Base<Machine>::Movsx> {
1093 public:
1094 static InstX86BaseMovsx *create(Cfg *Func, Variable *Dest, Operand *Src) {
1095 return new (Func->allocate<InstX86BaseMovsx>())
1096 InstX86BaseMovsx(Func, Dest, Src);
1097 }
1098
1099 void emitIAS(const Cfg *Func) const override;
1100
1101 private:
1102 InstX86BaseMovsx(Cfg *Func, Variable *Dest, Operand *Src)
1103 : InstX86BaseUnaryopGPR<Machine, InstX86Base<Machine>::Movsx>(Func, Dest,
1104 Src) {}
1105 };
1106
1107 template <class Machine>
1108 class InstX86BaseMovzx
1109 : public InstX86BaseUnaryopGPR<Machine, InstX86Base<Machine>::Movzx> {
1110 public:
1111 static InstX86BaseMovzx *create(Cfg *Func, Variable *Dest, Operand *Src) {
1112 return new (Func->allocate<InstX86BaseMovzx>())
1113 InstX86BaseMovzx(Func, Dest, Src);
1114 }
1115
1116 void emitIAS(const Cfg *Func) const override;
1117
1118 private:
1119 InstX86BaseMovzx(Cfg *Func, Variable *Dest, Operand *Src)
1120 : InstX86BaseUnaryopGPR<Machine, InstX86Base<Machine>::Movzx>(Func, Dest,
1121 Src) {}
1122 };
1123
1124 template <class Machine>
1125 class InstX86BaseMovd
1126 : public InstX86BaseUnaryopXmm<Machine, InstX86Base<Machine>::Movd> {
1127 public:
1128 static InstX86BaseMovd *create(Cfg *Func, Variable *Dest, Operand *Src) {
1129 return new (Func->allocate<InstX86BaseMovd>())
1130 InstX86BaseMovd(Func, Dest, Src);
1131 }
1132
1133 void emitIAS(const Cfg *Func) const override;
1134
1135 private:
1136 InstX86BaseMovd(Cfg *Func, Variable *Dest, Operand *Src)
1137 : InstX86BaseUnaryopXmm<Machine, InstX86Base<Machine>::Movd>(Func, Dest,
1138 Src) {}
1139 };
1140
1141 template <class Machine>
1142 class InstX86BaseSqrtss
1143 : public InstX86BaseUnaryopXmm<Machine, InstX86Base<Machine>::Sqrtss> {
1144 public:
1145 static InstX86BaseSqrtss *create(Cfg *Func, Variable *Dest, Operand *Src) {
1146 return new (Func->allocate<InstX86BaseSqrtss>())
1147 InstX86BaseSqrtss(Func, Dest, Src);
1148 }
1149
1150 virtual void emit(const Cfg *Func) const override;
1151
1152 private:
1153 InstX86BaseSqrtss(Cfg *Func, Variable *Dest, Operand *Src)
1154 : InstX86BaseUnaryopXmm<Machine, InstX86Base<Machine>::Sqrtss>(Func, Dest,
1155 Src) {}
1156 };
1157
1158 // Move/assignment instruction - wrapper for mov/movss/movsd.
1159 template <class Machine>
1160 class InstX86BaseMov
1161 : public InstX86BaseMovlike<Machine, InstX86Base<Machine>::Mov> {
1162 public:
1163 static InstX86BaseMov *create(Cfg *Func, Variable *Dest, Operand *Source) {
1164 return new (Func->allocate<InstX86BaseMov>())
1165 InstX86BaseMov(Func, Dest, Source);
1166 }
1167
1168 void emit(const Cfg *Func) const override;
1169 void emitIAS(const Cfg *Func) const override;
1170
1171 private:
1172 InstX86BaseMov(Cfg *Func, Variable *Dest, Operand *Source)
1173 : InstX86BaseMovlike<Machine, InstX86Base<Machine>::Mov>(Func, Dest,
1174 Source) {}
1175 };
1176
1177 // Move packed - copy 128 bit values between XMM registers, or mem128
1178 // and XMM registers.
1179 template <class Machine>
1180 class InstX86BaseMovp
1181 : public InstX86BaseMovlike<Machine, InstX86Base<Machine>::Movp> {
1182 public:
1183 static InstX86BaseMovp *create(Cfg *Func, Variable *Dest, Operand *Source) {
1184 return new (Func->allocate<InstX86BaseMovp>())
1185 InstX86BaseMovp(Func, Dest, Source);
1186 }
1187
1188 void emit(const Cfg *Func) const override;
1189 void emitIAS(const Cfg *Func) const override;
1190
1191 private:
1192 InstX86BaseMovp(Cfg *Func, Variable *Dest, Operand *Source)
1193 : InstX86BaseMovlike<Machine, InstX86Base<Machine>::Movp>(Func, Dest,
1194 Source) {}
1195 };
1196
1197 // Movq - copy between XMM registers, or mem64 and XMM registers.
1198 template <class Machine>
1199 class InstX86BaseMovq
1200 : public InstX86BaseMovlike<Machine, InstX86Base<Machine>::Movq> {
1201 public:
1202 static InstX86BaseMovq *create(Cfg *Func, Variable *Dest, Operand *Source) {
1203 return new (Func->allocate<InstX86BaseMovq>())
1204 InstX86BaseMovq(Func, Dest, Source);
1205 }
1206
1207 void emit(const Cfg *Func) const override;
1208 void emitIAS(const Cfg *Func) const override;
1209
1210 private:
1211 InstX86BaseMovq(Cfg *Func, Variable *Dest, Operand *Source)
1212 : InstX86BaseMovlike<Machine, InstX86Base<Machine>::Movq>(Func, Dest,
1213 Source) {}
1214 };
1215
1216 template <class Machine>
1217 class InstX86BaseAdd
1218 : public InstX86BaseBinopGPR<Machine, InstX86Base<Machine>::Add> {
1219 public:
1220 static InstX86BaseAdd *create(Cfg *Func, Variable *Dest, Operand *Source) {
1221 return new (Func->allocate<InstX86BaseAdd>())
1222 InstX86BaseAdd(Func, Dest, Source);
1223 }
1224
1225 private:
1226 InstX86BaseAdd(Cfg *Func, Variable *Dest, Operand *Source)
1227 : InstX86BaseBinopGPR<Machine, InstX86Base<Machine>::Add>(Func, Dest,
1228 Source) {}
1229 };
1230
1231 template <class Machine>
1232 class InstX86BaseAddRMW
1233 : public InstX86BaseBinopRMW<Machine, InstX86Base<Machine>::AddRMW> {
1234 public:
1235 static InstX86BaseAddRMW *
1236 create(Cfg *Func,
1237 typename InstX86Base<Machine>::Traits::X86OperandMem *DestSrc0,
1238 Operand *Src1) {
1239 return new (Func->allocate<InstX86BaseAddRMW>())
1240 InstX86BaseAddRMW(Func, DestSrc0, Src1);
1241 }
1242
1243 private:
1244 InstX86BaseAddRMW(
1245 Cfg *Func, typename InstX86Base<Machine>::Traits::X86OperandMem *DestSrc0,
1246 Operand *Src1)
1247 : InstX86BaseBinopRMW<Machine, InstX86Base<Machine>::AddRMW>(
1248 Func, DestSrc0, Src1) {}
1249 };
1250
1251 template <class Machine>
1252 class InstX86BaseAddps
1253 : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Addps, true> {
1254 public:
1255 static InstX86BaseAddps *create(Cfg *Func, Variable *Dest, Operand *Source) {
1256 return new (Func->allocate<InstX86BaseAddps>())
1257 InstX86BaseAddps(Func, Dest, Source);
1258 }
1259
1260 private:
1261 InstX86BaseAddps(Cfg *Func, Variable *Dest, Operand *Source)
1262 : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Addps, true>(
1263 Func, Dest, Source) {}
1264 };
1265
1266 template <class Machine>
1267 class InstX86BaseAdc
1268 : public InstX86BaseBinopGPR<Machine, InstX86Base<Machine>::Adc> {
1269 public:
1270 static InstX86BaseAdc *create(Cfg *Func, Variable *Dest, Operand *Source) {
1271 return new (Func->allocate<InstX86BaseAdc>())
1272 InstX86BaseAdc(Func, Dest, Source);
1273 }
1274
1275 private:
1276 InstX86BaseAdc(Cfg *Func, Variable *Dest, Operand *Source)
1277 : InstX86BaseBinopGPR<Machine, InstX86Base<Machine>::Adc>(Func, Dest,
1278 Source) {}
1279 };
1280
1281 template <class Machine>
1282 class InstX86BaseAdcRMW
1283 : public InstX86BaseBinopRMW<Machine, InstX86Base<Machine>::AdcRMW> {
1284 public:
1285 static InstX86BaseAdcRMW *
1286 create(Cfg *Func,
1287 typename InstX86Base<Machine>::Traits::X86OperandMem *DestSrc0,
1288 Operand *Src1) {
1289 return new (Func->allocate<InstX86BaseAdcRMW>())
1290 InstX86BaseAdcRMW(Func, DestSrc0, Src1);
1291 }
1292
1293 private:
1294 InstX86BaseAdcRMW(
1295 Cfg *Func, typename InstX86Base<Machine>::Traits::X86OperandMem *DestSrc0,
1296 Operand *Src1)
1297 : InstX86BaseBinopRMW<Machine, InstX86Base<Machine>::AdcRMW>(
1298 Func, DestSrc0, Src1) {}
1299 };
1300
1301 template <class Machine>
1302 class InstX86BaseAddss
1303 : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Addss, false> {
1304 public:
1305 static InstX86BaseAddss *create(Cfg *Func, Variable *Dest, Operand *Source) {
1306 return new (Func->allocate<InstX86BaseAddss>())
1307 InstX86BaseAddss(Func, Dest, Source);
1308 }
1309
1310 void emit(const Cfg *Func) const override;
1311
1312 private:
1313 InstX86BaseAddss(Cfg *Func, Variable *Dest, Operand *Source)
1314 : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Addss, false>(
1315 Func, Dest, Source) {}
1316 };
1317
1318 template <class Machine>
1319 class InstX86BasePadd
1320 : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Padd, true> {
1321 public:
1322 static InstX86BasePadd *create(Cfg *Func, Variable *Dest, Operand *Source) {
1323 return new (Func->allocate<InstX86BasePadd>())
1324 InstX86BasePadd(Func, Dest, Source);
1325 }
1326
1327 void emit(const Cfg *Func) const override;
1328
1329 private:
1330 InstX86BasePadd(Cfg *Func, Variable *Dest, Operand *Source)
1331 : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Padd, true>(
1332 Func, Dest, Source) {}
1333 };
1334
1335 template <class Machine>
1336 class InstX86BaseSub
1337 : public InstX86BaseBinopGPR<Machine, InstX86Base<Machine>::Sub> {
1338 public:
1339 static InstX86BaseSub *create(Cfg *Func, Variable *Dest, Operand *Source) {
1340 return new (Func->allocate<InstX86BaseSub>())
1341 InstX86BaseSub(Func, Dest, Source);
1342 }
1343
1344 private:
1345 InstX86BaseSub(Cfg *Func, Variable *Dest, Operand *Source)
1346 : InstX86BaseBinopGPR<Machine, InstX86Base<Machine>::Sub>(Func, Dest,
1347 Source) {}
1348 };
1349
1350 template <class Machine>
1351 class InstX86BaseSubRMW
1352 : public InstX86BaseBinopRMW<Machine, InstX86Base<Machine>::SubRMW> {
1353 public:
1354 static InstX86BaseSubRMW *
1355 create(Cfg *Func,
1356 typename InstX86Base<Machine>::Traits::X86OperandMem *DestSrc0,
1357 Operand *Src1) {
1358 return new (Func->allocate<InstX86BaseSubRMW>())
1359 InstX86BaseSubRMW(Func, DestSrc0, Src1);
1360 }
1361
1362 private:
1363 InstX86BaseSubRMW(
1364 Cfg *Func, typename InstX86Base<Machine>::Traits::X86OperandMem *DestSrc0,
1365 Operand *Src1)
1366 : InstX86BaseBinopRMW<Machine, InstX86Base<Machine>::SubRMW>(
1367 Func, DestSrc0, Src1) {}
1368 };
1369
1370 template <class Machine>
1371 class InstX86BaseSubps
1372 : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Subps, true> {
1373 public:
1374 static InstX86BaseSubps *create(Cfg *Func, Variable *Dest, Operand *Source) {
1375 return new (Func->allocate<InstX86BaseSubps>())
1376 InstX86BaseSubps(Func, Dest, Source);
1377 }
1378
1379 private:
1380 InstX86BaseSubps(Cfg *Func, Variable *Dest, Operand *Source)
1381 : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Subps, true>(
1382 Func, Dest, Source) {}
1383 };
1384
1385 template <class Machine>
1386 class InstX86BaseSubss
1387 : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Subss, false> {
1388 public:
1389 static InstX86BaseSubss *create(Cfg *Func, Variable *Dest, Operand *Source) {
1390 return new (Func->allocate<InstX86BaseSubss>())
1391 InstX86BaseSubss(Func, Dest, Source);
1392 }
1393
1394 void emit(const Cfg *Func) const override;
1395
1396 private:
1397 InstX86BaseSubss(Cfg *Func, Variable *Dest, Operand *Source)
1398 : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Subss, false>(
1399 Func, Dest, Source) {}
1400 };
1401
1402 template <class Machine>
1403 class InstX86BaseSbb
1404 : public InstX86BaseBinopGPR<Machine, InstX86Base<Machine>::Sbb> {
1405 public:
1406 static InstX86BaseSbb *create(Cfg *Func, Variable *Dest, Operand *Source) {
1407 return new (Func->allocate<InstX86BaseSbb>())
1408 InstX86BaseSbb(Func, Dest, Source);
1409 }
1410
1411 private:
1412 InstX86BaseSbb(Cfg *Func, Variable *Dest, Operand *Source)
1413 : InstX86BaseBinopGPR<Machine, InstX86Base<Machine>::Sbb>(Func, Dest,
1414 Source) {}
1415 };
1416
1417 template <class Machine>
1418 class InstX86BaseSbbRMW
1419 : public InstX86BaseBinopRMW<Machine, InstX86Base<Machine>::SbbRMW> {
1420 public:
1421 static InstX86BaseSbbRMW *
1422 create(Cfg *Func,
1423 typename InstX86Base<Machine>::Traits::X86OperandMem *DestSrc0,
1424 Operand *Src1) {
1425 return new (Func->allocate<InstX86BaseSbbRMW>())
1426 InstX86BaseSbbRMW(Func, DestSrc0, Src1);
1427 }
1428
1429 private:
1430 InstX86BaseSbbRMW(
1431 Cfg *Func, typename InstX86Base<Machine>::Traits::X86OperandMem *DestSrc0,
1432 Operand *Src1)
1433 : InstX86BaseBinopRMW<Machine, InstX86Base<Machine>::SbbRMW>(
1434 Func, DestSrc0, Src1) {}
1435 };
1436
1437 template <class Machine>
1438 class InstX86BasePsub
1439 : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Psub, true> {
1440 public:
1441 static InstX86BasePsub *create(Cfg *Func, Variable *Dest, Operand *Source) {
1442 return new (Func->allocate<InstX86BasePsub>())
1443 InstX86BasePsub(Func, Dest, Source);
1444 }
1445
1446 void emit(const Cfg *Func) const override;
1447
1448 private:
1449 InstX86BasePsub(Cfg *Func, Variable *Dest, Operand *Source)
1450 : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Psub, true>(
1451 Func, Dest, Source) {}
1452 };
1453
1454 template <class Machine>
1455 class InstX86BaseAnd
1456 : public InstX86BaseBinopGPR<Machine, InstX86Base<Machine>::And> {
1457 public:
1458 static InstX86BaseAnd *create(Cfg *Func, Variable *Dest, Operand *Source) {
1459 return new (Func->allocate<InstX86BaseAnd>())
1460 InstX86BaseAnd(Func, Dest, Source);
1461 }
1462
1463 private:
1464 InstX86BaseAnd(Cfg *Func, Variable *Dest, Operand *Source)
1465 : InstX86BaseBinopGPR<Machine, InstX86Base<Machine>::And>(Func, Dest,
1466 Source) {}
1467 };
1468
1469 template <class Machine>
1470 class InstX86BaseAndRMW
1471 : public InstX86BaseBinopRMW<Machine, InstX86Base<Machine>::AndRMW> {
1472 public:
1473 static InstX86BaseAndRMW *
1474 create(Cfg *Func,
1475 typename InstX86Base<Machine>::Traits::X86OperandMem *DestSrc0,
1476 Operand *Src1) {
1477 return new (Func->allocate<InstX86BaseAndRMW>())
1478 InstX86BaseAndRMW(Func, DestSrc0, Src1);
1479 }
1480
1481 private:
1482 InstX86BaseAndRMW(
1483 Cfg *Func, typename InstX86Base<Machine>::Traits::X86OperandMem *DestSrc0,
1484 Operand *Src1)
1485 : InstX86BaseBinopRMW<Machine, InstX86Base<Machine>::AndRMW>(
1486 Func, DestSrc0, Src1) {}
1487 };
1488
1489 template <class Machine>
1490 class InstX86BasePand
1491 : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pand, false> {
1492 public:
1493 static InstX86BasePand *create(Cfg *Func, Variable *Dest, Operand *Source) {
1494 return new (Func->allocate<InstX86BasePand>())
1495 InstX86BasePand(Func, Dest, Source);
1496 }
1497
1498 private:
1499 InstX86BasePand(Cfg *Func, Variable *Dest, Operand *Source)
1500 : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pand, false>(
1501 Func, Dest, Source) {}
1502 };
1503
1504 template <class Machine>
1505 class InstX86BasePandn
1506 : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pandn, false> {
1507 public:
1508 static InstX86BasePandn *create(Cfg *Func, Variable *Dest, Operand *Source) {
1509 return new (Func->allocate<InstX86BasePandn>())
1510 InstX86BasePandn(Func, Dest, Source);
1511 }
1512
1513 private:
1514 InstX86BasePandn(Cfg *Func, Variable *Dest, Operand *Source)
1515 : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pandn, false>(
1516 Func, Dest, Source) {}
1517 };
1518
1519 template <class Machine>
1520 class InstX86BaseOr
1521 : public InstX86BaseBinopGPR<Machine, InstX86Base<Machine>::Or> {
1522 public:
1523 static InstX86BaseOr *create(Cfg *Func, Variable *Dest, Operand *Source) {
1524 return new (Func->allocate<InstX86BaseOr>())
1525 InstX86BaseOr(Func, Dest, Source);
1526 }
1527
1528 private:
1529 InstX86BaseOr(Cfg *Func, Variable *Dest, Operand *Source)
1530 : InstX86BaseBinopGPR<Machine, InstX86Base<Machine>::Or>(Func, Dest,
1531 Source) {}
1532 };
1533
1534 template <class Machine>
1535 class InstX86BaseOrRMW
1536 : public InstX86BaseBinopRMW<Machine, InstX86Base<Machine>::OrRMW> {
1537 public:
1538 static InstX86BaseOrRMW *
1539 create(Cfg *Func,
1540 typename InstX86Base<Machine>::Traits::X86OperandMem *DestSrc0,
1541 Operand *Src1) {
1542 return new (Func->allocate<InstX86BaseOrRMW>())
1543 InstX86BaseOrRMW(Func, DestSrc0, Src1);
1544 }
1545
1546 private:
1547 InstX86BaseOrRMW(
1548 Cfg *Func, typename InstX86Base<Machine>::Traits::X86OperandMem *DestSrc0,
1549 Operand *Src1)
1550 : InstX86BaseBinopRMW<Machine, InstX86Base<Machine>::OrRMW>(
1551 Func, DestSrc0, Src1) {}
1552 };
1553
1554 template <class Machine>
1555 class InstX86BasePor
1556 : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Por, false> {
1557 public:
1558 static InstX86BasePor *create(Cfg *Func, Variable *Dest, Operand *Source) {
1559 return new (Func->allocate<InstX86BasePor>())
1560 InstX86BasePor(Func, Dest, Source);
1561 }
1562
1563 private:
1564 InstX86BasePor(Cfg *Func, Variable *Dest, Operand *Source)
1565 : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Por, false>(
1566 Func, Dest, Source) {}
1567 };
1568
1569 template <class Machine>
1570 class InstX86BaseXor
1571 : public InstX86BaseBinopGPR<Machine, InstX86Base<Machine>::Xor> {
1572 public:
1573 static InstX86BaseXor *create(Cfg *Func, Variable *Dest, Operand *Source) {
1574 return new (Func->allocate<InstX86BaseXor>())
1575 InstX86BaseXor(Func, Dest, Source);
1576 }
1577
1578 private:
1579 InstX86BaseXor(Cfg *Func, Variable *Dest, Operand *Source)
1580 : InstX86BaseBinopGPR<Machine, InstX86Base<Machine>::Xor>(Func, Dest,
1581 Source) {}
1582 };
1583
1584 template <class Machine>
1585 class InstX86BaseXorRMW
1586 : public InstX86BaseBinopRMW<Machine, InstX86Base<Machine>::XorRMW> {
1587 public:
1588 static InstX86BaseXorRMW *
1589 create(Cfg *Func,
1590 typename InstX86Base<Machine>::Traits::X86OperandMem *DestSrc0,
1591 Operand *Src1) {
1592 return new (Func->allocate<InstX86BaseXorRMW>())
1593 InstX86BaseXorRMW(Func, DestSrc0, Src1);
1594 }
1595
1596 private:
1597 InstX86BaseXorRMW(
1598 Cfg *Func, typename InstX86Base<Machine>::Traits::X86OperandMem *DestSrc0,
1599 Operand *Src1)
1600 : InstX86BaseBinopRMW<Machine, InstX86Base<Machine>::XorRMW>(
1601 Func, DestSrc0, Src1) {}
1602 };
1603
1604 template <class Machine>
1605 class InstX86BasePxor
1606 : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pxor, false> {
1607 public:
1608 static InstX86BasePxor *create(Cfg *Func, Variable *Dest, Operand *Source) {
1609 return new (Func->allocate<InstX86BasePxor>())
1610 InstX86BasePxor(Func, Dest, Source);
1611 }
1612
1613 private:
1614 InstX86BasePxor(Cfg *Func, Variable *Dest, Operand *Source)
1615 : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pxor, false>(
1616 Func, Dest, Source) {}
1617 };
1618
1619 template <class Machine>
1620 class InstX86BaseImul
1621 : public InstX86BaseBinopGPR<Machine, InstX86Base<Machine>::Imul> {
1622 public:
1623 static InstX86BaseImul *create(Cfg *Func, Variable *Dest, Operand *Source) {
1624 return new (Func->allocate<InstX86BaseImul>())
1625 InstX86BaseImul(Func, Dest, Source);
1626 }
1627
1628 void emit(const Cfg *Func) const override;
1629 void emitIAS(const Cfg *Func) const override;
1630
1631 private:
1632 InstX86BaseImul(Cfg *Func, Variable *Dest, Operand *Source)
1633 : InstX86BaseBinopGPR<Machine, InstX86Base<Machine>::Imul>(Func, Dest,
1634 Source) {}
1635 };
1636
1637 template <class Machine>
1638 class InstX86BaseMulps
1639 : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Mulps, true> {
1640 public:
1641 static InstX86BaseMulps *create(Cfg *Func, Variable *Dest, Operand *Source) {
1642 return new (Func->allocate<InstX86BaseMulps>())
1643 InstX86BaseMulps(Func, Dest, Source);
1644 }
1645
1646 private:
1647 InstX86BaseMulps(Cfg *Func, Variable *Dest, Operand *Source)
1648 : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Mulps, true>(
1649 Func, Dest, Source) {}
1650 };
1651
1652 template <class Machine>
1653 class InstX86BaseMulss
1654 : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Mulss, false> {
1655 public:
1656 static InstX86BaseMulss *create(Cfg *Func, Variable *Dest, Operand *Source) {
1657 return new (Func->allocate<InstX86BaseMulss>())
1658 InstX86BaseMulss(Func, Dest, Source);
1659 }
1660
1661 void emit(const Cfg *Func) const override;
1662
1663 private:
1664 InstX86BaseMulss(Cfg *Func, Variable *Dest, Operand *Source)
1665 : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Mulss, false>(
1666 Func, Dest, Source) {}
1667 };
1668
1669 template <class Machine>
1670 class InstX86BasePmull
1671 : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pmull, true> {
1672 public:
1673 static InstX86BasePmull *create(Cfg *Func, Variable *Dest, Operand *Source) {
1674 return new (Func->allocate<InstX86BasePmull>())
1675 InstX86BasePmull(Func, Dest, Source);
1676 }
1677
1678 void emit(const Cfg *Func) const override;
1679 void emitIAS(const Cfg *Func) const override;
1680
1681 private:
1682 InstX86BasePmull(Cfg *Func, Variable *Dest, Operand *Source)
1683 : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pmull, true>(
1684 Func, Dest, Source) {}
1685 };
1686
1687 template <class Machine>
1688 class InstX86BasePmuludq
1689 : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pmuludq,
1690 false> {
1691 public:
1692 static InstX86BasePmuludq *create(Cfg *Func, Variable *Dest,
1693 Operand *Source) {
1694 return new (Func->allocate<InstX86BasePmuludq>())
1695 InstX86BasePmuludq(Func, Dest, Source);
1696 }
1697
1698 void emit(const Cfg *Func) const override;
1699
1700 private:
1701 InstX86BasePmuludq(Cfg *Func, Variable *Dest, Operand *Source)
1702 : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pmuludq, false>(
1703 Func, Dest, Source) {}
1704 };
1705
1706 template <class Machine>
1707 class InstX86BaseDivps
1708 : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Divps, true> {
1709 public:
1710 static InstX86BaseDivps *create(Cfg *Func, Variable *Dest, Operand *Source) {
1711 return new (Func->allocate<InstX86BaseDivps>())
1712 InstX86BaseDivps(Func, Dest, Source);
1713 }
1714
1715 private:
1716 InstX86BaseDivps(Cfg *Func, Variable *Dest, Operand *Source)
1717 : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Divps, true>(
1718 Func, Dest, Source) {}
1719 };
1720
1721 template <class Machine>
1722 class InstX86BaseDivss
1723 : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Divss, false> {
1724 public:
1725 static InstX86BaseDivss *create(Cfg *Func, Variable *Dest, Operand *Source) {
1726 return new (Func->allocate<InstX86BaseDivss>())
1727 InstX86BaseDivss(Func, Dest, Source);
1728 }
1729
1730 void emit(const Cfg *Func) const override;
1731
1732 private:
1733 InstX86BaseDivss(Cfg *Func, Variable *Dest, Operand *Source)
1734 : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Divss, false>(
1735 Func, Dest, Source) {}
1736 };
1737
1738 template <class Machine>
1739 class InstX86BaseRol
1740 : public InstX86BaseBinopGPRShift<Machine, InstX86Base<Machine>::Rol> {
1741 public:
1742 static InstX86BaseRol *create(Cfg *Func, Variable *Dest, Operand *Source) {
1743 return new (Func->allocate<InstX86BaseRol>())
1744 InstX86BaseRol(Func, Dest, Source);
1745 }
1746
1747 private:
1748 InstX86BaseRol(Cfg *Func, Variable *Dest, Operand *Source)
1749 : InstX86BaseBinopGPRShift<Machine, InstX86Base<Machine>::Rol>(Func, Dest,
1750 Source) {}
1751 };
1752
1753 template <class Machine>
1754 class InstX86BaseShl
1755 : public InstX86BaseBinopGPRShift<Machine, InstX86Base<Machine>::Shl> {
1756 public:
1757 static InstX86BaseShl *create(Cfg *Func, Variable *Dest, Operand *Source) {
1758 return new (Func->allocate<InstX86BaseShl>())
1759 InstX86BaseShl(Func, Dest, Source);
1760 }
1761
1762 private:
1763 InstX86BaseShl(Cfg *Func, Variable *Dest, Operand *Source)
1764 : InstX86BaseBinopGPRShift<Machine, InstX86Base<Machine>::Shl>(Func, Dest,
1765 Source) {}
1766 };
1767
1768 template <class Machine>
1769 class InstX86BasePsll
1770 : public InstX86BaseBinopXmmShift<Machine, InstX86Base<Machine>::Psll> {
1771 public:
1772 static InstX86BasePsll *create(Cfg *Func, Variable *Dest, Operand *Source) {
1773 return new (Func->allocate<InstX86BasePsll>())
1774 InstX86BasePsll(Func, Dest, Source);
1775 }
1776
1777 void emit(const Cfg *Func) const override;
1778
1779 private:
1780 InstX86BasePsll(Cfg *Func, Variable *Dest, Operand *Source)
1781 : InstX86BaseBinopXmmShift<Machine, InstX86Base<Machine>::Psll>(
1782 Func, Dest, Source) {}
1783 };
1784
1785 template <class Machine>
1786 class InstX86BasePsrl
1787 : public InstX86BaseBinopXmmShift<Machine, InstX86Base<Machine>::Psrl,
1788 true> {
1789 public:
1790 static InstX86BasePsrl *create(Cfg *Func, Variable *Dest, Operand *Source) {
1791 return new (Func->allocate<InstX86BasePsrl>())
1792 InstX86BasePsrl(Func, Dest, Source);
1793 }
1794
1795 void emit(const Cfg *Func) const override;
1796
1797 private:
1798 InstX86BasePsrl(Cfg *Func, Variable *Dest, Operand *Source)
1799 : InstX86BaseBinopXmmShift<Machine, InstX86Base<Machine>::Psrl, true>(
1800 Func, Dest, Source) {}
1801 };
1802
1803 template <class Machine>
1804 class InstX86BaseShr
1805 : public InstX86BaseBinopGPRShift<Machine, InstX86Base<Machine>::Shr> {
1806 public:
1807 static InstX86BaseShr *create(Cfg *Func, Variable *Dest, Operand *Source) {
1808 return new (Func->allocate<InstX86BaseShr>())
1809 InstX86BaseShr(Func, Dest, Source);
1810 }
1811
1812 private:
1813 InstX86BaseShr(Cfg *Func, Variable *Dest, Operand *Source)
1814 : InstX86BaseBinopGPRShift<Machine, InstX86Base<Machine>::Shr>(Func, Dest,
1815 Source) {}
1816 };
1817
1818 template <class Machine>
1819 class InstX86BaseSar
1820 : public InstX86BaseBinopGPRShift<Machine, InstX86Base<Machine>::Sar> {
1821 public:
1822 static InstX86BaseSar *create(Cfg *Func, Variable *Dest, Operand *Source) {
1823 return new (Func->allocate<InstX86BaseSar>())
1824 InstX86BaseSar(Func, Dest, Source);
1825 }
1826
1827 private:
1828 InstX86BaseSar(Cfg *Func, Variable *Dest, Operand *Source)
1829 : InstX86BaseBinopGPRShift<Machine, InstX86Base<Machine>::Sar>(Func, Dest,
1830 Source) {}
1831 };
1832
1833 template <class Machine>
1834 class InstX86BasePsra
1835 : public InstX86BaseBinopXmmShift<Machine, InstX86Base<Machine>::Psra> {
1836 public:
1837 static InstX86BasePsra *create(Cfg *Func, Variable *Dest, Operand *Source) {
1838 return new (Func->allocate<InstX86BasePsra>())
1839 InstX86BasePsra(Func, Dest, Source);
1840 }
1841
1842 void emit(const Cfg *Func) const override;
1843
1844 private:
1845 InstX86BasePsra(Cfg *Func, Variable *Dest, Operand *Source)
1846 : InstX86BaseBinopXmmShift<Machine, InstX86Base<Machine>::Psra>(
1847 Func, Dest, Source) {}
1848 };
1849
1850 template <class Machine>
1851 class InstX86BasePcmpeq
1852 : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pcmpeq, true> {
1853 public:
1854 static InstX86BasePcmpeq *create(Cfg *Func, Variable *Dest, Operand *Source) {
1855 return new (Func->allocate<InstX86BasePcmpeq>())
1856 InstX86BasePcmpeq(Func, Dest, Source);
1857 }
1858
1859 void emit(const Cfg *Func) const override;
1860
1861 private:
1862 InstX86BasePcmpeq(Cfg *Func, Variable *Dest, Operand *Source)
1863 : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pcmpeq, true>(
1864 Func, Dest, Source) {}
1865 };
1866
1867 template <class Machine>
1868 class InstX86BasePcmpgt
1869 : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pcmpgt, true> {
1870 public:
1871 static InstX86BasePcmpgt *create(Cfg *Func, Variable *Dest, Operand *Source) {
1872 return new (Func->allocate<InstX86BasePcmpgt>())
1873 InstX86BasePcmpgt(Func, Dest, Source);
1874 }
1875
1876 void emit(const Cfg *Func) const override;
1877
1878 private:
1879 InstX86BasePcmpgt(Cfg *Func, Variable *Dest, Operand *Source)
1880 : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pcmpgt, true>(
1881 Func, Dest, Source) {}
1882 };
1883
1884 // movss is only a binary operation when the source and dest
1885 // operands are both registers (the high bits of dest are left untouched).
1886 // In other cases, it behaves like a copy (mov-like) operation (and the
1887 // high bits of dest are cleared).
1888 // InstX86BaseMovss will assert that both its source and dest operands are
1889 // registers, so the lowering code should use _mov instead of _movss
1890 // in cases where a copy operation is intended.
1891 template <class Machine>
1892 class InstX86BaseMovssRegs
1893 : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::MovssRegs,
1894 false> {
1895 public:
1896 static InstX86BaseMovssRegs *create(Cfg *Func, Variable *Dest,
1897 Operand *Source) {
1898 return new (Func->allocate<InstX86BaseMovssRegs>())
1899 InstX86BaseMovssRegs(Func, Dest, Source);
1900 }
1901
1902 void emitIAS(const Cfg *Func) const override;
1903
1904 private:
1905 InstX86BaseMovssRegs(Cfg *Func, Variable *Dest, Operand *Source)
1906 : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::MovssRegs, false>(
1907 Func, Dest, Source) {}
1908 };
1909
1910 template <class Machine>
1911 class InstX86BaseIdiv
1912 : public InstX86BaseTernop<Machine, InstX86Base<Machine>::Idiv> {
1913 public:
1914 static InstX86BaseIdiv *create(Cfg *Func, Variable *Dest, Operand *Source1,
1915 Operand *Source2) {
1916 return new (Func->allocate<InstX86BaseIdiv>())
1917 InstX86BaseIdiv(Func, Dest, Source1, Source2);
1918 }
1919
1920 void emit(const Cfg *Func) const override;
1921 void emitIAS(const Cfg *Func) const override;
1922
1923 private:
1924 InstX86BaseIdiv(Cfg *Func, Variable *Dest, Operand *Source1, Operand *Source2)
1925 : InstX86BaseTernop<Machine, InstX86Base<Machine>::Idiv>(
1926 Func, Dest, Source1, Source2) {}
1927 };
1928
1929 template <class Machine>
1930 class InstX86BaseDiv
1931 : public InstX86BaseTernop<Machine, InstX86Base<Machine>::Div> {
1932 public:
1933 static InstX86BaseDiv *create(Cfg *Func, Variable *Dest, Operand *Source1,
1934 Operand *Source2) {
1935 return new (Func->allocate<InstX86BaseDiv>())
1936 InstX86BaseDiv(Func, Dest, Source1, Source2);
1937 }
1938
1939 void emit(const Cfg *Func) const override;
1940 void emitIAS(const Cfg *Func) const override;
1941
1942 private:
1943 InstX86BaseDiv(Cfg *Func, Variable *Dest, Operand *Source1, Operand *Source2)
1944 : InstX86BaseTernop<Machine, InstX86Base<Machine>::Div>(
1945 Func, Dest, Source1, Source2) {}
1946 };
1947
1948 template <class Machine>
1949 class InstX86BaseInsertps
1950 : public InstX86BaseTernop<Machine, InstX86Base<Machine>::Insertps> {
1951 public:
1952 static InstX86BaseInsertps *create(Cfg *Func, Variable *Dest,
1953 Operand *Source1, Operand *Source2) {
1954 return new (Func->allocate<InstX86BaseInsertps>())
1955 InstX86BaseInsertps(Func, Dest, Source1, Source2);
1956 }
1957
1958 void emitIAS(const Cfg *Func) const override;
1959
1960 private:
1961 InstX86BaseInsertps(Cfg *Func, Variable *Dest, Operand *Source1,
1962 Operand *Source2)
1963 : InstX86BaseTernop<Machine, InstX86Base<Machine>::Insertps>(
1964 Func, Dest, Source1, Source2) {}
1965 };
1966
1967 template <class Machine>
1968 class InstX86BasePinsr
1969 : public InstX86BaseTernop<Machine, InstX86Base<Machine>::Pinsr> {
1970 public:
1971 static InstX86BasePinsr *create(Cfg *Func, Variable *Dest, Operand *Source1,
1972 Operand *Source2) {
1973 return new (Func->allocate<InstX86BasePinsr>())
1974 InstX86BasePinsr(Func, Dest, Source1, Source2);
1975 }
1976
1977 void emit(const Cfg *Func) const override;
1978 void emitIAS(const Cfg *Func) const override;
1979
1980 private:
1981 InstX86BasePinsr(Cfg *Func, Variable *Dest, Operand *Source1,
1982 Operand *Source2)
1983 : InstX86BaseTernop<Machine, InstX86Base<Machine>::Pinsr>(
1984 Func, Dest, Source1, Source2) {}
1985 };
1986
1987 template <class Machine>
1988 class InstX86BaseShufps
1989 : public InstX86BaseTernop<Machine, InstX86Base<Machine>::Shufps> {
1990 public:
1991 static InstX86BaseShufps *create(Cfg *Func, Variable *Dest, Operand *Source1,
1992 Operand *Source2) {
1993 return new (Func->allocate<InstX86BaseShufps>())
1994 InstX86BaseShufps(Func, Dest, Source1, Source2);
1995 }
1996
1997 void emitIAS(const Cfg *Func) const override;
1998
1999 private:
2000 InstX86BaseShufps(Cfg *Func, Variable *Dest, Operand *Source1,
2001 Operand *Source2)
2002 : InstX86BaseTernop<Machine, InstX86Base<Machine>::Shufps>(
2003 Func, Dest, Source1, Source2) {}
2004 };
2005
2006 template <class Machine>
2007 class InstX86BaseBlendvps
2008 : public InstX86BaseTernop<Machine, InstX86Base<Machine>::Blendvps> {
2009 public:
2010 static InstX86BaseBlendvps *create(Cfg *Func, Variable *Dest,
2011 Operand *Source1, Operand *Source2) {
2012 return new (Func->allocate<InstX86BaseBlendvps>())
2013 InstX86BaseBlendvps(Func, Dest, Source1, Source2);
2014 }
2015
2016 void emit(const Cfg *Func) const override;
2017 void emitIAS(const Cfg *Fund) const override;
2018
2019 private:
2020 InstX86BaseBlendvps(Cfg *Func, Variable *Dest, Operand *Source1,
2021 Operand *Source2)
2022 : InstX86BaseTernop<Machine, InstX86Base<Machine>::Blendvps>(
2023 Func, Dest, Source1, Source2) {}
2024 };
2025
2026 template <class Machine>
2027 class InstX86BasePblendvb
2028 : public InstX86BaseTernop<Machine, InstX86Base<Machine>::Pblendvb> {
2029 public:
2030 static InstX86BasePblendvb *create(Cfg *Func, Variable *Dest,
2031 Operand *Source1, Operand *Source2) {
2032 return new (Func->allocate<InstX86BasePblendvb>())
2033 InstX86BasePblendvb(Func, Dest, Source1, Source2);
2034 }
2035
2036 void emit(const Cfg *Func) const override;
2037 void emitIAS(const Cfg *Func) const override;
2038
2039 private:
2040 InstX86BasePblendvb(Cfg *Func, Variable *Dest, Operand *Source1,
2041 Operand *Source2)
2042 : InstX86BaseTernop<Machine, InstX86Base<Machine>::Pblendvb>(
2043 Func, Dest, Source1, Source2) {}
2044 };
2045
2046 template <class Machine>
2047 class InstX86BasePextr
2048 : public InstX86BaseThreeAddressop<Machine, InstX86Base<Machine>::Pextr> {
2049 public:
2050 static InstX86BasePextr *create(Cfg *Func, Variable *Dest, Operand *Source0,
2051 Operand *Source1) {
2052 return new (Func->allocate<InstX86BasePextr>())
2053 InstX86BasePextr(Func, Dest, Source0, Source1);
2054 }
2055
2056 void emit(const Cfg *Func) const override;
2057 void emitIAS(const Cfg *Func) const override;
2058
2059 private:
2060 InstX86BasePextr(Cfg *Func, Variable *Dest, Operand *Source0,
2061 Operand *Source1)
2062 : InstX86BaseThreeAddressop<Machine, InstX86Base<Machine>::Pextr>(
2063 Func, Dest, Source0, Source1) {}
2064 };
2065
2066 template <class Machine>
2067 class InstX86BasePshufd
2068 : public InstX86BaseThreeAddressop<Machine, InstX86Base<Machine>::Pshufd> {
2069 public:
2070 static InstX86BasePshufd *create(Cfg *Func, Variable *Dest, Operand *Source0,
2071 Operand *Source1) {
2072 return new (Func->allocate<InstX86BasePshufd>())
2073 InstX86BasePshufd(Func, Dest, Source0, Source1);
2074 }
2075
2076 void emitIAS(const Cfg *Func) const override;
2077
2078 private:
2079 InstX86BasePshufd(Cfg *Func, Variable *Dest, Operand *Source0,
2080 Operand *Source1)
2081 : InstX86BaseThreeAddressop<Machine, InstX86Base<Machine>::Pshufd>(
2082 Func, Dest, Source0, Source1) {}
2083 };
2084
2085 // Base class for a lockable x86-32 instruction (emits a locked prefix).
2086 template <class Machine>
2087 class InstX86BaseLockable : public InstX86Base<Machine> {
2088 InstX86BaseLockable() = delete;
2089 InstX86BaseLockable(const InstX86BaseLockable &) = delete;
2090 InstX86BaseLockable &operator=(const InstX86BaseLockable &) = delete;
2091
2092 protected:
2093 bool Locked;
2094
2095 InstX86BaseLockable(Cfg *Func,
2096 typename InstX86Base<Machine>::InstKindX86 Kind,
2097 SizeT Maxsrcs, Variable *Dest, bool Locked)
2098 : InstX86Base<Machine>(Func, Kind, Maxsrcs, Dest), Locked(Locked) {
2099 // Assume that such instructions are used for Atomics and be careful
2100 // with optimizations.
2101 this->HasSideEffects = Locked;
2102 }
2103 };
2104
2105 // Mul instruction - unsigned multiply.
2106 template <class Machine> class InstX86BaseMul : public InstX86Base<Machine> {
2107 InstX86BaseMul() = delete;
2108 InstX86BaseMul(const InstX86BaseMul &) = delete;
2109 InstX86BaseMul &operator=(const InstX86BaseMul &) = delete;
2110
2111 public:
2112 static InstX86BaseMul *create(Cfg *Func, Variable *Dest, Variable *Source1,
2113 Operand *Source2) {
2114 return new (Func->allocate<InstX86BaseMul>())
2115 InstX86BaseMul(Func, Dest, Source1, Source2);
2116 }
2117 void emit(const Cfg *Func) const override;
2118 void emitIAS(const Cfg *Func) const override;
2119 void dump(const Cfg *Func) const override;
2120 static bool classof(const Inst *Inst) {
2121 return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Mul);
2122 }
2123
2124 private:
2125 InstX86BaseMul(Cfg *Func, Variable *Dest, Variable *Source1,
2126 Operand *Source2);
2127 };
2128
2129 // Shld instruction - shift across a pair of operands.
2130 template <class Machine> class InstX86BaseShld : public InstX86Base<Machine> {
2131 InstX86BaseShld() = delete;
2132 InstX86BaseShld(const InstX86BaseShld &) = delete;
2133 InstX86BaseShld &operator=(const InstX86BaseShld &) = delete;
2134
2135 public:
2136 static InstX86BaseShld *create(Cfg *Func, Variable *Dest, Variable *Source1,
2137 Variable *Source2) {
2138 return new (Func->allocate<InstX86BaseShld>())
2139 InstX86BaseShld(Func, Dest, Source1, Source2);
2140 }
2141 void emit(const Cfg *Func) const override;
2142 void emitIAS(const Cfg *Func) const override;
2143 void dump(const Cfg *Func) const override;
2144 static bool classof(const Inst *Inst) {
2145 return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Shld);
2146 }
2147
2148 private:
2149 InstX86BaseShld(Cfg *Func, Variable *Dest, Variable *Source1,
2150 Variable *Source2);
2151 };
2152
2153 // Shrd instruction - shift across a pair of operands.
2154 template <class Machine> class InstX86BaseShrd : public InstX86Base<Machine> {
2155 InstX86BaseShrd() = delete;
2156 InstX86BaseShrd(const InstX86BaseShrd &) = delete;
2157 InstX86BaseShrd &operator=(const InstX86BaseShrd &) = delete;
2158
2159 public:
2160 static InstX86BaseShrd *create(Cfg *Func, Variable *Dest, Variable *Source1,
2161 Variable *Source2) {
2162 return new (Func->allocate<InstX86BaseShrd>())
2163 InstX86BaseShrd(Func, Dest, Source1, Source2);
2164 }
2165 void emit(const Cfg *Func) const override;
2166 void emitIAS(const Cfg *Func) const override;
2167 void dump(const Cfg *Func) const override;
2168 static bool classof(const Inst *Inst) {
2169 return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Shrd);
2170 }
2171
2172 private:
2173 InstX86BaseShrd(Cfg *Func, Variable *Dest, Variable *Source1,
2174 Variable *Source2);
2175 };
2176
2177 // Conditional move instruction.
2178 template <class Machine> class InstX86BaseCmov : public InstX86Base<Machine> {
2179 InstX86BaseCmov() = delete;
2180 InstX86BaseCmov(const InstX86BaseCmov &) = delete;
2181 InstX86BaseCmov &operator=(const InstX86BaseCmov &) = delete;
2182
2183 public:
2184 static InstX86BaseCmov *
2185 create(Cfg *Func, Variable *Dest, Operand *Source,
2186 typename InstX86Base<Machine>::Traits::Cond::BrCond Cond) {
2187 return new (Func->allocate<InstX86BaseCmov>())
2188 InstX86BaseCmov(Func, Dest, Source, Cond);
2189 }
2190 void emit(const Cfg *Func) const override;
2191 void emitIAS(const Cfg *Func) const override;
2192 void dump(const Cfg *Func) const override;
2193 static bool classof(const Inst *Inst) {
2194 return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Cmov);
2195 }
2196
2197 private:
2198 InstX86BaseCmov(Cfg *Func, Variable *Dest, Operand *Source,
2199 typename InstX86Base<Machine>::Traits::Cond::BrCond Cond);
2200
2201 typename InstX86Base<Machine>::Traits::Cond::BrCond Condition;
2202 };
2203
2204 // Cmpps instruction - compare packed singled-precision floating point
2205 // values
2206 template <class Machine> class InstX86BaseCmpps : public InstX86Base<Machine> {
2207 InstX86BaseCmpps() = delete;
2208 InstX86BaseCmpps(const InstX86BaseCmpps &) = delete;
2209 InstX86BaseCmpps &operator=(const InstX86BaseCmpps &) = delete;
2210
2211 public:
2212 static InstX86BaseCmpps *
2213 create(Cfg *Func, Variable *Dest, Operand *Source,
2214 typename InstX86Base<Machine>::Traits::Cond::CmppsCond Condition) {
2215 return new (Func->allocate<InstX86BaseCmpps>())
2216 InstX86BaseCmpps(Func, Dest, Source, Condition);
2217 }
2218 void emit(const Cfg *Func) const override;
2219 void emitIAS(const Cfg *Func) const override;
2220 void dump(const Cfg *Func) const override;
2221 static bool classof(const Inst *Inst) {
2222 return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Cmpps);
2223 }
2224
2225 private:
2226 InstX86BaseCmpps(Cfg *Func, Variable *Dest, Operand *Source,
2227 typename InstX86Base<Machine>::Traits::Cond::CmppsCond Cond);
2228
2229 typename InstX86Base<Machine>::Traits::Cond::CmppsCond Condition;
2230 };
2231
2232 // Cmpxchg instruction - cmpxchg <dest>, <desired> will compare if <dest>
2233 // equals eax. If so, the ZF is set and <desired> is stored in <dest>.
2234 // If not, ZF is cleared and <dest> is copied to eax (or subregister).
2235 // <dest> can be a register or memory, while <desired> must be a register.
2236 // It is the user's responsiblity to mark eax with a FakeDef.
2237 template <class Machine>
2238 class InstX86BaseCmpxchg : public InstX86BaseLockable<Machine> {
2239 InstX86BaseCmpxchg() = delete;
2240 InstX86BaseCmpxchg(const InstX86BaseCmpxchg &) = delete;
2241 InstX86BaseCmpxchg &operator=(const InstX86BaseCmpxchg &) = delete;
2242
2243 public:
2244 static InstX86BaseCmpxchg *create(Cfg *Func, Operand *DestOrAddr,
2245 Variable *Eax, Variable *Desired,
2246 bool Locked) {
2247 return new (Func->allocate<InstX86BaseCmpxchg>())
2248 InstX86BaseCmpxchg(Func, DestOrAddr, Eax, Desired, Locked);
2249 }
2250 void emit(const Cfg *Func) const override;
2251 void emitIAS(const Cfg *Func) const override;
2252 void dump(const Cfg *Func) const override;
2253 static bool classof(const Inst *Inst) {
2254 return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Cmpxchg);
2255 }
2256
2257 private:
2258 InstX86BaseCmpxchg(Cfg *Func, Operand *DestOrAddr, Variable *Eax,
2259 Variable *Desired, bool Locked);
2260 };
2261
2262 // Cmpxchg8b instruction - cmpxchg8b <m64> will compare if <m64>
2263 // equals edx:eax. If so, the ZF is set and ecx:ebx is stored in <m64>.
2264 // If not, ZF is cleared and <m64> is copied to edx:eax.
2265 // The caller is responsible for inserting FakeDefs to mark edx
2266 // and eax as modified.
2267 // <m64> must be a memory operand.
2268 template <class Machine>
2269 class InstX86BaseCmpxchg8b : public InstX86BaseLockable<Machine> {
2270 InstX86BaseCmpxchg8b() = delete;
2271 InstX86BaseCmpxchg8b(const InstX86BaseCmpxchg8b &) = delete;
2272 InstX86BaseCmpxchg8b &operator=(const InstX86BaseCmpxchg8b &) = delete;
2273
2274 public:
2275 static InstX86BaseCmpxchg8b *
2276 create(Cfg *Func, typename InstX86Base<Machine>::Traits::X86OperandMem *Dest,
2277 Variable *Edx, Variable *Eax, Variable *Ecx, Variable *Ebx,
2278 bool Locked) {
2279 return new (Func->allocate<InstX86BaseCmpxchg8b>())
2280 InstX86BaseCmpxchg8b(Func, Dest, Edx, Eax, Ecx, Ebx, Locked);
2281 }
2282 void emit(const Cfg *Func) const override;
2283 void emitIAS(const Cfg *Func) const override;
2284 void dump(const Cfg *Func) const override;
2285 static bool classof(const Inst *Inst) {
2286 return InstX86Base<Machine>::isClassof(Inst,
2287 InstX86Base<Machine>::Cmpxchg8b);
2288 }
2289
2290 private:
2291 InstX86BaseCmpxchg8b(
2292 Cfg *Func, typename InstX86Base<Machine>::Traits::X86OperandMem *Dest,
2293 Variable *Edx, Variable *Eax, Variable *Ecx, Variable *Ebx, bool Locked);
2294 };
2295
2296 // Cvt instruction - wrapper for cvtsX2sY where X and Y are in {s,d,i}
2297 // as appropriate. s=float, d=double, i=int. X and Y are determined
2298 // from dest/src types. Sign and zero extension on the integer
2299 // operand needs to be done separately.
2300 template <class Machine> class InstX86BaseCvt : public InstX86Base<Machine> {
2301 InstX86BaseCvt() = delete;
2302 InstX86BaseCvt(const InstX86BaseCvt &) = delete;
2303 InstX86BaseCvt &operator=(const InstX86BaseCvt &) = delete;
2304
2305 public:
2306 enum CvtVariant { Si2ss, Tss2si, Float2float, Dq2ps, Tps2dq };
2307 static InstX86BaseCvt *create(Cfg *Func, Variable *Dest, Operand *Source,
2308 CvtVariant Variant) {
2309 return new (Func->allocate<InstX86BaseCvt>())
2310 InstX86BaseCvt(Func, Dest, Source, Variant);
2311 }
2312 void emit(const Cfg *Func) const override;
2313 void emitIAS(const Cfg *Func) const override;
2314 void dump(const Cfg *Func) const override;
2315 static bool classof(const Inst *Inst) {
2316 return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Cvt);
2317 }
2318 bool isTruncating() const { return Variant == Tss2si || Variant == Tps2dq; }
2319
2320 private:
2321 CvtVariant Variant;
2322 InstX86BaseCvt(Cfg *Func, Variable *Dest, Operand *Source,
2323 CvtVariant Variant);
2324 };
2325
2326 // cmp - Integer compare instruction.
2327 template <class Machine> class InstX86BaseIcmp : public InstX86Base<Machine> {
2328 InstX86BaseIcmp() = delete;
2329 InstX86BaseIcmp(const InstX86BaseIcmp &) = delete;
2330 InstX86BaseIcmp &operator=(const InstX86BaseIcmp &) = delete;
2331
2332 public:
2333 static InstX86BaseIcmp *create(Cfg *Func, Operand *Src1, Operand *Src2) {
2334 return new (Func->allocate<InstX86BaseIcmp>())
2335 InstX86BaseIcmp(Func, Src1, Src2);
2336 }
2337 void emit(const Cfg *Func) const override;
2338 void emitIAS(const Cfg *Func) const override;
2339 void dump(const Cfg *Func) const override;
2340 static bool classof(const Inst *Inst) {
2341 return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Icmp);
2342 }
2343
2344 private:
2345 InstX86BaseIcmp(Cfg *Func, Operand *Src1, Operand *Src2);
2346 };
2347
2348 // ucomiss/ucomisd - floating-point compare instruction.
2349 template <class Machine>
2350 class InstX86BaseUcomiss : public InstX86Base<Machine> {
2351 InstX86BaseUcomiss() = delete;
2352 InstX86BaseUcomiss(const InstX86BaseUcomiss &) = delete;
2353 InstX86BaseUcomiss &operator=(const InstX86BaseUcomiss &) = delete;
2354
2355 public:
2356 static InstX86BaseUcomiss *create(Cfg *Func, Operand *Src1, Operand *Src2) {
2357 return new (Func->allocate<InstX86BaseUcomiss>())
2358 InstX86BaseUcomiss(Func, Src1, Src2);
2359 }
2360 void emit(const Cfg *Func) const override;
2361 void emitIAS(const Cfg *Func) const override;
2362 void dump(const Cfg *Func) const override;
2363 static bool classof(const Inst *Inst) {
2364 return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Ucomiss);
2365 }
2366
2367 private:
2368 InstX86BaseUcomiss(Cfg *Func, Operand *Src1, Operand *Src2);
2369 };
2370
2371 // UD2 instruction.
2372 template <class Machine> class InstX86BaseUD2 : public InstX86Base<Machine> {
2373 InstX86BaseUD2() = delete;
2374 InstX86BaseUD2(const InstX86BaseUD2 &) = delete;
2375 InstX86BaseUD2 &operator=(const InstX86BaseUD2 &) = delete;
2376
2377 public:
2378 static InstX86BaseUD2 *create(Cfg *Func) {
2379 return new (Func->allocate<InstX86BaseUD2>()) InstX86BaseUD2(Func);
2380 }
2381 void emit(const Cfg *Func) const override;
2382 void emitIAS(const Cfg *Func) const override;
2383 void dump(const Cfg *Func) const override;
2384 static bool classof(const Inst *Inst) {
2385 return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::UD2);
2386 }
2387
2388 private:
2389 explicit InstX86BaseUD2(Cfg *Func);
2390 };
2391
2392 // Test instruction.
2393 template <class Machine> class InstX86BaseTest : public InstX86Base<Machine> {
2394 InstX86BaseTest() = delete;
2395 InstX86BaseTest(const InstX86BaseTest &) = delete;
2396 InstX86BaseTest &operator=(const InstX86BaseTest &) = delete;
2397
2398 public:
2399 static InstX86BaseTest *create(Cfg *Func, Operand *Source1,
2400 Operand *Source2) {
2401 return new (Func->allocate<InstX86BaseTest>())
2402 InstX86BaseTest(Func, Source1, Source2);
2403 }
2404 void emit(const Cfg *Func) const override;
2405 void emitIAS(const Cfg *Func) const override;
2406 void dump(const Cfg *Func) const override;
2407 static bool classof(const Inst *Inst) {
2408 return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Test);
2409 }
2410
2411 private:
2412 InstX86BaseTest(Cfg *Func, Operand *Source1, Operand *Source2);
2413 };
2414
2415 // Mfence instruction.
2416 template <class Machine> class InstX86BaseMfence : public InstX86Base<Machine> {
2417 InstX86BaseMfence() = delete;
2418 InstX86BaseMfence(const InstX86BaseMfence &) = delete;
2419 InstX86BaseMfence &operator=(const InstX86BaseMfence &) = delete;
2420
2421 public:
2422 static InstX86BaseMfence *create(Cfg *Func) {
2423 return new (Func->allocate<InstX86BaseMfence>()) InstX86BaseMfence(Func);
2424 }
2425 void emit(const Cfg *Func) const override;
2426 void emitIAS(const Cfg *Func) const override;
2427 void dump(const Cfg *Func) const override;
2428 static bool classof(const Inst *Inst) {
2429 return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Mfence);
2430 }
2431
2432 private:
2433 explicit InstX86BaseMfence(Cfg *Func);
2434 };
2435
2436 // This is essentially a "mov" instruction with an typename
2437 // InstX86Base<Machine>::Traits::X86OperandMem
2438 // operand instead of Variable as the destination. It's important
2439 // for liveness that there is no Dest operand.
2440 template <class Machine> class InstX86BaseStore : public InstX86Base<Machine> {
2441 InstX86BaseStore() = delete;
2442 InstX86BaseStore(const InstX86BaseStore &) = delete;
2443 InstX86BaseStore &operator=(const InstX86BaseStore &) = delete;
2444
2445 public:
2446 static InstX86BaseStore *
2447 create(Cfg *Func, Operand *Value,
2448 typename InstX86Base<Machine>::Traits::X86Operand *Mem) {
2449 return new (Func->allocate<InstX86BaseStore>())
2450 InstX86BaseStore(Func, Value, Mem);
2451 }
2452 void emit(const Cfg *Func) const override;
2453 void emitIAS(const Cfg *Func) const override;
2454 void dump(const Cfg *Func) const override;
2455 static bool classof(const Inst *Inst) {
2456 return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Store);
2457 }
2458
2459 private:
2460 InstX86BaseStore(Cfg *Func, Operand *Value,
2461 typename InstX86Base<Machine>::Traits::X86Operand *Mem);
2462 };
2463
2464 // This is essentially a vector "mov" instruction with an typename
2465 // InstX86Base<Machine>::Traits::X86OperandMem
2466 // operand instead of Variable as the destination. It's important
2467 // for liveness that there is no Dest operand. The source must be an
2468 // Xmm register, since Dest is mem.
2469 template <class Machine> class InstX86BaseStoreP : public InstX86Base<Machine> {
2470 InstX86BaseStoreP() = delete;
2471 InstX86BaseStoreP(const InstX86BaseStoreP &) = delete;
2472 InstX86BaseStoreP &operator=(const InstX86BaseStoreP &) = delete;
2473
2474 public:
2475 static InstX86BaseStoreP *
2476 create(Cfg *Func, Variable *Value,
2477 typename InstX86Base<Machine>::Traits::X86OperandMem *Mem) {
2478 return new (Func->allocate<InstX86BaseStoreP>())
2479 InstX86BaseStoreP(Func, Value, Mem);
2480 }
2481 void emit(const Cfg *Func) const override;
2482 void emitIAS(const Cfg *Func) const override;
2483 void dump(const Cfg *Func) const override;
2484 static bool classof(const Inst *Inst) {
2485 return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::StoreP);
2486 }
2487
2488 private:
2489 InstX86BaseStoreP(Cfg *Func, Variable *Value,
2490 typename InstX86Base<Machine>::Traits::X86OperandMem *Mem);
2491 };
2492
2493 template <class Machine> class InstX86BaseStoreQ : public InstX86Base<Machine> {
2494 InstX86BaseStoreQ() = delete;
2495 InstX86BaseStoreQ(const InstX86BaseStoreQ &) = delete;
2496 InstX86BaseStoreQ &operator=(const InstX86BaseStoreQ &) = delete;
2497
2498 public:
2499 static InstX86BaseStoreQ *
2500 create(Cfg *Func, Variable *Value,
2501 typename InstX86Base<Machine>::Traits::X86OperandMem *Mem) {
2502 return new (Func->allocate<InstX86BaseStoreQ>())
2503 InstX86BaseStoreQ(Func, Value, Mem);
2504 }
2505 void emit(const Cfg *Func) const override;
2506 void emitIAS(const Cfg *Func) const override;
2507 void dump(const Cfg *Func) const override;
2508 static bool classof(const Inst *Inst) {
2509 return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::StoreQ);
2510 }
2511
2512 private:
2513 InstX86BaseStoreQ(Cfg *Func, Variable *Value,
2514 typename InstX86Base<Machine>::Traits::X86OperandMem *Mem);
2515 };
2516
2517 // Nop instructions of varying length
2518 template <class Machine> class InstX86BaseNop : public InstX86Base<Machine> {
2519 InstX86BaseNop() = delete;
2520 InstX86BaseNop(const InstX86BaseNop &) = delete;
2521 InstX86BaseNop &operator=(const InstX86BaseNop &) = delete;
2522
2523 public:
2524 // TODO: Replace with enum.
2525 typedef unsigned NopVariant;
2526
2527 static InstX86BaseNop *create(Cfg *Func, NopVariant Variant) {
2528 return new (Func->allocate<InstX86BaseNop>()) InstX86BaseNop(Func, Variant);
2529 }
2530 void emit(const Cfg *Func) const override;
2531 void emitIAS(const Cfg *Func) const override;
2532 void dump(const Cfg *Func) const override;
2533 static bool classof(const Inst *Inst) {
2534 return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Nop);
2535 }
2536
2537 private:
2538 InstX86BaseNop(Cfg *Func, SizeT Length);
2539
2540 NopVariant Variant;
2541 };
2542
2543 // Fld - load a value onto the x87 FP stack.
2544 template <class Machine> class InstX86BaseFld : public InstX86Base<Machine> {
2545 InstX86BaseFld() = delete;
2546 InstX86BaseFld(const InstX86BaseFld &) = delete;
2547 InstX86BaseFld &operator=(const InstX86BaseFld &) = delete;
2548
2549 public:
2550 static InstX86BaseFld *create(Cfg *Func, Operand *Src) {
2551 return new (Func->allocate<InstX86BaseFld>()) InstX86BaseFld(Func, Src);
2552 }
2553 void emit(const Cfg *Func) const override;
2554 void emitIAS(const Cfg *Func) const override;
2555 void dump(const Cfg *Func) const override;
2556 static bool classof(const Inst *Inst) {
2557 return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Fld);
2558 }
2559
2560 private:
2561 InstX86BaseFld(Cfg *Func, Operand *Src);
2562 };
2563
2564 // Fstp - store x87 st(0) into memory and pop st(0).
2565 template <class Machine> class InstX86BaseFstp : public InstX86Base<Machine> {
2566 InstX86BaseFstp() = delete;
2567 InstX86BaseFstp(const InstX86BaseFstp &) = delete;
2568 InstX86BaseFstp &operator=(const InstX86BaseFstp &) = delete;
2569
2570 public:
2571 static InstX86BaseFstp *create(Cfg *Func, Variable *Dest) {
2572 return new (Func->allocate<InstX86BaseFstp>()) InstX86BaseFstp(Func, Dest);
2573 }
2574 void emit(const Cfg *Func) const override;
2575 void emitIAS(const Cfg *Func) const override;
2576 void dump(const Cfg *Func) const override;
2577 static bool classof(const Inst *Inst) {
2578 return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Fstp);
2579 }
2580
2581 private:
2582 InstX86BaseFstp(Cfg *Func, Variable *Dest);
2583 };
2584
2585 template <class Machine> class InstX86BasePop : public InstX86Base<Machine> {
2586 InstX86BasePop() = delete;
2587 InstX86BasePop(const InstX86BasePop &) = delete;
2588 InstX86BasePop &operator=(const InstX86BasePop &) = delete;
2589
2590 public:
2591 static InstX86BasePop *create(Cfg *Func, Variable *Dest) {
2592 return new (Func->allocate<InstX86BasePop>()) InstX86BasePop(Func, Dest);
2593 }
2594 void emit(const Cfg *Func) const override;
2595 void emitIAS(const Cfg *Func) const override;
2596 void dump(const Cfg *Func) const override;
2597 static bool classof(const Inst *Inst) {
2598 return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Pop);
2599 }
2600
2601 private:
2602 InstX86BasePop(Cfg *Func, Variable *Dest);
2603 };
2604
2605 template <class Machine> class InstX86BasePush : public InstX86Base<Machine> {
2606 InstX86BasePush() = delete;
2607 InstX86BasePush(const InstX86BasePush &) = delete;
2608 InstX86BasePush &operator=(const InstX86BasePush &) = delete;
2609
2610 public:
2611 static InstX86BasePush *create(Cfg *Func, Variable *Source) {
2612 return new (Func->allocate<InstX86BasePush>())
2613 InstX86BasePush(Func, Source);
2614 }
2615 void emit(const Cfg *Func) const override;
2616 void emitIAS(const Cfg *Func) const override;
2617 void dump(const Cfg *Func) const override;
2618 static bool classof(const Inst *Inst) {
2619 return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Push);
2620 }
2621
2622 private:
2623 InstX86BasePush(Cfg *Func, Variable *Source);
2624 };
2625
2626 // Ret instruction. Currently only supports the "ret" version that
2627 // does not pop arguments. This instruction takes a Source operand
2628 // (for non-void returning functions) for liveness analysis, though
2629 // a FakeUse before the ret would do just as well.
2630 template <class Machine> class InstX86BaseRet : public InstX86Base<Machine> {
2631 InstX86BaseRet() = delete;
2632 InstX86BaseRet(const InstX86BaseRet &) = delete;
2633 InstX86BaseRet &operator=(const InstX86BaseRet &) = delete;
2634
2635 public:
2636 static InstX86BaseRet *create(Cfg *Func, Variable *Source = nullptr) {
2637 return new (Func->allocate<InstX86BaseRet>()) InstX86BaseRet(Func, Source);
2638 }
2639 void emit(const Cfg *Func) const override;
2640 void emitIAS(const Cfg *Func) const override;
2641 void dump(const Cfg *Func) const override;
2642 static bool classof(const Inst *Inst) {
2643 return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Ret);
2644 }
2645
2646 private:
2647 InstX86BaseRet(Cfg *Func, Variable *Source);
2648 };
2649
2650 // Conditional set-byte instruction.
2651 template <class Machine> class InstX86BaseSetcc : public InstX86Base<Machine> {
2652 InstX86BaseSetcc() = delete;
2653 InstX86BaseSetcc(const InstX86BaseCmov<Machine> &) = delete;
2654 InstX86BaseSetcc &operator=(const InstX86BaseSetcc &) = delete;
2655
2656 public:
2657 static InstX86BaseSetcc *
2658 create(Cfg *Func, Variable *Dest,
2659 typename InstX86Base<Machine>::Traits::Cond::BrCond Cond) {
2660 return new (Func->allocate<InstX86BaseSetcc>())
2661 InstX86BaseSetcc(Func, Dest, Cond);
2662 }
2663 void emit(const Cfg *Func) const override;
2664 void emitIAS(const Cfg *Func) const override;
2665 void dump(const Cfg *Func) const override;
2666 static bool classof(const Inst *Inst) {
2667 return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Setcc);
2668 }
2669
2670 private:
2671 InstX86BaseSetcc(Cfg *Func, Variable *Dest,
2672 typename InstX86Base<Machine>::Traits::Cond::BrCond Cond);
2673
2674 const typename InstX86Base<Machine>::Traits::Cond::BrCond Condition;
2675 };
2676
2677 // Exchanging Add instruction. Exchanges the first operand (destination
2678 // operand) with the second operand (source operand), then loads the sum
2679 // of the two values into the destination operand. The destination may be
2680 // a register or memory, while the source must be a register.
2681 //
2682 // Both the dest and source are updated. The caller should then insert a
2683 // FakeDef to reflect the second udpate.
2684 template <class Machine>
2685 class InstX86BaseXadd : public InstX86BaseLockable<Machine> {
2686 InstX86BaseXadd() = delete;
2687 InstX86BaseXadd(const InstX86BaseXadd &) = delete;
2688 InstX86BaseXadd &operator=(const InstX86BaseXadd &) = delete;
2689
2690 public:
2691 static InstX86BaseXadd *create(Cfg *Func, Operand *Dest, Variable *Source,
2692 bool Locked) {
2693 return new (Func->allocate<InstX86BaseXadd>())
2694 InstX86BaseXadd(Func, Dest, Source, Locked);
2695 }
2696 void emit(const Cfg *Func) const override;
2697 void emitIAS(const Cfg *Func) const override;
2698 void dump(const Cfg *Func) const override;
2699 static bool classof(const Inst *Inst) {
2700 return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Xadd);
2701 }
2702
2703 private:
2704 InstX86BaseXadd(Cfg *Func, Operand *Dest, Variable *Source, bool Locked);
2705 };
2706
2707 // Exchange instruction. Exchanges the first operand (destination
2708 // operand) with the second operand (source operand). At least one of
2709 // the operands must be a register (and the other can be reg or mem).
2710 // Both the Dest and Source are updated. If there is a memory operand,
2711 // then the instruction is automatically "locked" without the need for
2712 // a lock prefix.
2713 template <class Machine> class InstX86BaseXchg : public InstX86Base<Machine> {
2714 InstX86BaseXchg() = delete;
2715 InstX86BaseXchg(const InstX86BaseXchg &) = delete;
2716 InstX86BaseXchg &operator=(const InstX86BaseXchg &) = delete;
2717
2718 public:
2719 static InstX86BaseXchg *create(Cfg *Func, Operand *Dest, Variable *Source) {
2720 return new (Func->allocate<InstX86BaseXchg>())
2721 InstX86BaseXchg(Func, Dest, Source);
2722 }
2723 void emit(const Cfg *Func) const override;
2724 void emitIAS(const Cfg *Func) const override;
2725 void dump(const Cfg *Func) const override;
2726 static bool classof(const Inst *Inst) {
2727 return InstX86Base<Machine>::isClassof(Inst, InstX86Base<Machine>::Xchg);
2728 }
2729
2730 private:
2731 InstX86BaseXchg(Cfg *Func, Operand *Dest, Variable *Source);
2732 };
2733
2734 template <class Machine> struct Insts {
2735 using FakeRMW = InstX86BaseFakeRMW<Machine>;
2736 using Label = InstX86BaseLabel<Machine>;
2737
2738 using AdjustStack = InstX86BaseAdjustStack<Machine>;
2739 using Call = InstX86BaseCall<Machine>;
2740
2741 using Br = InstX86BaseBr<Machine>;
2742 using Jmp = InstX86BaseJmp<Machine>;
2743 using Bswap = InstX86BaseBswap<Machine>;
2744 using Neg = InstX86BaseNeg<Machine>;
2745 using Bsf = InstX86BaseBsf<Machine>;
2746 using Bsr = InstX86BaseBsr<Machine>;
2747 using Lea = InstX86BaseLea<Machine>;
2748 using Cbwdq = InstX86BaseCbwdq<Machine>;
2749 using Movsx = InstX86BaseMovsx<Machine>;
2750 using Movzx = InstX86BaseMovzx<Machine>;
2751 using Movd = InstX86BaseMovd<Machine>;
2752 using Sqrtss = InstX86BaseSqrtss<Machine>;
2753 using Mov = InstX86BaseMov<Machine>;
2754 using Movp = InstX86BaseMovp<Machine>;
2755 using Movq = InstX86BaseMovq<Machine>;
2756 using Add = InstX86BaseAdd<Machine>;
2757 using AddRMW = InstX86BaseAddRMW<Machine>;
2758 using Addps = InstX86BaseAddps<Machine>;
2759 using Adc = InstX86BaseAdc<Machine>;
2760 using AdcRMW = InstX86BaseAdcRMW<Machine>;
2761 using Addss = InstX86BaseAddss<Machine>;
2762 using Padd = InstX86BasePadd<Machine>;
2763 using Sub = InstX86BaseSub<Machine>;
2764 using SubRMW = InstX86BaseSubRMW<Machine>;
2765 using Subps = InstX86BaseSubps<Machine>;
2766 using Subss = InstX86BaseSubss<Machine>;
2767 using Sbb = InstX86BaseSbb<Machine>;
2768 using SbbRMW = InstX86BaseSbbRMW<Machine>;
2769 using Psub = InstX86BasePsub<Machine>;
2770 using And = InstX86BaseAnd<Machine>;
2771 using AndRMW = InstX86BaseAndRMW<Machine>;
2772 using Pand = InstX86BasePand<Machine>;
2773 using Pandn = InstX86BasePandn<Machine>;
2774 using Or = InstX86BaseOr<Machine>;
2775 using OrRMW = InstX86BaseOrRMW<Machine>;
2776 using Por = InstX86BasePor<Machine>;
2777 using Xor = InstX86BaseXor<Machine>;
2778 using XorRMW = InstX86BaseXorRMW<Machine>;
2779 using Pxor = InstX86BasePxor<Machine>;
2780 using Imul = InstX86BaseImul<Machine>;
2781 using Mulps = InstX86BaseMulps<Machine>;
2782 using Mulss = InstX86BaseMulss<Machine>;
2783 using Pmull = InstX86BasePmull<Machine>;
2784 using Pmuludq = InstX86BasePmuludq<Machine>;
2785 using Divps = InstX86BaseDivps<Machine>;
2786 using Divss = InstX86BaseDivss<Machine>;
2787 using Rol = InstX86BaseRol<Machine>;
2788 using Shl = InstX86BaseShl<Machine>;
2789 using Psll = InstX86BasePsll<Machine>;
2790 using Psrl = InstX86BasePsrl<Machine>;
2791 using Shr = InstX86BaseShr<Machine>;
2792 using Sar = InstX86BaseSar<Machine>;
2793 using Psra = InstX86BasePsra<Machine>;
2794 using Pcmpeq = InstX86BasePcmpeq<Machine>;
2795 using Pcmpgt = InstX86BasePcmpgt<Machine>;
2796 using MovssRegs = InstX86BaseMovssRegs<Machine>;
2797 using Idiv = InstX86BaseIdiv<Machine>;
2798 using Div = InstX86BaseDiv<Machine>;
2799 using Insertps = InstX86BaseInsertps<Machine>;
2800 using Pinsr = InstX86BasePinsr<Machine>;
2801 using Shufps = InstX86BaseShufps<Machine>;
2802 using Blendvps = InstX86BaseBlendvps<Machine>;
2803 using Pblendvb = InstX86BasePblendvb<Machine>;
2804 using Pextr = InstX86BasePextr<Machine>;
2805 using Pshufd = InstX86BasePshufd<Machine>;
2806 using Lockable = InstX86BaseLockable<Machine>;
2807 using Mul = InstX86BaseMul<Machine>;
2808 using Shld = InstX86BaseShld<Machine>;
2809 using Shrd = InstX86BaseShrd<Machine>;
2810 using Cmov = InstX86BaseCmov<Machine>;
2811 using Cmpps = InstX86BaseCmpps<Machine>;
2812 using Cmpxchg = InstX86BaseCmpxchg<Machine>;
2813 using Cmpxchg8b = InstX86BaseCmpxchg8b<Machine>;
2814 using Cvt = InstX86BaseCvt<Machine>;
2815 using Icmp = InstX86BaseIcmp<Machine>;
2816 using Ucomiss = InstX86BaseUcomiss<Machine>;
2817 using UD2 = InstX86BaseUD2<Machine>;
2818 using Test = InstX86BaseTest<Machine>;
2819 using Mfence = InstX86BaseMfence<Machine>;
2820 using Store = InstX86BaseStore<Machine>;
2821 using StoreP = InstX86BaseStoreP<Machine>;
2822 using StoreQ = InstX86BaseStoreQ<Machine>;
2823 using Nop = InstX86BaseNop<Machine>;
2824 using Fld = InstX86BaseFld<Machine>;
2825 using Fstp = InstX86BaseFstp<Machine>;
2826 using Pop = InstX86BasePop<Machine>;
2827 using Push = InstX86BasePush<Machine>;
2828 using Ret = InstX86BaseRet<Machine>;
2829 using Setcc = InstX86BaseSetcc<Machine>;
2830 using Xadd = InstX86BaseXadd<Machine>;
2831 using Xchg = InstX86BaseXchg<Machine>;
2832 };
2833
2834 #define X86INSTS_DEFINE_STATIC_DATA(Machine) \
2835 namespace Ice { \
2836 namespace X86Internal { \
2837 /* In-place ops */ \
2838 template <> const char *InstX86BaseBswap<Machine>::Base::Opcode = "bswap"; \
2839 template <> const char *InstX86BaseNeg<Machine>::Base::Opcode = "neg"; \
2840 /* Unary ops */ \
2841 template <> const char *InstX86BaseBsf<Machine>::Base::Opcode = "bsf"; \
2842 template <> const char *InstX86BaseBsr<Machine>::Base::Opcode = "bsr"; \
2843 template <> const char *InstX86BaseLea<Machine>::Base::Opcode = "lea"; \
2844 template <> const char *InstX86BaseMovd<Machine>::Base::Opcode = "movd"; \
2845 template <> const char *InstX86BaseMovsx<Machine>::Base::Opcode = "movs"; \
2846 template <> const char *InstX86BaseMovzx<Machine>::Base::Opcode = "movz"; \
2847 template <> const char *InstX86BaseSqrtss<Machine>::Base::Opcode = "sqrtss"; \
2848 template <> \
2849 const char *InstX86BaseCbwdq<Machine>::Base::Opcode = "cbw/cwd/cdq"; \
2850 /* Mov-like ops */ \
2851 template <> const char *InstX86BaseMov<Machine>::Base::Opcode = "mov"; \
2852 template <> const char *InstX86BaseMovp<Machine>::Base::Opcode = "movups"; \
2853 template <> const char *InstX86BaseMovq<Machine>::Base::Opcode = "movq"; \
2854 /* Binary ops */ \
2855 template <> const char *InstX86BaseAdd<Machine>::Base::Opcode = "add"; \
2856 template <> const char *InstX86BaseAddRMW<Machine>::Base::Opcode = "add"; \
2857 template <> const char *InstX86BaseAddps<Machine>::Base::Opcode = "addps"; \
2858 template <> const char *InstX86BaseAdc<Machine>::Base::Opcode = "adc"; \
2859 template <> const char *InstX86BaseAdcRMW<Machine>::Base::Opcode = "adc"; \
2860 template <> const char *InstX86BaseAddss<Machine>::Base::Opcode = "addss"; \
2861 template <> const char *InstX86BasePadd<Machine>::Base::Opcode = "padd"; \
2862 template <> const char *InstX86BaseSub<Machine>::Base::Opcode = "sub"; \
2863 template <> const char *InstX86BaseSubRMW<Machine>::Base::Opcode = "sub"; \
2864 template <> const char *InstX86BaseSubps<Machine>::Base::Opcode = "subps"; \
2865 template <> const char *InstX86BaseSubss<Machine>::Base::Opcode = "subss"; \
2866 template <> const char *InstX86BaseSbb<Machine>::Base::Opcode = "sbb"; \
2867 template <> const char *InstX86BaseSbbRMW<Machine>::Base::Opcode = "sbb"; \
2868 template <> const char *InstX86BasePsub<Machine>::Base::Opcode = "psub"; \
2869 template <> const char *InstX86BaseAnd<Machine>::Base::Opcode = "and"; \
2870 template <> const char *InstX86BaseAndRMW<Machine>::Base::Opcode = "and"; \
2871 template <> const char *InstX86BasePand<Machine>::Base::Opcode = "pand"; \
2872 template <> const char *InstX86BasePandn<Machine>::Base::Opcode = "pandn"; \
2873 template <> const char *InstX86BaseOr<Machine>::Base::Opcode = "or"; \
2874 template <> const char *InstX86BaseOrRMW<Machine>::Base::Opcode = "or"; \
2875 template <> const char *InstX86BasePor<Machine>::Base::Opcode = "por"; \
2876 template <> const char *InstX86BaseXor<Machine>::Base::Opcode = "xor"; \
2877 template <> const char *InstX86BaseXorRMW<Machine>::Base::Opcode = "xor"; \
2878 template <> const char *InstX86BasePxor<Machine>::Base::Opcode = "pxor"; \
2879 template <> const char *InstX86BaseImul<Machine>::Base::Opcode = "imul"; \
2880 template <> const char *InstX86BaseMulps<Machine>::Base::Opcode = "mulps"; \
2881 template <> const char *InstX86BaseMulss<Machine>::Base::Opcode = "mulss"; \
2882 template <> const char *InstX86BasePmull<Machine>::Base::Opcode = "pmull"; \
2883 template <> \
2884 const char *InstX86BasePmuludq<Machine>::Base::Opcode = "pmuludq"; \
2885 template <> const char *InstX86BaseDiv<Machine>::Base::Opcode = "div"; \
2886 template <> const char *InstX86BaseDivps<Machine>::Base::Opcode = "divps"; \
2887 template <> const char *InstX86BaseIdiv<Machine>::Base::Opcode = "idiv"; \
2888 template <> const char *InstX86BaseDivss<Machine>::Base::Opcode = "divss"; \
2889 template <> const char *InstX86BaseRol<Machine>::Base::Opcode = "rol"; \
2890 template <> const char *InstX86BaseShl<Machine>::Base::Opcode = "shl"; \
2891 template <> const char *InstX86BasePsll<Machine>::Base::Opcode = "psll"; \
2892 template <> const char *InstX86BaseShr<Machine>::Base::Opcode = "shr"; \
2893 template <> const char *InstX86BaseSar<Machine>::Base::Opcode = "sar"; \
2894 template <> const char *InstX86BasePsra<Machine>::Base::Opcode = "psra"; \
2895 template <> const char *InstX86BasePsrl<Machine>::Base::Opcode = "psrl"; \
2896 template <> const char *InstX86BasePcmpeq<Machine>::Base::Opcode = "pcmpeq"; \
2897 template <> const char *InstX86BasePcmpgt<Machine>::Base::Opcode = "pcmpgt"; \
2898 template <> \
2899 const char *InstX86BaseMovssRegs<Machine>::Base::Opcode = "movss"; \
2900 /* Ternary ops */ \
2901 template <> \
2902 const char *InstX86BaseInsertps<Machine>::Base::Opcode = "insertps"; \
2903 template <> const char *InstX86BaseShufps<Machine>::Base::Opcode = "shufps"; \
2904 template <> const char *InstX86BasePinsr<Machine>::Base::Opcode = "pinsr"; \
2905 template <> \
2906 const char *InstX86BaseBlendvps<Machine>::Base::Opcode = "blendvps"; \
2907 template <> \
2908 const char *InstX86BasePblendvb<Machine>::Base::Opcode = "pblendvb"; \
2909 /* Three address ops */ \
2910 template <> const char *InstX86BasePextr<Machine>::Base::Opcode = "pextr"; \
2911 template <> const char *InstX86BasePshufd<Machine>::Base::Opcode = "pshufd"; \
2912 /* Inplace GPR ops */ \
2913 template <> \
2914 const InstX86Base<Machine>::Traits::Assembler::GPREmitterOneOp \
2915 InstX86BaseBswap<Machine>::Base::Emitter = { \
2916 &InstX86Base<Machine>::Traits::Assembler::bswap, \
2917 nullptr /* only a reg form exists */ \
2918 }; \
2919 template <> \
2920 const InstX86Base<Machine>::Traits::Assembler::GPREmitterOneOp \
2921 InstX86BaseNeg<Machine>::Base::Emitter = { \
2922 &InstX86Base<Machine>::Traits::Assembler::neg, \
2923 &InstX86Base<Machine>::Traits::Assembler::neg}; \
2924 \
2925 /* Unary GPR ops */ \
2926 template <> /* uses specialized emitter. */ \
2927 const InstX86Base<Machine>::Traits::Assembler::GPREmitterRegOp \
2928 InstX86BaseCbwdq<Machine>::Base::Emitter = {nullptr, nullptr, nullptr}; \
2929 template <> \
2930 const InstX86Base<Machine>::Traits::Assembler::GPREmitterRegOp \
2931 InstX86BaseBsf<Machine>::Base::Emitter = { \
2932 &InstX86Base<Machine>::Traits::Assembler::bsf, \
2933 &InstX86Base<Machine>::Traits::Assembler::bsf, nullptr}; \
2934 template <> \
2935 const InstX86Base<Machine>::Traits::Assembler::GPREmitterRegOp \
2936 InstX86BaseBsr<Machine>::Base::Emitter = { \
2937 &InstX86Base<Machine>::Traits::Assembler::bsr, \
2938 &InstX86Base<Machine>::Traits::Assembler::bsr, nullptr}; \
2939 template <> \
2940 const InstX86Base<Machine>::Traits::Assembler::GPREmitterRegOp \
2941 InstX86BaseLea<Machine>::Base::Emitter = { \
2942 /* reg/reg and reg/imm are illegal */ nullptr, \
2943 &InstX86Base<Machine>::Traits::Assembler::lea, nullptr}; \
2944 template <> \
2945 const InstX86Base<Machine>::Traits::Assembler::GPREmitterRegOp \
2946 InstX86BaseMovsx<Machine>::Base::Emitter = { \
2947 &InstX86Base<Machine>::Traits::Assembler::movsx, \
2948 &InstX86Base<Machine>::Traits::Assembler::movsx, nullptr}; \
2949 template <> \
2950 const InstX86Base<Machine>::Traits::Assembler::GPREmitterRegOp \
2951 InstX86BaseMovzx<Machine>::Base::Emitter = { \
2952 &InstX86Base<Machine>::Traits::Assembler::movzx, \
2953 &InstX86Base<Machine>::Traits::Assembler::movzx, nullptr}; \
2954 \
2955 /* Unary XMM ops */ \
2956 template <> /* uses specialized emitter. */ \
2957 const InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp \
2958 InstX86BaseMovd<Machine>::Base::Emitter = {nullptr, nullptr}; \
2959 template <> \
2960 const InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp \
2961 InstX86BaseSqrtss<Machine>::Base::Emitter = { \
2962 &InstX86Base<Machine>::Traits::Assembler::sqrtss, \
2963 &InstX86Base<Machine>::Traits::Assembler::sqrtss}; \
2964 \
2965 /* Binary GPR ops */ \
2966 template <> /* uses specialized emitter. */ \
2967 const InstX86Base<Machine>::Traits::Assembler::GPREmitterRegOp \
2968 InstX86BaseImul<Machine>::Base::Emitter = {nullptr, nullptr, nullptr}; \
2969 template <> \
2970 const InstX86Base<Machine>::Traits::Assembler::GPREmitterRegOp \
2971 InstX86BaseAdd<Machine>::Base::Emitter = { \
2972 &InstX86Base<Machine>::Traits::Assembler::add, \
2973 &InstX86Base<Machine>::Traits::Assembler::add, \
2974 &InstX86Base<Machine>::Traits::Assembler::add}; \
2975 template <> \
2976 const InstX86Base<Machine>::Traits::Assembler::GPREmitterAddrOp \
2977 InstX86BaseAddRMW<Machine>::Base::Emitter = { \
2978 &InstX86Base<Machine>::Traits::Assembler::add, \
2979 &InstX86Base<Machine>::Traits::Assembler::add}; \
2980 template <> \
2981 const InstX86Base<Machine>::Traits::Assembler::GPREmitterRegOp \
2982 InstX86BaseAdc<Machine>::Base::Emitter = { \
2983 &InstX86Base<Machine>::Traits::Assembler::adc, \
2984 &InstX86Base<Machine>::Traits::Assembler::adc, \
2985 &InstX86Base<Machine>::Traits::Assembler::adc}; \
2986 template <> \
2987 const InstX86Base<Machine>::Traits::Assembler::GPREmitterAddrOp \
2988 InstX86BaseAdcRMW<Machine>::Base::Emitter = { \
2989 &InstX86Base<Machine>::Traits::Assembler::adc, \
2990 &InstX86Base<Machine>::Traits::Assembler::adc}; \
2991 template <> \
2992 const InstX86Base<Machine>::Traits::Assembler::GPREmitterRegOp \
2993 InstX86BaseAnd<Machine>::Base::Emitter = { \
2994 &InstX86Base<Machine>::Traits::Assembler::And, \
2995 &InstX86Base<Machine>::Traits::Assembler::And, \
2996 &InstX86Base<Machine>::Traits::Assembler::And}; \
2997 template <> \
2998 const InstX86Base<Machine>::Traits::Assembler::GPREmitterAddrOp \
2999 InstX86BaseAndRMW<Machine>::Base::Emitter = { \
3000 &InstX86Base<Machine>::Traits::Assembler::And, \
3001 &InstX86Base<Machine>::Traits::Assembler::And}; \
3002 template <> \
3003 const InstX86Base<Machine>::Traits::Assembler::GPREmitterRegOp \
3004 InstX86BaseOr<Machine>::Base::Emitter = { \
3005 &InstX86Base<Machine>::Traits::Assembler::Or, \
3006 &InstX86Base<Machine>::Traits::Assembler::Or, \
3007 &InstX86Base<Machine>::Traits::Assembler::Or}; \
3008 template <> \
3009 const InstX86Base<Machine>::Traits::Assembler::GPREmitterAddrOp \
3010 InstX86BaseOrRMW<Machine>::Base::Emitter = { \
3011 &InstX86Base<Machine>::Traits::Assembler::Or, \
3012 &InstX86Base<Machine>::Traits::Assembler::Or}; \
3013 template <> \
3014 const InstX86Base<Machine>::Traits::Assembler::GPREmitterRegOp \
3015 InstX86BaseSbb<Machine>::Base::Emitter = { \
3016 &InstX86Base<Machine>::Traits::Assembler::sbb, \
3017 &InstX86Base<Machine>::Traits::Assembler::sbb, \
3018 &InstX86Base<Machine>::Traits::Assembler::sbb}; \
3019 template <> \
3020 const InstX86Base<Machine>::Traits::Assembler::GPREmitterAddrOp \
3021 InstX86BaseSbbRMW<Machine>::Base::Emitter = { \
3022 &InstX86Base<Machine>::Traits::Assembler::sbb, \
3023 &InstX86Base<Machine>::Traits::Assembler::sbb}; \
3024 template <> \
3025 const InstX86Base<Machine>::Traits::Assembler::GPREmitterRegOp \
3026 InstX86BaseSub<Machine>::Base::Emitter = { \
3027 &InstX86Base<Machine>::Traits::Assembler::sub, \
3028 &InstX86Base<Machine>::Traits::Assembler::sub, \
3029 &InstX86Base<Machine>::Traits::Assembler::sub}; \
3030 template <> \
3031 const InstX86Base<Machine>::Traits::Assembler::GPREmitterAddrOp \
3032 InstX86BaseSubRMW<Machine>::Base::Emitter = { \
3033 &InstX86Base<Machine>::Traits::Assembler::sub, \
3034 &InstX86Base<Machine>::Traits::Assembler::sub}; \
3035 template <> \
3036 const InstX86Base<Machine>::Traits::Assembler::GPREmitterRegOp \
3037 InstX86BaseXor<Machine>::Base::Emitter = { \
3038 &InstX86Base<Machine>::Traits::Assembler::Xor, \
3039 &InstX86Base<Machine>::Traits::Assembler::Xor, \
3040 &InstX86Base<Machine>::Traits::Assembler::Xor}; \
3041 template <> \
3042 const InstX86Base<Machine>::Traits::Assembler::GPREmitterAddrOp \
3043 InstX86BaseXorRMW<Machine>::Base::Emitter = { \
3044 &InstX86Base<Machine>::Traits::Assembler::Xor, \
3045 &InstX86Base<Machine>::Traits::Assembler::Xor}; \
3046 \
3047 /* Binary Shift GPR ops */ \
3048 template <> \
3049 const InstX86Base<Machine>::Traits::Assembler::GPREmitterShiftOp \
3050 InstX86BaseRol<Machine>::Base::Emitter = { \
3051 &InstX86Base<Machine>::Traits::Assembler::rol, \
3052 &InstX86Base<Machine>::Traits::Assembler::rol}; \
3053 template <> \
3054 const InstX86Base<Machine>::Traits::Assembler::GPREmitterShiftOp \
3055 InstX86BaseSar<Machine>::Base::Emitter = { \
3056 &InstX86Base<Machine>::Traits::Assembler::sar, \
3057 &InstX86Base<Machine>::Traits::Assembler::sar}; \
3058 template <> \
3059 const InstX86Base<Machine>::Traits::Assembler::GPREmitterShiftOp \
3060 InstX86BaseShl<Machine>::Base::Emitter = { \
3061 &InstX86Base<Machine>::Traits::Assembler::shl, \
3062 &InstX86Base<Machine>::Traits::Assembler::shl}; \
3063 template <> \
3064 const InstX86Base<Machine>::Traits::Assembler::GPREmitterShiftOp \
3065 InstX86BaseShr<Machine>::Base::Emitter = { \
3066 &InstX86Base<Machine>::Traits::Assembler::shr, \
3067 &InstX86Base<Machine>::Traits::Assembler::shr}; \
3068 \
3069 /* Binary XMM ops */ \
3070 template <> /* uses specialized emitter. */ \
3071 const InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp \
3072 InstX86BaseMovssRegs<Machine>::Base::Emitter = {nullptr, nullptr}; \
3073 template <> \
3074 const InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp \
3075 InstX86BaseAddss<Machine>::Base::Emitter = { \
3076 &InstX86Base<Machine>::Traits::Assembler::addss, \
3077 &InstX86Base<Machine>::Traits::Assembler::addss}; \
3078 template <> \
3079 const InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp \
3080 InstX86BaseAddps<Machine>::Base::Emitter = { \
3081 &InstX86Base<Machine>::Traits::Assembler::addps, \
3082 &InstX86Base<Machine>::Traits::Assembler::addps}; \
3083 template <> \
3084 const InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp \
3085 InstX86BaseDivss<Machine>::Base::Emitter = { \
3086 &InstX86Base<Machine>::Traits::Assembler::divss, \
3087 &InstX86Base<Machine>::Traits::Assembler::divss}; \
3088 template <> \
3089 const InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp \
3090 InstX86BaseDivps<Machine>::Base::Emitter = { \
3091 &InstX86Base<Machine>::Traits::Assembler::divps, \
3092 &InstX86Base<Machine>::Traits::Assembler::divps}; \
3093 template <> \
3094 const InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp \
3095 InstX86BaseMulss<Machine>::Base::Emitter = { \
3096 &InstX86Base<Machine>::Traits::Assembler::mulss, \
3097 &InstX86Base<Machine>::Traits::Assembler::mulss}; \
3098 template <> \
3099 const InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp \
3100 InstX86BaseMulps<Machine>::Base::Emitter = { \
3101 &InstX86Base<Machine>::Traits::Assembler::mulps, \
3102 &InstX86Base<Machine>::Traits::Assembler::mulps}; \
3103 template <> \
3104 const InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp \
3105 InstX86BasePadd<Machine>::Base::Emitter = { \
3106 &InstX86Base<Machine>::Traits::Assembler::padd, \
3107 &InstX86Base<Machine>::Traits::Assembler::padd}; \
3108 template <> \
3109 const InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp \
3110 InstX86BasePand<Machine>::Base::Emitter = { \
3111 &InstX86Base<Machine>::Traits::Assembler::pand, \
3112 &InstX86Base<Machine>::Traits::Assembler::pand}; \
3113 template <> \
3114 const InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp \
3115 InstX86BasePandn<Machine>::Base::Emitter = { \
3116 &InstX86Base<Machine>::Traits::Assembler::pandn, \
3117 &InstX86Base<Machine>::Traits::Assembler::pandn}; \
3118 template <> \
3119 const InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp \
3120 InstX86BasePcmpeq<Machine>::Base::Emitter = { \
3121 &InstX86Base<Machine>::Traits::Assembler::pcmpeq, \
3122 &InstX86Base<Machine>::Traits::Assembler::pcmpeq}; \
3123 template <> \
3124 const InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp \
3125 InstX86BasePcmpgt<Machine>::Base::Emitter = { \
3126 &InstX86Base<Machine>::Traits::Assembler::pcmpgt, \
3127 &InstX86Base<Machine>::Traits::Assembler::pcmpgt}; \
3128 template <> \
3129 const InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp \
3130 InstX86BasePmull<Machine>::Base::Emitter = { \
3131 &InstX86Base<Machine>::Traits::Assembler::pmull, \
3132 &InstX86Base<Machine>::Traits::Assembler::pmull}; \
3133 template <> \
3134 const InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp \
3135 InstX86BasePmuludq<Machine>::Base::Emitter = { \
3136 &InstX86Base<Machine>::Traits::Assembler::pmuludq, \
3137 &InstX86Base<Machine>::Traits::Assembler::pmuludq}; \
3138 template <> \
3139 const InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp \
3140 InstX86BasePor<Machine>::Base::Emitter = { \
3141 &InstX86Base<Machine>::Traits::Assembler::por, \
3142 &InstX86Base<Machine>::Traits::Assembler::por}; \
3143 template <> \
3144 const InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp \
3145 InstX86BasePsub<Machine>::Base::Emitter = { \
3146 &InstX86Base<Machine>::Traits::Assembler::psub, \
3147 &InstX86Base<Machine>::Traits::Assembler::psub}; \
3148 template <> \
3149 const InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp \
3150 InstX86BasePxor<Machine>::Base::Emitter = { \
3151 &InstX86Base<Machine>::Traits::Assembler::pxor, \
3152 &InstX86Base<Machine>::Traits::Assembler::pxor}; \
3153 template <> \
3154 const InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp \
3155 InstX86BaseSubss<Machine>::Base::Emitter = { \
3156 &InstX86Base<Machine>::Traits::Assembler::subss, \
3157 &InstX86Base<Machine>::Traits::Assembler::subss}; \
3158 template <> \
3159 const InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp \
3160 InstX86BaseSubps<Machine>::Base::Emitter = { \
3161 &InstX86Base<Machine>::Traits::Assembler::subps, \
3162 &InstX86Base<Machine>::Traits::Assembler::subps}; \
3163 \
3164 /* Binary XMM Shift ops */ \
3165 template <> \
3166 const InstX86Base<Machine>::Traits::Assembler::XmmEmitterShiftOp \
3167 InstX86BasePsll<Machine>::Base::Emitter = { \
3168 &InstX86Base<Machine>::Traits::Assembler::psll, \
3169 &InstX86Base<Machine>::Traits::Assembler::psll, \
3170 &InstX86Base<Machine>::Traits::Assembler::psll}; \
3171 template <> \
3172 const InstX86Base<Machine>::Traits::Assembler::XmmEmitterShiftOp \
3173 InstX86BasePsra<Machine>::Base::Emitter = { \
3174 &InstX86Base<Machine>::Traits::Assembler::psra, \
3175 &InstX86Base<Machine>::Traits::Assembler::psra, \
3176 &InstX86Base<Machine>::Traits::Assembler::psra}; \
3177 template <> \
3178 const InstX86Base<Machine>::Traits::Assembler::XmmEmitterShiftOp \
3179 InstX86BasePsrl<Machine>::Base::Emitter = { \
3180 &InstX86Base<Machine>::Traits::Assembler::psrl, \
3181 &InstX86Base<Machine>::Traits::Assembler::psrl, \
3182 &InstX86Base<Machine>::Traits::Assembler::psrl}; \
3183 } \
3184 }
3185
3186 } // end of namespace X86Internal
3187 } // end of namespace Ice
3188
3189 #include "IceInstX86BaseImpl.h"
3190
3191 #endif // SUBZERO_SRC_ICEINSTX86BASE_H
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698