| OLD | NEW |
| 1 //===- subzero/src/IceInstX86Base.h - Generic x86 instructions -*- C++ -*--===// | 1 //===- subzero/src/IceInstX86Base.h - Generic x86 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 /// \file | 10 /// \file |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 194 const char *Suffix = "") const; | 194 const char *Suffix = "") const; |
| 195 | 195 |
| 196 static TargetLowering *getTarget(const Cfg *Func) { | 196 static TargetLowering *getTarget(const Cfg *Func) { |
| 197 return static_cast<TargetLowering *>(Func->getTarget()); | 197 return static_cast<TargetLowering *>(Func->getTarget()); |
| 198 } | 198 } |
| 199 | 199 |
| 200 protected: | 200 protected: |
| 201 InstX86Base(Cfg *Func, InstKindX86 Kind, SizeT Maxsrcs, Variable *Dest) | 201 InstX86Base(Cfg *Func, InstKindX86 Kind, SizeT Maxsrcs, Variable *Dest) |
| 202 : InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {} | 202 : InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {} |
| 203 | 203 |
| 204 static bool isClassof(const Inst *Inst, InstKindX86 MyKind) { | 204 static bool isClassof(const Inst *Instr, InstKindX86 MyKind) { |
| 205 return Inst->getKind() == static_cast<InstKind>(MyKind); | 205 return Instr->getKind() == static_cast<InstKind>(MyKind); |
| 206 } | 206 } |
| 207 // Most instructions that operate on vector arguments require vector memory | 207 // Most instructions that operate on vector arguments require vector memory |
| 208 // operands to be fully aligned (16-byte alignment for PNaCl vector types). | 208 // operands to be fully aligned (16-byte alignment for PNaCl vector types). |
| 209 // The stack frame layout and call ABI ensure proper alignment for stack | 209 // The stack frame layout and call ABI ensure proper alignment for stack |
| 210 // operands, but memory operands (originating from load/store bitcode | 210 // operands, but memory operands (originating from load/store bitcode |
| 211 // instructions) only have element-size alignment guarantees. This function | 211 // instructions) only have element-size alignment guarantees. This function |
| 212 // validates that none of the operands is a memory operand of vector type, | 212 // validates that none of the operands is a memory operand of vector type, |
| 213 // calling report_fatal_error() if one is found. This function should be | 213 // calling report_fatal_error() if one is found. This function should be |
| 214 // called during emission, and maybe also in the ctor (as long as that fits | 214 // called during emission, and maybe also in the ctor (as long as that fits |
| 215 // the lowering style). | 215 // the lowering style). |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 249 return new (Func->allocate<InstX86FakeRMW>()) | 249 return new (Func->allocate<InstX86FakeRMW>()) |
| 250 InstX86FakeRMW(Func, Data, Addr, Op, Beacon); | 250 InstX86FakeRMW(Func, Data, Addr, Op, Beacon); |
| 251 } | 251 } |
| 252 Operand *getAddr() const { return this->getSrc(1); } | 252 Operand *getAddr() const { return this->getSrc(1); } |
| 253 Operand *getData() const { return this->getSrc(0); } | 253 Operand *getData() const { return this->getSrc(0); } |
| 254 InstArithmetic::OpKind getOp() const { return Op; } | 254 InstArithmetic::OpKind getOp() const { return Op; } |
| 255 Variable *getBeacon() const { | 255 Variable *getBeacon() const { |
| 256 return llvm::cast<Variable>(this->getSrc(2)); | 256 return llvm::cast<Variable>(this->getSrc(2)); |
| 257 } | 257 } |
| 258 void dump(const Cfg *Func) const override; | 258 void dump(const Cfg *Func) const override; |
| 259 static bool classof(const Inst *Inst) { | 259 static bool classof(const Inst *Instr) { |
| 260 return InstX86Base::isClassof(Inst, InstX86Base::FakeRMW); | 260 return InstX86Base::isClassof(Instr, InstX86Base::FakeRMW); |
| 261 } | 261 } |
| 262 | 262 |
| 263 private: | 263 private: |
| 264 InstArithmetic::OpKind Op; | 264 InstArithmetic::OpKind Op; |
| 265 InstX86FakeRMW(Cfg *Func, Operand *Data, Operand *Addr, | 265 InstX86FakeRMW(Cfg *Func, Operand *Data, Operand *Addr, |
| 266 InstArithmetic::OpKind Op, Variable *Beacon); | 266 InstArithmetic::OpKind Op, Variable *Beacon); |
| 267 }; | 267 }; |
| 268 | 268 |
| 269 class InstX86GetIP final : public InstX86Base { | 269 class InstX86GetIP final : public InstX86Base { |
| 270 InstX86GetIP() = delete; | 270 InstX86GetIP() = delete; |
| 271 InstX86GetIP(const InstX86GetIP &) = delete; | 271 InstX86GetIP(const InstX86GetIP &) = delete; |
| 272 InstX86GetIP &operator=(const InstX86GetIP &) = delete; | 272 InstX86GetIP &operator=(const InstX86GetIP &) = delete; |
| 273 | 273 |
| 274 public: | 274 public: |
| 275 static InstX86GetIP *create(Cfg *Func, Variable *Dest) { | 275 static InstX86GetIP *create(Cfg *Func, Variable *Dest) { |
| 276 return new (Func->allocate<InstX86GetIP>()) InstX86GetIP(Func, Dest); | 276 return new (Func->allocate<InstX86GetIP>()) InstX86GetIP(Func, Dest); |
| 277 } | 277 } |
| 278 void emit(const Cfg *Func) const override; | 278 void emit(const Cfg *Func) const override; |
| 279 void emitIAS(const Cfg *Func) const override; | 279 void emitIAS(const Cfg *Func) const override; |
| 280 void dump(const Cfg *Func) const override; | 280 void dump(const Cfg *Func) const override; |
| 281 static bool classof(const Inst *Inst) { | 281 static bool classof(const Inst *Instr) { |
| 282 return InstX86Base::isClassof(Inst, InstX86Base::GetIP); | 282 return InstX86Base::isClassof(Instr, InstX86Base::GetIP); |
| 283 } | 283 } |
| 284 | 284 |
| 285 private: | 285 private: |
| 286 InstX86GetIP(Cfg *Func, Variable *Dest); | 286 InstX86GetIP(Cfg *Func, Variable *Dest); |
| 287 }; | 287 }; |
| 288 | 288 |
| 289 /// InstX86Label represents an intra-block label that is the target of an | 289 /// InstX86Label represents an intra-block label that is the target of an |
| 290 /// intra-block branch. The offset between the label and the branch must be | 290 /// intra-block branch. The offset between the label and the branch must be |
| 291 /// fit into one byte (considered "near"). These are used for lowering i1 | 291 /// fit into one byte (considered "near"). These are used for lowering i1 |
| 292 /// calculations, Select instructions, and 64-bit compares on a 32-bit | 292 /// calculations, Select instructions, and 64-bit compares on a 32-bit |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 405 ++Sum; | 405 ++Sum; |
| 406 return Sum; | 406 return Sum; |
| 407 } | 407 } |
| 408 bool isUnconditionalBranch() const override { | 408 bool isUnconditionalBranch() const override { |
| 409 return !Label && Condition == Cond::Br_None; | 409 return !Label && Condition == Cond::Br_None; |
| 410 } | 410 } |
| 411 bool repointEdges(CfgNode *OldNode, CfgNode *NewNode) override; | 411 bool repointEdges(CfgNode *OldNode, CfgNode *NewNode) override; |
| 412 void emit(const Cfg *Func) const override; | 412 void emit(const Cfg *Func) const override; |
| 413 void emitIAS(const Cfg *Func) const override; | 413 void emitIAS(const Cfg *Func) const override; |
| 414 void dump(const Cfg *Func) const override; | 414 void dump(const Cfg *Func) const override; |
| 415 static bool classof(const Inst *Inst) { | 415 static bool classof(const Inst *Instr) { |
| 416 return InstX86Base::isClassof(Inst, InstX86Base::Br); | 416 return InstX86Base::isClassof(Instr, InstX86Base::Br); |
| 417 } | 417 } |
| 418 | 418 |
| 419 private: | 419 private: |
| 420 InstX86Br(Cfg *Func, const CfgNode *TargetTrue, const CfgNode *TargetFalse, | 420 InstX86Br(Cfg *Func, const CfgNode *TargetTrue, const CfgNode *TargetFalse, |
| 421 const InstX86Label *Label, BrCond Condition, Mode Kind); | 421 const InstX86Label *Label, BrCond Condition, Mode Kind); |
| 422 | 422 |
| 423 BrCond Condition; | 423 BrCond Condition; |
| 424 const CfgNode *TargetTrue; | 424 const CfgNode *TargetTrue; |
| 425 const CfgNode *TargetFalse; | 425 const CfgNode *TargetFalse; |
| 426 const InstX86Label *Label; // Intra-block branch target | 426 const InstX86Label *Label; // Intra-block branch target |
| 427 const Mode Kind; | 427 const Mode Kind; |
| 428 }; | 428 }; |
| 429 | 429 |
| 430 /// Jump to a target outside this function, such as tailcall, nacljump, | 430 /// Jump to a target outside this function, such as tailcall, nacljump, |
| 431 /// naclret, unreachable. This is different from a Branch instruction in that | 431 /// naclret, unreachable. This is different from a Branch instruction in that |
| 432 /// there is no intra-function control flow to represent. | 432 /// there is no intra-function control flow to represent. |
| 433 class InstX86Jmp final : public InstX86Base { | 433 class InstX86Jmp final : public InstX86Base { |
| 434 InstX86Jmp() = delete; | 434 InstX86Jmp() = delete; |
| 435 InstX86Jmp(const InstX86Jmp &) = delete; | 435 InstX86Jmp(const InstX86Jmp &) = delete; |
| 436 InstX86Jmp &operator=(const InstX86Jmp &) = delete; | 436 InstX86Jmp &operator=(const InstX86Jmp &) = delete; |
| 437 | 437 |
| 438 public: | 438 public: |
| 439 static InstX86Jmp *create(Cfg *Func, Operand *Target) { | 439 static InstX86Jmp *create(Cfg *Func, Operand *Target) { |
| 440 return new (Func->allocate<InstX86Jmp>()) InstX86Jmp(Func, Target); | 440 return new (Func->allocate<InstX86Jmp>()) InstX86Jmp(Func, Target); |
| 441 } | 441 } |
| 442 Operand *getJmpTarget() const { return this->getSrc(0); } | 442 Operand *getJmpTarget() const { return this->getSrc(0); } |
| 443 void emit(const Cfg *Func) const override; | 443 void emit(const Cfg *Func) const override; |
| 444 void emitIAS(const Cfg *Func) const override; | 444 void emitIAS(const Cfg *Func) const override; |
| 445 void dump(const Cfg *Func) const override; | 445 void dump(const Cfg *Func) const override; |
| 446 static bool classof(const Inst *Inst) { | 446 static bool classof(const Inst *Instr) { |
| 447 return InstX86Base::isClassof(Inst, InstX86Base::Jmp); | 447 return InstX86Base::isClassof(Instr, InstX86Base::Jmp); |
| 448 } | 448 } |
| 449 | 449 |
| 450 private: | 450 private: |
| 451 InstX86Jmp(Cfg *Func, Operand *Target); | 451 InstX86Jmp(Cfg *Func, Operand *Target); |
| 452 }; | 452 }; |
| 453 | 453 |
| 454 /// Call instruction. Arguments should have already been pushed. | 454 /// Call instruction. Arguments should have already been pushed. |
| 455 class InstX86Call final : public InstX86Base { | 455 class InstX86Call final : public InstX86Base { |
| 456 InstX86Call() = delete; | 456 InstX86Call() = delete; |
| 457 InstX86Call(const InstX86Call &) = delete; | 457 InstX86Call(const InstX86Call &) = delete; |
| 458 InstX86Call &operator=(const InstX86Call &) = delete; | 458 InstX86Call &operator=(const InstX86Call &) = delete; |
| 459 | 459 |
| 460 public: | 460 public: |
| 461 static InstX86Call *create(Cfg *Func, Variable *Dest, Operand *CallTarget) { | 461 static InstX86Call *create(Cfg *Func, Variable *Dest, Operand *CallTarget) { |
| 462 return new (Func->allocate<InstX86Call>()) | 462 return new (Func->allocate<InstX86Call>()) |
| 463 InstX86Call(Func, Dest, CallTarget); | 463 InstX86Call(Func, Dest, CallTarget); |
| 464 } | 464 } |
| 465 Operand *getCallTarget() const { return this->getSrc(0); } | 465 Operand *getCallTarget() const { return this->getSrc(0); } |
| 466 void emit(const Cfg *Func) const override; | 466 void emit(const Cfg *Func) const override; |
| 467 void emitIAS(const Cfg *Func) const override; | 467 void emitIAS(const Cfg *Func) const override; |
| 468 void dump(const Cfg *Func) const override; | 468 void dump(const Cfg *Func) const override; |
| 469 static bool classof(const Inst *Inst) { | 469 static bool classof(const Inst *Instr) { |
| 470 return InstX86Base::isClassof(Inst, InstX86Base::Call); | 470 return InstX86Base::isClassof(Instr, InstX86Base::Call); |
| 471 } | 471 } |
| 472 | 472 |
| 473 private: | 473 private: |
| 474 InstX86Call(Cfg *Func, Variable *Dest, Operand *CallTarget); | 474 InstX86Call(Cfg *Func, Variable *Dest, Operand *CallTarget); |
| 475 }; | 475 }; |
| 476 | 476 |
| 477 /// Emit a one-operand (GPR) instruction. | 477 /// Emit a one-operand (GPR) instruction. |
| 478 static void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Var, | 478 static void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Var, |
| 479 const GPREmitterOneOp &Emitter); | 479 const GPREmitterOneOp &Emitter); |
| 480 | 480 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 510 SReg_t (*srcEnc)(int32_t)> | 510 SReg_t (*srcEnc)(int32_t)> |
| 511 static void | 511 static void |
| 512 emitIASThreeOpImmOps(const Cfg *Func, Type DispatchTy, const Variable *Dest, | 512 emitIASThreeOpImmOps(const Cfg *Func, Type DispatchTy, const Variable *Dest, |
| 513 const Operand *Src0, const Operand *Src1, | 513 const Operand *Src0, const Operand *Src1, |
| 514 const ThreeOpImmEmitter<DReg_t, SReg_t> Emitter); | 514 const ThreeOpImmEmitter<DReg_t, SReg_t> Emitter); |
| 515 | 515 |
| 516 static void emitIASMovlikeXMM(const Cfg *Func, const Variable *Dest, | 516 static void emitIASMovlikeXMM(const Cfg *Func, const Variable *Dest, |
| 517 const Operand *Src, | 517 const Operand *Src, |
| 518 const XmmEmitterMovOps Emitter); | 518 const XmmEmitterMovOps Emitter); |
| 519 | 519 |
| 520 static void emitVariableBlendInst(const char *Opcode, const Inst *Inst, | 520 static void emitVariableBlendInst(const char *Opcode, const Inst *Instr, |
| 521 const Cfg *Func); | 521 const Cfg *Func); |
| 522 | 522 |
| 523 static void emitIASVariableBlendInst(const Inst *Inst, const Cfg *Func, | 523 static void emitIASVariableBlendInst(const Inst *Instr, const Cfg *Func, |
| 524 const XmmEmitterRegOp &Emitter); | 524 const XmmEmitterRegOp &Emitter); |
| 525 | 525 |
| 526 static void emitIASXmmShift(const Cfg *Func, Type Ty, const Variable *Var, | 526 static void emitIASXmmShift(const Cfg *Func, Type Ty, const Variable *Var, |
| 527 const Operand *Src, | 527 const Operand *Src, |
| 528 const XmmEmitterShiftOp &Emitter); | 528 const XmmEmitterShiftOp &Emitter); |
| 529 | 529 |
| 530 /// Emit a two-operand (GPR) instruction, where the dest operand is a Variable | 530 /// Emit a two-operand (GPR) instruction, where the dest operand is a Variable |
| 531 /// that's guaranteed to be a register. | 531 /// that's guaranteed to be a register. |
| 532 template <bool VarCanBeByte = true, bool SrcCanBeByte = true> | 532 template <bool VarCanBeByte = true, bool SrcCanBeByte = true> |
| 533 static void emitIASRegOpTyGPR(const Cfg *Func, bool IsLea, Type Ty, | 533 static void emitIASRegOpTyGPR(const Cfg *Func, bool IsLea, Type Ty, |
| (...skipping 26 matching lines...) Expand all Loading... |
| 560 emitIASOpTyGPR(Func, Ty, Var, Emitter); | 560 emitIASOpTyGPR(Func, Ty, Var, Emitter); |
| 561 } | 561 } |
| 562 void dump(const Cfg *Func) const override { | 562 void dump(const Cfg *Func) const override { |
| 563 if (!BuildDefs::dump()) | 563 if (!BuildDefs::dump()) |
| 564 return; | 564 return; |
| 565 Ostream &Str = Func->getContext()->getStrDump(); | 565 Ostream &Str = Func->getContext()->getStrDump(); |
| 566 this->dumpDest(Func); | 566 this->dumpDest(Func); |
| 567 Str << " = " << Opcode << "." << this->getDest()->getType() << " "; | 567 Str << " = " << Opcode << "." << this->getDest()->getType() << " "; |
| 568 this->dumpSources(Func); | 568 this->dumpSources(Func); |
| 569 } | 569 } |
| 570 static bool classof(const Inst *Inst) { | 570 static bool classof(const Inst *Instr) { |
| 571 return InstX86Base::isClassof(Inst, InstX86Base::K); | 571 return InstX86Base::isClassof(Instr, InstX86Base::K); |
| 572 } | 572 } |
| 573 | 573 |
| 574 protected: | 574 protected: |
| 575 InstX86BaseInplaceopGPR(Cfg *Func, Operand *SrcDest) | 575 InstX86BaseInplaceopGPR(Cfg *Func, Operand *SrcDest) |
| 576 : InstX86Base(Func, K, 1, llvm::dyn_cast<Variable>(SrcDest)) { | 576 : InstX86Base(Func, K, 1, llvm::dyn_cast<Variable>(SrcDest)) { |
| 577 this->addSource(SrcDest); | 577 this->addSource(SrcDest); |
| 578 } | 578 } |
| 579 | 579 |
| 580 private: | 580 private: |
| 581 static const char *Opcode; | 581 static const char *Opcode; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 619 emitIASRegOpTyGPR(Func, IsLea, Ty, Var, Src, Emitter); | 619 emitIASRegOpTyGPR(Func, IsLea, Ty, Var, Src, Emitter); |
| 620 } | 620 } |
| 621 void dump(const Cfg *Func) const override { | 621 void dump(const Cfg *Func) const override { |
| 622 if (!BuildDefs::dump()) | 622 if (!BuildDefs::dump()) |
| 623 return; | 623 return; |
| 624 Ostream &Str = Func->getContext()->getStrDump(); | 624 Ostream &Str = Func->getContext()->getStrDump(); |
| 625 this->dumpDest(Func); | 625 this->dumpDest(Func); |
| 626 Str << " = " << Opcode << "." << this->getSrc(0)->getType() << " "; | 626 Str << " = " << Opcode << "." << this->getSrc(0)->getType() << " "; |
| 627 this->dumpSources(Func); | 627 this->dumpSources(Func); |
| 628 } | 628 } |
| 629 static bool classof(const Inst *Inst) { | 629 static bool classof(const Inst *Instr) { |
| 630 return InstX86Base::isClassof(Inst, InstX86Base::K); | 630 return InstX86Base::isClassof(Instr, InstX86Base::K); |
| 631 } | 631 } |
| 632 | 632 |
| 633 protected: | 633 protected: |
| 634 InstX86BaseUnaryopGPR(Cfg *Func, Variable *Dest, Operand *Src) | 634 InstX86BaseUnaryopGPR(Cfg *Func, Variable *Dest, Operand *Src) |
| 635 : InstX86Base(Func, K, 1, Dest) { | 635 : InstX86Base(Func, K, 1, Dest) { |
| 636 this->addSource(Src); | 636 this->addSource(Src); |
| 637 } | 637 } |
| 638 | 638 |
| 639 static const char *Opcode; | 639 static const char *Opcode; |
| 640 static const GPREmitterRegOp Emitter; | 640 static const GPREmitterRegOp Emitter; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 665 emitIASRegOpTyXMM(Func, Ty, this->getDest(), this->getSrc(0), Emitter); | 665 emitIASRegOpTyXMM(Func, Ty, this->getDest(), this->getSrc(0), Emitter); |
| 666 } | 666 } |
| 667 void dump(const Cfg *Func) const override { | 667 void dump(const Cfg *Func) const override { |
| 668 if (!BuildDefs::dump()) | 668 if (!BuildDefs::dump()) |
| 669 return; | 669 return; |
| 670 Ostream &Str = Func->getContext()->getStrDump(); | 670 Ostream &Str = Func->getContext()->getStrDump(); |
| 671 this->dumpDest(Func); | 671 this->dumpDest(Func); |
| 672 Str << " = " << Opcode << "." << this->getDest()->getType() << " "; | 672 Str << " = " << Opcode << "." << this->getDest()->getType() << " "; |
| 673 this->dumpSources(Func); | 673 this->dumpSources(Func); |
| 674 } | 674 } |
| 675 static bool classof(const Inst *Inst) { | 675 static bool classof(const Inst *Instr) { |
| 676 return InstX86Base::isClassof(Inst, InstX86Base::K); | 676 return InstX86Base::isClassof(Instr, InstX86Base::K); |
| 677 } | 677 } |
| 678 | 678 |
| 679 protected: | 679 protected: |
| 680 InstX86BaseUnaryopXmm(Cfg *Func, Variable *Dest, Operand *Src) | 680 InstX86BaseUnaryopXmm(Cfg *Func, Variable *Dest, Operand *Src) |
| 681 : InstX86Base(Func, K, 1, Dest) { | 681 : InstX86Base(Func, K, 1, Dest) { |
| 682 this->addSource(Src); | 682 this->addSource(Src); |
| 683 } | 683 } |
| 684 | 684 |
| 685 static const char *Opcode; | 685 static const char *Opcode; |
| 686 static const XmmEmitterRegOp Emitter; | 686 static const XmmEmitterRegOp Emitter; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 707 emitIASGPRShift(Func, Ty, this->getDest(), this->getSrc(1), Emitter); | 707 emitIASGPRShift(Func, Ty, this->getDest(), this->getSrc(1), Emitter); |
| 708 } | 708 } |
| 709 void dump(const Cfg *Func) const override { | 709 void dump(const Cfg *Func) const override { |
| 710 if (!BuildDefs::dump()) | 710 if (!BuildDefs::dump()) |
| 711 return; | 711 return; |
| 712 Ostream &Str = Func->getContext()->getStrDump(); | 712 Ostream &Str = Func->getContext()->getStrDump(); |
| 713 this->dumpDest(Func); | 713 this->dumpDest(Func); |
| 714 Str << " = " << Opcode << "." << this->getDest()->getType() << " "; | 714 Str << " = " << Opcode << "." << this->getDest()->getType() << " "; |
| 715 this->dumpSources(Func); | 715 this->dumpSources(Func); |
| 716 } | 716 } |
| 717 static bool classof(const Inst *Inst) { | 717 static bool classof(const Inst *Instr) { |
| 718 return InstX86Base::isClassof(Inst, InstX86Base::K); | 718 return InstX86Base::isClassof(Instr, InstX86Base::K); |
| 719 } | 719 } |
| 720 | 720 |
| 721 protected: | 721 protected: |
| 722 InstX86BaseBinopGPRShift(Cfg *Func, Variable *Dest, Operand *Source) | 722 InstX86BaseBinopGPRShift(Cfg *Func, Variable *Dest, Operand *Source) |
| 723 : InstX86Base(Func, K, 2, Dest) { | 723 : InstX86Base(Func, K, 2, Dest) { |
| 724 this->addSource(Dest); | 724 this->addSource(Dest); |
| 725 this->addSource(Source); | 725 this->addSource(Source); |
| 726 } | 726 } |
| 727 | 727 |
| 728 static const char *Opcode; | 728 static const char *Opcode; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 752 Emitter); | 752 Emitter); |
| 753 } | 753 } |
| 754 void dump(const Cfg *Func) const override { | 754 void dump(const Cfg *Func) const override { |
| 755 if (!BuildDefs::dump()) | 755 if (!BuildDefs::dump()) |
| 756 return; | 756 return; |
| 757 Ostream &Str = Func->getContext()->getStrDump(); | 757 Ostream &Str = Func->getContext()->getStrDump(); |
| 758 this->dumpDest(Func); | 758 this->dumpDest(Func); |
| 759 Str << " = " << Opcode << "." << this->getDest()->getType() << " "; | 759 Str << " = " << Opcode << "." << this->getDest()->getType() << " "; |
| 760 this->dumpSources(Func); | 760 this->dumpSources(Func); |
| 761 } | 761 } |
| 762 static bool classof(const Inst *Inst) { | 762 static bool classof(const Inst *Instr) { |
| 763 return InstX86Base::isClassof(Inst, InstX86Base::K); | 763 return InstX86Base::isClassof(Instr, InstX86Base::K); |
| 764 } | 764 } |
| 765 | 765 |
| 766 protected: | 766 protected: |
| 767 InstX86BaseBinopGPR(Cfg *Func, Variable *Dest, Operand *Source) | 767 InstX86BaseBinopGPR(Cfg *Func, Variable *Dest, Operand *Source) |
| 768 : InstX86Base(Func, K, 2, Dest) { | 768 : InstX86Base(Func, K, 2, Dest) { |
| 769 this->addSource(Dest); | 769 this->addSource(Dest); |
| 770 this->addSource(Source); | 770 this->addSource(Source); |
| 771 } | 771 } |
| 772 | 772 |
| 773 static const char *Opcode; | 773 static const char *Opcode; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 793 assert(this->getSrcSize() == 2); | 793 assert(this->getSrcSize() == 2); |
| 794 emitIASAsAddrOpTyGPR(Func, Ty, this->getSrc(0), this->getSrc(1), Emitter); | 794 emitIASAsAddrOpTyGPR(Func, Ty, this->getSrc(0), this->getSrc(1), Emitter); |
| 795 } | 795 } |
| 796 void dump(const Cfg *Func) const override { | 796 void dump(const Cfg *Func) const override { |
| 797 if (!BuildDefs::dump()) | 797 if (!BuildDefs::dump()) |
| 798 return; | 798 return; |
| 799 Ostream &Str = Func->getContext()->getStrDump(); | 799 Ostream &Str = Func->getContext()->getStrDump(); |
| 800 Str << Opcode << "." << this->getSrc(0)->getType() << " "; | 800 Str << Opcode << "." << this->getSrc(0)->getType() << " "; |
| 801 this->dumpSources(Func); | 801 this->dumpSources(Func); |
| 802 } | 802 } |
| 803 static bool classof(const Inst *Inst) { | 803 static bool classof(const Inst *Instr) { |
| 804 return InstX86Base::isClassof(Inst, InstX86Base::K); | 804 return InstX86Base::isClassof(Instr, InstX86Base::K); |
| 805 } | 805 } |
| 806 | 806 |
| 807 protected: | 807 protected: |
| 808 InstX86BaseBinopRMW(Cfg *Func, X86OperandMem *DestSrc0, Operand *Src1) | 808 InstX86BaseBinopRMW(Cfg *Func, X86OperandMem *DestSrc0, Operand *Src1) |
| 809 : InstX86Base(Func, K, 2, nullptr) { | 809 : InstX86Base(Func, K, 2, nullptr) { |
| 810 this->addSource(DestSrc0); | 810 this->addSource(DestSrc0); |
| 811 this->addSource(Src1); | 811 this->addSource(Src1); |
| 812 } | 812 } |
| 813 | 813 |
| 814 static const char *Opcode; | 814 static const char *Opcode; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 857 emitIASRegOpTyXMM(Func, Ty, this->getDest(), this->getSrc(1), Emitter); | 857 emitIASRegOpTyXMM(Func, Ty, this->getDest(), this->getSrc(1), Emitter); |
| 858 } | 858 } |
| 859 void dump(const Cfg *Func) const override { | 859 void dump(const Cfg *Func) const override { |
| 860 if (!BuildDefs::dump()) | 860 if (!BuildDefs::dump()) |
| 861 return; | 861 return; |
| 862 Ostream &Str = Func->getContext()->getStrDump(); | 862 Ostream &Str = Func->getContext()->getStrDump(); |
| 863 this->dumpDest(Func); | 863 this->dumpDest(Func); |
| 864 Str << " = " << Opcode << "." << this->getDest()->getType() << " "; | 864 Str << " = " << Opcode << "." << this->getDest()->getType() << " "; |
| 865 this->dumpSources(Func); | 865 this->dumpSources(Func); |
| 866 } | 866 } |
| 867 static bool classof(const Inst *Inst) { | 867 static bool classof(const Inst *Instr) { |
| 868 return InstX86Base::isClassof(Inst, InstX86Base::K); | 868 return InstX86Base::isClassof(Instr, InstX86Base::K); |
| 869 } | 869 } |
| 870 | 870 |
| 871 protected: | 871 protected: |
| 872 InstX86BaseBinopXmm(Cfg *Func, Variable *Dest, Operand *Source, | 872 InstX86BaseBinopXmm(Cfg *Func, Variable *Dest, Operand *Source, |
| 873 Type ArithmeticTypeOverride = IceType_void) | 873 Type ArithmeticTypeOverride = IceType_void) |
| 874 : InstX86Base(Func, K, 2, Dest), | 874 : InstX86Base(Func, K, 2, Dest), |
| 875 ArithmeticTypeOverride(ArithmeticTypeOverride) { | 875 ArithmeticTypeOverride(ArithmeticTypeOverride) { |
| 876 this->addSource(Dest); | 876 this->addSource(Dest); |
| 877 this->addSource(Source); | 877 this->addSource(Source); |
| 878 } | 878 } |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 911 Emitter); | 911 Emitter); |
| 912 } | 912 } |
| 913 void dump(const Cfg *Func) const override { | 913 void dump(const Cfg *Func) const override { |
| 914 if (!BuildDefs::dump()) | 914 if (!BuildDefs::dump()) |
| 915 return; | 915 return; |
| 916 Ostream &Str = Func->getContext()->getStrDump(); | 916 Ostream &Str = Func->getContext()->getStrDump(); |
| 917 this->dumpDest(Func); | 917 this->dumpDest(Func); |
| 918 Str << " = " << Opcode << "." << this->getDest()->getType() << " "; | 918 Str << " = " << Opcode << "." << this->getDest()->getType() << " "; |
| 919 this->dumpSources(Func); | 919 this->dumpSources(Func); |
| 920 } | 920 } |
| 921 static bool classof(const Inst *Inst) { | 921 static bool classof(const Inst *Instr) { |
| 922 return InstX86Base::isClassof(Inst, InstX86Base::K); | 922 return InstX86Base::isClassof(Instr, InstX86Base::K); |
| 923 } | 923 } |
| 924 | 924 |
| 925 protected: | 925 protected: |
| 926 InstX86BaseBinopXmmShift(Cfg *Func, Variable *Dest, Operand *Source) | 926 InstX86BaseBinopXmmShift(Cfg *Func, Variable *Dest, Operand *Source) |
| 927 : InstX86Base(Func, K, 2, Dest) { | 927 : InstX86Base(Func, K, 2, Dest) { |
| 928 this->addSource(Dest); | 928 this->addSource(Dest); |
| 929 this->addSource(Source); | 929 this->addSource(Source); |
| 930 } | 930 } |
| 931 | 931 |
| 932 static const char *Opcode; | 932 static const char *Opcode; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 955 this->getDest()->emit(Func); | 955 this->getDest()->emit(Func); |
| 956 } | 956 } |
| 957 void dump(const Cfg *Func) const override { | 957 void dump(const Cfg *Func) const override { |
| 958 if (!BuildDefs::dump()) | 958 if (!BuildDefs::dump()) |
| 959 return; | 959 return; |
| 960 Ostream &Str = Func->getContext()->getStrDump(); | 960 Ostream &Str = Func->getContext()->getStrDump(); |
| 961 this->dumpDest(Func); | 961 this->dumpDest(Func); |
| 962 Str << " = " << Opcode << "." << this->getDest()->getType() << " "; | 962 Str << " = " << Opcode << "." << this->getDest()->getType() << " "; |
| 963 this->dumpSources(Func); | 963 this->dumpSources(Func); |
| 964 } | 964 } |
| 965 static bool classof(const Inst *Inst) { | 965 static bool classof(const Inst *Instr) { |
| 966 return InstX86Base::isClassof(Inst, InstX86Base::K); | 966 return InstX86Base::isClassof(Instr, InstX86Base::K); |
| 967 } | 967 } |
| 968 | 968 |
| 969 protected: | 969 protected: |
| 970 InstX86BaseTernop(Cfg *Func, Variable *Dest, Operand *Source1, | 970 InstX86BaseTernop(Cfg *Func, Variable *Dest, Operand *Source1, |
| 971 Operand *Source2) | 971 Operand *Source2) |
| 972 : InstX86Base(Func, K, 3, Dest) { | 972 : InstX86Base(Func, K, 3, Dest) { |
| 973 this->addSource(Dest); | 973 this->addSource(Dest); |
| 974 this->addSource(Source1); | 974 this->addSource(Source1); |
| 975 this->addSource(Source2); | 975 this->addSource(Source2); |
| 976 } | 976 } |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1002 this->getDest()->emit(Func); | 1002 this->getDest()->emit(Func); |
| 1003 } | 1003 } |
| 1004 void dump(const Cfg *Func) const override { | 1004 void dump(const Cfg *Func) const override { |
| 1005 if (!BuildDefs::dump()) | 1005 if (!BuildDefs::dump()) |
| 1006 return; | 1006 return; |
| 1007 Ostream &Str = Func->getContext()->getStrDump(); | 1007 Ostream &Str = Func->getContext()->getStrDump(); |
| 1008 this->dumpDest(Func); | 1008 this->dumpDest(Func); |
| 1009 Str << " = " << Opcode << "." << this->getDest()->getType() << " "; | 1009 Str << " = " << Opcode << "." << this->getDest()->getType() << " "; |
| 1010 this->dumpSources(Func); | 1010 this->dumpSources(Func); |
| 1011 } | 1011 } |
| 1012 static bool classof(const Inst *Inst) { | 1012 static bool classof(const Inst *Instr) { |
| 1013 return InstX86Base::isClassof(Inst, InstX86Base::K); | 1013 return InstX86Base::isClassof(Instr, InstX86Base::K); |
| 1014 } | 1014 } |
| 1015 | 1015 |
| 1016 protected: | 1016 protected: |
| 1017 InstX86BaseThreeAddressop(Cfg *Func, Variable *Dest, Operand *Source0, | 1017 InstX86BaseThreeAddressop(Cfg *Func, Variable *Dest, Operand *Source0, |
| 1018 Operand *Source1) | 1018 Operand *Source1) |
| 1019 : InstX86Base(Func, K, 2, Dest) { | 1019 : InstX86Base(Func, K, 2, Dest) { |
| 1020 this->addSource(Source0); | 1020 this->addSource(Source0); |
| 1021 this->addSource(Source1); | 1021 this->addSource(Source1); |
| 1022 } | 1022 } |
| 1023 | 1023 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1059 } | 1059 } |
| 1060 void dump(const Cfg *Func) const override { | 1060 void dump(const Cfg *Func) const override { |
| 1061 if (!BuildDefs::dump()) | 1061 if (!BuildDefs::dump()) |
| 1062 return; | 1062 return; |
| 1063 Ostream &Str = Func->getContext()->getStrDump(); | 1063 Ostream &Str = Func->getContext()->getStrDump(); |
| 1064 Str << Opcode << "." << this->getDest()->getType() << " "; | 1064 Str << Opcode << "." << this->getDest()->getType() << " "; |
| 1065 this->dumpDest(Func); | 1065 this->dumpDest(Func); |
| 1066 Str << ", "; | 1066 Str << ", "; |
| 1067 this->dumpSources(Func); | 1067 this->dumpSources(Func); |
| 1068 } | 1068 } |
| 1069 static bool classof(const Inst *Inst) { | 1069 static bool classof(const Inst *Instr) { |
| 1070 return InstX86Base::isClassof(Inst, InstX86Base::K); | 1070 return InstX86Base::isClassof(Instr, InstX86Base::K); |
| 1071 } | 1071 } |
| 1072 | 1072 |
| 1073 protected: | 1073 protected: |
| 1074 InstX86BaseMovlike(Cfg *Func, Variable *Dest, Operand *Source) | 1074 InstX86BaseMovlike(Cfg *Func, Variable *Dest, Operand *Source) |
| 1075 : InstX86Base(Func, K, 1, Dest) { | 1075 : InstX86Base(Func, K, 1, Dest) { |
| 1076 this->addSource(Source); | 1076 this->addSource(Source); |
| 1077 // For an integer assignment, make sure it's either a same-type assignment | 1077 // For an integer assignment, make sure it's either a same-type assignment |
| 1078 // or a truncation. | 1078 // or a truncation. |
| 1079 assert(!isScalarIntegerType(Dest->getType()) || | 1079 assert(!isScalarIntegerType(Dest->getType()) || |
| 1080 (typeWidthInBytes(Dest->getType()) <= | 1080 (typeWidthInBytes(Dest->getType()) <= |
| (...skipping 1099 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2180 | 2180 |
| 2181 public: | 2181 public: |
| 2182 static InstX86Mul *create(Cfg *Func, Variable *Dest, Variable *Source1, | 2182 static InstX86Mul *create(Cfg *Func, Variable *Dest, Variable *Source1, |
| 2183 Operand *Source2) { | 2183 Operand *Source2) { |
| 2184 return new (Func->allocate<InstX86Mul>()) | 2184 return new (Func->allocate<InstX86Mul>()) |
| 2185 InstX86Mul(Func, Dest, Source1, Source2); | 2185 InstX86Mul(Func, Dest, Source1, Source2); |
| 2186 } | 2186 } |
| 2187 void emit(const Cfg *Func) const override; | 2187 void emit(const Cfg *Func) const override; |
| 2188 void emitIAS(const Cfg *Func) const override; | 2188 void emitIAS(const Cfg *Func) const override; |
| 2189 void dump(const Cfg *Func) const override; | 2189 void dump(const Cfg *Func) const override; |
| 2190 static bool classof(const Inst *Inst) { | 2190 static bool classof(const Inst *Instr) { |
| 2191 return InstX86Base::isClassof(Inst, InstX86Base::Mul); | 2191 return InstX86Base::isClassof(Instr, InstX86Base::Mul); |
| 2192 } | 2192 } |
| 2193 | 2193 |
| 2194 private: | 2194 private: |
| 2195 InstX86Mul(Cfg *Func, Variable *Dest, Variable *Source1, Operand *Source2); | 2195 InstX86Mul(Cfg *Func, Variable *Dest, Variable *Source1, Operand *Source2); |
| 2196 }; | 2196 }; |
| 2197 | 2197 |
| 2198 /// Shld instruction - shift across a pair of operands. | 2198 /// Shld instruction - shift across a pair of operands. |
| 2199 class InstX86Shld final : public InstX86Base { | 2199 class InstX86Shld final : public InstX86Base { |
| 2200 InstX86Shld() = delete; | 2200 InstX86Shld() = delete; |
| 2201 InstX86Shld(const InstX86Shld &) = delete; | 2201 InstX86Shld(const InstX86Shld &) = delete; |
| 2202 InstX86Shld &operator=(const InstX86Shld &) = delete; | 2202 InstX86Shld &operator=(const InstX86Shld &) = delete; |
| 2203 | 2203 |
| 2204 public: | 2204 public: |
| 2205 static InstX86Shld *create(Cfg *Func, Variable *Dest, Variable *Source1, | 2205 static InstX86Shld *create(Cfg *Func, Variable *Dest, Variable *Source1, |
| 2206 Operand *Source2) { | 2206 Operand *Source2) { |
| 2207 return new (Func->allocate<InstX86Shld>()) | 2207 return new (Func->allocate<InstX86Shld>()) |
| 2208 InstX86Shld(Func, Dest, Source1, Source2); | 2208 InstX86Shld(Func, Dest, Source1, Source2); |
| 2209 } | 2209 } |
| 2210 void emit(const Cfg *Func) const override; | 2210 void emit(const Cfg *Func) const override; |
| 2211 void emitIAS(const Cfg *Func) const override; | 2211 void emitIAS(const Cfg *Func) const override; |
| 2212 void dump(const Cfg *Func) const override; | 2212 void dump(const Cfg *Func) const override; |
| 2213 static bool classof(const Inst *Inst) { | 2213 static bool classof(const Inst *Instr) { |
| 2214 return InstX86Base::isClassof(Inst, InstX86Base::Shld); | 2214 return InstX86Base::isClassof(Instr, InstX86Base::Shld); |
| 2215 } | 2215 } |
| 2216 | 2216 |
| 2217 private: | 2217 private: |
| 2218 InstX86Shld(Cfg *Func, Variable *Dest, Variable *Source1, Operand *Source2); | 2218 InstX86Shld(Cfg *Func, Variable *Dest, Variable *Source1, Operand *Source2); |
| 2219 }; | 2219 }; |
| 2220 | 2220 |
| 2221 /// Shrd instruction - shift across a pair of operands. | 2221 /// Shrd instruction - shift across a pair of operands. |
| 2222 class InstX86Shrd final : public InstX86Base { | 2222 class InstX86Shrd final : public InstX86Base { |
| 2223 InstX86Shrd() = delete; | 2223 InstX86Shrd() = delete; |
| 2224 InstX86Shrd(const InstX86Shrd &) = delete; | 2224 InstX86Shrd(const InstX86Shrd &) = delete; |
| 2225 InstX86Shrd &operator=(const InstX86Shrd &) = delete; | 2225 InstX86Shrd &operator=(const InstX86Shrd &) = delete; |
| 2226 | 2226 |
| 2227 public: | 2227 public: |
| 2228 static InstX86Shrd *create(Cfg *Func, Variable *Dest, Variable *Source1, | 2228 static InstX86Shrd *create(Cfg *Func, Variable *Dest, Variable *Source1, |
| 2229 Operand *Source2) { | 2229 Operand *Source2) { |
| 2230 return new (Func->allocate<InstX86Shrd>()) | 2230 return new (Func->allocate<InstX86Shrd>()) |
| 2231 InstX86Shrd(Func, Dest, Source1, Source2); | 2231 InstX86Shrd(Func, Dest, Source1, Source2); |
| 2232 } | 2232 } |
| 2233 void emit(const Cfg *Func) const override; | 2233 void emit(const Cfg *Func) const override; |
| 2234 void emitIAS(const Cfg *Func) const override; | 2234 void emitIAS(const Cfg *Func) const override; |
| 2235 void dump(const Cfg *Func) const override; | 2235 void dump(const Cfg *Func) const override; |
| 2236 static bool classof(const Inst *Inst) { | 2236 static bool classof(const Inst *Instr) { |
| 2237 return InstX86Base::isClassof(Inst, InstX86Base::Shrd); | 2237 return InstX86Base::isClassof(Instr, InstX86Base::Shrd); |
| 2238 } | 2238 } |
| 2239 | 2239 |
| 2240 private: | 2240 private: |
| 2241 InstX86Shrd(Cfg *Func, Variable *Dest, Variable *Source1, Operand *Source2); | 2241 InstX86Shrd(Cfg *Func, Variable *Dest, Variable *Source1, Operand *Source2); |
| 2242 }; | 2242 }; |
| 2243 | 2243 |
| 2244 /// Conditional move instruction. | 2244 /// Conditional move instruction. |
| 2245 class InstX86Cmov final : public InstX86Base { | 2245 class InstX86Cmov final : public InstX86Base { |
| 2246 InstX86Cmov() = delete; | 2246 InstX86Cmov() = delete; |
| 2247 InstX86Cmov(const InstX86Cmov &) = delete; | 2247 InstX86Cmov(const InstX86Cmov &) = delete; |
| 2248 InstX86Cmov &operator=(const InstX86Cmov &) = delete; | 2248 InstX86Cmov &operator=(const InstX86Cmov &) = delete; |
| 2249 | 2249 |
| 2250 public: | 2250 public: |
| 2251 static InstX86Cmov *create(Cfg *Func, Variable *Dest, Operand *Source, | 2251 static InstX86Cmov *create(Cfg *Func, Variable *Dest, Operand *Source, |
| 2252 BrCond Cond) { | 2252 BrCond Cond) { |
| 2253 return new (Func->allocate<InstX86Cmov>()) | 2253 return new (Func->allocate<InstX86Cmov>()) |
| 2254 InstX86Cmov(Func, Dest, Source, Cond); | 2254 InstX86Cmov(Func, Dest, Source, Cond); |
| 2255 } | 2255 } |
| 2256 void emit(const Cfg *Func) const override; | 2256 void emit(const Cfg *Func) const override; |
| 2257 void emitIAS(const Cfg *Func) const override; | 2257 void emitIAS(const Cfg *Func) const override; |
| 2258 void dump(const Cfg *Func) const override; | 2258 void dump(const Cfg *Func) const override; |
| 2259 static bool classof(const Inst *Inst) { | 2259 static bool classof(const Inst *Instr) { |
| 2260 return InstX86Base::isClassof(Inst, InstX86Base::Cmov); | 2260 return InstX86Base::isClassof(Instr, InstX86Base::Cmov); |
| 2261 } | 2261 } |
| 2262 | 2262 |
| 2263 private: | 2263 private: |
| 2264 InstX86Cmov(Cfg *Func, Variable *Dest, Operand *Source, BrCond Cond); | 2264 InstX86Cmov(Cfg *Func, Variable *Dest, Operand *Source, BrCond Cond); |
| 2265 | 2265 |
| 2266 BrCond Condition; | 2266 BrCond Condition; |
| 2267 }; | 2267 }; |
| 2268 | 2268 |
| 2269 /// Cmpps instruction - compare packed singled-precision floating point values | 2269 /// Cmpps instruction - compare packed singled-precision floating point values |
| 2270 class InstX86Cmpps final : public InstX86Base { | 2270 class InstX86Cmpps final : public InstX86Base { |
| 2271 InstX86Cmpps() = delete; | 2271 InstX86Cmpps() = delete; |
| 2272 InstX86Cmpps(const InstX86Cmpps &) = delete; | 2272 InstX86Cmpps(const InstX86Cmpps &) = delete; |
| 2273 InstX86Cmpps &operator=(const InstX86Cmpps &) = delete; | 2273 InstX86Cmpps &operator=(const InstX86Cmpps &) = delete; |
| 2274 | 2274 |
| 2275 public: | 2275 public: |
| 2276 static InstX86Cmpps *create(Cfg *Func, Variable *Dest, Operand *Source, | 2276 static InstX86Cmpps *create(Cfg *Func, Variable *Dest, Operand *Source, |
| 2277 CmppsCond Condition) { | 2277 CmppsCond Condition) { |
| 2278 return new (Func->allocate<InstX86Cmpps>()) | 2278 return new (Func->allocate<InstX86Cmpps>()) |
| 2279 InstX86Cmpps(Func, Dest, Source, Condition); | 2279 InstX86Cmpps(Func, Dest, Source, Condition); |
| 2280 } | 2280 } |
| 2281 void emit(const Cfg *Func) const override; | 2281 void emit(const Cfg *Func) const override; |
| 2282 void emitIAS(const Cfg *Func) const override; | 2282 void emitIAS(const Cfg *Func) const override; |
| 2283 void dump(const Cfg *Func) const override; | 2283 void dump(const Cfg *Func) const override; |
| 2284 static bool classof(const Inst *Inst) { | 2284 static bool classof(const Inst *Instr) { |
| 2285 return InstX86Base::isClassof(Inst, InstX86Base::Cmpps); | 2285 return InstX86Base::isClassof(Instr, InstX86Base::Cmpps); |
| 2286 } | 2286 } |
| 2287 | 2287 |
| 2288 private: | 2288 private: |
| 2289 InstX86Cmpps(Cfg *Func, Variable *Dest, Operand *Source, CmppsCond Cond); | 2289 InstX86Cmpps(Cfg *Func, Variable *Dest, Operand *Source, CmppsCond Cond); |
| 2290 | 2290 |
| 2291 CmppsCond Condition; | 2291 CmppsCond Condition; |
| 2292 }; | 2292 }; |
| 2293 | 2293 |
| 2294 /// Cmpxchg instruction - cmpxchg <dest>, <desired> will compare if <dest> | 2294 /// Cmpxchg instruction - cmpxchg <dest>, <desired> will compare if <dest> |
| 2295 /// equals eax. If so, the ZF is set and <desired> is stored in <dest>. If | 2295 /// equals eax. If so, the ZF is set and <desired> is stored in <dest>. If |
| 2296 /// not, ZF is cleared and <dest> is copied to eax (or subregister). <dest> | 2296 /// not, ZF is cleared and <dest> is copied to eax (or subregister). <dest> |
| 2297 /// can be a register or memory, while <desired> must be a register. It is | 2297 /// can be a register or memory, while <desired> must be a register. It is |
| 2298 /// the user's responsibility to mark eax with a FakeDef. | 2298 /// the user's responsibility to mark eax with a FakeDef. |
| 2299 class InstX86Cmpxchg final : public InstX86BaseLockable { | 2299 class InstX86Cmpxchg final : public InstX86BaseLockable { |
| 2300 InstX86Cmpxchg() = delete; | 2300 InstX86Cmpxchg() = delete; |
| 2301 InstX86Cmpxchg(const InstX86Cmpxchg &) = delete; | 2301 InstX86Cmpxchg(const InstX86Cmpxchg &) = delete; |
| 2302 InstX86Cmpxchg &operator=(const InstX86Cmpxchg &) = delete; | 2302 InstX86Cmpxchg &operator=(const InstX86Cmpxchg &) = delete; |
| 2303 | 2303 |
| 2304 public: | 2304 public: |
| 2305 static InstX86Cmpxchg *create(Cfg *Func, Operand *DestOrAddr, Variable *Eax, | 2305 static InstX86Cmpxchg *create(Cfg *Func, Operand *DestOrAddr, Variable *Eax, |
| 2306 Variable *Desired, bool Locked) { | 2306 Variable *Desired, bool Locked) { |
| 2307 return new (Func->allocate<InstX86Cmpxchg>()) | 2307 return new (Func->allocate<InstX86Cmpxchg>()) |
| 2308 InstX86Cmpxchg(Func, DestOrAddr, Eax, Desired, Locked); | 2308 InstX86Cmpxchg(Func, DestOrAddr, Eax, Desired, Locked); |
| 2309 } | 2309 } |
| 2310 void emit(const Cfg *Func) const override; | 2310 void emit(const Cfg *Func) const override; |
| 2311 void emitIAS(const Cfg *Func) const override; | 2311 void emitIAS(const Cfg *Func) const override; |
| 2312 void dump(const Cfg *Func) const override; | 2312 void dump(const Cfg *Func) const override; |
| 2313 static bool classof(const Inst *Inst) { | 2313 static bool classof(const Inst *Instr) { |
| 2314 return InstX86Base::isClassof(Inst, InstX86Base::Cmpxchg); | 2314 return InstX86Base::isClassof(Instr, InstX86Base::Cmpxchg); |
| 2315 } | 2315 } |
| 2316 | 2316 |
| 2317 private: | 2317 private: |
| 2318 InstX86Cmpxchg(Cfg *Func, Operand *DestOrAddr, Variable *Eax, | 2318 InstX86Cmpxchg(Cfg *Func, Operand *DestOrAddr, Variable *Eax, |
| 2319 Variable *Desired, bool Locked); | 2319 Variable *Desired, bool Locked); |
| 2320 }; | 2320 }; |
| 2321 | 2321 |
| 2322 /// Cmpxchg8b instruction - cmpxchg8b <m64> will compare if <m64> equals | 2322 /// Cmpxchg8b instruction - cmpxchg8b <m64> will compare if <m64> equals |
| 2323 /// edx:eax. If so, the ZF is set and ecx:ebx is stored in <m64>. If not, ZF | 2323 /// edx:eax. If so, the ZF is set and ecx:ebx is stored in <m64>. If not, ZF |
| 2324 /// is cleared and <m64> is copied to edx:eax. The caller is responsible for | 2324 /// is cleared and <m64> is copied to edx:eax. The caller is responsible for |
| 2325 /// inserting FakeDefs to mark edx and eax as modified. <m64> must be a memory | 2325 /// inserting FakeDefs to mark edx and eax as modified. <m64> must be a memory |
| 2326 /// operand. | 2326 /// operand. |
| 2327 class InstX86Cmpxchg8b final : public InstX86BaseLockable { | 2327 class InstX86Cmpxchg8b final : public InstX86BaseLockable { |
| 2328 InstX86Cmpxchg8b() = delete; | 2328 InstX86Cmpxchg8b() = delete; |
| 2329 InstX86Cmpxchg8b(const InstX86Cmpxchg8b &) = delete; | 2329 InstX86Cmpxchg8b(const InstX86Cmpxchg8b &) = delete; |
| 2330 InstX86Cmpxchg8b &operator=(const InstX86Cmpxchg8b &) = delete; | 2330 InstX86Cmpxchg8b &operator=(const InstX86Cmpxchg8b &) = delete; |
| 2331 | 2331 |
| 2332 public: | 2332 public: |
| 2333 static InstX86Cmpxchg8b *create(Cfg *Func, X86OperandMem *Dest, | 2333 static InstX86Cmpxchg8b *create(Cfg *Func, X86OperandMem *Dest, |
| 2334 Variable *Edx, Variable *Eax, Variable *Ecx, | 2334 Variable *Edx, Variable *Eax, Variable *Ecx, |
| 2335 Variable *Ebx, bool Locked) { | 2335 Variable *Ebx, bool Locked) { |
| 2336 return new (Func->allocate<InstX86Cmpxchg8b>()) | 2336 return new (Func->allocate<InstX86Cmpxchg8b>()) |
| 2337 InstX86Cmpxchg8b(Func, Dest, Edx, Eax, Ecx, Ebx, Locked); | 2337 InstX86Cmpxchg8b(Func, Dest, Edx, Eax, Ecx, Ebx, Locked); |
| 2338 } | 2338 } |
| 2339 void emit(const Cfg *Func) const override; | 2339 void emit(const Cfg *Func) const override; |
| 2340 void emitIAS(const Cfg *Func) const override; | 2340 void emitIAS(const Cfg *Func) const override; |
| 2341 void dump(const Cfg *Func) const override; | 2341 void dump(const Cfg *Func) const override; |
| 2342 static bool classof(const Inst *Inst) { | 2342 static bool classof(const Inst *Instr) { |
| 2343 return InstX86Base::isClassof(Inst, InstX86Base::Cmpxchg8b); | 2343 return InstX86Base::isClassof(Instr, InstX86Base::Cmpxchg8b); |
| 2344 } | 2344 } |
| 2345 | 2345 |
| 2346 private: | 2346 private: |
| 2347 InstX86Cmpxchg8b(Cfg *Func, X86OperandMem *Dest, Variable *Edx, | 2347 InstX86Cmpxchg8b(Cfg *Func, X86OperandMem *Dest, Variable *Edx, |
| 2348 Variable *Eax, Variable *Ecx, Variable *Ebx, bool Locked); | 2348 Variable *Eax, Variable *Ecx, Variable *Ebx, bool Locked); |
| 2349 }; | 2349 }; |
| 2350 | 2350 |
| 2351 /// Cvt instruction - wrapper for cvtsX2sY where X and Y are in {s,d,i} as | 2351 /// Cvt instruction - wrapper for cvtsX2sY where X and Y are in {s,d,i} as |
| 2352 /// appropriate. s=float, d=double, i=int. X and Y are determined from | 2352 /// appropriate. s=float, d=double, i=int. X and Y are determined from |
| 2353 /// dest/src types. Sign and zero extension on the integer operand needs to be | 2353 /// dest/src types. Sign and zero extension on the integer operand needs to be |
| 2354 /// done separately. | 2354 /// done separately. |
| 2355 class InstX86Cvt final : public InstX86Base { | 2355 class InstX86Cvt final : public InstX86Base { |
| 2356 InstX86Cvt() = delete; | 2356 InstX86Cvt() = delete; |
| 2357 InstX86Cvt(const InstX86Cvt &) = delete; | 2357 InstX86Cvt(const InstX86Cvt &) = delete; |
| 2358 InstX86Cvt &operator=(const InstX86Cvt &) = delete; | 2358 InstX86Cvt &operator=(const InstX86Cvt &) = delete; |
| 2359 | 2359 |
| 2360 public: | 2360 public: |
| 2361 enum CvtVariant { Si2ss, Tss2si, Float2float, Dq2ps, Tps2dq }; | 2361 enum CvtVariant { Si2ss, Tss2si, Float2float, Dq2ps, Tps2dq }; |
| 2362 static InstX86Cvt *create(Cfg *Func, Variable *Dest, Operand *Source, | 2362 static InstX86Cvt *create(Cfg *Func, Variable *Dest, Operand *Source, |
| 2363 CvtVariant Variant) { | 2363 CvtVariant Variant) { |
| 2364 return new (Func->allocate<InstX86Cvt>()) | 2364 return new (Func->allocate<InstX86Cvt>()) |
| 2365 InstX86Cvt(Func, Dest, Source, Variant); | 2365 InstX86Cvt(Func, Dest, Source, Variant); |
| 2366 } | 2366 } |
| 2367 void emit(const Cfg *Func) const override; | 2367 void emit(const Cfg *Func) const override; |
| 2368 void emitIAS(const Cfg *Func) const override; | 2368 void emitIAS(const Cfg *Func) const override; |
| 2369 void dump(const Cfg *Func) const override; | 2369 void dump(const Cfg *Func) const override; |
| 2370 static bool classof(const Inst *Inst) { | 2370 static bool classof(const Inst *Instr) { |
| 2371 return InstX86Base::isClassof(Inst, InstX86Base::Cvt); | 2371 return InstX86Base::isClassof(Instr, InstX86Base::Cvt); |
| 2372 } | 2372 } |
| 2373 bool isTruncating() const { return Variant == Tss2si || Variant == Tps2dq; } | 2373 bool isTruncating() const { return Variant == Tss2si || Variant == Tps2dq; } |
| 2374 | 2374 |
| 2375 private: | 2375 private: |
| 2376 CvtVariant Variant; | 2376 CvtVariant Variant; |
| 2377 InstX86Cvt(Cfg *Func, Variable *Dest, Operand *Source, CvtVariant Variant); | 2377 InstX86Cvt(Cfg *Func, Variable *Dest, Operand *Source, CvtVariant Variant); |
| 2378 }; | 2378 }; |
| 2379 | 2379 |
| 2380 /// cmp - Integer compare instruction. | 2380 /// cmp - Integer compare instruction. |
| 2381 class InstX86Icmp final : public InstX86Base { | 2381 class InstX86Icmp final : public InstX86Base { |
| 2382 InstX86Icmp() = delete; | 2382 InstX86Icmp() = delete; |
| 2383 InstX86Icmp(const InstX86Icmp &) = delete; | 2383 InstX86Icmp(const InstX86Icmp &) = delete; |
| 2384 InstX86Icmp &operator=(const InstX86Icmp &) = delete; | 2384 InstX86Icmp &operator=(const InstX86Icmp &) = delete; |
| 2385 | 2385 |
| 2386 public: | 2386 public: |
| 2387 static InstX86Icmp *create(Cfg *Func, Operand *Src1, Operand *Src2) { | 2387 static InstX86Icmp *create(Cfg *Func, Operand *Src1, Operand *Src2) { |
| 2388 return new (Func->allocate<InstX86Icmp>()) InstX86Icmp(Func, Src1, Src2); | 2388 return new (Func->allocate<InstX86Icmp>()) InstX86Icmp(Func, Src1, Src2); |
| 2389 } | 2389 } |
| 2390 void emit(const Cfg *Func) const override; | 2390 void emit(const Cfg *Func) const override; |
| 2391 void emitIAS(const Cfg *Func) const override; | 2391 void emitIAS(const Cfg *Func) const override; |
| 2392 void dump(const Cfg *Func) const override; | 2392 void dump(const Cfg *Func) const override; |
| 2393 static bool classof(const Inst *Inst) { | 2393 static bool classof(const Inst *Instr) { |
| 2394 return InstX86Base::isClassof(Inst, InstX86Base::Icmp); | 2394 return InstX86Base::isClassof(Instr, InstX86Base::Icmp); |
| 2395 } | 2395 } |
| 2396 | 2396 |
| 2397 private: | 2397 private: |
| 2398 InstX86Icmp(Cfg *Func, Operand *Src1, Operand *Src2); | 2398 InstX86Icmp(Cfg *Func, Operand *Src1, Operand *Src2); |
| 2399 }; | 2399 }; |
| 2400 | 2400 |
| 2401 /// ucomiss/ucomisd - floating-point compare instruction. | 2401 /// ucomiss/ucomisd - floating-point compare instruction. |
| 2402 class InstX86Ucomiss final : public InstX86Base { | 2402 class InstX86Ucomiss final : public InstX86Base { |
| 2403 InstX86Ucomiss() = delete; | 2403 InstX86Ucomiss() = delete; |
| 2404 InstX86Ucomiss(const InstX86Ucomiss &) = delete; | 2404 InstX86Ucomiss(const InstX86Ucomiss &) = delete; |
| 2405 InstX86Ucomiss &operator=(const InstX86Ucomiss &) = delete; | 2405 InstX86Ucomiss &operator=(const InstX86Ucomiss &) = delete; |
| 2406 | 2406 |
| 2407 public: | 2407 public: |
| 2408 static InstX86Ucomiss *create(Cfg *Func, Operand *Src1, Operand *Src2) { | 2408 static InstX86Ucomiss *create(Cfg *Func, Operand *Src1, Operand *Src2) { |
| 2409 return new (Func->allocate<InstX86Ucomiss>()) | 2409 return new (Func->allocate<InstX86Ucomiss>()) |
| 2410 InstX86Ucomiss(Func, Src1, Src2); | 2410 InstX86Ucomiss(Func, Src1, Src2); |
| 2411 } | 2411 } |
| 2412 void emit(const Cfg *Func) const override; | 2412 void emit(const Cfg *Func) const override; |
| 2413 void emitIAS(const Cfg *Func) const override; | 2413 void emitIAS(const Cfg *Func) const override; |
| 2414 void dump(const Cfg *Func) const override; | 2414 void dump(const Cfg *Func) const override; |
| 2415 static bool classof(const Inst *Inst) { | 2415 static bool classof(const Inst *Instr) { |
| 2416 return InstX86Base::isClassof(Inst, InstX86Base::Ucomiss); | 2416 return InstX86Base::isClassof(Instr, InstX86Base::Ucomiss); |
| 2417 } | 2417 } |
| 2418 | 2418 |
| 2419 private: | 2419 private: |
| 2420 InstX86Ucomiss(Cfg *Func, Operand *Src1, Operand *Src2); | 2420 InstX86Ucomiss(Cfg *Func, Operand *Src1, Operand *Src2); |
| 2421 }; | 2421 }; |
| 2422 | 2422 |
| 2423 /// UD2 instruction. | 2423 /// UD2 instruction. |
| 2424 class InstX86UD2 final : public InstX86Base { | 2424 class InstX86UD2 final : public InstX86Base { |
| 2425 InstX86UD2() = delete; | 2425 InstX86UD2() = delete; |
| 2426 InstX86UD2(const InstX86UD2 &) = delete; | 2426 InstX86UD2(const InstX86UD2 &) = delete; |
| 2427 InstX86UD2 &operator=(const InstX86UD2 &) = delete; | 2427 InstX86UD2 &operator=(const InstX86UD2 &) = delete; |
| 2428 | 2428 |
| 2429 public: | 2429 public: |
| 2430 static InstX86UD2 *create(Cfg *Func) { | 2430 static InstX86UD2 *create(Cfg *Func) { |
| 2431 return new (Func->allocate<InstX86UD2>()) InstX86UD2(Func); | 2431 return new (Func->allocate<InstX86UD2>()) InstX86UD2(Func); |
| 2432 } | 2432 } |
| 2433 void emit(const Cfg *Func) const override; | 2433 void emit(const Cfg *Func) const override; |
| 2434 void emitIAS(const Cfg *Func) const override; | 2434 void emitIAS(const Cfg *Func) const override; |
| 2435 void dump(const Cfg *Func) const override; | 2435 void dump(const Cfg *Func) const override; |
| 2436 static bool classof(const Inst *Inst) { | 2436 static bool classof(const Inst *Instr) { |
| 2437 return InstX86Base::isClassof(Inst, InstX86Base::UD2); | 2437 return InstX86Base::isClassof(Instr, InstX86Base::UD2); |
| 2438 } | 2438 } |
| 2439 | 2439 |
| 2440 private: | 2440 private: |
| 2441 explicit InstX86UD2(Cfg *Func); | 2441 explicit InstX86UD2(Cfg *Func); |
| 2442 }; | 2442 }; |
| 2443 | 2443 |
| 2444 /// Test instruction. | 2444 /// Test instruction. |
| 2445 class InstX86Test final : public InstX86Base { | 2445 class InstX86Test final : public InstX86Base { |
| 2446 InstX86Test() = delete; | 2446 InstX86Test() = delete; |
| 2447 InstX86Test(const InstX86Test &) = delete; | 2447 InstX86Test(const InstX86Test &) = delete; |
| 2448 InstX86Test &operator=(const InstX86Test &) = delete; | 2448 InstX86Test &operator=(const InstX86Test &) = delete; |
| 2449 | 2449 |
| 2450 public: | 2450 public: |
| 2451 static InstX86Test *create(Cfg *Func, Operand *Source1, Operand *Source2) { | 2451 static InstX86Test *create(Cfg *Func, Operand *Source1, Operand *Source2) { |
| 2452 return new (Func->allocate<InstX86Test>()) | 2452 return new (Func->allocate<InstX86Test>()) |
| 2453 InstX86Test(Func, Source1, Source2); | 2453 InstX86Test(Func, Source1, Source2); |
| 2454 } | 2454 } |
| 2455 void emit(const Cfg *Func) const override; | 2455 void emit(const Cfg *Func) const override; |
| 2456 void emitIAS(const Cfg *Func) const override; | 2456 void emitIAS(const Cfg *Func) const override; |
| 2457 void dump(const Cfg *Func) const override; | 2457 void dump(const Cfg *Func) const override; |
| 2458 static bool classof(const Inst *Inst) { | 2458 static bool classof(const Inst *Instr) { |
| 2459 return InstX86Base::isClassof(Inst, InstX86Base::Test); | 2459 return InstX86Base::isClassof(Instr, InstX86Base::Test); |
| 2460 } | 2460 } |
| 2461 | 2461 |
| 2462 private: | 2462 private: |
| 2463 InstX86Test(Cfg *Func, Operand *Source1, Operand *Source2); | 2463 InstX86Test(Cfg *Func, Operand *Source1, Operand *Source2); |
| 2464 }; | 2464 }; |
| 2465 | 2465 |
| 2466 /// Mfence instruction. | 2466 /// Mfence instruction. |
| 2467 class InstX86Mfence final : public InstX86Base { | 2467 class InstX86Mfence final : public InstX86Base { |
| 2468 InstX86Mfence() = delete; | 2468 InstX86Mfence() = delete; |
| 2469 InstX86Mfence(const InstX86Mfence &) = delete; | 2469 InstX86Mfence(const InstX86Mfence &) = delete; |
| 2470 InstX86Mfence &operator=(const InstX86Mfence &) = delete; | 2470 InstX86Mfence &operator=(const InstX86Mfence &) = delete; |
| 2471 | 2471 |
| 2472 public: | 2472 public: |
| 2473 static InstX86Mfence *create(Cfg *Func) { | 2473 static InstX86Mfence *create(Cfg *Func) { |
| 2474 return new (Func->allocate<InstX86Mfence>()) InstX86Mfence(Func); | 2474 return new (Func->allocate<InstX86Mfence>()) InstX86Mfence(Func); |
| 2475 } | 2475 } |
| 2476 void emit(const Cfg *Func) const override; | 2476 void emit(const Cfg *Func) const override; |
| 2477 void emitIAS(const Cfg *Func) const override; | 2477 void emitIAS(const Cfg *Func) const override; |
| 2478 void dump(const Cfg *Func) const override; | 2478 void dump(const Cfg *Func) const override; |
| 2479 static bool classof(const Inst *Inst) { | 2479 static bool classof(const Inst *Instr) { |
| 2480 return InstX86Base::isClassof(Inst, InstX86Base::Mfence); | 2480 return InstX86Base::isClassof(Instr, InstX86Base::Mfence); |
| 2481 } | 2481 } |
| 2482 | 2482 |
| 2483 private: | 2483 private: |
| 2484 explicit InstX86Mfence(Cfg *Func); | 2484 explicit InstX86Mfence(Cfg *Func); |
| 2485 }; | 2485 }; |
| 2486 | 2486 |
| 2487 /// This is essentially a "mov" instruction with anX86OperandMem operand | 2487 /// This is essentially a "mov" instruction with anX86OperandMem operand |
| 2488 /// instead of Variable as the destination. It's important for liveness that | 2488 /// instead of Variable as the destination. It's important for liveness that |
| 2489 /// there is no Dest operand. | 2489 /// there is no Dest operand. |
| 2490 class InstX86Store final : public InstX86Base { | 2490 class InstX86Store final : public InstX86Base { |
| 2491 InstX86Store() = delete; | 2491 InstX86Store() = delete; |
| 2492 InstX86Store(const InstX86Store &) = delete; | 2492 InstX86Store(const InstX86Store &) = delete; |
| 2493 InstX86Store &operator=(const InstX86Store &) = delete; | 2493 InstX86Store &operator=(const InstX86Store &) = delete; |
| 2494 | 2494 |
| 2495 public: | 2495 public: |
| 2496 static InstX86Store *create(Cfg *Func, Operand *Value, X86Operand *Mem) { | 2496 static InstX86Store *create(Cfg *Func, Operand *Value, X86Operand *Mem) { |
| 2497 return new (Func->allocate<InstX86Store>()) | 2497 return new (Func->allocate<InstX86Store>()) |
| 2498 InstX86Store(Func, Value, Mem); | 2498 InstX86Store(Func, Value, Mem); |
| 2499 } | 2499 } |
| 2500 void emit(const Cfg *Func) const override; | 2500 void emit(const Cfg *Func) const override; |
| 2501 void emitIAS(const Cfg *Func) const override; | 2501 void emitIAS(const Cfg *Func) const override; |
| 2502 void dump(const Cfg *Func) const override; | 2502 void dump(const Cfg *Func) const override; |
| 2503 static bool classof(const Inst *Inst) { | 2503 static bool classof(const Inst *Instr) { |
| 2504 return InstX86Base::isClassof(Inst, InstX86Base::Store); | 2504 return InstX86Base::isClassof(Instr, InstX86Base::Store); |
| 2505 } | 2505 } |
| 2506 | 2506 |
| 2507 private: | 2507 private: |
| 2508 InstX86Store(Cfg *Func, Operand *Value, X86Operand *Mem); | 2508 InstX86Store(Cfg *Func, Operand *Value, X86Operand *Mem); |
| 2509 }; | 2509 }; |
| 2510 | 2510 |
| 2511 /// This is essentially a vector "mov" instruction with an typename | 2511 /// This is essentially a vector "mov" instruction with an typename |
| 2512 /// X86OperandMem operand instead of Variable as the destination. It's | 2512 /// X86OperandMem operand instead of Variable as the destination. It's |
| 2513 /// important for liveness that there is no Dest operand. The source must be | 2513 /// important for liveness that there is no Dest operand. The source must be |
| 2514 /// an Xmm register, since Dest is mem. | 2514 /// an Xmm register, since Dest is mem. |
| 2515 class InstX86StoreP final : public InstX86Base { | 2515 class InstX86StoreP final : public InstX86Base { |
| 2516 InstX86StoreP() = delete; | 2516 InstX86StoreP() = delete; |
| 2517 InstX86StoreP(const InstX86StoreP &) = delete; | 2517 InstX86StoreP(const InstX86StoreP &) = delete; |
| 2518 InstX86StoreP &operator=(const InstX86StoreP &) = delete; | 2518 InstX86StoreP &operator=(const InstX86StoreP &) = delete; |
| 2519 | 2519 |
| 2520 public: | 2520 public: |
| 2521 static InstX86StoreP *create(Cfg *Func, Variable *Value, | 2521 static InstX86StoreP *create(Cfg *Func, Variable *Value, |
| 2522 X86OperandMem *Mem) { | 2522 X86OperandMem *Mem) { |
| 2523 return new (Func->allocate<InstX86StoreP>()) | 2523 return new (Func->allocate<InstX86StoreP>()) |
| 2524 InstX86StoreP(Func, Value, Mem); | 2524 InstX86StoreP(Func, Value, Mem); |
| 2525 } | 2525 } |
| 2526 void emit(const Cfg *Func) const override; | 2526 void emit(const Cfg *Func) const override; |
| 2527 void emitIAS(const Cfg *Func) const override; | 2527 void emitIAS(const Cfg *Func) const override; |
| 2528 void dump(const Cfg *Func) const override; | 2528 void dump(const Cfg *Func) const override; |
| 2529 static bool classof(const Inst *Inst) { | 2529 static bool classof(const Inst *Instr) { |
| 2530 return InstX86Base::isClassof(Inst, InstX86Base::StoreP); | 2530 return InstX86Base::isClassof(Instr, InstX86Base::StoreP); |
| 2531 } | 2531 } |
| 2532 | 2532 |
| 2533 private: | 2533 private: |
| 2534 InstX86StoreP(Cfg *Func, Variable *Value, X86OperandMem *Mem); | 2534 InstX86StoreP(Cfg *Func, Variable *Value, X86OperandMem *Mem); |
| 2535 }; | 2535 }; |
| 2536 | 2536 |
| 2537 class InstX86StoreQ final : public InstX86Base { | 2537 class InstX86StoreQ final : public InstX86Base { |
| 2538 InstX86StoreQ() = delete; | 2538 InstX86StoreQ() = delete; |
| 2539 InstX86StoreQ(const InstX86StoreQ &) = delete; | 2539 InstX86StoreQ(const InstX86StoreQ &) = delete; |
| 2540 InstX86StoreQ &operator=(const InstX86StoreQ &) = delete; | 2540 InstX86StoreQ &operator=(const InstX86StoreQ &) = delete; |
| 2541 | 2541 |
| 2542 public: | 2542 public: |
| 2543 static InstX86StoreQ *create(Cfg *Func, Variable *Value, | 2543 static InstX86StoreQ *create(Cfg *Func, Variable *Value, |
| 2544 X86OperandMem *Mem) { | 2544 X86OperandMem *Mem) { |
| 2545 return new (Func->allocate<InstX86StoreQ>()) | 2545 return new (Func->allocate<InstX86StoreQ>()) |
| 2546 InstX86StoreQ(Func, Value, Mem); | 2546 InstX86StoreQ(Func, Value, Mem); |
| 2547 } | 2547 } |
| 2548 void emit(const Cfg *Func) const override; | 2548 void emit(const Cfg *Func) const override; |
| 2549 void emitIAS(const Cfg *Func) const override; | 2549 void emitIAS(const Cfg *Func) const override; |
| 2550 void dump(const Cfg *Func) const override; | 2550 void dump(const Cfg *Func) const override; |
| 2551 static bool classof(const Inst *Inst) { | 2551 static bool classof(const Inst *Instr) { |
| 2552 return InstX86Base::isClassof(Inst, InstX86Base::StoreQ); | 2552 return InstX86Base::isClassof(Instr, InstX86Base::StoreQ); |
| 2553 } | 2553 } |
| 2554 | 2554 |
| 2555 private: | 2555 private: |
| 2556 InstX86StoreQ(Cfg *Func, Variable *Value, X86OperandMem *Mem); | 2556 InstX86StoreQ(Cfg *Func, Variable *Value, X86OperandMem *Mem); |
| 2557 }; | 2557 }; |
| 2558 | 2558 |
| 2559 /// Nop instructions of varying length | 2559 /// Nop instructions of varying length |
| 2560 class InstX86Nop final : public InstX86Base { | 2560 class InstX86Nop final : public InstX86Base { |
| 2561 InstX86Nop() = delete; | 2561 InstX86Nop() = delete; |
| 2562 InstX86Nop(const InstX86Nop &) = delete; | 2562 InstX86Nop(const InstX86Nop &) = delete; |
| 2563 InstX86Nop &operator=(const InstX86Nop &) = delete; | 2563 InstX86Nop &operator=(const InstX86Nop &) = delete; |
| 2564 | 2564 |
| 2565 public: | 2565 public: |
| 2566 // TODO: Replace with enum. | 2566 // TODO: Replace with enum. |
| 2567 using NopVariant = unsigned; | 2567 using NopVariant = unsigned; |
| 2568 | 2568 |
| 2569 static InstX86Nop *create(Cfg *Func, NopVariant Variant) { | 2569 static InstX86Nop *create(Cfg *Func, NopVariant Variant) { |
| 2570 return new (Func->allocate<InstX86Nop>()) InstX86Nop(Func, Variant); | 2570 return new (Func->allocate<InstX86Nop>()) InstX86Nop(Func, Variant); |
| 2571 } | 2571 } |
| 2572 void emit(const Cfg *Func) const override; | 2572 void emit(const Cfg *Func) const override; |
| 2573 void emitIAS(const Cfg *Func) const override; | 2573 void emitIAS(const Cfg *Func) const override; |
| 2574 void dump(const Cfg *Func) const override; | 2574 void dump(const Cfg *Func) const override; |
| 2575 static bool classof(const Inst *Inst) { | 2575 static bool classof(const Inst *Instr) { |
| 2576 return InstX86Base::isClassof(Inst, InstX86Base::Nop); | 2576 return InstX86Base::isClassof(Instr, InstX86Base::Nop); |
| 2577 } | 2577 } |
| 2578 | 2578 |
| 2579 private: | 2579 private: |
| 2580 InstX86Nop(Cfg *Func, SizeT Length); | 2580 InstX86Nop(Cfg *Func, SizeT Length); |
| 2581 | 2581 |
| 2582 NopVariant Variant; | 2582 NopVariant Variant; |
| 2583 }; | 2583 }; |
| 2584 | 2584 |
| 2585 /// Fld - load a value onto the x87 FP stack. | 2585 /// Fld - load a value onto the x87 FP stack. |
| 2586 class InstX86Fld final : public InstX86Base { | 2586 class InstX86Fld final : public InstX86Base { |
| 2587 InstX86Fld() = delete; | 2587 InstX86Fld() = delete; |
| 2588 InstX86Fld(const InstX86Fld &) = delete; | 2588 InstX86Fld(const InstX86Fld &) = delete; |
| 2589 InstX86Fld &operator=(const InstX86Fld &) = delete; | 2589 InstX86Fld &operator=(const InstX86Fld &) = delete; |
| 2590 | 2590 |
| 2591 public: | 2591 public: |
| 2592 static InstX86Fld *create(Cfg *Func, Operand *Src) { | 2592 static InstX86Fld *create(Cfg *Func, Operand *Src) { |
| 2593 return new (Func->allocate<InstX86Fld>()) InstX86Fld(Func, Src); | 2593 return new (Func->allocate<InstX86Fld>()) InstX86Fld(Func, Src); |
| 2594 } | 2594 } |
| 2595 void emit(const Cfg *Func) const override; | 2595 void emit(const Cfg *Func) const override; |
| 2596 void emitIAS(const Cfg *Func) const override; | 2596 void emitIAS(const Cfg *Func) const override; |
| 2597 void dump(const Cfg *Func) const override; | 2597 void dump(const Cfg *Func) const override; |
| 2598 static bool classof(const Inst *Inst) { | 2598 static bool classof(const Inst *Instr) { |
| 2599 return InstX86Base::isClassof(Inst, InstX86Base::Fld); | 2599 return InstX86Base::isClassof(Instr, InstX86Base::Fld); |
| 2600 } | 2600 } |
| 2601 | 2601 |
| 2602 private: | 2602 private: |
| 2603 InstX86Fld(Cfg *Func, Operand *Src); | 2603 InstX86Fld(Cfg *Func, Operand *Src); |
| 2604 }; | 2604 }; |
| 2605 | 2605 |
| 2606 /// Fstp - store x87 st(0) into memory and pop st(0). | 2606 /// Fstp - store x87 st(0) into memory and pop st(0). |
| 2607 class InstX86Fstp final : public InstX86Base { | 2607 class InstX86Fstp final : public InstX86Base { |
| 2608 InstX86Fstp() = delete; | 2608 InstX86Fstp() = delete; |
| 2609 InstX86Fstp(const InstX86Fstp &) = delete; | 2609 InstX86Fstp(const InstX86Fstp &) = delete; |
| 2610 InstX86Fstp &operator=(const InstX86Fstp &) = delete; | 2610 InstX86Fstp &operator=(const InstX86Fstp &) = delete; |
| 2611 | 2611 |
| 2612 public: | 2612 public: |
| 2613 static InstX86Fstp *create(Cfg *Func, Variable *Dest) { | 2613 static InstX86Fstp *create(Cfg *Func, Variable *Dest) { |
| 2614 return new (Func->allocate<InstX86Fstp>()) InstX86Fstp(Func, Dest); | 2614 return new (Func->allocate<InstX86Fstp>()) InstX86Fstp(Func, Dest); |
| 2615 } | 2615 } |
| 2616 void emit(const Cfg *Func) const override; | 2616 void emit(const Cfg *Func) const override; |
| 2617 void emitIAS(const Cfg *Func) const override; | 2617 void emitIAS(const Cfg *Func) const override; |
| 2618 void dump(const Cfg *Func) const override; | 2618 void dump(const Cfg *Func) const override; |
| 2619 static bool classof(const Inst *Inst) { | 2619 static bool classof(const Inst *Instr) { |
| 2620 return InstX86Base::isClassof(Inst, InstX86Base::Fstp); | 2620 return InstX86Base::isClassof(Instr, InstX86Base::Fstp); |
| 2621 } | 2621 } |
| 2622 | 2622 |
| 2623 private: | 2623 private: |
| 2624 InstX86Fstp(Cfg *Func, Variable *Dest); | 2624 InstX86Fstp(Cfg *Func, Variable *Dest); |
| 2625 }; | 2625 }; |
| 2626 | 2626 |
| 2627 class InstX86Pop final : public InstX86Base { | 2627 class InstX86Pop final : public InstX86Base { |
| 2628 InstX86Pop() = delete; | 2628 InstX86Pop() = delete; |
| 2629 InstX86Pop(const InstX86Pop &) = delete; | 2629 InstX86Pop(const InstX86Pop &) = delete; |
| 2630 InstX86Pop &operator=(const InstX86Pop &) = delete; | 2630 InstX86Pop &operator=(const InstX86Pop &) = delete; |
| 2631 | 2631 |
| 2632 public: | 2632 public: |
| 2633 static InstX86Pop *create(Cfg *Func, Variable *Dest) { | 2633 static InstX86Pop *create(Cfg *Func, Variable *Dest) { |
| 2634 return new (Func->allocate<InstX86Pop>()) InstX86Pop(Func, Dest); | 2634 return new (Func->allocate<InstX86Pop>()) InstX86Pop(Func, Dest); |
| 2635 } | 2635 } |
| 2636 void emit(const Cfg *Func) const override; | 2636 void emit(const Cfg *Func) const override; |
| 2637 void emitIAS(const Cfg *Func) const override; | 2637 void emitIAS(const Cfg *Func) const override; |
| 2638 void dump(const Cfg *Func) const override; | 2638 void dump(const Cfg *Func) const override; |
| 2639 static bool classof(const Inst *Inst) { | 2639 static bool classof(const Inst *Instr) { |
| 2640 return InstX86Base::isClassof(Inst, InstX86Base::Pop); | 2640 return InstX86Base::isClassof(Instr, InstX86Base::Pop); |
| 2641 } | 2641 } |
| 2642 | 2642 |
| 2643 private: | 2643 private: |
| 2644 InstX86Pop(Cfg *Func, Variable *Dest); | 2644 InstX86Pop(Cfg *Func, Variable *Dest); |
| 2645 }; | 2645 }; |
| 2646 | 2646 |
| 2647 class InstX86Push final : public InstX86Base { | 2647 class InstX86Push final : public InstX86Base { |
| 2648 InstX86Push() = delete; | 2648 InstX86Push() = delete; |
| 2649 InstX86Push(const InstX86Push &) = delete; | 2649 InstX86Push(const InstX86Push &) = delete; |
| 2650 InstX86Push &operator=(const InstX86Push &) = delete; | 2650 InstX86Push &operator=(const InstX86Push &) = delete; |
| 2651 | 2651 |
| 2652 public: | 2652 public: |
| 2653 static InstX86Push *create(Cfg *Func, InstX86Label *Label) { | 2653 static InstX86Push *create(Cfg *Func, InstX86Label *Label) { |
| 2654 return new (Func->allocate<InstX86Push>()) InstX86Push(Func, Label); | 2654 return new (Func->allocate<InstX86Push>()) InstX86Push(Func, Label); |
| 2655 } | 2655 } |
| 2656 static InstX86Push *create(Cfg *Func, Operand *Source) { | 2656 static InstX86Push *create(Cfg *Func, Operand *Source) { |
| 2657 return new (Func->allocate<InstX86Push>()) InstX86Push(Func, Source); | 2657 return new (Func->allocate<InstX86Push>()) InstX86Push(Func, Source); |
| 2658 } | 2658 } |
| 2659 void emit(const Cfg *Func) const override; | 2659 void emit(const Cfg *Func) const override; |
| 2660 void emitIAS(const Cfg *Func) const override; | 2660 void emitIAS(const Cfg *Func) const override; |
| 2661 void dump(const Cfg *Func) const override; | 2661 void dump(const Cfg *Func) const override; |
| 2662 static bool classof(const Inst *Inst) { | 2662 static bool classof(const Inst *Instr) { |
| 2663 return InstX86Base::isClassof(Inst, InstX86Base::Push); | 2663 return InstX86Base::isClassof(Instr, InstX86Base::Push); |
| 2664 } | 2664 } |
| 2665 | 2665 |
| 2666 private: | 2666 private: |
| 2667 InstX86Label *Label = nullptr; | 2667 InstX86Label *Label = nullptr; |
| 2668 | 2668 |
| 2669 InstX86Push(Cfg *Func, Operand *Source); | 2669 InstX86Push(Cfg *Func, Operand *Source); |
| 2670 InstX86Push(Cfg *Func, InstX86Label *Label); | 2670 InstX86Push(Cfg *Func, InstX86Label *Label); |
| 2671 }; | 2671 }; |
| 2672 | 2672 |
| 2673 /// Ret instruction. Currently only supports the "ret" version that does not | 2673 /// Ret instruction. Currently only supports the "ret" version that does not |
| 2674 /// pop arguments. This instruction takes a Source operand (for non-void | 2674 /// pop arguments. This instruction takes a Source operand (for non-void |
| 2675 /// returning functions) for liveness analysis, though a FakeUse before the | 2675 /// returning functions) for liveness analysis, though a FakeUse before the |
| 2676 /// ret would do just as well. | 2676 /// ret would do just as well. |
| 2677 class InstX86Ret final : public InstX86Base { | 2677 class InstX86Ret final : public InstX86Base { |
| 2678 InstX86Ret() = delete; | 2678 InstX86Ret() = delete; |
| 2679 InstX86Ret(const InstX86Ret &) = delete; | 2679 InstX86Ret(const InstX86Ret &) = delete; |
| 2680 InstX86Ret &operator=(const InstX86Ret &) = delete; | 2680 InstX86Ret &operator=(const InstX86Ret &) = delete; |
| 2681 | 2681 |
| 2682 public: | 2682 public: |
| 2683 static InstX86Ret *create(Cfg *Func, Variable *Source = nullptr) { | 2683 static InstX86Ret *create(Cfg *Func, Variable *Source = nullptr) { |
| 2684 return new (Func->allocate<InstX86Ret>()) InstX86Ret(Func, Source); | 2684 return new (Func->allocate<InstX86Ret>()) InstX86Ret(Func, Source); |
| 2685 } | 2685 } |
| 2686 void emit(const Cfg *Func) const override; | 2686 void emit(const Cfg *Func) const override; |
| 2687 void emitIAS(const Cfg *Func) const override; | 2687 void emitIAS(const Cfg *Func) const override; |
| 2688 void dump(const Cfg *Func) const override; | 2688 void dump(const Cfg *Func) const override; |
| 2689 static bool classof(const Inst *Inst) { | 2689 static bool classof(const Inst *Instr) { |
| 2690 return InstX86Base::isClassof(Inst, InstX86Base::Ret); | 2690 return InstX86Base::isClassof(Instr, InstX86Base::Ret); |
| 2691 } | 2691 } |
| 2692 | 2692 |
| 2693 private: | 2693 private: |
| 2694 InstX86Ret(Cfg *Func, Variable *Source); | 2694 InstX86Ret(Cfg *Func, Variable *Source); |
| 2695 }; | 2695 }; |
| 2696 | 2696 |
| 2697 /// Conditional set-byte instruction. | 2697 /// Conditional set-byte instruction. |
| 2698 class InstX86Setcc final : public InstX86Base { | 2698 class InstX86Setcc final : public InstX86Base { |
| 2699 InstX86Setcc() = delete; | 2699 InstX86Setcc() = delete; |
| 2700 InstX86Setcc(const InstX86Cmov &) = delete; | 2700 InstX86Setcc(const InstX86Cmov &) = delete; |
| 2701 InstX86Setcc &operator=(const InstX86Setcc &) = delete; | 2701 InstX86Setcc &operator=(const InstX86Setcc &) = delete; |
| 2702 | 2702 |
| 2703 public: | 2703 public: |
| 2704 static InstX86Setcc *create(Cfg *Func, Variable *Dest, BrCond Cond) { | 2704 static InstX86Setcc *create(Cfg *Func, Variable *Dest, BrCond Cond) { |
| 2705 return new (Func->allocate<InstX86Setcc>()) | 2705 return new (Func->allocate<InstX86Setcc>()) |
| 2706 InstX86Setcc(Func, Dest, Cond); | 2706 InstX86Setcc(Func, Dest, Cond); |
| 2707 } | 2707 } |
| 2708 void emit(const Cfg *Func) const override; | 2708 void emit(const Cfg *Func) const override; |
| 2709 void emitIAS(const Cfg *Func) const override; | 2709 void emitIAS(const Cfg *Func) const override; |
| 2710 void dump(const Cfg *Func) const override; | 2710 void dump(const Cfg *Func) const override; |
| 2711 static bool classof(const Inst *Inst) { | 2711 static bool classof(const Inst *Instr) { |
| 2712 return InstX86Base::isClassof(Inst, InstX86Base::Setcc); | 2712 return InstX86Base::isClassof(Instr, InstX86Base::Setcc); |
| 2713 } | 2713 } |
| 2714 | 2714 |
| 2715 private: | 2715 private: |
| 2716 InstX86Setcc(Cfg *Func, Variable *Dest, BrCond Cond); | 2716 InstX86Setcc(Cfg *Func, Variable *Dest, BrCond Cond); |
| 2717 | 2717 |
| 2718 const BrCond Condition; | 2718 const BrCond Condition; |
| 2719 }; | 2719 }; |
| 2720 | 2720 |
| 2721 /// Exchanging Add instruction. Exchanges the first operand (destination | 2721 /// Exchanging Add instruction. Exchanges the first operand (destination |
| 2722 /// operand) with the second operand (source operand), then loads the sum of | 2722 /// operand) with the second operand (source operand), then loads the sum of |
| 2723 /// the two values into the destination operand. The destination may be a | 2723 /// the two values into the destination operand. The destination may be a |
| 2724 /// register or memory, while the source must be a register. | 2724 /// register or memory, while the source must be a register. |
| 2725 /// | 2725 /// |
| 2726 /// Both the dest and source are updated. The caller should then insert a | 2726 /// Both the dest and source are updated. The caller should then insert a |
| 2727 /// FakeDef to reflect the second udpate. | 2727 /// FakeDef to reflect the second udpate. |
| 2728 class InstX86Xadd final : public InstX86BaseLockable { | 2728 class InstX86Xadd final : public InstX86BaseLockable { |
| 2729 InstX86Xadd() = delete; | 2729 InstX86Xadd() = delete; |
| 2730 InstX86Xadd(const InstX86Xadd &) = delete; | 2730 InstX86Xadd(const InstX86Xadd &) = delete; |
| 2731 InstX86Xadd &operator=(const InstX86Xadd &) = delete; | 2731 InstX86Xadd &operator=(const InstX86Xadd &) = delete; |
| 2732 | 2732 |
| 2733 public: | 2733 public: |
| 2734 static InstX86Xadd *create(Cfg *Func, Operand *Dest, Variable *Source, | 2734 static InstX86Xadd *create(Cfg *Func, Operand *Dest, Variable *Source, |
| 2735 bool Locked) { | 2735 bool Locked) { |
| 2736 return new (Func->allocate<InstX86Xadd>()) | 2736 return new (Func->allocate<InstX86Xadd>()) |
| 2737 InstX86Xadd(Func, Dest, Source, Locked); | 2737 InstX86Xadd(Func, Dest, Source, Locked); |
| 2738 } | 2738 } |
| 2739 void emit(const Cfg *Func) const override; | 2739 void emit(const Cfg *Func) const override; |
| 2740 void emitIAS(const Cfg *Func) const override; | 2740 void emitIAS(const Cfg *Func) const override; |
| 2741 void dump(const Cfg *Func) const override; | 2741 void dump(const Cfg *Func) const override; |
| 2742 static bool classof(const Inst *Inst) { | 2742 static bool classof(const Inst *Instr) { |
| 2743 return InstX86Base::isClassof(Inst, InstX86Base::Xadd); | 2743 return InstX86Base::isClassof(Instr, InstX86Base::Xadd); |
| 2744 } | 2744 } |
| 2745 | 2745 |
| 2746 private: | 2746 private: |
| 2747 InstX86Xadd(Cfg *Func, Operand *Dest, Variable *Source, bool Locked); | 2747 InstX86Xadd(Cfg *Func, Operand *Dest, Variable *Source, bool Locked); |
| 2748 }; | 2748 }; |
| 2749 | 2749 |
| 2750 /// Exchange instruction. Exchanges the first operand (destination operand) | 2750 /// Exchange instruction. Exchanges the first operand (destination operand) |
| 2751 /// with the second operand (source operand). At least one of the operands | 2751 /// with the second operand (source operand). At least one of the operands |
| 2752 /// must be a register (and the other can be reg or mem). Both the Dest and | 2752 /// must be a register (and the other can be reg or mem). Both the Dest and |
| 2753 /// Source are updated. If there is a memory operand, then the instruction is | 2753 /// Source are updated. If there is a memory operand, then the instruction is |
| 2754 /// automatically "locked" without the need for a lock prefix. | 2754 /// automatically "locked" without the need for a lock prefix. |
| 2755 class InstX86Xchg final : public InstX86Base { | 2755 class InstX86Xchg final : public InstX86Base { |
| 2756 InstX86Xchg() = delete; | 2756 InstX86Xchg() = delete; |
| 2757 InstX86Xchg(const InstX86Xchg &) = delete; | 2757 InstX86Xchg(const InstX86Xchg &) = delete; |
| 2758 InstX86Xchg &operator=(const InstX86Xchg &) = delete; | 2758 InstX86Xchg &operator=(const InstX86Xchg &) = delete; |
| 2759 | 2759 |
| 2760 public: | 2760 public: |
| 2761 static InstX86Xchg *create(Cfg *Func, Operand *Dest, Variable *Source) { | 2761 static InstX86Xchg *create(Cfg *Func, Operand *Dest, Variable *Source) { |
| 2762 return new (Func->allocate<InstX86Xchg>()) | 2762 return new (Func->allocate<InstX86Xchg>()) |
| 2763 InstX86Xchg(Func, Dest, Source); | 2763 InstX86Xchg(Func, Dest, Source); |
| 2764 } | 2764 } |
| 2765 void emit(const Cfg *Func) const override; | 2765 void emit(const Cfg *Func) const override; |
| 2766 void emitIAS(const Cfg *Func) const override; | 2766 void emitIAS(const Cfg *Func) const override; |
| 2767 void dump(const Cfg *Func) const override; | 2767 void dump(const Cfg *Func) const override; |
| 2768 static bool classof(const Inst *Inst) { | 2768 static bool classof(const Inst *Instr) { |
| 2769 return InstX86Base::isClassof(Inst, InstX86Base::Xchg); | 2769 return InstX86Base::isClassof(Instr, InstX86Base::Xchg); |
| 2770 } | 2770 } |
| 2771 | 2771 |
| 2772 private: | 2772 private: |
| 2773 InstX86Xchg(Cfg *Func, Operand *Dest, Variable *Source); | 2773 InstX86Xchg(Cfg *Func, Operand *Dest, Variable *Source); |
| 2774 }; | 2774 }; |
| 2775 | 2775 |
| 2776 /// Start marker for the Intel Architecture Code Analyzer. This is not an | 2776 /// Start marker for the Intel Architecture Code Analyzer. This is not an |
| 2777 /// executable instruction and must only be used for analysis. | 2777 /// executable instruction and must only be used for analysis. |
| 2778 class InstX86IacaStart final : public InstX86Base { | 2778 class InstX86IacaStart final : public InstX86Base { |
| 2779 InstX86IacaStart() = delete; | 2779 InstX86IacaStart() = delete; |
| 2780 InstX86IacaStart(const InstX86IacaStart &) = delete; | 2780 InstX86IacaStart(const InstX86IacaStart &) = delete; |
| 2781 InstX86IacaStart &operator=(const InstX86IacaStart &) = delete; | 2781 InstX86IacaStart &operator=(const InstX86IacaStart &) = delete; |
| 2782 | 2782 |
| 2783 public: | 2783 public: |
| 2784 static InstX86IacaStart *create(Cfg *Func) { | 2784 static InstX86IacaStart *create(Cfg *Func) { |
| 2785 return new (Func->allocate<InstX86IacaStart>()) InstX86IacaStart(Func); | 2785 return new (Func->allocate<InstX86IacaStart>()) InstX86IacaStart(Func); |
| 2786 } | 2786 } |
| 2787 void emit(const Cfg *Func) const override; | 2787 void emit(const Cfg *Func) const override; |
| 2788 void emitIAS(const Cfg *Func) const override; | 2788 void emitIAS(const Cfg *Func) const override; |
| 2789 void dump(const Cfg *Func) const override; | 2789 void dump(const Cfg *Func) const override; |
| 2790 static bool classof(const Inst *Inst) { | 2790 static bool classof(const Inst *Instr) { |
| 2791 return InstX86Base::isClassof(Inst, InstX86Base::IacaStart); | 2791 return InstX86Base::isClassof(Instr, InstX86Base::IacaStart); |
| 2792 } | 2792 } |
| 2793 | 2793 |
| 2794 private: | 2794 private: |
| 2795 InstX86IacaStart(Cfg *Func); | 2795 InstX86IacaStart(Cfg *Func); |
| 2796 }; | 2796 }; |
| 2797 | 2797 |
| 2798 /// End marker for the Intel Architecture Code Analyzer. This is not an | 2798 /// End marker for the Intel Architecture Code Analyzer. This is not an |
| 2799 /// executable instruction and must only be used for analysis. | 2799 /// executable instruction and must only be used for analysis. |
| 2800 class InstX86IacaEnd final : public InstX86Base { | 2800 class InstX86IacaEnd final : public InstX86Base { |
| 2801 InstX86IacaEnd() = delete; | 2801 InstX86IacaEnd() = delete; |
| 2802 InstX86IacaEnd(const InstX86IacaEnd &) = delete; | 2802 InstX86IacaEnd(const InstX86IacaEnd &) = delete; |
| 2803 InstX86IacaEnd &operator=(const InstX86IacaEnd &) = delete; | 2803 InstX86IacaEnd &operator=(const InstX86IacaEnd &) = delete; |
| 2804 | 2804 |
| 2805 public: | 2805 public: |
| 2806 static InstX86IacaEnd *create(Cfg *Func) { | 2806 static InstX86IacaEnd *create(Cfg *Func) { |
| 2807 return new (Func->allocate<InstX86IacaEnd>()) InstX86IacaEnd(Func); | 2807 return new (Func->allocate<InstX86IacaEnd>()) InstX86IacaEnd(Func); |
| 2808 } | 2808 } |
| 2809 void emit(const Cfg *Func) const override; | 2809 void emit(const Cfg *Func) const override; |
| 2810 void emitIAS(const Cfg *Func) const override; | 2810 void emitIAS(const Cfg *Func) const override; |
| 2811 void dump(const Cfg *Func) const override; | 2811 void dump(const Cfg *Func) const override; |
| 2812 static bool classof(const Inst *Inst) { | 2812 static bool classof(const Inst *Instr) { |
| 2813 return InstX86Base::isClassof(Inst, InstX86Base::IacaEnd); | 2813 return InstX86Base::isClassof(Instr, InstX86Base::IacaEnd); |
| 2814 } | 2814 } |
| 2815 | 2815 |
| 2816 private: | 2816 private: |
| 2817 InstX86IacaEnd(Cfg *Func); | 2817 InstX86IacaEnd(Cfg *Func); |
| 2818 }; | 2818 }; |
| 2819 }; // struct InstImpl | 2819 }; // struct InstImpl |
| 2820 | 2820 |
| 2821 /// struct Insts is a template that can be used to instantiate all the X86 | 2821 /// struct Insts is a template that can be used to instantiate all the X86 |
| 2822 /// instructions for a target with a simple | 2822 /// instructions for a target with a simple |
| 2823 /// | 2823 /// |
| (...skipping 704 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3528 &InstImpl<TraitsType>::Assembler::psrl}; \ | 3528 &InstImpl<TraitsType>::Assembler::psrl}; \ |
| 3529 } \ | 3529 } \ |
| 3530 } | 3530 } |
| 3531 | 3531 |
| 3532 } // end of namespace X86NAMESPACE | 3532 } // end of namespace X86NAMESPACE |
| 3533 } // end of namespace Ice | 3533 } // end of namespace Ice |
| 3534 | 3534 |
| 3535 #include "IceInstX86BaseImpl.h" | 3535 #include "IceInstX86BaseImpl.h" |
| 3536 | 3536 |
| 3537 #endif // SUBZERO_SRC_ICEINSTX86BASE_H | 3537 #endif // SUBZERO_SRC_ICEINSTX86BASE_H |
| OLD | NEW |