| 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 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 330 public: | 330 public: |
| 331 static InstX86Label *create(Cfg *Func, TargetLowering *Target) { | 331 static InstX86Label *create(Cfg *Func, TargetLowering *Target) { |
| 332 return new (Func->allocate<InstX86Label>()) InstX86Label(Func, Target); | 332 return new (Func->allocate<InstX86Label>()) InstX86Label(Func, Target); |
| 333 } | 333 } |
| 334 uint32_t getEmitInstCount() const override { return 0; } | 334 uint32_t getEmitInstCount() const override { return 0; } |
| 335 IceString getName(const Cfg *Func) const; | 335 IceString getName(const Cfg *Func) const; |
| 336 SizeT getNumber() const { return Number; } | 336 SizeT getNumber() const { return Number; } |
| 337 void emit(const Cfg *Func) const override; | 337 void emit(const Cfg *Func) const override; |
| 338 void emitIAS(const Cfg *Func) const override; | 338 void emitIAS(const Cfg *Func) const override; |
| 339 void dump(const Cfg *Func) const override; | 339 void dump(const Cfg *Func) const override; |
| 340 void setIsReturnLocation(bool Value) { IsReturnLocation = Value; } |
| 340 | 341 |
| 341 private: | 342 private: |
| 342 InstX86Label(Cfg *Func, TargetLowering *Target); | 343 InstX86Label(Cfg *Func, TargetLowering *Target); |
| 343 | 344 |
| 344 SizeT Number; // used for unique label generation. | 345 SizeT Number; // used for unique label generation. |
| 346 bool IsReturnLocation = false; |
| 345 }; | 347 }; |
| 346 | 348 |
| 347 /// Conditional and unconditional branch instruction. | 349 /// Conditional and unconditional branch instruction. |
| 348 class InstX86Br final : public InstX86Base { | 350 class InstX86Br final : public InstX86Base { |
| 349 InstX86Br() = delete; | 351 InstX86Br() = delete; |
| 350 InstX86Br(const InstX86Br &) = delete; | 352 InstX86Br(const InstX86Br &) = delete; |
| 351 InstX86Br &operator=(const InstX86Br &) = delete; | 353 InstX86Br &operator=(const InstX86Br &) = delete; |
| 352 | 354 |
| 353 public: | 355 public: |
| 354 enum Mode { Near, Far }; | 356 enum Mode { Near, Far }; |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 521 static void emitIASVariableBlendInst(const Inst *Inst, const Cfg *Func, | 523 static void emitIASVariableBlendInst(const Inst *Inst, const Cfg *Func, |
| 522 const XmmEmitterRegOp &Emitter); | 524 const XmmEmitterRegOp &Emitter); |
| 523 | 525 |
| 524 static void emitIASXmmShift(const Cfg *Func, Type Ty, const Variable *Var, | 526 static void emitIASXmmShift(const Cfg *Func, Type Ty, const Variable *Var, |
| 525 const Operand *Src, | 527 const Operand *Src, |
| 526 const XmmEmitterShiftOp &Emitter); | 528 const XmmEmitterShiftOp &Emitter); |
| 527 | 529 |
| 528 /// 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 |
| 529 /// that's guaranteed to be a register. | 531 /// that's guaranteed to be a register. |
| 530 template <bool VarCanBeByte = true, bool SrcCanBeByte = true> | 532 template <bool VarCanBeByte = true, bool SrcCanBeByte = true> |
| 531 static void emitIASRegOpTyGPR(const Cfg *Func, Type Ty, const Variable *Dst, | 533 static void emitIASRegOpTyGPR(const Cfg *Func, bool IsLea, Type Ty, |
| 532 const Operand *Src, | 534 const Variable *Dst, const Operand *Src, |
| 533 const GPREmitterRegOp &Emitter); | 535 const GPREmitterRegOp &Emitter); |
| 534 | 536 |
| 535 /// Instructions of the form x := op(x). | 537 /// Instructions of the form x := op(x). |
| 536 template <typename InstX86Base::InstKindX86 K> | 538 template <typename InstX86Base::InstKindX86 K> |
| 537 class InstX86BaseInplaceopGPR : public InstX86Base { | 539 class InstX86BaseInplaceopGPR : public InstX86Base { |
| 538 InstX86BaseInplaceopGPR() = delete; | 540 InstX86BaseInplaceopGPR() = delete; |
| 539 InstX86BaseInplaceopGPR(const InstX86BaseInplaceopGPR &) = delete; | 541 InstX86BaseInplaceopGPR(const InstX86BaseInplaceopGPR &) = delete; |
| 540 InstX86BaseInplaceopGPR & | 542 InstX86BaseInplaceopGPR & |
| 541 operator=(const InstX86BaseInplaceopGPR &) = delete; | 543 operator=(const InstX86BaseInplaceopGPR &) = delete; |
| 542 | 544 |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 606 Str << "\t"; | 608 Str << "\t"; |
| 607 this->getSrc(0)->emit(Func); | 609 this->getSrc(0)->emit(Func); |
| 608 Str << ", "; | 610 Str << ", "; |
| 609 this->getDest()->emit(Func); | 611 this->getDest()->emit(Func); |
| 610 } | 612 } |
| 611 void emitIAS(const Cfg *Func) const override { | 613 void emitIAS(const Cfg *Func) const override { |
| 612 assert(this->getSrcSize() == 1); | 614 assert(this->getSrcSize() == 1); |
| 613 const Variable *Var = this->getDest(); | 615 const Variable *Var = this->getDest(); |
| 614 Type Ty = Var->getType(); | 616 Type Ty = Var->getType(); |
| 615 const Operand *Src = this->getSrc(0); | 617 const Operand *Src = this->getSrc(0); |
| 616 emitIASRegOpTyGPR(Func, Ty, Var, Src, Emitter); | 618 constexpr bool IsLea = K == InstX86Base::Lea; |
| 619 emitIASRegOpTyGPR(Func, IsLea, Ty, Var, Src, Emitter); |
| 617 } | 620 } |
| 618 void dump(const Cfg *Func) const override { | 621 void dump(const Cfg *Func) const override { |
| 619 if (!BuildDefs::dump()) | 622 if (!BuildDefs::dump()) |
| 620 return; | 623 return; |
| 621 Ostream &Str = Func->getContext()->getStrDump(); | 624 Ostream &Str = Func->getContext()->getStrDump(); |
| 622 this->dumpDest(Func); | 625 this->dumpDest(Func); |
| 623 Str << " = " << Opcode << "." << this->getSrc(0)->getType() << " "; | 626 Str << " = " << Opcode << "." << this->getSrc(0)->getType() << " "; |
| 624 this->dumpSources(Func); | 627 this->dumpSources(Func); |
| 625 } | 628 } |
| 626 static bool classof(const Inst *Inst) { | 629 static bool classof(const Inst *Inst) { |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 736 using Base = InstX86BaseBinopGPR<K>; | 739 using Base = InstX86BaseBinopGPR<K>; |
| 737 | 740 |
| 738 void emit(const Cfg *Func) const override { | 741 void emit(const Cfg *Func) const override { |
| 739 if (!BuildDefs::dump()) | 742 if (!BuildDefs::dump()) |
| 740 return; | 743 return; |
| 741 this->emitTwoAddress(Func, Opcode); | 744 this->emitTwoAddress(Func, Opcode); |
| 742 } | 745 } |
| 743 void emitIAS(const Cfg *Func) const override { | 746 void emitIAS(const Cfg *Func) const override { |
| 744 Type Ty = this->getDest()->getType(); | 747 Type Ty = this->getDest()->getType(); |
| 745 assert(this->getSrcSize() == 2); | 748 assert(this->getSrcSize() == 2); |
| 746 emitIASRegOpTyGPR(Func, Ty, this->getDest(), this->getSrc(1), Emitter); | 749 constexpr bool ThisIsLEA = K == InstX86Base::Lea; |
| 750 static_assert(!ThisIsLEA, "Lea should be a unaryop."); |
| 751 emitIASRegOpTyGPR(Func, !ThisIsLEA, Ty, this->getDest(), this->getSrc(1), |
| 752 Emitter); |
| 747 } | 753 } |
| 748 void dump(const Cfg *Func) const override { | 754 void dump(const Cfg *Func) const override { |
| 749 if (!BuildDefs::dump()) | 755 if (!BuildDefs::dump()) |
| 750 return; | 756 return; |
| 751 Ostream &Str = Func->getContext()->getStrDump(); | 757 Ostream &Str = Func->getContext()->getStrDump(); |
| 752 this->dumpDest(Func); | 758 this->dumpDest(Func); |
| 753 Str << " = " << Opcode << "." << this->getDest()->getType() << " "; | 759 Str << " = " << Opcode << "." << this->getDest()->getType() << " "; |
| 754 this->dumpSources(Func); | 760 this->dumpSources(Func); |
| 755 } | 761 } |
| 756 static bool classof(const Inst *Inst) { | 762 static bool classof(const Inst *Inst) { |
| (...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1170 static InstX86Movzx *create(Cfg *Func, Variable *Dest, Operand *Src) { | 1176 static InstX86Movzx *create(Cfg *Func, Variable *Dest, Operand *Src) { |
| 1171 assert(typeWidthInBytes(Dest->getType()) > | 1177 assert(typeWidthInBytes(Dest->getType()) > |
| 1172 typeWidthInBytes(Src->getType())); | 1178 typeWidthInBytes(Src->getType())); |
| 1173 return new (Func->allocate<InstX86Movzx>()) InstX86Movzx(Func, Dest, Src); | 1179 return new (Func->allocate<InstX86Movzx>()) InstX86Movzx(Func, Dest, Src); |
| 1174 } | 1180 } |
| 1175 | 1181 |
| 1176 void emit(const Cfg *Func) const override; | 1182 void emit(const Cfg *Func) const override; |
| 1177 | 1183 |
| 1178 void emitIAS(const Cfg *Func) const override; | 1184 void emitIAS(const Cfg *Func) const override; |
| 1179 | 1185 |
| 1186 void setMustKeep() { MustKeep = true; } |
| 1187 |
| 1180 private: | 1188 private: |
| 1189 bool MustKeep = false; |
| 1190 |
| 1181 InstX86Movzx(Cfg *Func, Variable *Dest, Operand *Src) | 1191 InstX86Movzx(Cfg *Func, Variable *Dest, Operand *Src) |
| 1182 : InstX86BaseUnaryopGPR<InstX86Base::Movzx>(Func, Dest, Src) {} | 1192 : InstX86BaseUnaryopGPR<InstX86Base::Movzx>(Func, Dest, Src) {} |
| 1193 |
| 1194 bool mayBeElided(const Variable *Dest, const Operand *Src) const; |
| 1183 }; | 1195 }; |
| 1184 | 1196 |
| 1185 class InstX86Movd : public InstX86BaseUnaryopXmm<InstX86Base::Movd> { | 1197 class InstX86Movd : public InstX86BaseUnaryopXmm<InstX86Base::Movd> { |
| 1186 public: | 1198 public: |
| 1187 static InstX86Movd *create(Cfg *Func, Variable *Dest, Operand *Src) { | 1199 static InstX86Movd *create(Cfg *Func, Variable *Dest, Operand *Src) { |
| 1188 return new (Func->allocate<InstX86Movd>()) InstX86Movd(Func, Dest, Src); | 1200 return new (Func->allocate<InstX86Movd>()) InstX86Movd(Func, Dest, Src); |
| 1189 } | 1201 } |
| 1190 | 1202 |
| 1191 void emit(const Cfg *Func) const override; | 1203 void emit(const Cfg *Func) const override; |
| 1192 | 1204 |
| (...skipping 1438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2631 private: | 2643 private: |
| 2632 InstX86Pop(Cfg *Func, Variable *Dest); | 2644 InstX86Pop(Cfg *Func, Variable *Dest); |
| 2633 }; | 2645 }; |
| 2634 | 2646 |
| 2635 class InstX86Push final : public InstX86Base { | 2647 class InstX86Push final : public InstX86Base { |
| 2636 InstX86Push() = delete; | 2648 InstX86Push() = delete; |
| 2637 InstX86Push(const InstX86Push &) = delete; | 2649 InstX86Push(const InstX86Push &) = delete; |
| 2638 InstX86Push &operator=(const InstX86Push &) = delete; | 2650 InstX86Push &operator=(const InstX86Push &) = delete; |
| 2639 | 2651 |
| 2640 public: | 2652 public: |
| 2641 static InstX86Push *create(Cfg *Func, Variable *Source) { | 2653 static InstX86Push *create(Cfg *Func, InstX86Label *Label) { |
| 2654 return new (Func->allocate<InstX86Push>()) InstX86Push(Func, Label); |
| 2655 } |
| 2656 static InstX86Push *create(Cfg *Func, Operand *Source) { |
| 2642 return new (Func->allocate<InstX86Push>()) InstX86Push(Func, Source); | 2657 return new (Func->allocate<InstX86Push>()) InstX86Push(Func, Source); |
| 2643 } | 2658 } |
| 2644 void emit(const Cfg *Func) const override; | 2659 void emit(const Cfg *Func) const override; |
| 2645 void emitIAS(const Cfg *Func) const override; | 2660 void emitIAS(const Cfg *Func) const override; |
| 2646 void dump(const Cfg *Func) const override; | 2661 void dump(const Cfg *Func) const override; |
| 2647 static bool classof(const Inst *Inst) { | 2662 static bool classof(const Inst *Inst) { |
| 2648 return InstX86Base::isClassof(Inst, InstX86Base::Push); | 2663 return InstX86Base::isClassof(Inst, InstX86Base::Push); |
| 2649 } | 2664 } |
| 2650 | 2665 |
| 2651 private: | 2666 private: |
| 2652 InstX86Push(Cfg *Func, Variable *Source); | 2667 InstX86Label *Label = nullptr; |
| 2668 |
| 2669 InstX86Push(Cfg *Func, Operand *Source); |
| 2670 InstX86Push(Cfg *Func, InstX86Label *Label); |
| 2653 }; | 2671 }; |
| 2654 | 2672 |
| 2655 /// Ret instruction. Currently only supports the "ret" version that does not | 2673 /// Ret instruction. Currently only supports the "ret" version that does not |
| 2656 /// pop arguments. This instruction takes a Source operand (for non-void | 2674 /// pop arguments. This instruction takes a Source operand (for non-void |
| 2657 /// returning functions) for liveness analysis, though a FakeUse before the | 2675 /// returning functions) for liveness analysis, though a FakeUse before the |
| 2658 /// ret would do just as well. | 2676 /// ret would do just as well. |
| 2659 class InstX86Ret final : public InstX86Base { | 2677 class InstX86Ret final : public InstX86Base { |
| 2660 InstX86Ret() = delete; | 2678 InstX86Ret() = delete; |
| 2661 InstX86Ret(const InstX86Ret &) = delete; | 2679 InstX86Ret(const InstX86Ret &) = delete; |
| 2662 InstX86Ret &operator=(const InstX86Ret &) = delete; | 2680 InstX86Ret &operator=(const InstX86Ret &) = delete; |
| (...skipping 847 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3510 &InstImpl<TraitsType>::Assembler::psrl}; \ | 3528 &InstImpl<TraitsType>::Assembler::psrl}; \ |
| 3511 } \ | 3529 } \ |
| 3512 } | 3530 } |
| 3513 | 3531 |
| 3514 } // end of namespace X86NAMESPACE | 3532 } // end of namespace X86NAMESPACE |
| 3515 } // end of namespace Ice | 3533 } // end of namespace Ice |
| 3516 | 3534 |
| 3517 #include "IceInstX86BaseImpl.h" | 3535 #include "IceInstX86BaseImpl.h" |
| 3518 | 3536 |
| 3519 #endif // SUBZERO_SRC_ICEINSTX86BASE_H | 3537 #endif // SUBZERO_SRC_ICEINSTX86BASE_H |
| OLD | NEW |