| OLD | NEW |
| 1 //===- subzero/src/IceTargetLoweringARM32.h - ARM32 lowering ----*- C++ -*-===// | 1 //===- subzero/src/IceTargetLoweringARM32.h - ARM32 lowering ----*- 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 804 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 815 // TODO(jpp): This could live in the Parser, if we provided a Target-specific | 815 // TODO(jpp): This could live in the Parser, if we provided a Target-specific |
| 816 // method that the Parser could call. | 816 // method that the Parser could call. |
| 817 void findMaxStackOutArgsSize(); | 817 void findMaxStackOutArgsSize(); |
| 818 | 818 |
| 819 /// Returns true if the given Offset can be represented in a Load/Store Mem | 819 /// Returns true if the given Offset can be represented in a Load/Store Mem |
| 820 /// Operand. | 820 /// Operand. |
| 821 bool isLegalMemOffset(Type Ty, int32_t Offset) const; | 821 bool isLegalMemOffset(Type Ty, int32_t Offset) const; |
| 822 | 822 |
| 823 void postLowerLegalization(); | 823 void postLowerLegalization(); |
| 824 | 824 |
| 825 /// Sandboxer defines methods for ensuring that "dangerous" operations are |
| 826 /// masked during sandboxed code emission. For regular, non-sandboxed code |
| 827 /// emission, its methods are simple pass-through methods. |
| 828 /// |
| 829 /// The Sandboxer also emits BundleLock/BundleUnlock pseudo-instructions |
| 830 /// in the constructor/destructor during sandboxed code emission. Therefore, |
| 831 /// it is a bad idea to create an object of this type and "keep it around." |
| 832 /// The recommended usage is: |
| 833 /// |
| 834 /// AutoSandboxing(this).<<operation>>(...); |
| 835 /// |
| 836 /// This usage ensures that no other instructions are inadvertently added to |
| 837 /// the bundle. |
| 838 class Sandboxer { |
| 839 Sandboxer() = delete; |
| 840 Sandboxer(const Sandboxer &) = delete; |
| 841 Sandboxer &operator=(const Sandboxer &) = delete; |
| 842 |
| 843 public: |
| 844 explicit Sandboxer( |
| 845 TargetARM32 *Target, |
| 846 InstBundleLock::Option BundleOption = InstBundleLock::Opt_None); |
| 847 ~Sandboxer(); |
| 848 |
| 849 /// Increments sp: |
| 850 /// |
| 851 /// add sp, sp, AddAmount |
| 852 /// bic sp, sp, 0xc0000000 |
| 853 /// |
| 854 /// (for the rationale, see the ARM 32-bit Sandbox Specification.) |
| 855 void add_sp(Operand *AddAmount); |
| 856 |
| 857 /// Emits code to align sp to the specified alignment: |
| 858 /// |
| 859 /// bic/and sp, sp, Alignment |
| 860 /// bic, sp, sp, 0xc0000000 |
| 861 void align_sp(size_t Alignment); |
| 862 |
| 863 /// Emits a call instruction. If CallTarget is a Variable, it emits |
| 864 /// |
| 865 /// bic CallTarget, CallTarget, 0xc000000f |
| 866 /// bl CallTarget |
| 867 /// |
| 868 /// Otherwise, it emits |
| 869 /// |
| 870 /// bl CallTarget |
| 871 /// |
| 872 /// Note: in sandboxed code calls are always emitted in addresses 12 mod 16. |
| 873 InstARM32Call *bl(Variable *ReturnReg, Operand *CallTarget); |
| 874 |
| 875 /// Emits a load: |
| 876 /// |
| 877 /// bic rBase, rBase, 0xc0000000 |
| 878 /// ldr rDest, [rBase, #Offset] |
| 879 /// |
| 880 /// Exception: if rBase is r9 or sp, then the load is emitted as: |
| 881 /// |
| 882 /// ldr rDest, [rBase, #Offset] |
| 883 /// |
| 884 /// because the NaCl ARM 32-bit Sandbox Specification guarantees they are |
| 885 /// always valid. |
| 886 void ldr(Variable *Dest, OperandARM32Mem *Mem, CondARM32::Cond Pred); |
| 887 |
| 888 /// Emits a load exclusive: |
| 889 /// |
| 890 /// bic rBase, rBase, 0xc0000000 |
| 891 /// ldrex rDest, [rBase] |
| 892 /// |
| 893 /// Exception: if rBase is r9 or sp, then the load is emitted as: |
| 894 /// |
| 895 /// ldrex rDest, [rBase] |
| 896 /// |
| 897 /// because the NaCl ARM 32-bit Sandbox Specification guarantees they are |
| 898 /// always valid. |
| 899 void ldrex(Variable *Dest, OperandARM32Mem *Mem, CondARM32::Cond Pred); |
| 900 |
| 901 /// Resets sp to Src: |
| 902 /// |
| 903 /// mov sp, Src |
| 904 /// bic sp, sp, 0xc0000000 |
| 905 void reset_sp(Variable *Src); |
| 906 |
| 907 /// Emits code to return from a function: |
| 908 /// |
| 909 /// bic lr, lr, 0xc000000f |
| 910 /// bx lr |
| 911 void ret(Variable *RetAddr, Variable *RetValue); |
| 912 |
| 913 /// Emits a store: |
| 914 /// |
| 915 /// bic rBase, rBase, 0xc0000000 |
| 916 /// str rSrc, [rBase, #Offset] |
| 917 /// |
| 918 /// Exception: if rBase is r9 or sp, then the store is emitted as: |
| 919 /// |
| 920 /// str rDest, [rBase, #Offset] |
| 921 /// |
| 922 /// because the NaCl ARM 32-bit Sandbox Specification guarantees they are |
| 923 /// always valid. |
| 924 void str(Variable *Src, OperandARM32Mem *Mem, CondARM32::Cond Pred); |
| 925 |
| 926 /// Emits a store exclusive: |
| 927 /// |
| 928 /// bic rBase, rBase, 0xc0000000 |
| 929 /// strex rDest, rSrc, [rBase] |
| 930 /// |
| 931 /// Exception: if rBase is r9 or sp, then the store is emitted as: |
| 932 /// |
| 933 /// strex rDest, rSrc, [rBase] |
| 934 /// |
| 935 /// because the NaCl ARM 32-bit Sandbox Specification guarantees they are |
| 936 /// always valid. |
| 937 void strex(Variable *Dest, Variable *Src, OperandARM32Mem *Mem, |
| 938 CondARM32::Cond Pred); |
| 939 |
| 940 /// Decrements sp: |
| 941 /// |
| 942 /// sub sp, sp, SubAmount |
| 943 /// bic sp, sp, 0xc0000000 |
| 944 void sub_sp(Operand *SubAmount); |
| 945 |
| 946 private: |
| 947 TargetARM32 *Target; |
| 948 }; |
| 949 |
| 825 class PostLoweringLegalizer { | 950 class PostLoweringLegalizer { |
| 826 PostLoweringLegalizer() = delete; | 951 PostLoweringLegalizer() = delete; |
| 827 PostLoweringLegalizer(const PostLoweringLegalizer &) = delete; | 952 PostLoweringLegalizer(const PostLoweringLegalizer &) = delete; |
| 828 PostLoweringLegalizer &operator=(const PostLoweringLegalizer &) = delete; | 953 PostLoweringLegalizer &operator=(const PostLoweringLegalizer &) = delete; |
| 829 | 954 |
| 830 public: | 955 public: |
| 831 explicit PostLoweringLegalizer(TargetARM32 *Target) | 956 explicit PostLoweringLegalizer(TargetARM32 *Target) |
| 832 : Target(Target), StackOrFrameReg(Target->getPhysicalRegister( | 957 : Target(Target), StackOrFrameReg(Target->getPhysicalRegister( |
| 833 Target->getFrameOrStackReg())) {} | 958 Target->getFrameOrStackReg())) {} |
| 834 | 959 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 871 /// a new base register ip=Base+Offset is created, and the method returns a | 996 /// a new base register ip=Base+Offset is created, and the method returns a |
| 872 /// memory operand expressing [ip, #0]. | 997 /// memory operand expressing [ip, #0]. |
| 873 OperandARM32Mem *createMemOperand(Type Ty, Variable *Base, int32_t Offset, | 998 OperandARM32Mem *createMemOperand(Type Ty, Variable *Base, int32_t Offset, |
| 874 bool AllowOffsets = true); | 999 bool AllowOffsets = true); |
| 875 TargetARM32 *const Target; | 1000 TargetARM32 *const Target; |
| 876 Variable *const StackOrFrameReg; | 1001 Variable *const StackOrFrameReg; |
| 877 Variable *TempBaseReg = nullptr; | 1002 Variable *TempBaseReg = nullptr; |
| 878 int32_t TempBaseOffset = 0; | 1003 int32_t TempBaseOffset = 0; |
| 879 }; | 1004 }; |
| 880 | 1005 |
| 1006 const bool NeedSandboxing; |
| 881 TargetARM32Features CPUFeatures; | 1007 TargetARM32Features CPUFeatures; |
| 882 bool UsesFramePointer = false; | 1008 bool UsesFramePointer = false; |
| 883 bool NeedsStackAlignment = false; | 1009 bool NeedsStackAlignment = false; |
| 884 bool MaybeLeafFunc = true; | 1010 bool MaybeLeafFunc = true; |
| 885 size_t SpillAreaSizeBytes = 0; | 1011 size_t SpillAreaSizeBytes = 0; |
| 886 size_t FixedAllocaSizeBytes = 0; | 1012 size_t FixedAllocaSizeBytes = 0; |
| 887 size_t FixedAllocaAlignBytes = 0; | 1013 size_t FixedAllocaAlignBytes = 0; |
| 888 bool PrologEmitsFixedAllocas = false; | 1014 bool PrologEmitsFixedAllocas = false; |
| 889 uint32_t MaxOutArgsSizeBytes = 0; | 1015 uint32_t MaxOutArgsSizeBytes = 0; |
| 890 // TODO(jpp): std::array instead of array. | 1016 // TODO(jpp): std::array instead of array. |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1076 | 1202 |
| 1077 private: | 1203 private: |
| 1078 ~TargetHeaderARM32() = default; | 1204 ~TargetHeaderARM32() = default; |
| 1079 | 1205 |
| 1080 TargetARM32Features CPUFeatures; | 1206 TargetARM32Features CPUFeatures; |
| 1081 }; | 1207 }; |
| 1082 | 1208 |
| 1083 } // end of namespace Ice | 1209 } // end of namespace Ice |
| 1084 | 1210 |
| 1085 #endif // SUBZERO_SRC_ICETARGETLOWERINGARM32_H | 1211 #endif // SUBZERO_SRC_ICETARGETLOWERINGARM32_H |
| OLD | NEW |