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

Side by Side Diff: src/IceInstX86Base.h

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

Powered by Google App Engine
This is Rietveld 408576698