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