| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |