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

Side by Side Diff: src/IceInstX8632.h

Issue 1181013016: Subzero. Fixes memory leaks. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Addresses codereview comments. Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/IceInstARM32.h ('k') | src/IceOperand.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 //===- subzero/src/IceInstX8632.h - x86-32 machine instructions -*- C++ -*-===// 1 //===- subzero/src/IceInstX8632.h - x86-32 machine instructions -*- C++ -*-===//
2 // 2 //
3 // The Subzero Code Generator 3 // The Subzero Code Generator
4 // 4 //
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 // 9 //
10 // This file declares the InstX8632 and OperandX8632 classes and 10 // This file declares the InstX8632 and OperandX8632 classes and
(...skipping 27 matching lines...) Expand all
38 enum OperandKindX8632 { k__Start = Operand::kTarget, kMem, kSplit }; 38 enum OperandKindX8632 { k__Start = Operand::kTarget, kMem, kSplit };
39 using Operand::dump; 39 using Operand::dump;
40 void dump(const Cfg *, Ostream &Str) const override { 40 void dump(const Cfg *, Ostream &Str) const override {
41 if (ALLOW_DUMP) 41 if (ALLOW_DUMP)
42 Str << "<OperandX8632>"; 42 Str << "<OperandX8632>";
43 } 43 }
44 44
45 protected: 45 protected:
46 OperandX8632(OperandKindX8632 Kind, Type Ty) 46 OperandX8632(OperandKindX8632 Kind, Type Ty)
47 : Operand(static_cast<OperandKind>(Kind), Ty) {} 47 : Operand(static_cast<OperandKind>(Kind), Ty) {}
48 ~OperandX8632() override {}
49 }; 48 };
50 49
51 // OperandX8632Mem represents the m32 addressing mode, with optional 50 // OperandX8632Mem represents the m32 addressing mode, with optional
52 // base and index registers, a constant offset, and a fixed shift 51 // base and index registers, a constant offset, and a fixed shift
53 // value for the index register. 52 // value for the index register.
54 class OperandX8632Mem : public OperandX8632 { 53 class OperandX8632Mem : public OperandX8632 {
55 OperandX8632Mem() = delete; 54 OperandX8632Mem() = delete;
56 OperandX8632Mem(const OperandX8632Mem &) = delete; 55 OperandX8632Mem(const OperandX8632Mem &) = delete;
57 OperandX8632Mem &operator=(const OperandX8632Mem &) = delete; 56 OperandX8632Mem &operator=(const OperandX8632Mem &) = delete;
58 57
(...skipping 23 matching lines...) Expand all
82 using OperandX8632::dump; 81 using OperandX8632::dump;
83 void dump(const Cfg *Func, Ostream &Str) const override; 82 void dump(const Cfg *Func, Ostream &Str) const override;
84 83
85 static bool classof(const Operand *Operand) { 84 static bool classof(const Operand *Operand) {
86 return Operand->getKind() == static_cast<OperandKind>(kMem); 85 return Operand->getKind() == static_cast<OperandKind>(kMem);
87 } 86 }
88 87
89 private: 88 private:
90 OperandX8632Mem(Cfg *Func, Type Ty, Variable *Base, Constant *Offset, 89 OperandX8632Mem(Cfg *Func, Type Ty, Variable *Base, Constant *Offset,
91 Variable *Index, uint16_t Shift, SegmentRegisters SegmentReg); 90 Variable *Index, uint16_t Shift, SegmentRegisters SegmentReg);
92 ~OperandX8632Mem() override {} 91
93 Variable *Base; 92 Variable *Base;
94 Constant *Offset; 93 Constant *Offset;
95 Variable *Index; 94 Variable *Index;
96 uint16_t Shift; 95 uint16_t Shift;
97 SegmentRegisters SegmentReg : 16; 96 SegmentRegisters SegmentReg : 16;
98 }; 97 };
99 98
100 // VariableSplit is a way to treat an f64 memory location as a pair 99 // VariableSplit is a way to treat an f64 memory location as a pair
101 // of i32 locations (Low and High). This is needed for some cases 100 // of i32 locations (Low and High). This is needed for some cases
102 // of the Bitcast instruction. Since it's not possible for integer 101 // of the Bitcast instruction. Since it's not possible for integer
(...skipping 16 matching lines...) Expand all
119 void emit(const Cfg *Func) const override; 118 void emit(const Cfg *Func) const override;
120 using OperandX8632::dump; 119 using OperandX8632::dump;
121 void dump(const Cfg *Func, Ostream &Str) const override; 120 void dump(const Cfg *Func, Ostream &Str) const override;
122 121
123 static bool classof(const Operand *Operand) { 122 static bool classof(const Operand *Operand) {
124 return Operand->getKind() == static_cast<OperandKind>(kSplit); 123 return Operand->getKind() == static_cast<OperandKind>(kSplit);
125 } 124 }
126 125
127 private: 126 private:
128 VariableSplit(Cfg *Func, Variable *Var, Portion Part) 127 VariableSplit(Cfg *Func, Variable *Var, Portion Part)
129 : OperandX8632(kSplit, IceType_i32), Func(Func), Var(Var), Part(Part) { 128 : OperandX8632(kSplit, IceType_i32), Var(Var), Part(Part) {
130 assert(Var->getType() == IceType_f64); 129 assert(Var->getType() == IceType_f64);
131 Vars = Func->allocateArrayOf<Variable *>(1); 130 Vars = Func->allocateArrayOf<Variable *>(1);
132 Vars[0] = Var; 131 Vars[0] = Var;
133 NumVars = 1; 132 NumVars = 1;
134 } 133 }
135 ~VariableSplit() override { Func->deallocateArrayOf<Variable *>(Vars); } 134
136 Cfg *Func; // Held only for the destructor.
137 Variable *Var; 135 Variable *Var;
138 Portion Part; 136 Portion Part;
139 }; 137 };
140 138
141 // SpillVariable decorates a Variable by linking it to another 139 // SpillVariable decorates a Variable by linking it to another
142 // Variable. When stack frame offsets are computed, the SpillVariable 140 // Variable. When stack frame offsets are computed, the SpillVariable
143 // is given a distinct stack slot only if its linked Variable has a 141 // is given a distinct stack slot only if its linked Variable has a
144 // register. If the linked Variable has a stack slot, then the 142 // register. If the linked Variable has a stack slot, then the
145 // Variable and SpillVariable share that slot. 143 // Variable and SpillVariable share that slot.
146 class SpillVariable : public Variable { 144 class SpillVariable : public Variable {
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
277 const Cfg *Func, bool ShiftHack = false); 275 const Cfg *Func, bool ShiftHack = false);
278 276
279 static void 277 static void
280 emitIASGPRShift(const Cfg *Func, Type Ty, const Variable *Var, 278 emitIASGPRShift(const Cfg *Func, Type Ty, const Variable *Var,
281 const Operand *Src, 279 const Operand *Src,
282 const X8632::AssemblerX8632::GPREmitterShiftOp &Emitter); 280 const X8632::AssemblerX8632::GPREmitterShiftOp &Emitter);
283 281
284 protected: 282 protected:
285 InstX8632(Cfg *Func, InstKindX8632 Kind, SizeT Maxsrcs, Variable *Dest) 283 InstX8632(Cfg *Func, InstKindX8632 Kind, SizeT Maxsrcs, Variable *Dest)
286 : InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {} 284 : InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {}
287 ~InstX8632() override {} 285
288 static bool isClassof(const Inst *Inst, InstKindX8632 MyKind) { 286 static bool isClassof(const Inst *Inst, InstKindX8632 MyKind) {
289 return Inst->getKind() == static_cast<InstKind>(MyKind); 287 return Inst->getKind() == static_cast<InstKind>(MyKind);
290 } 288 }
291 // Most instructions that operate on vector arguments require vector 289 // Most instructions that operate on vector arguments require vector
292 // memory operands to be fully aligned (16-byte alignment for PNaCl 290 // memory operands to be fully aligned (16-byte alignment for PNaCl
293 // vector types). The stack frame layout and call ABI ensure proper 291 // vector types). The stack frame layout and call ABI ensure proper
294 // alignment for stack operands, but memory operands (originating 292 // alignment for stack operands, but memory operands (originating
295 // from load/store bitcode instructions) only have element-size 293 // from load/store bitcode instructions) only have element-size
296 // alignment guarantees. This function validates that none of the 294 // alignment guarantees. This function validates that none of the
297 // operands is a memory operand of vector type, calling 295 // operands is a memory operand of vector type, calling
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
338 Operand *getData() const { return getSrc(0); } 336 Operand *getData() const { return getSrc(0); }
339 InstArithmetic::OpKind getOp() const { return Op; } 337 InstArithmetic::OpKind getOp() const { return Op; }
340 Variable *getBeacon() const { return llvm::cast<Variable>(getSrc(2)); } 338 Variable *getBeacon() const { return llvm::cast<Variable>(getSrc(2)); }
341 void dump(const Cfg *Func) const override; 339 void dump(const Cfg *Func) const override;
342 static bool classof(const Inst *Inst) { return isClassof(Inst, FakeRMW); } 340 static bool classof(const Inst *Inst) { return isClassof(Inst, FakeRMW); }
343 341
344 private: 342 private:
345 InstArithmetic::OpKind Op; 343 InstArithmetic::OpKind Op;
346 InstX8632FakeRMW(Cfg *Func, Operand *Data, Operand *Addr, 344 InstX8632FakeRMW(Cfg *Func, Operand *Data, Operand *Addr,
347 InstArithmetic::OpKind Op, Variable *Beacon); 345 InstArithmetic::OpKind Op, Variable *Beacon);
348 ~InstX8632FakeRMW() override {}
349 }; 346 };
350 347
351 // InstX8632Label represents an intra-block label that is the target 348 // InstX8632Label represents an intra-block label that is the target
352 // of an intra-block branch. The offset between the label and the 349 // of an intra-block branch. The offset between the label and the
353 // branch must be fit into one byte (considered "near"). These are 350 // branch must be fit into one byte (considered "near"). These are
354 // used for lowering i1 calculations, Select instructions, and 64-bit 351 // used for lowering i1 calculations, Select instructions, and 64-bit
355 // compares on a 32-bit architecture, without basic block splitting. 352 // compares on a 32-bit architecture, without basic block splitting.
356 // Basic block splitting is not so desirable for several reasons, one 353 // Basic block splitting is not so desirable for several reasons, one
357 // of which is the impact on decisions based on whether a variable's 354 // of which is the impact on decisions based on whether a variable's
358 // live range spans multiple basic blocks. 355 // live range spans multiple basic blocks.
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
397 } 394 }
398 uint32_t getEmitInstCount() const override { return 0; } 395 uint32_t getEmitInstCount() const override { return 0; }
399 IceString getName(const Cfg *Func) const; 396 IceString getName(const Cfg *Func) const;
400 SizeT getNumber() const { return Number; } 397 SizeT getNumber() const { return Number; }
401 void emit(const Cfg *Func) const override; 398 void emit(const Cfg *Func) const override;
402 void emitIAS(const Cfg *Func) const override; 399 void emitIAS(const Cfg *Func) const override;
403 void dump(const Cfg *Func) const override; 400 void dump(const Cfg *Func) const override;
404 401
405 private: 402 private:
406 InstX8632Label(Cfg *Func, TargetX8632 *Target); 403 InstX8632Label(Cfg *Func, TargetX8632 *Target);
407 ~InstX8632Label() override {} 404
408 SizeT Number; // used for unique label generation. 405 SizeT Number; // used for unique label generation.
409 }; 406 };
410 407
411 // Conditional and unconditional branch instruction. 408 // Conditional and unconditional branch instruction.
412 class InstX8632Br : public InstX8632 { 409 class InstX8632Br : public InstX8632 {
413 InstX8632Br() = delete; 410 InstX8632Br() = delete;
414 InstX8632Br(const InstX8632Br &) = delete; 411 InstX8632Br(const InstX8632Br &) = delete;
415 InstX8632Br &operator=(const InstX8632Br &) = delete; 412 InstX8632Br &operator=(const InstX8632Br &) = delete;
416 413
417 public: 414 public:
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
468 } 465 }
469 bool repointEdge(CfgNode *OldNode, CfgNode *NewNode) override; 466 bool repointEdge(CfgNode *OldNode, CfgNode *NewNode) override;
470 void emit(const Cfg *Func) const override; 467 void emit(const Cfg *Func) const override;
471 void emitIAS(const Cfg *Func) const override; 468 void emitIAS(const Cfg *Func) const override;
472 void dump(const Cfg *Func) const override; 469 void dump(const Cfg *Func) const override;
473 static bool classof(const Inst *Inst) { return isClassof(Inst, Br); } 470 static bool classof(const Inst *Inst) { return isClassof(Inst, Br); }
474 471
475 private: 472 private:
476 InstX8632Br(Cfg *Func, const CfgNode *TargetTrue, const CfgNode *TargetFalse, 473 InstX8632Br(Cfg *Func, const CfgNode *TargetTrue, const CfgNode *TargetFalse,
477 const InstX8632Label *Label, CondX86::BrCond Condition); 474 const InstX8632Label *Label, CondX86::BrCond Condition);
478 ~InstX8632Br() override {} 475
479 CondX86::BrCond Condition; 476 CondX86::BrCond Condition;
480 const CfgNode *TargetTrue; 477 const CfgNode *TargetTrue;
481 const CfgNode *TargetFalse; 478 const CfgNode *TargetFalse;
482 const InstX8632Label *Label; // Intra-block branch target 479 const InstX8632Label *Label; // Intra-block branch target
483 }; 480 };
484 481
485 // Jump to a target outside this function, such as tailcall, nacljump, 482 // Jump to a target outside this function, such as tailcall, nacljump,
486 // naclret, unreachable. This is different from a Branch instruction 483 // naclret, unreachable. This is different from a Branch instruction
487 // in that there is no intra-function control flow to represent. 484 // in that there is no intra-function control flow to represent.
488 class InstX8632Jmp : public InstX8632 { 485 class InstX8632Jmp : public InstX8632 {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
538 InstX8632Call(Func, Dest, CallTarget); 535 InstX8632Call(Func, Dest, CallTarget);
539 } 536 }
540 Operand *getCallTarget() const { return getSrc(0); } 537 Operand *getCallTarget() const { return getSrc(0); }
541 void emit(const Cfg *Func) const override; 538 void emit(const Cfg *Func) const override;
542 void emitIAS(const Cfg *Func) const override; 539 void emitIAS(const Cfg *Func) const override;
543 void dump(const Cfg *Func) const override; 540 void dump(const Cfg *Func) const override;
544 static bool classof(const Inst *Inst) { return isClassof(Inst, Call); } 541 static bool classof(const Inst *Inst) { return isClassof(Inst, Call); }
545 542
546 private: 543 private:
547 InstX8632Call(Cfg *Func, Variable *Dest, Operand *CallTarget); 544 InstX8632Call(Cfg *Func, Variable *Dest, Operand *CallTarget);
548 ~InstX8632Call() override {}
549 }; 545 };
550 546
551 // Emit a one-operand (GPR) instruction. 547 // Emit a one-operand (GPR) instruction.
552 void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Var, 548 void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Var,
553 const X8632::AssemblerX8632::GPREmitterOneOp &Emitter); 549 const X8632::AssemblerX8632::GPREmitterOneOp &Emitter);
554 void emitIASAsAddrOpTyGPR( 550 void emitIASAsAddrOpTyGPR(
555 const Cfg *Func, Type Ty, const Operand *Op0, const Operand *Op1, 551 const Cfg *Func, Type Ty, const Operand *Op0, const Operand *Op1,
556 const X8632::AssemblerX8632::GPREmitterAddrOp &Emitter); 552 const X8632::AssemblerX8632::GPREmitterAddrOp &Emitter);
557 553
558 // Instructions of the form x := op(x). 554 // Instructions of the form x := op(x).
(...skipping 30 matching lines...) Expand all
589 Str << " = " << Opcode << "." << getDest()->getType() << " "; 585 Str << " = " << Opcode << "." << getDest()->getType() << " ";
590 dumpSources(Func); 586 dumpSources(Func);
591 } 587 }
592 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } 588 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
593 589
594 private: 590 private:
595 InstX8632InplaceopGPR(Cfg *Func, Operand *SrcDest) 591 InstX8632InplaceopGPR(Cfg *Func, Operand *SrcDest)
596 : InstX8632(Func, K, 1, llvm::dyn_cast<Variable>(SrcDest)) { 592 : InstX8632(Func, K, 1, llvm::dyn_cast<Variable>(SrcDest)) {
597 addSource(SrcDest); 593 addSource(SrcDest);
598 } 594 }
599 ~InstX8632InplaceopGPR() override {} 595
600 static const char *Opcode; 596 static const char *Opcode;
601 static const X8632::AssemblerX8632::GPREmitterOneOp Emitter; 597 static const X8632::AssemblerX8632::GPREmitterOneOp Emitter;
602 }; 598 };
603 599
604 // Emit a two-operand (GPR) instruction, where the dest operand is a 600 // Emit a two-operand (GPR) instruction, where the dest operand is a
605 // Variable that's guaranteed to be a register. 601 // Variable that's guaranteed to be a register.
606 template <bool VarCanBeByte = true, bool SrcCanBeByte = true> 602 template <bool VarCanBeByte = true, bool SrcCanBeByte = true>
607 void emitIASRegOpTyGPR(const Cfg *Func, Type Ty, const Variable *Dst, 603 void emitIASRegOpTyGPR(const Cfg *Func, Type Ty, const Variable *Dst,
608 const Operand *Src, 604 const Operand *Src,
609 const X8632::AssemblerX8632::GPREmitterRegOp &Emitter); 605 const X8632::AssemblerX8632::GPREmitterRegOp &Emitter);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
653 Str << " = " << Opcode << "." << getSrc(0)->getType() << " "; 649 Str << " = " << Opcode << "." << getSrc(0)->getType() << " ";
654 dumpSources(Func); 650 dumpSources(Func);
655 } 651 }
656 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } 652 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
657 653
658 private: 654 private:
659 InstX8632UnaryopGPR(Cfg *Func, Variable *Dest, Operand *Src) 655 InstX8632UnaryopGPR(Cfg *Func, Variable *Dest, Operand *Src)
660 : InstX8632(Func, K, 1, Dest) { 656 : InstX8632(Func, K, 1, Dest) {
661 addSource(Src); 657 addSource(Src);
662 } 658 }
663 ~InstX8632UnaryopGPR() override {} 659
664 static const char *Opcode; 660 static const char *Opcode;
665 static const X8632::AssemblerX8632::GPREmitterRegOp Emitter; 661 static const X8632::AssemblerX8632::GPREmitterRegOp Emitter;
666 }; 662 };
667 663
668 void emitIASRegOpTyXMM(const Cfg *Func, Type Ty, const Variable *Var, 664 void emitIASRegOpTyXMM(const Cfg *Func, Type Ty, const Variable *Var,
669 const Operand *Src, 665 const Operand *Src,
670 const X8632::AssemblerX8632::XmmEmitterRegOp &Emitter); 666 const X8632::AssemblerX8632::XmmEmitterRegOp &Emitter);
671 667
672 template <InstX8632::InstKindX8632 K> 668 template <InstX8632::InstKindX8632 K>
673 class InstX8632UnaryopXmm : public InstX8632 { 669 class InstX8632UnaryopXmm : public InstX8632 {
(...skipping 29 matching lines...) Expand all
703 Str << " = " << Opcode << "." << getDest()->getType() << " "; 699 Str << " = " << Opcode << "." << getDest()->getType() << " ";
704 dumpSources(Func); 700 dumpSources(Func);
705 } 701 }
706 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } 702 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
707 703
708 private: 704 private:
709 InstX8632UnaryopXmm(Cfg *Func, Variable *Dest, Operand *Src) 705 InstX8632UnaryopXmm(Cfg *Func, Variable *Dest, Operand *Src)
710 : InstX8632(Func, K, 1, Dest) { 706 : InstX8632(Func, K, 1, Dest) {
711 addSource(Src); 707 addSource(Src);
712 } 708 }
713 ~InstX8632UnaryopXmm() override {} 709
714 static const char *Opcode; 710 static const char *Opcode;
715 static const X8632::AssemblerX8632::XmmEmitterRegOp Emitter; 711 static const X8632::AssemblerX8632::XmmEmitterRegOp Emitter;
716 }; 712 };
717 713
718 template <InstX8632::InstKindX8632 K> 714 template <InstX8632::InstKindX8632 K>
719 class InstX8632BinopGPRShift : public InstX8632 { 715 class InstX8632BinopGPRShift : public InstX8632 {
720 InstX8632BinopGPRShift() = delete; 716 InstX8632BinopGPRShift() = delete;
721 InstX8632BinopGPRShift(const InstX8632BinopGPRShift &) = delete; 717 InstX8632BinopGPRShift(const InstX8632BinopGPRShift &) = delete;
722 InstX8632BinopGPRShift &operator=(const InstX8632BinopGPRShift &) = delete; 718 InstX8632BinopGPRShift &operator=(const InstX8632BinopGPRShift &) = delete;
723 719
(...skipping 24 matching lines...) Expand all
748 dumpSources(Func); 744 dumpSources(Func);
749 } 745 }
750 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } 746 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
751 747
752 private: 748 private:
753 InstX8632BinopGPRShift(Cfg *Func, Variable *Dest, Operand *Source) 749 InstX8632BinopGPRShift(Cfg *Func, Variable *Dest, Operand *Source)
754 : InstX8632(Func, K, 2, Dest) { 750 : InstX8632(Func, K, 2, Dest) {
755 addSource(Dest); 751 addSource(Dest);
756 addSource(Source); 752 addSource(Source);
757 } 753 }
758 ~InstX8632BinopGPRShift() override {} 754
759 static const char *Opcode; 755 static const char *Opcode;
760 static const X8632::AssemblerX8632::GPREmitterShiftOp Emitter; 756 static const X8632::AssemblerX8632::GPREmitterShiftOp Emitter;
761 }; 757 };
762 758
763 template <InstX8632::InstKindX8632 K> 759 template <InstX8632::InstKindX8632 K>
764 class InstX8632BinopGPR : public InstX8632 { 760 class InstX8632BinopGPR : public InstX8632 {
765 InstX8632BinopGPR() = delete; 761 InstX8632BinopGPR() = delete;
766 InstX8632BinopGPR(const InstX8632BinopGPR &) = delete; 762 InstX8632BinopGPR(const InstX8632BinopGPR &) = delete;
767 InstX8632BinopGPR &operator=(const InstX8632BinopGPR &) = delete; 763 InstX8632BinopGPR &operator=(const InstX8632BinopGPR &) = delete;
768 764
(...skipping 23 matching lines...) Expand all
792 dumpSources(Func); 788 dumpSources(Func);
793 } 789 }
794 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } 790 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
795 791
796 private: 792 private:
797 InstX8632BinopGPR(Cfg *Func, Variable *Dest, Operand *Source) 793 InstX8632BinopGPR(Cfg *Func, Variable *Dest, Operand *Source)
798 : InstX8632(Func, K, 2, Dest) { 794 : InstX8632(Func, K, 2, Dest) {
799 addSource(Dest); 795 addSource(Dest);
800 addSource(Source); 796 addSource(Source);
801 } 797 }
802 ~InstX8632BinopGPR() override {} 798
803 static const char *Opcode; 799 static const char *Opcode;
804 static const X8632::AssemblerX8632::GPREmitterRegOp Emitter; 800 static const X8632::AssemblerX8632::GPREmitterRegOp Emitter;
805 }; 801 };
806 802
807 template <InstX8632::InstKindX8632 K> 803 template <InstX8632::InstKindX8632 K>
808 class InstX8632BinopRMW : public InstX8632 { 804 class InstX8632BinopRMW : public InstX8632 {
809 InstX8632BinopRMW() = delete; 805 InstX8632BinopRMW() = delete;
810 InstX8632BinopRMW(const InstX8632BinopRMW &) = delete; 806 InstX8632BinopRMW(const InstX8632BinopRMW &) = delete;
811 InstX8632BinopRMW &operator=(const InstX8632BinopRMW &) = delete; 807 InstX8632BinopRMW &operator=(const InstX8632BinopRMW &) = delete;
812 808
(...skipping 23 matching lines...) Expand all
836 dumpSources(Func); 832 dumpSources(Func);
837 } 833 }
838 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } 834 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
839 835
840 private: 836 private:
841 InstX8632BinopRMW(Cfg *Func, OperandX8632Mem *DestSrc0, Operand *Src1) 837 InstX8632BinopRMW(Cfg *Func, OperandX8632Mem *DestSrc0, Operand *Src1)
842 : InstX8632(Func, K, 2, nullptr) { 838 : InstX8632(Func, K, 2, nullptr) {
843 addSource(DestSrc0); 839 addSource(DestSrc0);
844 addSource(Src1); 840 addSource(Src1);
845 } 841 }
846 ~InstX8632BinopRMW() override {}
847 static const char *Opcode; 842 static const char *Opcode;
848 static const X8632::AssemblerX8632::GPREmitterAddrOp Emitter; 843 static const X8632::AssemblerX8632::GPREmitterAddrOp Emitter;
849 }; 844 };
850 845
851 template <InstX8632::InstKindX8632 K, bool NeedsElementType> 846 template <InstX8632::InstKindX8632 K, bool NeedsElementType>
852 class InstX8632BinopXmm : public InstX8632 { 847 class InstX8632BinopXmm : public InstX8632 {
853 InstX8632BinopXmm() = delete; 848 InstX8632BinopXmm() = delete;
854 InstX8632BinopXmm(const InstX8632BinopXmm &) = delete; 849 InstX8632BinopXmm(const InstX8632BinopXmm &) = delete;
855 InstX8632BinopXmm &operator=(const InstX8632BinopXmm &) = delete; 850 InstX8632BinopXmm &operator=(const InstX8632BinopXmm &) = delete;
856 851
(...skipping 27 matching lines...) Expand all
884 dumpSources(Func); 879 dumpSources(Func);
885 } 880 }
886 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } 881 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
887 882
888 private: 883 private:
889 InstX8632BinopXmm(Cfg *Func, Variable *Dest, Operand *Source) 884 InstX8632BinopXmm(Cfg *Func, Variable *Dest, Operand *Source)
890 : InstX8632(Func, K, 2, Dest) { 885 : InstX8632(Func, K, 2, Dest) {
891 addSource(Dest); 886 addSource(Dest);
892 addSource(Source); 887 addSource(Source);
893 } 888 }
894 ~InstX8632BinopXmm() override {} 889
895 static const char *Opcode; 890 static const char *Opcode;
896 static const X8632::AssemblerX8632::XmmEmitterRegOp Emitter; 891 static const X8632::AssemblerX8632::XmmEmitterRegOp Emitter;
897 }; 892 };
898 893
899 void emitIASXmmShift(const Cfg *Func, Type Ty, const Variable *Var, 894 void emitIASXmmShift(const Cfg *Func, Type Ty, const Variable *Var,
900 const Operand *Src, 895 const Operand *Src,
901 const X8632::AssemblerX8632::XmmEmitterShiftOp &Emitter); 896 const X8632::AssemblerX8632::XmmEmitterShiftOp &Emitter);
902 897
903 template <InstX8632::InstKindX8632 K, bool AllowAllTypes = false> 898 template <InstX8632::InstKindX8632 K, bool AllowAllTypes = false>
904 class InstX8632BinopXmmShift : public InstX8632 { 899 class InstX8632BinopXmmShift : public InstX8632 {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
937 dumpSources(Func); 932 dumpSources(Func);
938 } 933 }
939 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } 934 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
940 935
941 private: 936 private:
942 InstX8632BinopXmmShift(Cfg *Func, Variable *Dest, Operand *Source) 937 InstX8632BinopXmmShift(Cfg *Func, Variable *Dest, Operand *Source)
943 : InstX8632(Func, K, 2, Dest) { 938 : InstX8632(Func, K, 2, Dest) {
944 addSource(Dest); 939 addSource(Dest);
945 addSource(Source); 940 addSource(Source);
946 } 941 }
947 ~InstX8632BinopXmmShift() override {} 942
948 static const char *Opcode; 943 static const char *Opcode;
949 static const X8632::AssemblerX8632::XmmEmitterShiftOp Emitter; 944 static const X8632::AssemblerX8632::XmmEmitterShiftOp Emitter;
950 }; 945 };
951 946
952 template <InstX8632::InstKindX8632 K> class InstX8632Ternop : public InstX8632 { 947 template <InstX8632::InstKindX8632 K> class InstX8632Ternop : public InstX8632 {
953 InstX8632Ternop() = delete; 948 InstX8632Ternop() = delete;
954 InstX8632Ternop(const InstX8632Ternop &) = delete; 949 InstX8632Ternop(const InstX8632Ternop &) = delete;
955 InstX8632Ternop &operator=(const InstX8632Ternop &) = delete; 950 InstX8632Ternop &operator=(const InstX8632Ternop &) = delete;
956 951
957 public: 952 public:
(...skipping 26 matching lines...) Expand all
984 } 979 }
985 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } 980 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
986 981
987 private: 982 private:
988 InstX8632Ternop(Cfg *Func, Variable *Dest, Operand *Source1, Operand *Source2) 983 InstX8632Ternop(Cfg *Func, Variable *Dest, Operand *Source1, Operand *Source2)
989 : InstX8632(Func, K, 3, Dest) { 984 : InstX8632(Func, K, 3, Dest) {
990 addSource(Dest); 985 addSource(Dest);
991 addSource(Source1); 986 addSource(Source1);
992 addSource(Source2); 987 addSource(Source2);
993 } 988 }
994 ~InstX8632Ternop() override {} 989
995 static const char *Opcode; 990 static const char *Opcode;
996 }; 991 };
997 992
998 // Instructions of the form x := y op z 993 // Instructions of the form x := y op z
999 template <InstX8632::InstKindX8632 K> 994 template <InstX8632::InstKindX8632 K>
1000 class InstX8632ThreeAddressop : public InstX8632 { 995 class InstX8632ThreeAddressop : public InstX8632 {
1001 InstX8632ThreeAddressop() = delete; 996 InstX8632ThreeAddressop() = delete;
1002 InstX8632ThreeAddressop(const InstX8632ThreeAddressop &) = delete; 997 InstX8632ThreeAddressop(const InstX8632ThreeAddressop &) = delete;
1003 InstX8632ThreeAddressop &operator=(const InstX8632ThreeAddressop &) = delete; 998 InstX8632ThreeAddressop &operator=(const InstX8632ThreeAddressop &) = delete;
1004 999
(...skipping 26 matching lines...) Expand all
1031 } 1026 }
1032 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } 1027 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
1033 1028
1034 private: 1029 private:
1035 InstX8632ThreeAddressop(Cfg *Func, Variable *Dest, Operand *Source0, 1030 InstX8632ThreeAddressop(Cfg *Func, Variable *Dest, Operand *Source0,
1036 Operand *Source1) 1031 Operand *Source1)
1037 : InstX8632(Func, K, 2, Dest) { 1032 : InstX8632(Func, K, 2, Dest) {
1038 addSource(Source0); 1033 addSource(Source0);
1039 addSource(Source1); 1034 addSource(Source1);
1040 } 1035 }
1041 ~InstX8632ThreeAddressop() override {} 1036
1042 static const char *Opcode; 1037 static const char *Opcode;
1043 }; 1038 };
1044 1039
1045 // Base class for assignment instructions 1040 // Base class for assignment instructions
1046 template <InstX8632::InstKindX8632 K> 1041 template <InstX8632::InstKindX8632 K>
1047 class InstX8632Movlike : public InstX8632 { 1042 class InstX8632Movlike : public InstX8632 {
1048 InstX8632Movlike() = delete; 1043 InstX8632Movlike() = delete;
1049 InstX8632Movlike(const InstX8632Movlike &) = delete; 1044 InstX8632Movlike(const InstX8632Movlike &) = delete;
1050 InstX8632Movlike &operator=(const InstX8632Movlike &) = delete; 1045 InstX8632Movlike &operator=(const InstX8632Movlike &) = delete;
1051 1046
(...skipping 17 matching lines...) Expand all
1069 Str << ", "; 1064 Str << ", ";
1070 dumpSources(Func); 1065 dumpSources(Func);
1071 } 1066 }
1072 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } 1067 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
1073 1068
1074 private: 1069 private:
1075 InstX8632Movlike(Cfg *Func, Variable *Dest, Operand *Source) 1070 InstX8632Movlike(Cfg *Func, Variable *Dest, Operand *Source)
1076 : InstX8632(Func, K, 1, Dest) { 1071 : InstX8632(Func, K, 1, Dest) {
1077 addSource(Source); 1072 addSource(Source);
1078 } 1073 }
1079 ~InstX8632Movlike() override {}
1080 1074
1081 static const char *Opcode; 1075 static const char *Opcode;
1082 }; 1076 };
1083 1077
1084 typedef InstX8632InplaceopGPR<InstX8632::Bswap> InstX8632Bswap; 1078 typedef InstX8632InplaceopGPR<InstX8632::Bswap> InstX8632Bswap;
1085 typedef InstX8632InplaceopGPR<InstX8632::Neg> InstX8632Neg; 1079 typedef InstX8632InplaceopGPR<InstX8632::Neg> InstX8632Neg;
1086 typedef InstX8632UnaryopGPR<InstX8632::Bsf> InstX8632Bsf; 1080 typedef InstX8632UnaryopGPR<InstX8632::Bsf> InstX8632Bsf;
1087 typedef InstX8632UnaryopGPR<InstX8632::Bsr> InstX8632Bsr; 1081 typedef InstX8632UnaryopGPR<InstX8632::Bsr> InstX8632Bsr;
1088 typedef InstX8632UnaryopGPR<InstX8632::Lea> InstX8632Lea; 1082 typedef InstX8632UnaryopGPR<InstX8632::Lea> InstX8632Lea;
1089 // Cbwdq instruction - wrapper for cbw, cwd, and cdq 1083 // Cbwdq instruction - wrapper for cbw, cwd, and cdq
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1160 protected: 1154 protected:
1161 bool Locked; 1155 bool Locked;
1162 1156
1163 InstX8632Lockable(Cfg *Func, InstKindX8632 Kind, SizeT Maxsrcs, 1157 InstX8632Lockable(Cfg *Func, InstKindX8632 Kind, SizeT Maxsrcs,
1164 Variable *Dest, bool Locked) 1158 Variable *Dest, bool Locked)
1165 : InstX8632(Func, Kind, Maxsrcs, Dest), Locked(Locked) { 1159 : InstX8632(Func, Kind, Maxsrcs, Dest), Locked(Locked) {
1166 // Assume that such instructions are used for Atomics and be careful 1160 // Assume that such instructions are used for Atomics and be careful
1167 // with optimizations. 1161 // with optimizations.
1168 HasSideEffects = Locked; 1162 HasSideEffects = Locked;
1169 } 1163 }
1170 ~InstX8632Lockable() override {}
1171 }; 1164 };
1172 1165
1173 // Mul instruction - unsigned multiply. 1166 // Mul instruction - unsigned multiply.
1174 class InstX8632Mul : public InstX8632 { 1167 class InstX8632Mul : public InstX8632 {
1175 InstX8632Mul() = delete; 1168 InstX8632Mul() = delete;
1176 InstX8632Mul(const InstX8632Mul &) = delete; 1169 InstX8632Mul(const InstX8632Mul &) = delete;
1177 InstX8632Mul &operator=(const InstX8632Mul &) = delete; 1170 InstX8632Mul &operator=(const InstX8632Mul &) = delete;
1178 1171
1179 public: 1172 public:
1180 static InstX8632Mul *create(Cfg *Func, Variable *Dest, Variable *Source1, 1173 static InstX8632Mul *create(Cfg *Func, Variable *Dest, Variable *Source1,
1181 Operand *Source2) { 1174 Operand *Source2) {
1182 return new (Func->allocate<InstX8632Mul>()) 1175 return new (Func->allocate<InstX8632Mul>())
1183 InstX8632Mul(Func, Dest, Source1, Source2); 1176 InstX8632Mul(Func, Dest, Source1, Source2);
1184 } 1177 }
1185 void emit(const Cfg *Func) const override; 1178 void emit(const Cfg *Func) const override;
1186 void emitIAS(const Cfg *Func) const override; 1179 void emitIAS(const Cfg *Func) const override;
1187 void dump(const Cfg *Func) const override; 1180 void dump(const Cfg *Func) const override;
1188 static bool classof(const Inst *Inst) { return isClassof(Inst, Mul); } 1181 static bool classof(const Inst *Inst) { return isClassof(Inst, Mul); }
1189 1182
1190 private: 1183 private:
1191 InstX8632Mul(Cfg *Func, Variable *Dest, Variable *Source1, Operand *Source2); 1184 InstX8632Mul(Cfg *Func, Variable *Dest, Variable *Source1, Operand *Source2);
1192 ~InstX8632Mul() override {}
1193 }; 1185 };
1194 1186
1195 // Shld instruction - shift across a pair of operands. 1187 // Shld instruction - shift across a pair of operands.
1196 class InstX8632Shld : public InstX8632 { 1188 class InstX8632Shld : public InstX8632 {
1197 InstX8632Shld() = delete; 1189 InstX8632Shld() = delete;
1198 InstX8632Shld(const InstX8632Shld &) = delete; 1190 InstX8632Shld(const InstX8632Shld &) = delete;
1199 InstX8632Shld &operator=(const InstX8632Shld &) = delete; 1191 InstX8632Shld &operator=(const InstX8632Shld &) = delete;
1200 1192
1201 public: 1193 public:
1202 static InstX8632Shld *create(Cfg *Func, Variable *Dest, Variable *Source1, 1194 static InstX8632Shld *create(Cfg *Func, Variable *Dest, Variable *Source1,
1203 Variable *Source2) { 1195 Variable *Source2) {
1204 return new (Func->allocate<InstX8632Shld>()) 1196 return new (Func->allocate<InstX8632Shld>())
1205 InstX8632Shld(Func, Dest, Source1, Source2); 1197 InstX8632Shld(Func, Dest, Source1, Source2);
1206 } 1198 }
1207 void emit(const Cfg *Func) const override; 1199 void emit(const Cfg *Func) const override;
1208 void emitIAS(const Cfg *Func) const override; 1200 void emitIAS(const Cfg *Func) const override;
1209 void dump(const Cfg *Func) const override; 1201 void dump(const Cfg *Func) const override;
1210 static bool classof(const Inst *Inst) { return isClassof(Inst, Shld); } 1202 static bool classof(const Inst *Inst) { return isClassof(Inst, Shld); }
1211 1203
1212 private: 1204 private:
1213 InstX8632Shld(Cfg *Func, Variable *Dest, Variable *Source1, 1205 InstX8632Shld(Cfg *Func, Variable *Dest, Variable *Source1,
1214 Variable *Source2); 1206 Variable *Source2);
1215 ~InstX8632Shld() override {}
1216 }; 1207 };
1217 1208
1218 // Shrd instruction - shift across a pair of operands. 1209 // Shrd instruction - shift across a pair of operands.
1219 class InstX8632Shrd : public InstX8632 { 1210 class InstX8632Shrd : public InstX8632 {
1220 InstX8632Shrd() = delete; 1211 InstX8632Shrd() = delete;
1221 InstX8632Shrd(const InstX8632Shrd &) = delete; 1212 InstX8632Shrd(const InstX8632Shrd &) = delete;
1222 InstX8632Shrd &operator=(const InstX8632Shrd &) = delete; 1213 InstX8632Shrd &operator=(const InstX8632Shrd &) = delete;
1223 1214
1224 public: 1215 public:
1225 static InstX8632Shrd *create(Cfg *Func, Variable *Dest, Variable *Source1, 1216 static InstX8632Shrd *create(Cfg *Func, Variable *Dest, Variable *Source1,
1226 Variable *Source2) { 1217 Variable *Source2) {
1227 return new (Func->allocate<InstX8632Shrd>()) 1218 return new (Func->allocate<InstX8632Shrd>())
1228 InstX8632Shrd(Func, Dest, Source1, Source2); 1219 InstX8632Shrd(Func, Dest, Source1, Source2);
1229 } 1220 }
1230 void emit(const Cfg *Func) const override; 1221 void emit(const Cfg *Func) const override;
1231 void emitIAS(const Cfg *Func) const override; 1222 void emitIAS(const Cfg *Func) const override;
1232 void dump(const Cfg *Func) const override; 1223 void dump(const Cfg *Func) const override;
1233 static bool classof(const Inst *Inst) { return isClassof(Inst, Shrd); } 1224 static bool classof(const Inst *Inst) { return isClassof(Inst, Shrd); }
1234 1225
1235 private: 1226 private:
1236 InstX8632Shrd(Cfg *Func, Variable *Dest, Variable *Source1, 1227 InstX8632Shrd(Cfg *Func, Variable *Dest, Variable *Source1,
1237 Variable *Source2); 1228 Variable *Source2);
1238 ~InstX8632Shrd() override {}
1239 }; 1229 };
1240 1230
1241 // Conditional move instruction. 1231 // Conditional move instruction.
1242 class InstX8632Cmov : public InstX8632 { 1232 class InstX8632Cmov : public InstX8632 {
1243 InstX8632Cmov() = delete; 1233 InstX8632Cmov() = delete;
1244 InstX8632Cmov(const InstX8632Cmov &) = delete; 1234 InstX8632Cmov(const InstX8632Cmov &) = delete;
1245 InstX8632Cmov &operator=(const InstX8632Cmov &) = delete; 1235 InstX8632Cmov &operator=(const InstX8632Cmov &) = delete;
1246 1236
1247 public: 1237 public:
1248 static InstX8632Cmov *create(Cfg *Func, Variable *Dest, Operand *Source, 1238 static InstX8632Cmov *create(Cfg *Func, Variable *Dest, Operand *Source,
1249 CondX86::BrCond Cond) { 1239 CondX86::BrCond Cond) {
1250 return new (Func->allocate<InstX8632Cmov>()) 1240 return new (Func->allocate<InstX8632Cmov>())
1251 InstX8632Cmov(Func, Dest, Source, Cond); 1241 InstX8632Cmov(Func, Dest, Source, Cond);
1252 } 1242 }
1253 void emit(const Cfg *Func) const override; 1243 void emit(const Cfg *Func) const override;
1254 void emitIAS(const Cfg *Func) const override; 1244 void emitIAS(const Cfg *Func) const override;
1255 void dump(const Cfg *Func) const override; 1245 void dump(const Cfg *Func) const override;
1256 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmov); } 1246 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmov); }
1257 1247
1258 private: 1248 private:
1259 InstX8632Cmov(Cfg *Func, Variable *Dest, Operand *Source, 1249 InstX8632Cmov(Cfg *Func, Variable *Dest, Operand *Source,
1260 CondX86::BrCond Cond); 1250 CondX86::BrCond Cond);
1261 ~InstX8632Cmov() override {}
1262 1251
1263 CondX86::BrCond Condition; 1252 CondX86::BrCond Condition;
1264 }; 1253 };
1265 1254
1266 // Cmpps instruction - compare packed singled-precision floating point 1255 // Cmpps instruction - compare packed singled-precision floating point
1267 // values 1256 // values
1268 class InstX8632Cmpps : public InstX8632 { 1257 class InstX8632Cmpps : public InstX8632 {
1269 InstX8632Cmpps() = delete; 1258 InstX8632Cmpps() = delete;
1270 InstX8632Cmpps(const InstX8632Cmpps &) = delete; 1259 InstX8632Cmpps(const InstX8632Cmpps &) = delete;
1271 InstX8632Cmpps &operator=(const InstX8632Cmpps &) = delete; 1260 InstX8632Cmpps &operator=(const InstX8632Cmpps &) = delete;
1272 1261
1273 public: 1262 public:
1274 static InstX8632Cmpps *create(Cfg *Func, Variable *Dest, Operand *Source, 1263 static InstX8632Cmpps *create(Cfg *Func, Variable *Dest, Operand *Source,
1275 CondX86::CmppsCond Condition) { 1264 CondX86::CmppsCond Condition) {
1276 return new (Func->allocate<InstX8632Cmpps>()) 1265 return new (Func->allocate<InstX8632Cmpps>())
1277 InstX8632Cmpps(Func, Dest, Source, Condition); 1266 InstX8632Cmpps(Func, Dest, Source, Condition);
1278 } 1267 }
1279 void emit(const Cfg *Func) const override; 1268 void emit(const Cfg *Func) const override;
1280 void emitIAS(const Cfg *Func) const override; 1269 void emitIAS(const Cfg *Func) const override;
1281 void dump(const Cfg *Func) const override; 1270 void dump(const Cfg *Func) const override;
1282 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpps); } 1271 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpps); }
1283 1272
1284 private: 1273 private:
1285 InstX8632Cmpps(Cfg *Func, Variable *Dest, Operand *Source, 1274 InstX8632Cmpps(Cfg *Func, Variable *Dest, Operand *Source,
1286 CondX86::CmppsCond Cond); 1275 CondX86::CmppsCond Cond);
1287 ~InstX8632Cmpps() override {}
1288 1276
1289 CondX86::CmppsCond Condition; 1277 CondX86::CmppsCond Condition;
1290 }; 1278 };
1291 1279
1292 // Cmpxchg instruction - cmpxchg <dest>, <desired> will compare if <dest> 1280 // Cmpxchg instruction - cmpxchg <dest>, <desired> will compare if <dest>
1293 // equals eax. If so, the ZF is set and <desired> is stored in <dest>. 1281 // equals eax. If so, the ZF is set and <desired> is stored in <dest>.
1294 // If not, ZF is cleared and <dest> is copied to eax (or subregister). 1282 // If not, ZF is cleared and <dest> is copied to eax (or subregister).
1295 // <dest> can be a register or memory, while <desired> must be a register. 1283 // <dest> can be a register or memory, while <desired> must be a register.
1296 // It is the user's responsiblity to mark eax with a FakeDef. 1284 // It is the user's responsiblity to mark eax with a FakeDef.
1297 class InstX8632Cmpxchg : public InstX8632Lockable { 1285 class InstX8632Cmpxchg : public InstX8632Lockable {
1298 InstX8632Cmpxchg() = delete; 1286 InstX8632Cmpxchg() = delete;
1299 InstX8632Cmpxchg(const InstX8632Cmpxchg &) = delete; 1287 InstX8632Cmpxchg(const InstX8632Cmpxchg &) = delete;
1300 InstX8632Cmpxchg &operator=(const InstX8632Cmpxchg &) = delete; 1288 InstX8632Cmpxchg &operator=(const InstX8632Cmpxchg &) = delete;
1301 1289
1302 public: 1290 public:
1303 static InstX8632Cmpxchg *create(Cfg *Func, Operand *DestOrAddr, Variable *Eax, 1291 static InstX8632Cmpxchg *create(Cfg *Func, Operand *DestOrAddr, Variable *Eax,
1304 Variable *Desired, bool Locked) { 1292 Variable *Desired, bool Locked) {
1305 return new (Func->allocate<InstX8632Cmpxchg>()) 1293 return new (Func->allocate<InstX8632Cmpxchg>())
1306 InstX8632Cmpxchg(Func, DestOrAddr, Eax, Desired, Locked); 1294 InstX8632Cmpxchg(Func, DestOrAddr, Eax, Desired, Locked);
1307 } 1295 }
1308 void emit(const Cfg *Func) const override; 1296 void emit(const Cfg *Func) const override;
1309 void emitIAS(const Cfg *Func) const override; 1297 void emitIAS(const Cfg *Func) const override;
1310 void dump(const Cfg *Func) const override; 1298 void dump(const Cfg *Func) const override;
1311 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpxchg); } 1299 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpxchg); }
1312 1300
1313 private: 1301 private:
1314 InstX8632Cmpxchg(Cfg *Func, Operand *DestOrAddr, Variable *Eax, 1302 InstX8632Cmpxchg(Cfg *Func, Operand *DestOrAddr, Variable *Eax,
1315 Variable *Desired, bool Locked); 1303 Variable *Desired, bool Locked);
1316 ~InstX8632Cmpxchg() override {}
1317 }; 1304 };
1318 1305
1319 // Cmpxchg8b instruction - cmpxchg8b <m64> will compare if <m64> 1306 // Cmpxchg8b instruction - cmpxchg8b <m64> will compare if <m64>
1320 // equals edx:eax. If so, the ZF is set and ecx:ebx is stored in <m64>. 1307 // equals edx:eax. If so, the ZF is set and ecx:ebx is stored in <m64>.
1321 // If not, ZF is cleared and <m64> is copied to edx:eax. 1308 // If not, ZF is cleared and <m64> is copied to edx:eax.
1322 // The caller is responsible for inserting FakeDefs to mark edx 1309 // The caller is responsible for inserting FakeDefs to mark edx
1323 // and eax as modified. 1310 // and eax as modified.
1324 // <m64> must be a memory operand. 1311 // <m64> must be a memory operand.
1325 class InstX8632Cmpxchg8b : public InstX8632Lockable { 1312 class InstX8632Cmpxchg8b : public InstX8632Lockable {
1326 InstX8632Cmpxchg8b() = delete; 1313 InstX8632Cmpxchg8b() = delete;
1327 InstX8632Cmpxchg8b(const InstX8632Cmpxchg8b &) = delete; 1314 InstX8632Cmpxchg8b(const InstX8632Cmpxchg8b &) = delete;
1328 InstX8632Cmpxchg8b &operator=(const InstX8632Cmpxchg8b &) = delete; 1315 InstX8632Cmpxchg8b &operator=(const InstX8632Cmpxchg8b &) = delete;
1329 1316
1330 public: 1317 public:
1331 static InstX8632Cmpxchg8b *create(Cfg *Func, OperandX8632Mem *Dest, 1318 static InstX8632Cmpxchg8b *create(Cfg *Func, OperandX8632Mem *Dest,
1332 Variable *Edx, Variable *Eax, Variable *Ecx, 1319 Variable *Edx, Variable *Eax, Variable *Ecx,
1333 Variable *Ebx, bool Locked) { 1320 Variable *Ebx, bool Locked) {
1334 return new (Func->allocate<InstX8632Cmpxchg8b>()) 1321 return new (Func->allocate<InstX8632Cmpxchg8b>())
1335 InstX8632Cmpxchg8b(Func, Dest, Edx, Eax, Ecx, Ebx, Locked); 1322 InstX8632Cmpxchg8b(Func, Dest, Edx, Eax, Ecx, Ebx, Locked);
1336 } 1323 }
1337 void emit(const Cfg *Func) const override; 1324 void emit(const Cfg *Func) const override;
1338 void emitIAS(const Cfg *Func) const override; 1325 void emitIAS(const Cfg *Func) const override;
1339 void dump(const Cfg *Func) const override; 1326 void dump(const Cfg *Func) const override;
1340 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpxchg8b); } 1327 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpxchg8b); }
1341 1328
1342 private: 1329 private:
1343 InstX8632Cmpxchg8b(Cfg *Func, OperandX8632Mem *Dest, Variable *Edx, 1330 InstX8632Cmpxchg8b(Cfg *Func, OperandX8632Mem *Dest, Variable *Edx,
1344 Variable *Eax, Variable *Ecx, Variable *Ebx, bool Locked); 1331 Variable *Eax, Variable *Ecx, Variable *Ebx, bool Locked);
1345 ~InstX8632Cmpxchg8b() override {}
1346 }; 1332 };
1347 1333
1348 // Cvt instruction - wrapper for cvtsX2sY where X and Y are in {s,d,i} 1334 // Cvt instruction - wrapper for cvtsX2sY where X and Y are in {s,d,i}
1349 // as appropriate. s=float, d=double, i=int. X and Y are determined 1335 // as appropriate. s=float, d=double, i=int. X and Y are determined
1350 // from dest/src types. Sign and zero extension on the integer 1336 // from dest/src types. Sign and zero extension on the integer
1351 // operand needs to be done separately. 1337 // operand needs to be done separately.
1352 class InstX8632Cvt : public InstX8632 { 1338 class InstX8632Cvt : public InstX8632 {
1353 InstX8632Cvt() = delete; 1339 InstX8632Cvt() = delete;
1354 InstX8632Cvt(const InstX8632Cvt &) = delete; 1340 InstX8632Cvt(const InstX8632Cvt &) = delete;
1355 InstX8632Cvt &operator=(const InstX8632Cvt &) = delete; 1341 InstX8632Cvt &operator=(const InstX8632Cvt &) = delete;
1356 1342
1357 public: 1343 public:
1358 enum CvtVariant { Si2ss, Tss2si, Float2float, Dq2ps, Tps2dq }; 1344 enum CvtVariant { Si2ss, Tss2si, Float2float, Dq2ps, Tps2dq };
1359 static InstX8632Cvt *create(Cfg *Func, Variable *Dest, Operand *Source, 1345 static InstX8632Cvt *create(Cfg *Func, Variable *Dest, Operand *Source,
1360 CvtVariant Variant) { 1346 CvtVariant Variant) {
1361 return new (Func->allocate<InstX8632Cvt>()) 1347 return new (Func->allocate<InstX8632Cvt>())
1362 InstX8632Cvt(Func, Dest, Source, Variant); 1348 InstX8632Cvt(Func, Dest, Source, Variant);
1363 } 1349 }
1364 void emit(const Cfg *Func) const override; 1350 void emit(const Cfg *Func) const override;
1365 void emitIAS(const Cfg *Func) const override; 1351 void emitIAS(const Cfg *Func) const override;
1366 void dump(const Cfg *Func) const override; 1352 void dump(const Cfg *Func) const override;
1367 static bool classof(const Inst *Inst) { return isClassof(Inst, Cvt); } 1353 static bool classof(const Inst *Inst) { return isClassof(Inst, Cvt); }
1368 bool isTruncating() const { return Variant == Tss2si || Variant == Tps2dq; } 1354 bool isTruncating() const { return Variant == Tss2si || Variant == Tps2dq; }
1369 1355
1370 private: 1356 private:
1371 CvtVariant Variant; 1357 CvtVariant Variant;
1372 InstX8632Cvt(Cfg *Func, Variable *Dest, Operand *Source, CvtVariant Variant); 1358 InstX8632Cvt(Cfg *Func, Variable *Dest, Operand *Source, CvtVariant Variant);
1373 ~InstX8632Cvt() override {}
1374 }; 1359 };
1375 1360
1376 // cmp - Integer compare instruction. 1361 // cmp - Integer compare instruction.
1377 class InstX8632Icmp : public InstX8632 { 1362 class InstX8632Icmp : public InstX8632 {
1378 InstX8632Icmp() = delete; 1363 InstX8632Icmp() = delete;
1379 InstX8632Icmp(const InstX8632Icmp &) = delete; 1364 InstX8632Icmp(const InstX8632Icmp &) = delete;
1380 InstX8632Icmp &operator=(const InstX8632Icmp &) = delete; 1365 InstX8632Icmp &operator=(const InstX8632Icmp &) = delete;
1381 1366
1382 public: 1367 public:
1383 static InstX8632Icmp *create(Cfg *Func, Operand *Src1, Operand *Src2) { 1368 static InstX8632Icmp *create(Cfg *Func, Operand *Src1, Operand *Src2) {
1384 return new (Func->allocate<InstX8632Icmp>()) 1369 return new (Func->allocate<InstX8632Icmp>())
1385 InstX8632Icmp(Func, Src1, Src2); 1370 InstX8632Icmp(Func, Src1, Src2);
1386 } 1371 }
1387 void emit(const Cfg *Func) const override; 1372 void emit(const Cfg *Func) const override;
1388 void emitIAS(const Cfg *Func) const override; 1373 void emitIAS(const Cfg *Func) const override;
1389 void dump(const Cfg *Func) const override; 1374 void dump(const Cfg *Func) const override;
1390 static bool classof(const Inst *Inst) { return isClassof(Inst, Icmp); } 1375 static bool classof(const Inst *Inst) { return isClassof(Inst, Icmp); }
1391 1376
1392 private: 1377 private:
1393 InstX8632Icmp(Cfg *Func, Operand *Src1, Operand *Src2); 1378 InstX8632Icmp(Cfg *Func, Operand *Src1, Operand *Src2);
1394 ~InstX8632Icmp() override {}
1395 }; 1379 };
1396 1380
1397 // ucomiss/ucomisd - floating-point compare instruction. 1381 // ucomiss/ucomisd - floating-point compare instruction.
1398 class InstX8632Ucomiss : public InstX8632 { 1382 class InstX8632Ucomiss : public InstX8632 {
1399 InstX8632Ucomiss() = delete; 1383 InstX8632Ucomiss() = delete;
1400 InstX8632Ucomiss(const InstX8632Ucomiss &) = delete; 1384 InstX8632Ucomiss(const InstX8632Ucomiss &) = delete;
1401 InstX8632Ucomiss &operator=(const InstX8632Ucomiss &) = delete; 1385 InstX8632Ucomiss &operator=(const InstX8632Ucomiss &) = delete;
1402 1386
1403 public: 1387 public:
1404 static InstX8632Ucomiss *create(Cfg *Func, Operand *Src1, Operand *Src2) { 1388 static InstX8632Ucomiss *create(Cfg *Func, Operand *Src1, Operand *Src2) {
1405 return new (Func->allocate<InstX8632Ucomiss>()) 1389 return new (Func->allocate<InstX8632Ucomiss>())
1406 InstX8632Ucomiss(Func, Src1, Src2); 1390 InstX8632Ucomiss(Func, Src1, Src2);
1407 } 1391 }
1408 void emit(const Cfg *Func) const override; 1392 void emit(const Cfg *Func) const override;
1409 void emitIAS(const Cfg *Func) const override; 1393 void emitIAS(const Cfg *Func) const override;
1410 void dump(const Cfg *Func) const override; 1394 void dump(const Cfg *Func) const override;
1411 static bool classof(const Inst *Inst) { return isClassof(Inst, Ucomiss); } 1395 static bool classof(const Inst *Inst) { return isClassof(Inst, Ucomiss); }
1412 1396
1413 private: 1397 private:
1414 InstX8632Ucomiss(Cfg *Func, Operand *Src1, Operand *Src2); 1398 InstX8632Ucomiss(Cfg *Func, Operand *Src1, Operand *Src2);
1415 ~InstX8632Ucomiss() override {}
1416 }; 1399 };
1417 1400
1418 // UD2 instruction. 1401 // UD2 instruction.
1419 class InstX8632UD2 : public InstX8632 { 1402 class InstX8632UD2 : public InstX8632 {
1420 InstX8632UD2() = delete; 1403 InstX8632UD2() = delete;
1421 InstX8632UD2(const InstX8632UD2 &) = delete; 1404 InstX8632UD2(const InstX8632UD2 &) = delete;
1422 InstX8632UD2 &operator=(const InstX8632UD2 &) = delete; 1405 InstX8632UD2 &operator=(const InstX8632UD2 &) = delete;
1423 1406
1424 public: 1407 public:
1425 static InstX8632UD2 *create(Cfg *Func) { 1408 static InstX8632UD2 *create(Cfg *Func) {
1426 return new (Func->allocate<InstX8632UD2>()) InstX8632UD2(Func); 1409 return new (Func->allocate<InstX8632UD2>()) InstX8632UD2(Func);
1427 } 1410 }
1428 void emit(const Cfg *Func) const override; 1411 void emit(const Cfg *Func) const override;
1429 void emitIAS(const Cfg *Func) const override; 1412 void emitIAS(const Cfg *Func) const override;
1430 void dump(const Cfg *Func) const override; 1413 void dump(const Cfg *Func) const override;
1431 static bool classof(const Inst *Inst) { return isClassof(Inst, UD2); } 1414 static bool classof(const Inst *Inst) { return isClassof(Inst, UD2); }
1432 1415
1433 private: 1416 private:
1434 explicit InstX8632UD2(Cfg *Func); 1417 explicit InstX8632UD2(Cfg *Func);
1435 ~InstX8632UD2() override {}
1436 }; 1418 };
1437 1419
1438 // Test instruction. 1420 // Test instruction.
1439 class InstX8632Test : public InstX8632 { 1421 class InstX8632Test : public InstX8632 {
1440 InstX8632Test() = delete; 1422 InstX8632Test() = delete;
1441 InstX8632Test(const InstX8632Test &) = delete; 1423 InstX8632Test(const InstX8632Test &) = delete;
1442 InstX8632Test &operator=(const InstX8632Test &) = delete; 1424 InstX8632Test &operator=(const InstX8632Test &) = delete;
1443 1425
1444 public: 1426 public:
1445 static InstX8632Test *create(Cfg *Func, Operand *Source1, Operand *Source2) { 1427 static InstX8632Test *create(Cfg *Func, Operand *Source1, Operand *Source2) {
1446 return new (Func->allocate<InstX8632Test>()) 1428 return new (Func->allocate<InstX8632Test>())
1447 InstX8632Test(Func, Source1, Source2); 1429 InstX8632Test(Func, Source1, Source2);
1448 } 1430 }
1449 void emit(const Cfg *Func) const override; 1431 void emit(const Cfg *Func) const override;
1450 void emitIAS(const Cfg *Func) const override; 1432 void emitIAS(const Cfg *Func) const override;
1451 void dump(const Cfg *Func) const override; 1433 void dump(const Cfg *Func) const override;
1452 static bool classof(const Inst *Inst) { return isClassof(Inst, Test); } 1434 static bool classof(const Inst *Inst) { return isClassof(Inst, Test); }
1453 1435
1454 private: 1436 private:
1455 InstX8632Test(Cfg *Func, Operand *Source1, Operand *Source2); 1437 InstX8632Test(Cfg *Func, Operand *Source1, Operand *Source2);
1456 ~InstX8632Test() override {}
1457 }; 1438 };
1458 1439
1459 // Mfence instruction. 1440 // Mfence instruction.
1460 class InstX8632Mfence : public InstX8632 { 1441 class InstX8632Mfence : public InstX8632 {
1461 InstX8632Mfence() = delete; 1442 InstX8632Mfence() = delete;
1462 InstX8632Mfence(const InstX8632Mfence &) = delete; 1443 InstX8632Mfence(const InstX8632Mfence &) = delete;
1463 InstX8632Mfence &operator=(const InstX8632Mfence &) = delete; 1444 InstX8632Mfence &operator=(const InstX8632Mfence &) = delete;
1464 1445
1465 public: 1446 public:
1466 static InstX8632Mfence *create(Cfg *Func) { 1447 static InstX8632Mfence *create(Cfg *Func) {
1467 return new (Func->allocate<InstX8632Mfence>()) InstX8632Mfence(Func); 1448 return new (Func->allocate<InstX8632Mfence>()) InstX8632Mfence(Func);
1468 } 1449 }
1469 void emit(const Cfg *Func) const override; 1450 void emit(const Cfg *Func) const override;
1470 void emitIAS(const Cfg *Func) const override; 1451 void emitIAS(const Cfg *Func) const override;
1471 void dump(const Cfg *Func) const override; 1452 void dump(const Cfg *Func) const override;
1472 static bool classof(const Inst *Inst) { return isClassof(Inst, Mfence); } 1453 static bool classof(const Inst *Inst) { return isClassof(Inst, Mfence); }
1473 1454
1474 private: 1455 private:
1475 explicit InstX8632Mfence(Cfg *Func); 1456 explicit InstX8632Mfence(Cfg *Func);
1476 ~InstX8632Mfence() override {}
1477 }; 1457 };
1478 1458
1479 // This is essentially a "mov" instruction with an OperandX8632Mem 1459 // This is essentially a "mov" instruction with an OperandX8632Mem
1480 // operand instead of Variable as the destination. It's important 1460 // operand instead of Variable as the destination. It's important
1481 // for liveness that there is no Dest operand. 1461 // for liveness that there is no Dest operand.
1482 class InstX8632Store : public InstX8632 { 1462 class InstX8632Store : public InstX8632 {
1483 InstX8632Store() = delete; 1463 InstX8632Store() = delete;
1484 InstX8632Store(const InstX8632Store &) = delete; 1464 InstX8632Store(const InstX8632Store &) = delete;
1485 InstX8632Store &operator=(const InstX8632Store &) = delete; 1465 InstX8632Store &operator=(const InstX8632Store &) = delete;
1486 1466
1487 public: 1467 public:
1488 static InstX8632Store *create(Cfg *Func, Operand *Value, OperandX8632 *Mem) { 1468 static InstX8632Store *create(Cfg *Func, Operand *Value, OperandX8632 *Mem) {
1489 return new (Func->allocate<InstX8632Store>()) 1469 return new (Func->allocate<InstX8632Store>())
1490 InstX8632Store(Func, Value, Mem); 1470 InstX8632Store(Func, Value, Mem);
1491 } 1471 }
1492 void emit(const Cfg *Func) const override; 1472 void emit(const Cfg *Func) const override;
1493 void emitIAS(const Cfg *Func) const override; 1473 void emitIAS(const Cfg *Func) const override;
1494 void dump(const Cfg *Func) const override; 1474 void dump(const Cfg *Func) const override;
1495 static bool classof(const Inst *Inst) { return isClassof(Inst, Store); } 1475 static bool classof(const Inst *Inst) { return isClassof(Inst, Store); }
1496 1476
1497 private: 1477 private:
1498 InstX8632Store(Cfg *Func, Operand *Value, OperandX8632 *Mem); 1478 InstX8632Store(Cfg *Func, Operand *Value, OperandX8632 *Mem);
1499 ~InstX8632Store() override {}
1500 }; 1479 };
1501 1480
1502 // This is essentially a vector "mov" instruction with an OperandX8632Mem 1481 // This is essentially a vector "mov" instruction with an OperandX8632Mem
1503 // operand instead of Variable as the destination. It's important 1482 // operand instead of Variable as the destination. It's important
1504 // for liveness that there is no Dest operand. The source must be an 1483 // for liveness that there is no Dest operand. The source must be an
1505 // Xmm register, since Dest is mem. 1484 // Xmm register, since Dest is mem.
1506 class InstX8632StoreP : public InstX8632 { 1485 class InstX8632StoreP : public InstX8632 {
1507 InstX8632StoreP() = delete; 1486 InstX8632StoreP() = delete;
1508 InstX8632StoreP(const InstX8632StoreP &) = delete; 1487 InstX8632StoreP(const InstX8632StoreP &) = delete;
1509 InstX8632StoreP &operator=(const InstX8632StoreP &) = delete; 1488 InstX8632StoreP &operator=(const InstX8632StoreP &) = delete;
1510 1489
1511 public: 1490 public:
1512 static InstX8632StoreP *create(Cfg *Func, Variable *Value, 1491 static InstX8632StoreP *create(Cfg *Func, Variable *Value,
1513 OperandX8632Mem *Mem) { 1492 OperandX8632Mem *Mem) {
1514 return new (Func->allocate<InstX8632StoreP>()) 1493 return new (Func->allocate<InstX8632StoreP>())
1515 InstX8632StoreP(Func, Value, Mem); 1494 InstX8632StoreP(Func, Value, Mem);
1516 } 1495 }
1517 void emit(const Cfg *Func) const override; 1496 void emit(const Cfg *Func) const override;
1518 void emitIAS(const Cfg *Func) const override; 1497 void emitIAS(const Cfg *Func) const override;
1519 void dump(const Cfg *Func) const override; 1498 void dump(const Cfg *Func) const override;
1520 static bool classof(const Inst *Inst) { return isClassof(Inst, StoreP); } 1499 static bool classof(const Inst *Inst) { return isClassof(Inst, StoreP); }
1521 1500
1522 private: 1501 private:
1523 InstX8632StoreP(Cfg *Func, Variable *Value, OperandX8632Mem *Mem); 1502 InstX8632StoreP(Cfg *Func, Variable *Value, OperandX8632Mem *Mem);
1524 ~InstX8632StoreP() override {}
1525 }; 1503 };
1526 1504
1527 class InstX8632StoreQ : public InstX8632 { 1505 class InstX8632StoreQ : public InstX8632 {
1528 InstX8632StoreQ() = delete; 1506 InstX8632StoreQ() = delete;
1529 InstX8632StoreQ(const InstX8632StoreQ &) = delete; 1507 InstX8632StoreQ(const InstX8632StoreQ &) = delete;
1530 InstX8632StoreQ &operator=(const InstX8632StoreQ &) = delete; 1508 InstX8632StoreQ &operator=(const InstX8632StoreQ &) = delete;
1531 1509
1532 public: 1510 public:
1533 static InstX8632StoreQ *create(Cfg *Func, Variable *Value, 1511 static InstX8632StoreQ *create(Cfg *Func, Variable *Value,
1534 OperandX8632Mem *Mem) { 1512 OperandX8632Mem *Mem) {
1535 return new (Func->allocate<InstX8632StoreQ>()) 1513 return new (Func->allocate<InstX8632StoreQ>())
1536 InstX8632StoreQ(Func, Value, Mem); 1514 InstX8632StoreQ(Func, Value, Mem);
1537 } 1515 }
1538 void emit(const Cfg *Func) const override; 1516 void emit(const Cfg *Func) const override;
1539 void emitIAS(const Cfg *Func) const override; 1517 void emitIAS(const Cfg *Func) const override;
1540 void dump(const Cfg *Func) const override; 1518 void dump(const Cfg *Func) const override;
1541 static bool classof(const Inst *Inst) { return isClassof(Inst, StoreQ); } 1519 static bool classof(const Inst *Inst) { return isClassof(Inst, StoreQ); }
1542 1520
1543 private: 1521 private:
1544 InstX8632StoreQ(Cfg *Func, Variable *Value, OperandX8632Mem *Mem); 1522 InstX8632StoreQ(Cfg *Func, Variable *Value, OperandX8632Mem *Mem);
1545 ~InstX8632StoreQ() override {}
1546 }; 1523 };
1547 1524
1548 // Nop instructions of varying length 1525 // Nop instructions of varying length
1549 class InstX8632Nop : public InstX8632 { 1526 class InstX8632Nop : public InstX8632 {
1550 InstX8632Nop() = delete; 1527 InstX8632Nop() = delete;
1551 InstX8632Nop(const InstX8632Nop &) = delete; 1528 InstX8632Nop(const InstX8632Nop &) = delete;
1552 InstX8632Nop &operator=(const InstX8632Nop &) = delete; 1529 InstX8632Nop &operator=(const InstX8632Nop &) = delete;
1553 1530
1554 public: 1531 public:
1555 // TODO: Replace with enum. 1532 // TODO: Replace with enum.
1556 typedef unsigned NopVariant; 1533 typedef unsigned NopVariant;
1557 1534
1558 static InstX8632Nop *create(Cfg *Func, NopVariant Variant) { 1535 static InstX8632Nop *create(Cfg *Func, NopVariant Variant) {
1559 return new (Func->allocate<InstX8632Nop>()) InstX8632Nop(Func, Variant); 1536 return new (Func->allocate<InstX8632Nop>()) InstX8632Nop(Func, Variant);
1560 } 1537 }
1561 void emit(const Cfg *Func) const override; 1538 void emit(const Cfg *Func) const override;
1562 void emitIAS(const Cfg *Func) const override; 1539 void emitIAS(const Cfg *Func) const override;
1563 void dump(const Cfg *Func) const override; 1540 void dump(const Cfg *Func) const override;
1564 static bool classof(const Inst *Inst) { return isClassof(Inst, Nop); } 1541 static bool classof(const Inst *Inst) { return isClassof(Inst, Nop); }
1565 1542
1566 private: 1543 private:
1567 InstX8632Nop(Cfg *Func, SizeT Length); 1544 InstX8632Nop(Cfg *Func, SizeT Length);
1568 ~InstX8632Nop() override {}
1569 1545
1570 NopVariant Variant; 1546 NopVariant Variant;
1571 }; 1547 };
1572 1548
1573 // Fld - load a value onto the x87 FP stack. 1549 // Fld - load a value onto the x87 FP stack.
1574 class InstX8632Fld : public InstX8632 { 1550 class InstX8632Fld : public InstX8632 {
1575 InstX8632Fld() = delete; 1551 InstX8632Fld() = delete;
1576 InstX8632Fld(const InstX8632Fld &) = delete; 1552 InstX8632Fld(const InstX8632Fld &) = delete;
1577 InstX8632Fld &operator=(const InstX8632Fld &) = delete; 1553 InstX8632Fld &operator=(const InstX8632Fld &) = delete;
1578 1554
1579 public: 1555 public:
1580 static InstX8632Fld *create(Cfg *Func, Operand *Src) { 1556 static InstX8632Fld *create(Cfg *Func, Operand *Src) {
1581 return new (Func->allocate<InstX8632Fld>()) InstX8632Fld(Func, Src); 1557 return new (Func->allocate<InstX8632Fld>()) InstX8632Fld(Func, Src);
1582 } 1558 }
1583 void emit(const Cfg *Func) const override; 1559 void emit(const Cfg *Func) const override;
1584 void emitIAS(const Cfg *Func) const override; 1560 void emitIAS(const Cfg *Func) const override;
1585 void dump(const Cfg *Func) const override; 1561 void dump(const Cfg *Func) const override;
1586 static bool classof(const Inst *Inst) { return isClassof(Inst, Fld); } 1562 static bool classof(const Inst *Inst) { return isClassof(Inst, Fld); }
1587 1563
1588 private: 1564 private:
1589 InstX8632Fld(Cfg *Func, Operand *Src); 1565 InstX8632Fld(Cfg *Func, Operand *Src);
1590 ~InstX8632Fld() override {}
1591 }; 1566 };
1592 1567
1593 // Fstp - store x87 st(0) into memory and pop st(0). 1568 // Fstp - store x87 st(0) into memory and pop st(0).
1594 class InstX8632Fstp : public InstX8632 { 1569 class InstX8632Fstp : public InstX8632 {
1595 InstX8632Fstp() = delete; 1570 InstX8632Fstp() = delete;
1596 InstX8632Fstp(const InstX8632Fstp &) = delete; 1571 InstX8632Fstp(const InstX8632Fstp &) = delete;
1597 InstX8632Fstp &operator=(const InstX8632Fstp &) = delete; 1572 InstX8632Fstp &operator=(const InstX8632Fstp &) = delete;
1598 1573
1599 public: 1574 public:
1600 static InstX8632Fstp *create(Cfg *Func, Variable *Dest) { 1575 static InstX8632Fstp *create(Cfg *Func, Variable *Dest) {
1601 return new (Func->allocate<InstX8632Fstp>()) InstX8632Fstp(Func, Dest); 1576 return new (Func->allocate<InstX8632Fstp>()) InstX8632Fstp(Func, Dest);
1602 } 1577 }
1603 void emit(const Cfg *Func) const override; 1578 void emit(const Cfg *Func) const override;
1604 void emitIAS(const Cfg *Func) const override; 1579 void emitIAS(const Cfg *Func) const override;
1605 void dump(const Cfg *Func) const override; 1580 void dump(const Cfg *Func) const override;
1606 static bool classof(const Inst *Inst) { return isClassof(Inst, Fstp); } 1581 static bool classof(const Inst *Inst) { return isClassof(Inst, Fstp); }
1607 1582
1608 private: 1583 private:
1609 InstX8632Fstp(Cfg *Func, Variable *Dest); 1584 InstX8632Fstp(Cfg *Func, Variable *Dest);
1610 ~InstX8632Fstp() override {}
1611 }; 1585 };
1612 1586
1613 class InstX8632Pop : public InstX8632 { 1587 class InstX8632Pop : public InstX8632 {
1614 InstX8632Pop() = delete; 1588 InstX8632Pop() = delete;
1615 InstX8632Pop(const InstX8632Pop &) = delete; 1589 InstX8632Pop(const InstX8632Pop &) = delete;
1616 InstX8632Pop &operator=(const InstX8632Pop &) = delete; 1590 InstX8632Pop &operator=(const InstX8632Pop &) = delete;
1617 1591
1618 public: 1592 public:
1619 static InstX8632Pop *create(Cfg *Func, Variable *Dest) { 1593 static InstX8632Pop *create(Cfg *Func, Variable *Dest) {
1620 return new (Func->allocate<InstX8632Pop>()) InstX8632Pop(Func, Dest); 1594 return new (Func->allocate<InstX8632Pop>()) InstX8632Pop(Func, Dest);
1621 } 1595 }
1622 void emit(const Cfg *Func) const override; 1596 void emit(const Cfg *Func) const override;
1623 void emitIAS(const Cfg *Func) const override; 1597 void emitIAS(const Cfg *Func) const override;
1624 void dump(const Cfg *Func) const override; 1598 void dump(const Cfg *Func) const override;
1625 static bool classof(const Inst *Inst) { return isClassof(Inst, Pop); } 1599 static bool classof(const Inst *Inst) { return isClassof(Inst, Pop); }
1626 1600
1627 private: 1601 private:
1628 InstX8632Pop(Cfg *Func, Variable *Dest); 1602 InstX8632Pop(Cfg *Func, Variable *Dest);
1629 ~InstX8632Pop() override {}
1630 }; 1603 };
1631 1604
1632 class InstX8632Push : public InstX8632 { 1605 class InstX8632Push : public InstX8632 {
1633 InstX8632Push() = delete; 1606 InstX8632Push() = delete;
1634 InstX8632Push(const InstX8632Push &) = delete; 1607 InstX8632Push(const InstX8632Push &) = delete;
1635 InstX8632Push &operator=(const InstX8632Push &) = delete; 1608 InstX8632Push &operator=(const InstX8632Push &) = delete;
1636 1609
1637 public: 1610 public:
1638 static InstX8632Push *create(Cfg *Func, Variable *Source) { 1611 static InstX8632Push *create(Cfg *Func, Variable *Source) {
1639 return new (Func->allocate<InstX8632Push>()) InstX8632Push(Func, Source); 1612 return new (Func->allocate<InstX8632Push>()) InstX8632Push(Func, Source);
1640 } 1613 }
1641 void emit(const Cfg *Func) const override; 1614 void emit(const Cfg *Func) const override;
1642 void emitIAS(const Cfg *Func) const override; 1615 void emitIAS(const Cfg *Func) const override;
1643 void dump(const Cfg *Func) const override; 1616 void dump(const Cfg *Func) const override;
1644 static bool classof(const Inst *Inst) { return isClassof(Inst, Push); } 1617 static bool classof(const Inst *Inst) { return isClassof(Inst, Push); }
1645 1618
1646 private: 1619 private:
1647 InstX8632Push(Cfg *Func, Variable *Source); 1620 InstX8632Push(Cfg *Func, Variable *Source);
1648 ~InstX8632Push() override {}
1649 }; 1621 };
1650 1622
1651 // Ret instruction. Currently only supports the "ret" version that 1623 // Ret instruction. Currently only supports the "ret" version that
1652 // does not pop arguments. This instruction takes a Source operand 1624 // does not pop arguments. This instruction takes a Source operand
1653 // (for non-void returning functions) for liveness analysis, though 1625 // (for non-void returning functions) for liveness analysis, though
1654 // a FakeUse before the ret would do just as well. 1626 // a FakeUse before the ret would do just as well.
1655 class InstX8632Ret : public InstX8632 { 1627 class InstX8632Ret : public InstX8632 {
1656 InstX8632Ret() = delete; 1628 InstX8632Ret() = delete;
1657 InstX8632Ret(const InstX8632Ret &) = delete; 1629 InstX8632Ret(const InstX8632Ret &) = delete;
1658 InstX8632Ret &operator=(const InstX8632Ret &) = delete; 1630 InstX8632Ret &operator=(const InstX8632Ret &) = delete;
1659 1631
1660 public: 1632 public:
1661 static InstX8632Ret *create(Cfg *Func, Variable *Source = nullptr) { 1633 static InstX8632Ret *create(Cfg *Func, Variable *Source = nullptr) {
1662 return new (Func->allocate<InstX8632Ret>()) InstX8632Ret(Func, Source); 1634 return new (Func->allocate<InstX8632Ret>()) InstX8632Ret(Func, Source);
1663 } 1635 }
1664 void emit(const Cfg *Func) const override; 1636 void emit(const Cfg *Func) const override;
1665 void emitIAS(const Cfg *Func) const override; 1637 void emitIAS(const Cfg *Func) const override;
1666 void dump(const Cfg *Func) const override; 1638 void dump(const Cfg *Func) const override;
1667 static bool classof(const Inst *Inst) { return isClassof(Inst, Ret); } 1639 static bool classof(const Inst *Inst) { return isClassof(Inst, Ret); }
1668 1640
1669 private: 1641 private:
1670 InstX8632Ret(Cfg *Func, Variable *Source); 1642 InstX8632Ret(Cfg *Func, Variable *Source);
1671 ~InstX8632Ret() override {}
1672 }; 1643 };
1673 1644
1674 // Conditional set-byte instruction. 1645 // Conditional set-byte instruction.
1675 class InstX8632Setcc : public InstX8632 { 1646 class InstX8632Setcc : public InstX8632 {
1676 InstX8632Setcc() = delete; 1647 InstX8632Setcc() = delete;
1677 InstX8632Setcc(const InstX8632Cmov &) = delete; 1648 InstX8632Setcc(const InstX8632Cmov &) = delete;
1678 InstX8632Setcc &operator=(const InstX8632Setcc &) = delete; 1649 InstX8632Setcc &operator=(const InstX8632Setcc &) = delete;
1679 1650
1680 public: 1651 public:
1681 static InstX8632Setcc *create(Cfg *Func, Variable *Dest, 1652 static InstX8632Setcc *create(Cfg *Func, Variable *Dest,
1682 CondX86::BrCond Cond) { 1653 CondX86::BrCond Cond) {
1683 return new (Func->allocate<InstX8632Setcc>()) 1654 return new (Func->allocate<InstX8632Setcc>())
1684 InstX8632Setcc(Func, Dest, Cond); 1655 InstX8632Setcc(Func, Dest, Cond);
1685 } 1656 }
1686 void emit(const Cfg *Func) const override; 1657 void emit(const Cfg *Func) const override;
1687 void emitIAS(const Cfg *Func) const override; 1658 void emitIAS(const Cfg *Func) const override;
1688 void dump(const Cfg *Func) const override; 1659 void dump(const Cfg *Func) const override;
1689 static bool classof(const Inst *Inst) { return isClassof(Inst, Setcc); } 1660 static bool classof(const Inst *Inst) { return isClassof(Inst, Setcc); }
1690 1661
1691 private: 1662 private:
1692 InstX8632Setcc(Cfg *Func, Variable *Dest, CondX86::BrCond Cond); 1663 InstX8632Setcc(Cfg *Func, Variable *Dest, CondX86::BrCond Cond);
1693 ~InstX8632Setcc() override {}
1694 1664
1695 const CondX86::BrCond Condition; 1665 const CondX86::BrCond Condition;
1696 }; 1666 };
1697 1667
1698 // Exchanging Add instruction. Exchanges the first operand (destination 1668 // Exchanging Add instruction. Exchanges the first operand (destination
1699 // operand) with the second operand (source operand), then loads the sum 1669 // operand) with the second operand (source operand), then loads the sum
1700 // of the two values into the destination operand. The destination may be 1670 // of the two values into the destination operand. The destination may be
1701 // a register or memory, while the source must be a register. 1671 // a register or memory, while the source must be a register.
1702 // 1672 //
1703 // Both the dest and source are updated. The caller should then insert a 1673 // Both the dest and source are updated. The caller should then insert a
1704 // FakeDef to reflect the second udpate. 1674 // FakeDef to reflect the second udpate.
1705 class InstX8632Xadd : public InstX8632Lockable { 1675 class InstX8632Xadd : public InstX8632Lockable {
1706 InstX8632Xadd() = delete; 1676 InstX8632Xadd() = delete;
1707 InstX8632Xadd(const InstX8632Xadd &) = delete; 1677 InstX8632Xadd(const InstX8632Xadd &) = delete;
1708 InstX8632Xadd &operator=(const InstX8632Xadd &) = delete; 1678 InstX8632Xadd &operator=(const InstX8632Xadd &) = delete;
1709 1679
1710 public: 1680 public:
1711 static InstX8632Xadd *create(Cfg *Func, Operand *Dest, Variable *Source, 1681 static InstX8632Xadd *create(Cfg *Func, Operand *Dest, Variable *Source,
1712 bool Locked) { 1682 bool Locked) {
1713 return new (Func->allocate<InstX8632Xadd>()) 1683 return new (Func->allocate<InstX8632Xadd>())
1714 InstX8632Xadd(Func, Dest, Source, Locked); 1684 InstX8632Xadd(Func, Dest, Source, Locked);
1715 } 1685 }
1716 void emit(const Cfg *Func) const override; 1686 void emit(const Cfg *Func) const override;
1717 void emitIAS(const Cfg *Func) const override; 1687 void emitIAS(const Cfg *Func) const override;
1718 void dump(const Cfg *Func) const override; 1688 void dump(const Cfg *Func) const override;
1719 static bool classof(const Inst *Inst) { return isClassof(Inst, Xadd); } 1689 static bool classof(const Inst *Inst) { return isClassof(Inst, Xadd); }
1720 1690
1721 private: 1691 private:
1722 InstX8632Xadd(Cfg *Func, Operand *Dest, Variable *Source, bool Locked); 1692 InstX8632Xadd(Cfg *Func, Operand *Dest, Variable *Source, bool Locked);
1723 ~InstX8632Xadd() override {}
1724 }; 1693 };
1725 1694
1726 // Exchange instruction. Exchanges the first operand (destination 1695 // Exchange instruction. Exchanges the first operand (destination
1727 // operand) with the second operand (source operand). At least one of 1696 // operand) with the second operand (source operand). At least one of
1728 // the operands must be a register (and the other can be reg or mem). 1697 // the operands must be a register (and the other can be reg or mem).
1729 // Both the Dest and Source are updated. If there is a memory operand, 1698 // Both the Dest and Source are updated. If there is a memory operand,
1730 // then the instruction is automatically "locked" without the need for 1699 // then the instruction is automatically "locked" without the need for
1731 // a lock prefix. 1700 // a lock prefix.
1732 class InstX8632Xchg : public InstX8632 { 1701 class InstX8632Xchg : public InstX8632 {
1733 InstX8632Xchg() = delete; 1702 InstX8632Xchg() = delete;
1734 InstX8632Xchg(const InstX8632Xchg &) = delete; 1703 InstX8632Xchg(const InstX8632Xchg &) = delete;
1735 InstX8632Xchg &operator=(const InstX8632Xchg &) = delete; 1704 InstX8632Xchg &operator=(const InstX8632Xchg &) = delete;
1736 1705
1737 public: 1706 public:
1738 static InstX8632Xchg *create(Cfg *Func, Operand *Dest, Variable *Source) { 1707 static InstX8632Xchg *create(Cfg *Func, Operand *Dest, Variable *Source) {
1739 return new (Func->allocate<InstX8632Xchg>()) 1708 return new (Func->allocate<InstX8632Xchg>())
1740 InstX8632Xchg(Func, Dest, Source); 1709 InstX8632Xchg(Func, Dest, Source);
1741 } 1710 }
1742 void emit(const Cfg *Func) const override; 1711 void emit(const Cfg *Func) const override;
1743 void emitIAS(const Cfg *Func) const override; 1712 void emitIAS(const Cfg *Func) const override;
1744 void dump(const Cfg *Func) const override; 1713 void dump(const Cfg *Func) const override;
1745 static bool classof(const Inst *Inst) { return isClassof(Inst, Xchg); } 1714 static bool classof(const Inst *Inst) { return isClassof(Inst, Xchg); }
1746 1715
1747 private: 1716 private:
1748 InstX8632Xchg(Cfg *Func, Operand *Dest, Variable *Source); 1717 InstX8632Xchg(Cfg *Func, Operand *Dest, Variable *Source);
1749 ~InstX8632Xchg() override {}
1750 }; 1718 };
1751 1719
1752 // Declare partial template specializations of emit() methods that 1720 // Declare partial template specializations of emit() methods that
1753 // already have default implementations. Without this, there is the 1721 // already have default implementations. Without this, there is the
1754 // possibility of ODR violations and link errors. 1722 // possibility of ODR violations and link errors.
1755 template <> void InstX8632Addss::emit(const Cfg *Func) const; 1723 template <> void InstX8632Addss::emit(const Cfg *Func) const;
1756 template <> void InstX8632Blendvps::emit(const Cfg *Func) const; 1724 template <> void InstX8632Blendvps::emit(const Cfg *Func) const;
1757 template <> void InstX8632Cbwdq::emit(const Cfg *Func) const; 1725 template <> void InstX8632Cbwdq::emit(const Cfg *Func) const;
1758 template <> void InstX8632Div::emit(const Cfg *Func) const; 1726 template <> void InstX8632Div::emit(const Cfg *Func) const;
1759 template <> void InstX8632Divss::emit(const Cfg *Func) const; 1727 template <> void InstX8632Divss::emit(const Cfg *Func) const;
(...skipping 29 matching lines...) Expand all
1789 template <> void InstX8632Pinsr::emitIAS(const Cfg *Func) const; 1757 template <> void InstX8632Pinsr::emitIAS(const Cfg *Func) const;
1790 template <> void InstX8632Movsx::emitIAS(const Cfg *Func) const; 1758 template <> void InstX8632Movsx::emitIAS(const Cfg *Func) const;
1791 template <> void InstX8632Movzx::emitIAS(const Cfg *Func) const; 1759 template <> void InstX8632Movzx::emitIAS(const Cfg *Func) const;
1792 template <> void InstX8632Pmull::emitIAS(const Cfg *Func) const; 1760 template <> void InstX8632Pmull::emitIAS(const Cfg *Func) const;
1793 template <> void InstX8632Pshufd::emitIAS(const Cfg *Func) const; 1761 template <> void InstX8632Pshufd::emitIAS(const Cfg *Func) const;
1794 template <> void InstX8632Shufps::emitIAS(const Cfg *Func) const; 1762 template <> void InstX8632Shufps::emitIAS(const Cfg *Func) const;
1795 1763
1796 } // end of namespace Ice 1764 } // end of namespace Ice
1797 1765
1798 #endif // SUBZERO_SRC_ICEINSTX8632_H 1766 #endif // SUBZERO_SRC_ICEINSTX8632_H
OLDNEW
« no previous file with comments | « src/IceInstARM32.h ('k') | src/IceOperand.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698