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 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1169 static InstX86Movzx *create(Cfg *Func, Variable *Dest, Operand *Src) { | 1175 static InstX86Movzx *create(Cfg *Func, Variable *Dest, Operand *Src) { |
1170 assert(typeWidthInBytes(Dest->getType()) > | 1176 assert(typeWidthInBytes(Dest->getType()) > |
1171 typeWidthInBytes(Src->getType())); | 1177 typeWidthInBytes(Src->getType())); |
1172 return new (Func->allocate<InstX86Movzx>()) InstX86Movzx(Func, Dest, Src); | 1178 return new (Func->allocate<InstX86Movzx>()) InstX86Movzx(Func, Dest, Src); |
1173 } | 1179 } |
1174 | 1180 |
1175 void emit(const Cfg *Func) const override; | 1181 void emit(const Cfg *Func) const override; |
1176 | 1182 |
1177 void emitIAS(const Cfg *Func) const override; | 1183 void emitIAS(const Cfg *Func) const override; |
1178 | 1184 |
| 1185 void setMustKeep() { MustKeep = true; } |
| 1186 |
1179 private: | 1187 private: |
| 1188 bool MustKeep = false; |
| 1189 |
1180 InstX86Movzx(Cfg *Func, Variable *Dest, Operand *Src) | 1190 InstX86Movzx(Cfg *Func, Variable *Dest, Operand *Src) |
1181 : InstX86BaseUnaryopGPR<InstX86Base::Movzx>(Func, Dest, Src) {} | 1191 : InstX86BaseUnaryopGPR<InstX86Base::Movzx>(Func, Dest, Src) {} |
| 1192 |
| 1193 bool mayBeElided(const Variable *Dest, const Operand *Src) const; |
1182 }; | 1194 }; |
1183 | 1195 |
1184 class InstX86Movd : public InstX86BaseUnaryopXmm<InstX86Base::Movd> { | 1196 class InstX86Movd : public InstX86BaseUnaryopXmm<InstX86Base::Movd> { |
1185 public: | 1197 public: |
1186 static InstX86Movd *create(Cfg *Func, Variable *Dest, Operand *Src) { | 1198 static InstX86Movd *create(Cfg *Func, Variable *Dest, Operand *Src) { |
1187 return new (Func->allocate<InstX86Movd>()) InstX86Movd(Func, Dest, Src); | 1199 return new (Func->allocate<InstX86Movd>()) InstX86Movd(Func, Dest, Src); |
1188 } | 1200 } |
1189 | 1201 |
1190 void emit(const Cfg *Func) const override; | 1202 void emit(const Cfg *Func) const override; |
1191 | 1203 |
(...skipping 1426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2618 private: | 2630 private: |
2619 InstX86Pop(Cfg *Func, Variable *Dest); | 2631 InstX86Pop(Cfg *Func, Variable *Dest); |
2620 }; | 2632 }; |
2621 | 2633 |
2622 class InstX86Push final : public InstX86Base { | 2634 class InstX86Push final : public InstX86Base { |
2623 InstX86Push() = delete; | 2635 InstX86Push() = delete; |
2624 InstX86Push(const InstX86Push &) = delete; | 2636 InstX86Push(const InstX86Push &) = delete; |
2625 InstX86Push &operator=(const InstX86Push &) = delete; | 2637 InstX86Push &operator=(const InstX86Push &) = delete; |
2626 | 2638 |
2627 public: | 2639 public: |
2628 static InstX86Push *create(Cfg *Func, Variable *Source) { | 2640 static InstX86Push *create(Cfg *Func, InstX86Label *Label) { |
| 2641 return new (Func->allocate<InstX86Push>()) InstX86Push(Func, Label); |
| 2642 } |
| 2643 static InstX86Push *create(Cfg *Func, Operand *Source) { |
2629 return new (Func->allocate<InstX86Push>()) InstX86Push(Func, Source); | 2644 return new (Func->allocate<InstX86Push>()) InstX86Push(Func, Source); |
2630 } | 2645 } |
2631 void emit(const Cfg *Func) const override; | 2646 void emit(const Cfg *Func) const override; |
2632 void emitIAS(const Cfg *Func) const override; | 2647 void emitIAS(const Cfg *Func) const override; |
2633 void dump(const Cfg *Func) const override; | 2648 void dump(const Cfg *Func) const override; |
2634 static bool classof(const Inst *Inst) { | 2649 static bool classof(const Inst *Inst) { |
2635 return InstX86Base::isClassof(Inst, InstX86Base::Push); | 2650 return InstX86Base::isClassof(Inst, InstX86Base::Push); |
2636 } | 2651 } |
2637 | 2652 |
2638 private: | 2653 private: |
2639 InstX86Push(Cfg *Func, Variable *Source); | 2654 InstX86Label *Label = nullptr; |
| 2655 |
| 2656 InstX86Push(Cfg *Func, Operand *Source); |
| 2657 InstX86Push(Cfg *Func, InstX86Label *Label); |
2640 }; | 2658 }; |
2641 | 2659 |
2642 /// Ret instruction. Currently only supports the "ret" version that does not | 2660 /// Ret instruction. Currently only supports the "ret" version that does not |
2643 /// pop arguments. This instruction takes a Source operand (for non-void | 2661 /// pop arguments. This instruction takes a Source operand (for non-void |
2644 /// returning functions) for liveness analysis, though a FakeUse before the | 2662 /// returning functions) for liveness analysis, though a FakeUse before the |
2645 /// ret would do just as well. | 2663 /// ret would do just as well. |
2646 class InstX86Ret final : public InstX86Base { | 2664 class InstX86Ret final : public InstX86Base { |
2647 InstX86Ret() = delete; | 2665 InstX86Ret() = delete; |
2648 InstX86Ret(const InstX86Ret &) = delete; | 2666 InstX86Ret(const InstX86Ret &) = delete; |
2649 InstX86Ret &operator=(const InstX86Ret &) = delete; | 2667 InstX86Ret &operator=(const InstX86Ret &) = delete; |
(...skipping 847 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3497 &InstImpl<TraitsType>::Assembler::psrl}; \ | 3515 &InstImpl<TraitsType>::Assembler::psrl}; \ |
3498 } \ | 3516 } \ |
3499 } | 3517 } |
3500 | 3518 |
3501 } // end of namespace X86NAMESPACE | 3519 } // end of namespace X86NAMESPACE |
3502 } // end of namespace Ice | 3520 } // end of namespace Ice |
3503 | 3521 |
3504 #include "IceInstX86BaseImpl.h" | 3522 #include "IceInstX86BaseImpl.h" |
3505 | 3523 |
3506 #endif // SUBZERO_SRC_ICEINSTX86BASE_H | 3524 #endif // SUBZERO_SRC_ICEINSTX86BASE_H |
OLD | NEW |