| OLD | NEW |
| 1 //===- subzero/src/IceInstARM32.h - ARM32 machine instructions --*- C++ -*-===// | 1 //===- subzero/src/IceInstARM32.h - ARM32 machine 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 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 408 Tst, | 408 Tst, |
| 409 Udiv, | 409 Udiv, |
| 410 Umull, | 410 Umull, |
| 411 Uxt, | 411 Uxt, |
| 412 Vabs, | 412 Vabs, |
| 413 Vadd, | 413 Vadd, |
| 414 Vcmp, | 414 Vcmp, |
| 415 Vcvt, | 415 Vcvt, |
| 416 Vdiv, | 416 Vdiv, |
| 417 Veor, | 417 Veor, |
| 418 Vmla, |
| 419 Vmls, |
| 418 Vmrs, | 420 Vmrs, |
| 419 Vmul, | 421 Vmul, |
| 420 Vsqrt, | 422 Vsqrt, |
| 421 Vsub | 423 Vsub |
| 422 }; | 424 }; |
| 423 | 425 |
| 424 static constexpr size_t InstSize = sizeof(uint32_t); | 426 static constexpr size_t InstSize = sizeof(uint32_t); |
| 425 | 427 |
| 426 static const char *getWidthString(Type Ty); | 428 static const char *getWidthString(Type Ty); |
| 427 static const char *getVecWidthString(Type Ty); | 429 static const char *getVecWidthString(Type Ty); |
| 428 static CondARM32::Cond getOppositeCondition(CondARM32::Cond Cond); | 430 static CondARM32::Cond getOppositeCondition(CondARM32::Cond Cond); |
| 429 | 431 |
| 430 /// Called inside derived methods emit() to communicate that multiple | 432 /// Called inside derived methods emit() to communicate that multiple |
| 431 /// instructions are being generated. Used by emitIAS() methods to | 433 /// instructions are being generated. Used by emitIAS() methods to |
| 432 /// generate textual fixups for instructions that are not yet | 434 /// generate textual fixups for instructions that are not yet |
| 433 /// implemented. | 435 /// implemented. |
| 434 void startNextInst(const Cfg *Func) const; | 436 void startNextInst(const Cfg *Func) const; |
| 435 | 437 |
| 436 /// Shared emit routines for common forms of instructions. | 438 /// Shared emit routines for common forms of instructions. |
| 437 static void emitThreeAddrFP(const char *Opcode, const InstARM32 *Inst, | 439 static void emitThreeAddrFP(const char *Opcode, const InstARM32 *Inst, |
| 438 const Cfg *Func); | 440 const Cfg *Func); |
| 441 static void emitFourAddrFP(const char *Opcode, const InstARM32 *Inst, |
| 442 const Cfg *Func); |
| 439 | 443 |
| 440 void dump(const Cfg *Func) const override; | 444 void dump(const Cfg *Func) const override; |
| 441 | 445 |
| 442 void emitIAS(const Cfg *Func) const override; | 446 void emitIAS(const Cfg *Func) const override; |
| 443 | 447 |
| 444 protected: | 448 protected: |
| 445 InstARM32(Cfg *Func, InstKindARM32 Kind, SizeT Maxsrcs, Variable *Dest) | 449 InstARM32(Cfg *Func, InstKindARM32 Kind, SizeT Maxsrcs, Variable *Dest) |
| 446 : InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {} | 450 : InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {} |
| 447 | 451 |
| 448 static bool isClassof(const Inst *Inst, InstKindARM32 MyKind) { | 452 static bool isClassof(const Inst *Inst, InstKindARM32 MyKind) { |
| (...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 701 addSource(Src1); | 705 addSource(Src1); |
| 702 } | 706 } |
| 703 | 707 |
| 704 static const char *Opcode; | 708 static const char *Opcode; |
| 705 bool SetFlags; | 709 bool SetFlags; |
| 706 }; | 710 }; |
| 707 | 711 |
| 708 /// Instructions of the form x := y op z, for vector/FP. We leave these as | 712 /// Instructions of the form x := y op z, for vector/FP. We leave these as |
| 709 /// unconditional: "ARM deprecates the conditional execution of any instruction | 713 /// unconditional: "ARM deprecates the conditional execution of any instruction |
| 710 /// encoding provided by the Advanced SIMD Extension that is not also provided | 714 /// encoding provided by the Advanced SIMD Extension that is not also provided |
| 711 /// by the Floating-point (VFP) extension". They do not set flags. | 715 /// by the floating-point (VFP) extension". They do not set flags. |
| 712 template <InstARM32::InstKindARM32 K> | 716 template <InstARM32::InstKindARM32 K> |
| 713 class InstARM32ThreeAddrFP : public InstARM32 { | 717 class InstARM32ThreeAddrFP : public InstARM32 { |
| 714 InstARM32ThreeAddrFP() = delete; | 718 InstARM32ThreeAddrFP() = delete; |
| 715 InstARM32ThreeAddrFP(const InstARM32ThreeAddrFP &) = delete; | 719 InstARM32ThreeAddrFP(const InstARM32ThreeAddrFP &) = delete; |
| 716 InstARM32ThreeAddrFP &operator=(const InstARM32ThreeAddrFP &) = delete; | 720 InstARM32ThreeAddrFP &operator=(const InstARM32ThreeAddrFP &) = delete; |
| 717 | 721 |
| 718 public: | 722 public: |
| 719 /// Create a vector/FP binary-op instruction like vadd, and vsub. Everything | 723 /// Create a vector/FP binary-op instruction like vadd, and vsub. Everything |
| 720 /// must be a register. | 724 /// must be a register. |
| 721 static InstARM32ThreeAddrFP *create(Cfg *Func, Variable *Dest, Variable *Src0, | 725 static InstARM32ThreeAddrFP *create(Cfg *Func, Variable *Dest, Variable *Src0, |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 789 CondARM32::Cond Predicate) | 793 CondARM32::Cond Predicate) |
| 790 : InstARM32Pred(Func, K, 3, Dest, Predicate) { | 794 : InstARM32Pred(Func, K, 3, Dest, Predicate) { |
| 791 addSource(Src0); | 795 addSource(Src0); |
| 792 addSource(Src1); | 796 addSource(Src1); |
| 793 addSource(Src2); | 797 addSource(Src2); |
| 794 } | 798 } |
| 795 | 799 |
| 796 static const char *Opcode; | 800 static const char *Opcode; |
| 797 }; | 801 }; |
| 798 | 802 |
| 803 /// Instructions of the form x := x op1 (y op2 z). E.g., multiply accumulate. |
| 804 /// We leave these as unconditional: "ARM deprecates the conditional execution |
| 805 /// of any instruction encoding provided by the Advanced SIMD Extension that is |
| 806 /// not also provided by the floating-point (VFP) extension". They do not set |
| 807 /// flags. |
| 808 template <InstARM32::InstKindARM32 K> |
| 809 class InstARM32FourAddrFP : public InstARM32 { |
| 810 InstARM32FourAddrFP() = delete; |
| 811 InstARM32FourAddrFP(const InstARM32FourAddrFP &) = delete; |
| 812 InstARM32FourAddrFP &operator=(const InstARM32FourAddrFP &) = delete; |
| 813 |
| 814 public: |
| 815 // Every operand must be a register. |
| 816 static InstARM32FourAddrFP *create(Cfg *Func, Variable *Dest, Variable *Src0, |
| 817 Variable *Src1) { |
| 818 return new (Func->allocate<InstARM32FourAddrFP>()) |
| 819 InstARM32FourAddrFP(Func, Dest, Src0, Src1); |
| 820 } |
| 821 void emit(const Cfg *Func) const override { |
| 822 if (!BuildDefs::dump()) |
| 823 return; |
| 824 emitFourAddrFP(Opcode, this, Func); |
| 825 } |
| 826 void emitIAS(const Cfg *Func) const override { emitUsingTextFixup(Func); } |
| 827 void dump(const Cfg *Func) const override { |
| 828 if (!BuildDefs::dump()) |
| 829 return; |
| 830 Ostream &Str = Func->getContext()->getStrDump(); |
| 831 dumpDest(Func); |
| 832 Str << " = "; |
| 833 Str << Opcode << "." << getDest()->getType() << " "; |
| 834 dumpDest(Func); |
| 835 Str << ", "; |
| 836 dumpSources(Func); |
| 837 } |
| 838 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } |
| 839 |
| 840 private: |
| 841 InstARM32FourAddrFP(Cfg *Func, Variable *Dest, Variable *Src0, Variable *Src1) |
| 842 : InstARM32(Func, K, 3, Dest) { |
| 843 addSource(Dest); |
| 844 addSource(Src0); |
| 845 addSource(Src1); |
| 846 } |
| 847 |
| 848 static const char *Opcode; |
| 849 }; |
| 850 |
| 799 /// Instructions of the form x cmpop y (setting flags). | 851 /// Instructions of the form x cmpop y (setting flags). |
| 800 template <InstARM32::InstKindARM32 K> | 852 template <InstARM32::InstKindARM32 K> |
| 801 class InstARM32CmpLike : public InstARM32Pred { | 853 class InstARM32CmpLike : public InstARM32Pred { |
| 802 InstARM32CmpLike() = delete; | 854 InstARM32CmpLike() = delete; |
| 803 InstARM32CmpLike(const InstARM32CmpLike &) = delete; | 855 InstARM32CmpLike(const InstARM32CmpLike &) = delete; |
| 804 InstARM32CmpLike &operator=(const InstARM32CmpLike &) = delete; | 856 InstARM32CmpLike &operator=(const InstARM32CmpLike &) = delete; |
| 805 | 857 |
| 806 public: | 858 public: |
| 807 static InstARM32CmpLike *create(Cfg *Func, Variable *Src0, Operand *Src1, | 859 static InstARM32CmpLike *create(Cfg *Func, Variable *Src0, Operand *Src1, |
| 808 CondARM32::Cond Predicate) { | 860 CondARM32::Cond Predicate) { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 848 using InstARM32Mul = InstARM32ThreeAddrGPR<InstARM32::Mul>; | 900 using InstARM32Mul = InstARM32ThreeAddrGPR<InstARM32::Mul>; |
| 849 using InstARM32Orr = InstARM32ThreeAddrGPR<InstARM32::Orr>; | 901 using InstARM32Orr = InstARM32ThreeAddrGPR<InstARM32::Orr>; |
| 850 using InstARM32Rsb = InstARM32ThreeAddrGPR<InstARM32::Rsb>; | 902 using InstARM32Rsb = InstARM32ThreeAddrGPR<InstARM32::Rsb>; |
| 851 using InstARM32Rsc = InstARM32ThreeAddrGPR<InstARM32::Rsc>; | 903 using InstARM32Rsc = InstARM32ThreeAddrGPR<InstARM32::Rsc>; |
| 852 using InstARM32Sbc = InstARM32ThreeAddrGPR<InstARM32::Sbc>; | 904 using InstARM32Sbc = InstARM32ThreeAddrGPR<InstARM32::Sbc>; |
| 853 using InstARM32Sdiv = InstARM32ThreeAddrGPR<InstARM32::Sdiv>; | 905 using InstARM32Sdiv = InstARM32ThreeAddrGPR<InstARM32::Sdiv>; |
| 854 using InstARM32Sub = InstARM32ThreeAddrGPR<InstARM32::Sub>; | 906 using InstARM32Sub = InstARM32ThreeAddrGPR<InstARM32::Sub>; |
| 855 using InstARM32Udiv = InstARM32ThreeAddrGPR<InstARM32::Udiv>; | 907 using InstARM32Udiv = InstARM32ThreeAddrGPR<InstARM32::Udiv>; |
| 856 using InstARM32Vadd = InstARM32ThreeAddrFP<InstARM32::Vadd>; | 908 using InstARM32Vadd = InstARM32ThreeAddrFP<InstARM32::Vadd>; |
| 857 using InstARM32Vdiv = InstARM32ThreeAddrFP<InstARM32::Vdiv>; | 909 using InstARM32Vdiv = InstARM32ThreeAddrFP<InstARM32::Vdiv>; |
| 910 using InstARM32Veor = InstARM32ThreeAddrFP<InstARM32::Veor>; |
| 911 using InstARM32Vmla = InstARM32FourAddrFP<InstARM32::Vmla>; |
| 912 using InstARM32Vmls = InstARM32FourAddrFP<InstARM32::Vmls>; |
| 858 using InstARM32Vmul = InstARM32ThreeAddrFP<InstARM32::Vmul>; | 913 using InstARM32Vmul = InstARM32ThreeAddrFP<InstARM32::Vmul>; |
| 859 using InstARM32Veor = InstARM32ThreeAddrFP<InstARM32::Veor>; | |
| 860 using InstARM32Vsub = InstARM32ThreeAddrFP<InstARM32::Vsub>; | 914 using InstARM32Vsub = InstARM32ThreeAddrFP<InstARM32::Vsub>; |
| 861 using InstARM32Ldr = InstARM32LoadBase<InstARM32::Ldr>; | 915 using InstARM32Ldr = InstARM32LoadBase<InstARM32::Ldr>; |
| 862 using InstARM32Ldrex = InstARM32LoadBase<InstARM32::Ldrex>; | 916 using InstARM32Ldrex = InstARM32LoadBase<InstARM32::Ldrex>; |
| 863 /// MovT leaves the bottom bits alone so dest is also a source. This helps | 917 /// MovT leaves the bottom bits alone so dest is also a source. This helps |
| 864 /// indicate that a previous MovW setting dest is not dead code. | 918 /// indicate that a previous MovW setting dest is not dead code. |
| 865 using InstARM32Movt = InstARM32TwoAddrGPR<InstARM32::Movt>; | 919 using InstARM32Movt = InstARM32TwoAddrGPR<InstARM32::Movt>; |
| 866 using InstARM32Movw = InstARM32UnaryopGPR<InstARM32::Movw, false>; | 920 using InstARM32Movw = InstARM32UnaryopGPR<InstARM32::Movw, false>; |
| 867 using InstARM32Clz = InstARM32UnaryopGPR<InstARM32::Clz, false>; | 921 using InstARM32Clz = InstARM32UnaryopGPR<InstARM32::Clz, false>; |
| 868 using InstARM32Mvn = InstARM32UnaryopGPR<InstARM32::Mvn, false>; | 922 using InstARM32Mvn = InstARM32UnaryopGPR<InstARM32::Mvn, false>; |
| 869 using InstARM32Rbit = InstARM32UnaryopGPR<InstARM32::Rbit, false>; | 923 using InstARM32Rbit = InstARM32UnaryopGPR<InstARM32::Rbit, false>; |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 994 Operand *getCallTarget() const { return getSrc(0); } | 1048 Operand *getCallTarget() const { return getSrc(0); } |
| 995 void emit(const Cfg *Func) const override; | 1049 void emit(const Cfg *Func) const override; |
| 996 void emitIAS(const Cfg *Func) const override; | 1050 void emitIAS(const Cfg *Func) const override; |
| 997 void dump(const Cfg *Func) const override; | 1051 void dump(const Cfg *Func) const override; |
| 998 static bool classof(const Inst *Inst) { return isClassof(Inst, Call); } | 1052 static bool classof(const Inst *Inst) { return isClassof(Inst, Call); } |
| 999 | 1053 |
| 1000 private: | 1054 private: |
| 1001 InstARM32Call(Cfg *Func, Variable *Dest, Operand *CallTarget); | 1055 InstARM32Call(Cfg *Func, Variable *Dest, Operand *CallTarget); |
| 1002 }; | 1056 }; |
| 1003 | 1057 |
| 1004 /// Pop into a list of GPRs. Technically this can be predicated, but we don't | 1058 /// Pops a list of registers. It may be a list of GPRs, or a list of VFP "s" |
| 1005 /// need that functionality. | 1059 /// regs, but not both. In any case, the list must be sorted. |
| 1006 class InstARM32Pop : public InstARM32 { | 1060 class InstARM32Pop : public InstARM32 { |
| 1007 InstARM32Pop() = delete; | 1061 InstARM32Pop() = delete; |
| 1008 InstARM32Pop(const InstARM32Pop &) = delete; | 1062 InstARM32Pop(const InstARM32Pop &) = delete; |
| 1009 InstARM32Pop &operator=(const InstARM32Pop &) = delete; | 1063 InstARM32Pop &operator=(const InstARM32Pop &) = delete; |
| 1010 | 1064 |
| 1011 public: | 1065 public: |
| 1012 static InstARM32Pop *create(Cfg *Func, const VarList &Dests) { | 1066 static InstARM32Pop *create(Cfg *Func, const VarList &Dests) { |
| 1013 return new (Func->allocate<InstARM32Pop>()) InstARM32Pop(Func, Dests); | 1067 return new (Func->allocate<InstARM32Pop>()) InstARM32Pop(Func, Dests); |
| 1014 } | 1068 } |
| 1015 void emit(const Cfg *Func) const override; | 1069 void emit(const Cfg *Func) const override; |
| 1016 void emitIAS(const Cfg *Func) const override; | 1070 void emitIAS(const Cfg *Func) const override; |
| 1017 void dump(const Cfg *Func) const override; | 1071 void dump(const Cfg *Func) const override; |
| 1018 static bool classof(const Inst *Inst) { return isClassof(Inst, Pop); } | 1072 static bool classof(const Inst *Inst) { return isClassof(Inst, Pop); } |
| 1019 | 1073 |
| 1020 private: | 1074 private: |
| 1021 InstARM32Pop(Cfg *Func, const VarList &Dests); | 1075 InstARM32Pop(Cfg *Func, const VarList &Dests); |
| 1022 | 1076 |
| 1023 VarList Dests; | 1077 VarList Dests; |
| 1024 }; | 1078 }; |
| 1025 | 1079 |
| 1026 /// Push a list of GPRs. Technically this can be predicated, but we don't need | 1080 /// Pushes a list of registers. Just like Pop (see above), the list may be of |
| 1027 /// that functionality. | 1081 /// GPRs, or VFP "s" registers, but not both. |
| 1028 class InstARM32Push : public InstARM32 { | 1082 class InstARM32Push : public InstARM32 { |
| 1029 InstARM32Push() = delete; | 1083 InstARM32Push() = delete; |
| 1030 InstARM32Push(const InstARM32Push &) = delete; | 1084 InstARM32Push(const InstARM32Push &) = delete; |
| 1031 InstARM32Push &operator=(const InstARM32Push &) = delete; | 1085 InstARM32Push &operator=(const InstARM32Push &) = delete; |
| 1032 | 1086 |
| 1033 public: | 1087 public: |
| 1034 static InstARM32Push *create(Cfg *Func, const VarList &Srcs) { | 1088 static InstARM32Push *create(Cfg *Func, const VarList &Srcs) { |
| 1035 return new (Func->allocate<InstARM32Push>()) InstARM32Push(Func, Srcs); | 1089 return new (Func->allocate<InstARM32Push>()) InstARM32Push(Func, Srcs); |
| 1036 } | 1090 } |
| 1037 void emit(const Cfg *Func) const override; | 1091 void emit(const Cfg *Func) const override; |
| (...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1317 // default implementations. Without this, there is the possibility of ODR | 1371 // default implementations. Without this, there is the possibility of ODR |
| 1318 // violations and link errors. | 1372 // violations and link errors. |
| 1319 | 1373 |
| 1320 template <> void InstARM32Ldr::emit(const Cfg *Func) const; | 1374 template <> void InstARM32Ldr::emit(const Cfg *Func) const; |
| 1321 template <> void InstARM32Movw::emit(const Cfg *Func) const; | 1375 template <> void InstARM32Movw::emit(const Cfg *Func) const; |
| 1322 template <> void InstARM32Movt::emit(const Cfg *Func) const; | 1376 template <> void InstARM32Movt::emit(const Cfg *Func) const; |
| 1323 | 1377 |
| 1324 } // end of namespace Ice | 1378 } // end of namespace Ice |
| 1325 | 1379 |
| 1326 #endif // SUBZERO_SRC_ICEINSTARM32_H | 1380 #endif // SUBZERO_SRC_ICEINSTARM32_H |
| OLD | NEW |