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 |