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 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
71 Computations.forgetProducers(); | 71 Computations.forgetProducers(); |
72 Computations.recordProducers(Node); | 72 Computations.recordProducers(Node); |
73 Computations.dump(Func); | 73 Computations.dump(Func); |
74 } | 74 } |
75 | 75 |
76 void translateOm1() override; | 76 void translateOm1() override; |
77 void translateO2() override; | 77 void translateO2() override; |
78 bool doBranchOpt(Inst *I, const CfgNode *NextNode) override; | 78 bool doBranchOpt(Inst *I, const CfgNode *NextNode) override; |
79 | 79 |
80 SizeT getNumRegisters() const override { return RegARM32::Reg_NUM; } | 80 SizeT getNumRegisters() const override { return RegARM32::Reg_NUM; } |
81 Variable *getPhysicalRegister(SizeT RegNum, Type Ty = IceType_void) override; | 81 Variable *getPhysicalRegister(RegNumT RegNum, |
82 IceString getRegName(SizeT RegNum, Type Ty) const override; | 82 Type Ty = IceType_void) override; |
| 83 IceString getRegName(RegNumT RegNum, Type Ty) const override; |
83 llvm::SmallBitVector getRegisterSet(RegSetMask Include, | 84 llvm::SmallBitVector getRegisterSet(RegSetMask Include, |
84 RegSetMask Exclude) const override; | 85 RegSetMask Exclude) const override; |
85 const llvm::SmallBitVector & | 86 const llvm::SmallBitVector & |
86 getRegistersForVariable(const Variable *Var) const override { | 87 getRegistersForVariable(const Variable *Var) const override { |
87 RegClass RC = Var->getRegClass(); | 88 RegClass RC = Var->getRegClass(); |
88 assert(RC < RC_Target); | 89 assert(RC < RC_Target); |
89 return TypeToRegisterSet[RC]; | 90 return TypeToRegisterSet[RC]; |
90 } | 91 } |
91 const llvm::SmallBitVector & | 92 const llvm::SmallBitVector & |
92 getAllRegistersForVariable(const Variable *Var) const override { | 93 getAllRegistersForVariable(const Variable *Var) const override { |
93 RegClass RC = Var->getRegClass(); | 94 RegClass RC = Var->getRegClass(); |
94 assert(RC < RC_Target); | 95 assert(RC < RC_Target); |
95 return TypeToRegisterSetUnfiltered[RC]; | 96 return TypeToRegisterSetUnfiltered[RC]; |
96 } | 97 } |
97 const llvm::SmallBitVector &getAliasesForRegister(SizeT Reg) const override { | 98 const llvm::SmallBitVector & |
| 99 getAliasesForRegister(RegNumT Reg) const override { |
98 return RegisterAliases[Reg]; | 100 return RegisterAliases[Reg]; |
99 } | 101 } |
100 bool hasFramePointer() const override { return UsesFramePointer; } | 102 bool hasFramePointer() const override { return UsesFramePointer; } |
101 void setHasFramePointer() override { UsesFramePointer = true; } | 103 void setHasFramePointer() override { UsesFramePointer = true; } |
102 SizeT getStackReg() const override { return RegARM32::Reg_sp; } | 104 RegNumT getStackReg() const override { return RegARM32::Reg_sp; } |
103 SizeT getFrameReg() const override { return RegARM32::Reg_fp; } | 105 RegNumT getFrameReg() const override { return RegARM32::Reg_fp; } |
104 SizeT getFrameOrStackReg() const override { | 106 RegNumT getFrameOrStackReg() const override { |
105 return UsesFramePointer ? getFrameReg() : getStackReg(); | 107 return UsesFramePointer ? getFrameReg() : getStackReg(); |
106 } | 108 } |
107 int32_t getReservedTmpReg() const { return RegARM32::Reg_ip; } | 109 RegNumT getReservedTmpReg() const { return RegARM32::Reg_ip; } |
108 | 110 |
109 size_t typeWidthInBytesOnStack(Type Ty) const override { | 111 size_t typeWidthInBytesOnStack(Type Ty) const override { |
110 // Round up to the next multiple of 4 bytes. In particular, i1, i8, and i16 | 112 // Round up to the next multiple of 4 bytes. In particular, i1, i8, and i16 |
111 // are rounded up to 4 bytes. | 113 // are rounded up to 4 bytes. |
112 return (typeWidthInBytes(Ty) + 3) & ~3; | 114 return (typeWidthInBytes(Ty) + 3) & ~3; |
113 } | 115 } |
114 uint32_t getStackAlignment() const override; | 116 uint32_t getStackAlignment() const override; |
115 void reserveFixedAllocaArea(size_t Size, size_t Align) override { | 117 void reserveFixedAllocaArea(size_t Size, size_t Align) override { |
116 FixedAllocaSizeBytes = Size; | 118 FixedAllocaSizeBytes = Size; |
117 assert(llvm::isPowerOf2_32(Align)); | 119 assert(llvm::isPowerOf2_32(Align)); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
157 enum OperandLegalization { | 159 enum OperandLegalization { |
158 Legal_Reg = 1 << 0, /// physical register, not stack location | 160 Legal_Reg = 1 << 0, /// physical register, not stack location |
159 Legal_Flex = 1 << 1, /// A flexible operand2, which can hold rotated small | 161 Legal_Flex = 1 << 1, /// A flexible operand2, which can hold rotated small |
160 /// immediates, shifted registers, or modified fp imm. | 162 /// immediates, shifted registers, or modified fp imm. |
161 Legal_Mem = 1 << 2, /// includes [r0, r1 lsl #2] as well as [sp, #12] | 163 Legal_Mem = 1 << 2, /// includes [r0, r1 lsl #2] as well as [sp, #12] |
162 Legal_Rematerializable = 1 << 3, | 164 Legal_Rematerializable = 1 << 3, |
163 Legal_Default = ~Legal_Rematerializable, | 165 Legal_Default = ~Legal_Rematerializable, |
164 }; | 166 }; |
165 | 167 |
166 using LegalMask = uint32_t; | 168 using LegalMask = uint32_t; |
167 Operand *legalizeUndef(Operand *From, int32_t RegNum = Variable::NoRegister); | 169 Operand *legalizeUndef(Operand *From, RegNumT RegNum = RegNumT::NoRegister); |
168 Operand *legalize(Operand *From, LegalMask Allowed = Legal_Default, | 170 Operand *legalize(Operand *From, LegalMask Allowed = Legal_Default, |
169 int32_t RegNum = Variable::NoRegister); | 171 RegNumT RegNum = RegNumT::NoRegister); |
170 Variable *legalizeToReg(Operand *From, int32_t RegNum = Variable::NoRegister); | 172 Variable *legalizeToReg(Operand *From, RegNumT RegNum = RegNumT::NoRegister); |
171 | 173 |
172 OperandARM32ShAmtImm *shAmtImm(uint32_t ShAmtImm) const { | 174 OperandARM32ShAmtImm *shAmtImm(uint32_t ShAmtImm) const { |
173 assert(ShAmtImm < 32); | 175 assert(ShAmtImm < 32); |
174 return OperandARM32ShAmtImm::create( | 176 return OperandARM32ShAmtImm::create( |
175 Func, | 177 Func, |
176 llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(ShAmtImm & 0x1F))); | 178 llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(ShAmtImm & 0x1F))); |
177 } | 179 } |
178 | 180 |
179 GlobalContext *getCtx() const { return Ctx; } | 181 GlobalContext *getCtx() const { return Ctx; } |
180 | 182 |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
253 uint32_t getCallStackArgumentsSizeBytes(const InstCall *Instr) override; | 255 uint32_t getCallStackArgumentsSizeBytes(const InstCall *Instr) override; |
254 void genTargetHelperCallFor(Inst *Instr) override; | 256 void genTargetHelperCallFor(Inst *Instr) override; |
255 void doAddressOptLoad() override; | 257 void doAddressOptLoad() override; |
256 void doAddressOptStore() override; | 258 void doAddressOptStore() override; |
257 void randomlyInsertNop(float Probability, | 259 void randomlyInsertNop(float Probability, |
258 RandomNumberGenerator &RNG) override; | 260 RandomNumberGenerator &RNG) override; |
259 | 261 |
260 OperandARM32Mem *formMemoryOperand(Operand *Ptr, Type Ty); | 262 OperandARM32Mem *formMemoryOperand(Operand *Ptr, Type Ty); |
261 | 263 |
262 Variable64On32 *makeI64RegPair(); | 264 Variable64On32 *makeI64RegPair(); |
263 Variable *makeReg(Type Ty, int32_t RegNum = Variable::NoRegister); | 265 Variable *makeReg(Type Ty, RegNumT RegNum = RegNumT::NoRegister); |
264 static Type stackSlotType(); | 266 static Type stackSlotType(); |
265 Variable *copyToReg(Operand *Src, int32_t RegNum = Variable::NoRegister); | 267 Variable *copyToReg(Operand *Src, RegNumT RegNum = RegNumT::NoRegister); |
266 void alignRegisterPow2(Variable *Reg, uint32_t Align, | 268 void alignRegisterPow2(Variable *Reg, uint32_t Align, |
267 int32_t TmpRegNum = Variable::NoRegister); | 269 RegNumT TmpRegNum = RegNumT::NoRegister); |
268 | 270 |
269 /// Returns a vector in a register with the given constant entries. | 271 /// Returns a vector in a register with the given constant entries. |
270 Variable *makeVectorOfZeros(Type Ty, int32_t RegNum = Variable::NoRegister); | 272 Variable *makeVectorOfZeros(Type Ty, RegNumT RegNum = RegNumT::NoRegister); |
271 | 273 |
272 void | 274 void |
273 makeRandomRegisterPermutation(llvm::SmallVectorImpl<int32_t> &Permutation, | 275 makeRandomRegisterPermutation(llvm::SmallVectorImpl<RegNumT> &Permutation, |
274 const llvm::SmallBitVector &ExcludeRegisters, | 276 const llvm::SmallBitVector &ExcludeRegisters, |
275 uint64_t Salt) const override; | 277 uint64_t Salt) const override; |
276 | 278 |
277 // If a divide-by-zero check is needed, inserts a: test; branch .LSKIP; trap; | 279 // If a divide-by-zero check is needed, inserts a: test; branch .LSKIP; trap; |
278 // .LSKIP: <continuation>. If no check is needed nothing is inserted. | 280 // .LSKIP: <continuation>. If no check is needed nothing is inserted. |
279 void div0Check(Type Ty, Operand *SrcLo, Operand *SrcHi); | 281 void div0Check(Type Ty, Operand *SrcLo, Operand *SrcHi); |
280 using ExtInstr = void (TargetARM32::*)(Variable *, Variable *, | 282 using ExtInstr = void (TargetARM32::*)(Variable *, Variable *, |
281 CondARM32::Cond); | 283 CondARM32::Cond); |
282 using DivInstr = void (TargetARM32::*)(Variable *, Variable *, Variable *, | 284 using DivInstr = void (TargetARM32::*)(Variable *, Variable *, Variable *, |
283 CondARM32::Cond); | 285 CondARM32::Cond); |
(...skipping 702 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
986 /// Legalizes Mov if its Source (or Destination) is a spilled Variable, or | 988 /// Legalizes Mov if its Source (or Destination) is a spilled Variable, or |
987 /// if its Source is a Rematerializable variable (this form is used in lieu | 989 /// if its Source is a Rematerializable variable (this form is used in lieu |
988 /// of lea, which is not available in ARM.) | 990 /// of lea, which is not available in ARM.) |
989 /// | 991 /// |
990 /// Moves to memory become store instructions, and moves from memory, loads. | 992 /// Moves to memory become store instructions, and moves from memory, loads. |
991 void legalizeMov(InstARM32Mov *Mov); | 993 void legalizeMov(InstARM32Mov *Mov); |
992 | 994 |
993 private: | 995 private: |
994 /// Creates a new Base register centered around [Base, +/- Offset]. | 996 /// Creates a new Base register centered around [Base, +/- Offset]. |
995 Variable *newBaseRegister(Variable *Base, int32_t Offset, | 997 Variable *newBaseRegister(Variable *Base, int32_t Offset, |
996 int32_t ScratchRegNum); | 998 RegNumT ScratchRegNum); |
997 | 999 |
998 /// Creates a new, legal OperandARM32Mem for accessing Base + Offset. | 1000 /// Creates a new, legal OperandARM32Mem for accessing Base + Offset. |
999 /// The returned mem operand is a legal operand for accessing memory that is | 1001 /// The returned mem operand is a legal operand for accessing memory that is |
1000 /// of type Ty. | 1002 /// of type Ty. |
1001 /// | 1003 /// |
1002 /// If [Base, #Offset] is encodable, then the method returns a Mem operand | 1004 /// If [Base, #Offset] is encodable, then the method returns a Mem operand |
1003 /// expressing it. Otherwise, | 1005 /// expressing it. Otherwise, |
1004 /// | 1006 /// |
1005 /// if [TempBaseReg, #Offset-TempBaseOffset] is a valid memory operand, the | 1007 /// if [TempBaseReg, #Offset-TempBaseOffset] is a valid memory operand, the |
1006 /// method will return that. Otherwise, | 1008 /// method will return that. Otherwise, |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1053 CallingConv &operator=(const CallingConv &) = delete; | 1055 CallingConv &operator=(const CallingConv &) = delete; |
1054 | 1056 |
1055 public: | 1057 public: |
1056 CallingConv(); | 1058 CallingConv(); |
1057 ~CallingConv() = default; | 1059 ~CallingConv() = default; |
1058 | 1060 |
1059 /// argInGPR returns true if there is a GPR available for the requested | 1061 /// argInGPR returns true if there is a GPR available for the requested |
1060 /// type, and false otherwise. If it returns true, Reg is set to the | 1062 /// type, and false otherwise. If it returns true, Reg is set to the |
1061 /// appropriate register number. Note that, when Ty == IceType_i64, Reg will | 1063 /// appropriate register number. Note that, when Ty == IceType_i64, Reg will |
1062 /// be an I64 register pair. | 1064 /// be an I64 register pair. |
1063 bool argInGPR(Type Ty, int32_t *Reg); | 1065 bool argInGPR(Type Ty, RegNumT *Reg); |
1064 | 1066 |
1065 /// argInVFP is to floating-point/vector types what argInGPR is for integer | 1067 /// argInVFP is to floating-point/vector types what argInGPR is for integer |
1066 /// types. | 1068 /// types. |
1067 bool argInVFP(Type Ty, int32_t *Reg); | 1069 bool argInVFP(Type Ty, RegNumT *Reg); |
1068 | 1070 |
1069 private: | 1071 private: |
1070 void discardUnavailableGPRsAndTheirAliases(CfgVector<SizeT> *Regs); | 1072 void discardUnavailableGPRsAndTheirAliases(CfgVector<RegNumT> *Regs); |
1071 llvm::SmallBitVector GPRegsUsed; | 1073 llvm::SmallBitVector GPRegsUsed; |
1072 CfgVector<SizeT> GPRArgs; | 1074 CfgVector<RegNumT> GPRArgs; |
1073 CfgVector<SizeT> I64Args; | 1075 CfgVector<RegNumT> I64Args; |
1074 | 1076 |
1075 void discardUnavailableVFPRegs(CfgVector<SizeT> *Regs); | 1077 void discardUnavailableVFPRegs(CfgVector<RegNumT> *Regs); |
1076 llvm::SmallBitVector VFPRegsUsed; | 1078 llvm::SmallBitVector VFPRegsUsed; |
1077 CfgVector<SizeT> FP32Args; | 1079 CfgVector<RegNumT> FP32Args; |
1078 CfgVector<SizeT> FP64Args; | 1080 CfgVector<RegNumT> FP64Args; |
1079 CfgVector<SizeT> Vec128Args; | 1081 CfgVector<RegNumT> Vec128Args; |
1080 }; | 1082 }; |
1081 | 1083 |
1082 private: | 1084 private: |
1083 ENABLE_MAKE_UNIQUE; | 1085 ENABLE_MAKE_UNIQUE; |
1084 | 1086 |
1085 OperandARM32Mem *formAddressingMode(Type Ty, Cfg *Func, const Inst *LdSt, | 1087 OperandARM32Mem *formAddressingMode(Type Ty, Cfg *Func, const Inst *LdSt, |
1086 Operand *Base); | 1088 Operand *Base); |
1087 | 1089 |
1088 void postambleCtpop64(const InstCall *Instr); | 1090 void postambleCtpop64(const InstCall *Instr); |
1089 void preambleDivRem(const InstCall *Instr); | 1091 void preambleDivRem(const InstCall *Instr); |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1217 private: | 1219 private: |
1218 ~TargetHeaderARM32() = default; | 1220 ~TargetHeaderARM32() = default; |
1219 | 1221 |
1220 TargetARM32Features CPUFeatures; | 1222 TargetARM32Features CPUFeatures; |
1221 }; | 1223 }; |
1222 | 1224 |
1223 } // end of namespace ARM32 | 1225 } // end of namespace ARM32 |
1224 } // end of namespace Ice | 1226 } // end of namespace Ice |
1225 | 1227 |
1226 #endif // SUBZERO_SRC_ICETARGETLOWERINGARM32_H | 1228 #endif // SUBZERO_SRC_ICETARGETLOWERINGARM32_H |
OLD | NEW |