OLD | NEW |
---|---|
1 //===- subzero/src/IceInstX8632.h - Low-level x86 instructions --*- C++ -*-===// | 1 //===- subzero/src/IceInstX8632.h - Low-level 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 // This file declares the InstX8632 and OperandX8632 classes and | 10 // This file declares the InstX8632 and OperandX8632 classes and |
(...skipping 553 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
564 ~InstX8632UnaryopXmm() override {} | 564 ~InstX8632UnaryopXmm() override {} |
565 static const char *Opcode; | 565 static const char *Opcode; |
566 static const x86::AssemblerX86::XmmEmitterTwoOps Emitter; | 566 static const x86::AssemblerX86::XmmEmitterTwoOps Emitter; |
567 }; | 567 }; |
568 | 568 |
569 // See the definition of emitTwoAddress() for a description of | 569 // See the definition of emitTwoAddress() for a description of |
570 // ShiftHack. | 570 // ShiftHack. |
571 void emitTwoAddress(const char *Opcode, const Inst *Inst, const Cfg *Func, | 571 void emitTwoAddress(const char *Opcode, const Inst *Inst, const Cfg *Func, |
572 bool ShiftHack = false); | 572 bool ShiftHack = false); |
573 | 573 |
574 template <InstX8632::InstKindX8632 K, bool ShiftHack = false> | 574 template <InstX8632::InstKindX8632 K> class InstX8632Binop : public InstX8632 { |
575 class InstX8632Binop : public InstX8632 { | |
576 public: | 575 public: |
577 // Create a binary-op instruction like shifts. | 576 // Create a binary-op instruction (not yet migrated to integrated assembler) |
578 static InstX8632Binop *create(Cfg *Func, Variable *Dest, Operand *Source) { | 577 static InstX8632Binop *create(Cfg *Func, Variable *Dest, Operand *Source) { |
579 return new (Func->allocate<InstX8632Binop>()) | 578 return new (Func->allocate<InstX8632Binop>()) |
580 InstX8632Binop(Func, Dest, Source); | 579 InstX8632Binop(Func, Dest, Source); |
581 } | 580 } |
582 void emit(const Cfg *Func) const override { | 581 void emit(const Cfg *Func) const override { |
582 bool ShiftHack = false; | |
Jim Stichnoth
2014/10/02 20:35:17
const bool
jvoung (off chromium)
2014/10/02 22:04:13
Done.
| |
583 emitTwoAddress(Opcode, this, Func, ShiftHack); | 583 emitTwoAddress(Opcode, this, Func, ShiftHack); |
584 } | 584 } |
585 void dump(const Cfg *Func) const override { | 585 void dump(const Cfg *Func) const override { |
586 Ostream &Str = Func->getContext()->getStrDump(); | 586 Ostream &Str = Func->getContext()->getStrDump(); |
587 dumpDest(Func); | 587 dumpDest(Func); |
588 Str << " = " << Opcode << "." << getDest()->getType() << " "; | 588 Str << " = " << Opcode << "." << getDest()->getType() << " "; |
589 dumpSources(Func); | 589 dumpSources(Func); |
590 } | 590 } |
591 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } | 591 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } |
592 | 592 |
593 private: | 593 private: |
594 InstX8632Binop(Cfg *Func, Variable *Dest, Operand *Source) | 594 InstX8632Binop(Cfg *Func, Variable *Dest, Operand *Source) |
595 : InstX8632(Func, K, 2, Dest) { | 595 : InstX8632(Func, K, 2, Dest) { |
596 addSource(Dest); | 596 addSource(Dest); |
597 addSource(Source); | 597 addSource(Source); |
598 } | 598 } |
599 InstX8632Binop(const InstX8632Binop &) = delete; | 599 InstX8632Binop(const InstX8632Binop &) = delete; |
600 InstX8632Binop &operator=(const InstX8632Binop &) = delete; | 600 InstX8632Binop &operator=(const InstX8632Binop &) = delete; |
601 ~InstX8632Binop() override {} | 601 ~InstX8632Binop() override {} |
602 static const char *Opcode; | 602 static const char *Opcode; |
603 }; | 603 }; |
604 | 604 |
605 void emitIASGPRShift(const Cfg *Func, Type Ty, const Variable *Var, | |
606 const Operand *Src, | |
607 const x86::AssemblerX86::GPREmitterShiftOp &Emitter); | |
608 | |
609 template <InstX8632::InstKindX8632 K> | |
610 class InstX8632BinopGPRShift : public InstX8632 { | |
611 public: | |
612 // Create a binary-op GPR shift instruction. | |
613 static InstX8632BinopGPRShift *create(Cfg *Func, Variable *Dest, | |
614 Operand *Source) { | |
615 return new (Func->allocate<InstX8632BinopGPRShift>()) | |
616 InstX8632BinopGPRShift(Func, Dest, Source); | |
617 } | |
618 void emit(const Cfg *Func) const override { | |
619 bool ShiftHack = true; | |
620 emitTwoAddress(Opcode, this, Func, ShiftHack); | |
621 } | |
622 void emitIAS(const Cfg *Func) const override { | |
623 Type Ty = getDest()->getType(); | |
624 assert(getSrcSize() == 2); | |
625 emitIASGPRShift(Func, Ty, getDest(), getSrc(1), Emitter); | |
626 } | |
627 void dump(const Cfg *Func) const override { | |
628 Ostream &Str = Func->getContext()->getStrDump(); | |
629 dumpDest(Func); | |
630 Str << " = " << Opcode << "." << getDest()->getType() << " "; | |
631 dumpSources(Func); | |
632 } | |
633 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } | |
634 | |
635 private: | |
636 InstX8632BinopGPRShift(Cfg *Func, Variable *Dest, Operand *Source) | |
637 : InstX8632(Func, K, 2, Dest) { | |
638 addSource(Dest); | |
639 addSource(Source); | |
640 } | |
641 InstX8632BinopGPRShift(const InstX8632BinopGPRShift &) = delete; | |
642 InstX8632BinopGPRShift &operator=(const InstX8632BinopGPRShift &) = delete; | |
643 ~InstX8632BinopGPRShift() override {} | |
644 static const char *Opcode; | |
645 static const x86::AssemblerX86::GPREmitterShiftOp Emitter; | |
646 }; | |
647 | |
605 template <InstX8632::InstKindX8632 K> | 648 template <InstX8632::InstKindX8632 K> |
606 class InstX8632BinopGPR : public InstX8632 { | 649 class InstX8632BinopGPR : public InstX8632 { |
607 public: | 650 public: |
608 // Create an ordinary binary-op instruction like add or sub. | 651 // Create an ordinary binary-op instruction like add or sub. |
609 static InstX8632BinopGPR *create(Cfg *Func, Variable *Dest, Operand *Source) { | 652 static InstX8632BinopGPR *create(Cfg *Func, Variable *Dest, Operand *Source) { |
610 return new (Func->allocate<InstX8632BinopGPR>()) | 653 return new (Func->allocate<InstX8632BinopGPR>()) |
611 InstX8632BinopGPR(Func, Dest, Source); | 654 InstX8632BinopGPR(Func, Dest, Source); |
612 } | 655 } |
613 void emit(const Cfg *Func) const override { | 656 void emit(const Cfg *Func) const override { |
614 const bool ShiftHack = false; | 657 const bool ShiftHack = false; |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
673 addSource(Dest); | 716 addSource(Dest); |
674 addSource(Source); | 717 addSource(Source); |
675 } | 718 } |
676 InstX8632BinopXmm(const InstX8632BinopXmm &) = delete; | 719 InstX8632BinopXmm(const InstX8632BinopXmm &) = delete; |
677 InstX8632BinopXmm &operator=(const InstX8632BinopXmm &) = delete; | 720 InstX8632BinopXmm &operator=(const InstX8632BinopXmm &) = delete; |
678 ~InstX8632BinopXmm() override {} | 721 ~InstX8632BinopXmm() override {} |
679 static const char *Opcode; | 722 static const char *Opcode; |
680 static const x86::AssemblerX86::XmmEmitterTwoOps Emitter; | 723 static const x86::AssemblerX86::XmmEmitterTwoOps Emitter; |
681 }; | 724 }; |
682 | 725 |
726 void emitIASXmmShift(const Cfg *Func, Type Ty, const Variable *Var, | |
727 const Operand *Src, | |
728 const x86::AssemblerX86::XmmEmitterShiftOp &Emitter); | |
729 | |
730 template <InstX8632::InstKindX8632 K> | |
731 class InstX8632BinopXmmShift : public InstX8632 { | |
732 public: | |
733 // Create an XMM binary-op instruction like addss or addps. | |
734 static InstX8632BinopXmmShift *create(Cfg *Func, Variable *Dest, | |
735 Operand *Source) { | |
736 return new (Func->allocate<InstX8632BinopXmmShift>()) | |
737 InstX8632BinopXmmShift(Func, Dest, Source); | |
738 } | |
739 void emit(const Cfg *Func) const override { | |
740 const bool ShiftHack = false; | |
741 emitTwoAddress(Opcode, this, Func, ShiftHack); | |
742 } | |
743 void emitIAS(const Cfg *Func) const override { | |
744 Type Ty = getDest()->getType(); | |
745 assert(Ty == IceType_v8i16 || Ty == IceType_v8i1 || Ty == IceType_v4i32 || | |
746 Ty == IceType_v4i1); | |
747 Type ElementTy = typeElementType(Ty); | |
748 assert(getSrcSize() == 2); | |
749 emitIASXmmShift(Func, ElementTy, getDest(), getSrc(1), Emitter); | |
750 } | |
751 void dump(const Cfg *Func) const override { | |
752 Ostream &Str = Func->getContext()->getStrDump(); | |
753 dumpDest(Func); | |
754 Str << " = " << Opcode << "." << getDest()->getType() << " "; | |
755 dumpSources(Func); | |
756 } | |
757 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } | |
758 | |
759 private: | |
760 InstX8632BinopXmmShift(Cfg *Func, Variable *Dest, Operand *Source) | |
761 : InstX8632(Func, K, 2, Dest) { | |
762 addSource(Dest); | |
763 addSource(Source); | |
764 } | |
765 InstX8632BinopXmmShift(const InstX8632BinopXmmShift &) = delete; | |
766 InstX8632BinopXmmShift &operator=(const InstX8632BinopXmmShift &) = delete; | |
767 ~InstX8632BinopXmmShift() override {} | |
768 static const char *Opcode; | |
769 static const x86::AssemblerX86::XmmEmitterShiftOp Emitter; | |
770 }; | |
771 | |
683 template <InstX8632::InstKindX8632 K> class InstX8632Ternop : public InstX8632 { | 772 template <InstX8632::InstKindX8632 K> class InstX8632Ternop : public InstX8632 { |
684 public: | 773 public: |
685 // Create a ternary-op instruction like div or idiv. | 774 // Create a ternary-op instruction like div or idiv. |
686 static InstX8632Ternop *create(Cfg *Func, Variable *Dest, Operand *Source1, | 775 static InstX8632Ternop *create(Cfg *Func, Variable *Dest, Operand *Source1, |
687 Operand *Source2) { | 776 Operand *Source2) { |
688 return new (Func->allocate<InstX8632Ternop>()) | 777 return new (Func->allocate<InstX8632Ternop>()) |
689 InstX8632Ternop(Func, Dest, Source1, Source2); | 778 InstX8632Ternop(Func, Dest, Source1, Source2); |
690 } | 779 } |
691 void emit(const Cfg *Func) const override { | 780 void emit(const Cfg *Func) const override { |
692 Ostream &Str = Func->getContext()->getStrEmit(); | 781 Ostream &Str = Func->getContext()->getStrEmit(); |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
827 typedef InstX8632BinopGPR<InstX8632::And> InstX8632And; | 916 typedef InstX8632BinopGPR<InstX8632::And> InstX8632And; |
828 typedef InstX8632BinopXmm<InstX8632::Pand, false> InstX8632Pand; | 917 typedef InstX8632BinopXmm<InstX8632::Pand, false> InstX8632Pand; |
829 typedef InstX8632BinopXmm<InstX8632::Pandn, false> InstX8632Pandn; | 918 typedef InstX8632BinopXmm<InstX8632::Pandn, false> InstX8632Pandn; |
830 typedef InstX8632BinopGPR<InstX8632::Or> InstX8632Or; | 919 typedef InstX8632BinopGPR<InstX8632::Or> InstX8632Or; |
831 typedef InstX8632BinopXmm<InstX8632::Por, false> InstX8632Por; | 920 typedef InstX8632BinopXmm<InstX8632::Por, false> InstX8632Por; |
832 typedef InstX8632BinopGPR<InstX8632::Xor> InstX8632Xor; | 921 typedef InstX8632BinopGPR<InstX8632::Xor> InstX8632Xor; |
833 typedef InstX8632BinopXmm<InstX8632::Pxor, false> InstX8632Pxor; | 922 typedef InstX8632BinopXmm<InstX8632::Pxor, false> InstX8632Pxor; |
834 typedef InstX8632BinopGPR<InstX8632::Imul> InstX8632Imul; | 923 typedef InstX8632BinopGPR<InstX8632::Imul> InstX8632Imul; |
835 typedef InstX8632BinopXmm<InstX8632::Mulps, true> InstX8632Mulps; | 924 typedef InstX8632BinopXmm<InstX8632::Mulps, true> InstX8632Mulps; |
836 typedef InstX8632BinopXmm<InstX8632::Mulss, false> InstX8632Mulss; | 925 typedef InstX8632BinopXmm<InstX8632::Mulss, false> InstX8632Mulss; |
837 typedef InstX8632Binop<InstX8632::Pmull> InstX8632Pmull; | 926 typedef InstX8632BinopXmm<InstX8632::Pmull, true> InstX8632Pmull; |
838 typedef InstX8632BinopXmm<InstX8632::Pmuludq, false> InstX8632Pmuludq; | 927 typedef InstX8632BinopXmm<InstX8632::Pmuludq, false> InstX8632Pmuludq; |
839 typedef InstX8632BinopXmm<InstX8632::Divps, true> InstX8632Divps; | 928 typedef InstX8632BinopXmm<InstX8632::Divps, true> InstX8632Divps; |
840 typedef InstX8632BinopXmm<InstX8632::Divss, false> InstX8632Divss; | 929 typedef InstX8632BinopXmm<InstX8632::Divss, false> InstX8632Divss; |
841 typedef InstX8632Binop<InstX8632::Rol, true> InstX8632Rol; | 930 typedef InstX8632BinopGPRShift<InstX8632::Rol> InstX8632Rol; |
842 typedef InstX8632Binop<InstX8632::Shl, true> InstX8632Shl; | 931 typedef InstX8632BinopGPRShift<InstX8632::Shl> InstX8632Shl; |
843 typedef InstX8632Binop<InstX8632::Psll> InstX8632Psll; | 932 typedef InstX8632BinopXmmShift<InstX8632::Psll> InstX8632Psll; |
844 typedef InstX8632Binop<InstX8632::Shr, true> InstX8632Shr; | 933 typedef InstX8632BinopGPRShift<InstX8632::Shr> InstX8632Shr; |
845 typedef InstX8632Binop<InstX8632::Sar, true> InstX8632Sar; | 934 typedef InstX8632BinopGPRShift<InstX8632::Sar> InstX8632Sar; |
846 typedef InstX8632Binop<InstX8632::Psra> InstX8632Psra; | 935 typedef InstX8632BinopXmmShift<InstX8632::Psra> InstX8632Psra; |
847 typedef InstX8632BinopXmm<InstX8632::Pcmpeq, true> InstX8632Pcmpeq; | 936 typedef InstX8632BinopXmm<InstX8632::Pcmpeq, true> InstX8632Pcmpeq; |
848 typedef InstX8632BinopXmm<InstX8632::Pcmpgt, true> InstX8632Pcmpgt; | 937 typedef InstX8632BinopXmm<InstX8632::Pcmpgt, true> InstX8632Pcmpgt; |
849 // TODO: movss is only a binary operation when the source and dest | 938 // TODO: movss is only a binary operation when the source and dest |
850 // operands are both registers. In other cases, it behaves like a copy | 939 // operands are both registers. In other cases, it behaves like a copy |
851 // (mov-like) operation. Eventually, InstX8632Movss should assert that | 940 // (mov-like) operation. Eventually, InstX8632Movss should assert that |
852 // both its source and dest operands are registers, and the lowering | 941 // both its source and dest operands are registers, and the lowering |
853 // code should use _mov instead of _movss in cases where a copy | 942 // code should use _mov instead of _movss in cases where a copy |
854 // operation is intended. | 943 // operation is intended. |
855 typedef InstX8632Binop<InstX8632::Movss> InstX8632Movss; | 944 typedef InstX8632Binop<InstX8632::Movss> InstX8632Movss; |
856 typedef InstX8632Ternop<InstX8632::Idiv> InstX8632Idiv; | 945 typedef InstX8632Ternop<InstX8632::Idiv> InstX8632Idiv; |
(...skipping 582 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1439 template <> void InstX8632Psra::emit(const Cfg *Func) const; | 1528 template <> void InstX8632Psra::emit(const Cfg *Func) const; |
1440 template <> void InstX8632Psub::emit(const Cfg *Func) const; | 1529 template <> void InstX8632Psub::emit(const Cfg *Func) const; |
1441 template <> void InstX8632Sqrtss::emit(const Cfg *Func) const; | 1530 template <> void InstX8632Sqrtss::emit(const Cfg *Func) const; |
1442 template <> void InstX8632Subss::emit(const Cfg *Func) const; | 1531 template <> void InstX8632Subss::emit(const Cfg *Func) const; |
1443 | 1532 |
1444 template <> void InstX8632Div::emitIAS(const Cfg *Func) const; | 1533 template <> void InstX8632Div::emitIAS(const Cfg *Func) const; |
1445 template <> void InstX8632Idiv::emitIAS(const Cfg *Func) const; | 1534 template <> void InstX8632Idiv::emitIAS(const Cfg *Func) const; |
1446 template <> void InstX8632Imul::emitIAS(const Cfg *Func) const; | 1535 template <> void InstX8632Imul::emitIAS(const Cfg *Func) const; |
1447 template <> void InstX8632Cbwdq::emitIAS(const Cfg *Func) const; | 1536 template <> void InstX8632Cbwdq::emitIAS(const Cfg *Func) const; |
1448 template <> void InstX8632Movd::emitIAS(const Cfg *Func) const; | 1537 template <> void InstX8632Movd::emitIAS(const Cfg *Func) const; |
1538 template <> void InstX8632Pmull::emitIAS(const Cfg *Func) const; | |
1449 | 1539 |
1450 } // end of namespace Ice | 1540 } // end of namespace Ice |
1451 | 1541 |
1452 #endif // SUBZERO_SRC_ICEINSTX8632_H | 1542 #endif // SUBZERO_SRC_ICEINSTX8632_H |
OLD | NEW |