Chromium Code Reviews| 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 |