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 switch (RC) { | 89 switch (RC) { |
89 default: | 90 default: |
90 assert(RC < RC_Target); | 91 assert(RC < RC_Target); |
91 return TypeToRegisterSet[RC]; | 92 return TypeToRegisterSet[RC]; |
92 case RegARM32::RCARM32_QtoS: | 93 case RegARM32::RCARM32_QtoS: |
93 return TypeToRegisterSet[RC]; | 94 return TypeToRegisterSet[RC]; |
94 } | 95 } |
95 } | 96 } |
96 const llvm::SmallBitVector & | 97 const llvm::SmallBitVector & |
97 getAllRegistersForVariable(const Variable *Var) const override { | 98 getAllRegistersForVariable(const Variable *Var) const override { |
98 RegClass RC = Var->getRegClass(); | 99 RegClass RC = Var->getRegClass(); |
99 assert((RegARM32::RegClassARM32)RC < RegARM32::RCARM32_NUM); | 100 assert((RegARM32::RegClassARM32)RC < RegARM32::RCARM32_NUM); |
100 return TypeToRegisterSetUnfiltered[RC]; | 101 return TypeToRegisterSetUnfiltered[RC]; |
101 } | 102 } |
102 const llvm::SmallBitVector &getAliasesForRegister(SizeT Reg) const override { | 103 const llvm::SmallBitVector & |
| 104 getAliasesForRegister(RegNumT Reg) const override { |
103 return RegisterAliases[Reg]; | 105 return RegisterAliases[Reg]; |
104 } | 106 } |
105 bool hasFramePointer() const override { return UsesFramePointer; } | 107 bool hasFramePointer() const override { return UsesFramePointer; } |
106 void setHasFramePointer() override { UsesFramePointer = true; } | 108 void setHasFramePointer() override { UsesFramePointer = true; } |
107 SizeT getStackReg() const override { return RegARM32::Reg_sp; } | 109 RegNumT getStackReg() const override { return RegARM32::Reg_sp; } |
108 SizeT getFrameReg() const override { return RegARM32::Reg_fp; } | 110 RegNumT getFrameReg() const override { return RegARM32::Reg_fp; } |
109 SizeT getFrameOrStackReg() const override { | 111 RegNumT getFrameOrStackReg() const override { |
110 return UsesFramePointer ? getFrameReg() : getStackReg(); | 112 return UsesFramePointer ? getFrameReg() : getStackReg(); |
111 } | 113 } |
112 int32_t getReservedTmpReg() const { return RegARM32::Reg_ip; } | 114 RegNumT getReservedTmpReg() const { return RegARM32::Reg_ip; } |
113 | 115 |
114 size_t typeWidthInBytesOnStack(Type Ty) const override { | 116 size_t typeWidthInBytesOnStack(Type Ty) const override { |
115 // Round up to the next multiple of 4 bytes. In particular, i1, i8, and i16 | 117 // Round up to the next multiple of 4 bytes. In particular, i1, i8, and i16 |
116 // are rounded up to 4 bytes. | 118 // are rounded up to 4 bytes. |
117 return (typeWidthInBytes(Ty) + 3) & ~3; | 119 return (typeWidthInBytes(Ty) + 3) & ~3; |
118 } | 120 } |
119 uint32_t getStackAlignment() const override; | 121 uint32_t getStackAlignment() const override; |
120 void reserveFixedAllocaArea(size_t Size, size_t Align) override { | 122 void reserveFixedAllocaArea(size_t Size, size_t Align) override { |
121 FixedAllocaSizeBytes = Size; | 123 FixedAllocaSizeBytes = Size; |
122 assert(llvm::isPowerOf2_32(Align)); | 124 assert(llvm::isPowerOf2_32(Align)); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
162 enum OperandLegalization { | 164 enum OperandLegalization { |
163 Legal_Reg = 1 << 0, /// physical register, not stack location | 165 Legal_Reg = 1 << 0, /// physical register, not stack location |
164 Legal_Flex = 1 << 1, /// A flexible operand2, which can hold rotated small | 166 Legal_Flex = 1 << 1, /// A flexible operand2, which can hold rotated small |
165 /// immediates, shifted registers, or modified fp imm. | 167 /// immediates, shifted registers, or modified fp imm. |
166 Legal_Mem = 1 << 2, /// includes [r0, r1 lsl #2] as well as [sp, #12] | 168 Legal_Mem = 1 << 2, /// includes [r0, r1 lsl #2] as well as [sp, #12] |
167 Legal_Rematerializable = 1 << 3, | 169 Legal_Rematerializable = 1 << 3, |
168 Legal_Default = ~Legal_Rematerializable, | 170 Legal_Default = ~Legal_Rematerializable, |
169 }; | 171 }; |
170 | 172 |
171 using LegalMask = uint32_t; | 173 using LegalMask = uint32_t; |
172 Operand *legalizeUndef(Operand *From, int32_t RegNum = Variable::NoRegister); | 174 Operand *legalizeUndef(Operand *From, RegNumT RegNum = RegNumT::NoRegister); |
173 Operand *legalize(Operand *From, LegalMask Allowed = Legal_Default, | 175 Operand *legalize(Operand *From, LegalMask Allowed = Legal_Default, |
174 int32_t RegNum = Variable::NoRegister); | 176 RegNumT RegNum = RegNumT::NoRegister); |
175 Variable *legalizeToReg(Operand *From, int32_t RegNum = Variable::NoRegister); | 177 Variable *legalizeToReg(Operand *From, RegNumT RegNum = RegNumT::NoRegister); |
176 | 178 |
177 OperandARM32ShAmtImm *shAmtImm(uint32_t ShAmtImm) const { | 179 OperandARM32ShAmtImm *shAmtImm(uint32_t ShAmtImm) const { |
178 assert(ShAmtImm < 32); | 180 assert(ShAmtImm < 32); |
179 return OperandARM32ShAmtImm::create( | 181 return OperandARM32ShAmtImm::create( |
180 Func, | 182 Func, |
181 llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(ShAmtImm & 0x1F))); | 183 llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(ShAmtImm & 0x1F))); |
182 } | 184 } |
183 | 185 |
184 GlobalContext *getCtx() const { return Ctx; } | 186 GlobalContext *getCtx() const { return Ctx; } |
185 | 187 |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
258 uint32_t getCallStackArgumentsSizeBytes(const InstCall *Instr) override; | 260 uint32_t getCallStackArgumentsSizeBytes(const InstCall *Instr) override; |
259 void genTargetHelperCallFor(Inst *Instr) override; | 261 void genTargetHelperCallFor(Inst *Instr) override; |
260 void doAddressOptLoad() override; | 262 void doAddressOptLoad() override; |
261 void doAddressOptStore() override; | 263 void doAddressOptStore() override; |
262 void randomlyInsertNop(float Probability, | 264 void randomlyInsertNop(float Probability, |
263 RandomNumberGenerator &RNG) override; | 265 RandomNumberGenerator &RNG) override; |
264 | 266 |
265 OperandARM32Mem *formMemoryOperand(Operand *Ptr, Type Ty); | 267 OperandARM32Mem *formMemoryOperand(Operand *Ptr, Type Ty); |
266 | 268 |
267 Variable64On32 *makeI64RegPair(); | 269 Variable64On32 *makeI64RegPair(); |
268 Variable *makeReg(Type Ty, int32_t RegNum = Variable::NoRegister); | 270 Variable *makeReg(Type Ty, RegNumT RegNum = RegNumT::NoRegister); |
269 static Type stackSlotType(); | 271 static Type stackSlotType(); |
270 Variable *copyToReg(Operand *Src, int32_t RegNum = Variable::NoRegister); | 272 Variable *copyToReg(Operand *Src, RegNumT RegNum = RegNumT::NoRegister); |
271 void alignRegisterPow2(Variable *Reg, uint32_t Align, | 273 void alignRegisterPow2(Variable *Reg, uint32_t Align, |
272 int32_t TmpRegNum = Variable::NoRegister); | 274 RegNumT TmpRegNum = RegNumT::NoRegister); |
273 | 275 |
274 /// Returns a vector in a register with the given constant entries. | 276 /// Returns a vector in a register with the given constant entries. |
275 Variable *makeVectorOfZeros(Type Ty, int32_t RegNum = Variable::NoRegister); | 277 Variable *makeVectorOfZeros(Type Ty, RegNumT RegNum = RegNumT::NoRegister); |
276 | 278 |
277 void | 279 void |
278 makeRandomRegisterPermutation(llvm::SmallVectorImpl<int32_t> &Permutation, | 280 makeRandomRegisterPermutation(llvm::SmallVectorImpl<RegNumT> &Permutation, |
279 const llvm::SmallBitVector &ExcludeRegisters, | 281 const llvm::SmallBitVector &ExcludeRegisters, |
280 uint64_t Salt) const override; | 282 uint64_t Salt) const override; |
281 | 283 |
282 // If a divide-by-zero check is needed, inserts a: test; branch .LSKIP; trap; | 284 // If a divide-by-zero check is needed, inserts a: test; branch .LSKIP; trap; |
283 // .LSKIP: <continuation>. If no check is needed nothing is inserted. | 285 // .LSKIP: <continuation>. If no check is needed nothing is inserted. |
284 void div0Check(Type Ty, Operand *SrcLo, Operand *SrcHi); | 286 void div0Check(Type Ty, Operand *SrcLo, Operand *SrcHi); |
285 using ExtInstr = void (TargetARM32::*)(Variable *, Variable *, | 287 using ExtInstr = void (TargetARM32::*)(Variable *, Variable *, |
286 CondARM32::Cond); | 288 CondARM32::Cond); |
287 using DivInstr = void (TargetARM32::*)(Variable *, Variable *, Variable *, | 289 using DivInstr = void (TargetARM32::*)(Variable *, Variable *, Variable *, |
288 CondARM32::Cond); | 290 CondARM32::Cond); |
(...skipping 718 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1007 /// Legalizes Mov if its Source (or Destination) is a spilled Variable, or | 1009 /// Legalizes Mov if its Source (or Destination) is a spilled Variable, or |
1008 /// if its Source is a Rematerializable variable (this form is used in lieu | 1010 /// if its Source is a Rematerializable variable (this form is used in lieu |
1009 /// of lea, which is not available in ARM.) | 1011 /// of lea, which is not available in ARM.) |
1010 /// | 1012 /// |
1011 /// Moves to memory become store instructions, and moves from memory, loads. | 1013 /// Moves to memory become store instructions, and moves from memory, loads. |
1012 void legalizeMov(InstARM32Mov *Mov); | 1014 void legalizeMov(InstARM32Mov *Mov); |
1013 | 1015 |
1014 private: | 1016 private: |
1015 /// Creates a new Base register centered around [Base, +/- Offset]. | 1017 /// Creates a new Base register centered around [Base, +/- Offset]. |
1016 Variable *newBaseRegister(Variable *Base, int32_t Offset, | 1018 Variable *newBaseRegister(Variable *Base, int32_t Offset, |
1017 int32_t ScratchRegNum); | 1019 RegNumT ScratchRegNum); |
1018 | 1020 |
1019 /// Creates a new, legal OperandARM32Mem for accessing Base + Offset. | 1021 /// Creates a new, legal OperandARM32Mem for accessing Base + Offset. |
1020 /// The returned mem operand is a legal operand for accessing memory that is | 1022 /// The returned mem operand is a legal operand for accessing memory that is |
1021 /// of type Ty. | 1023 /// of type Ty. |
1022 /// | 1024 /// |
1023 /// If [Base, #Offset] is encodable, then the method returns a Mem operand | 1025 /// If [Base, #Offset] is encodable, then the method returns a Mem operand |
1024 /// expressing it. Otherwise, | 1026 /// expressing it. Otherwise, |
1025 /// | 1027 /// |
1026 /// if [TempBaseReg, #Offset-TempBaseOffset] is a valid memory operand, the | 1028 /// if [TempBaseReg, #Offset-TempBaseOffset] is a valid memory operand, the |
1027 /// method will return that. Otherwise, | 1029 /// method will return that. Otherwise, |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1074 CallingConv &operator=(const CallingConv &) = delete; | 1076 CallingConv &operator=(const CallingConv &) = delete; |
1075 | 1077 |
1076 public: | 1078 public: |
1077 CallingConv(); | 1079 CallingConv(); |
1078 ~CallingConv() = default; | 1080 ~CallingConv() = default; |
1079 | 1081 |
1080 /// argInGPR returns true if there is a GPR available for the requested | 1082 /// argInGPR returns true if there is a GPR available for the requested |
1081 /// type, and false otherwise. If it returns true, Reg is set to the | 1083 /// type, and false otherwise. If it returns true, Reg is set to the |
1082 /// appropriate register number. Note that, when Ty == IceType_i64, Reg will | 1084 /// appropriate register number. Note that, when Ty == IceType_i64, Reg will |
1083 /// be an I64 register pair. | 1085 /// be an I64 register pair. |
1084 bool argInGPR(Type Ty, int32_t *Reg); | 1086 bool argInGPR(Type Ty, RegNumT *Reg); |
1085 | 1087 |
1086 /// argInVFP is to floating-point/vector types what argInGPR is for integer | 1088 /// argInVFP is to floating-point/vector types what argInGPR is for integer |
1087 /// types. | 1089 /// types. |
1088 bool argInVFP(Type Ty, int32_t *Reg); | 1090 bool argInVFP(Type Ty, RegNumT *Reg); |
1089 | 1091 |
1090 private: | 1092 private: |
1091 void discardUnavailableGPRsAndTheirAliases(CfgVector<SizeT> *Regs); | 1093 void discardUnavailableGPRsAndTheirAliases(CfgVector<RegNumT> *Regs); |
1092 llvm::SmallBitVector GPRegsUsed; | 1094 llvm::SmallBitVector GPRegsUsed; |
1093 CfgVector<SizeT> GPRArgs; | 1095 CfgVector<RegNumT> GPRArgs; |
1094 CfgVector<SizeT> I64Args; | 1096 CfgVector<RegNumT> I64Args; |
1095 | 1097 |
1096 void discardUnavailableVFPRegs(CfgVector<SizeT> *Regs); | 1098 void discardUnavailableVFPRegs(CfgVector<RegNumT> *Regs); |
1097 llvm::SmallBitVector VFPRegsUsed; | 1099 llvm::SmallBitVector VFPRegsUsed; |
1098 CfgVector<SizeT> FP32Args; | 1100 CfgVector<RegNumT> FP32Args; |
1099 CfgVector<SizeT> FP64Args; | 1101 CfgVector<RegNumT> FP64Args; |
1100 CfgVector<SizeT> Vec128Args; | 1102 CfgVector<RegNumT> Vec128Args; |
1101 }; | 1103 }; |
1102 | 1104 |
1103 private: | 1105 private: |
1104 ENABLE_MAKE_UNIQUE; | 1106 ENABLE_MAKE_UNIQUE; |
1105 | 1107 |
1106 OperandARM32Mem *formAddressingMode(Type Ty, Cfg *Func, const Inst *LdSt, | 1108 OperandARM32Mem *formAddressingMode(Type Ty, Cfg *Func, const Inst *LdSt, |
1107 Operand *Base); | 1109 Operand *Base); |
1108 | 1110 |
1109 void postambleCtpop64(const InstCall *Instr); | 1111 void postambleCtpop64(const InstCall *Instr); |
1110 void preambleDivRem(const InstCall *Instr); | 1112 void preambleDivRem(const InstCall *Instr); |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1238 private: | 1240 private: |
1239 ~TargetHeaderARM32() = default; | 1241 ~TargetHeaderARM32() = default; |
1240 | 1242 |
1241 TargetARM32Features CPUFeatures; | 1243 TargetARM32Features CPUFeatures; |
1242 }; | 1244 }; |
1243 | 1245 |
1244 } // end of namespace ARM32 | 1246 } // end of namespace ARM32 |
1245 } // end of namespace Ice | 1247 } // end of namespace Ice |
1246 | 1248 |
1247 #endif // SUBZERO_SRC_ICETARGETLOWERINGARM32_H | 1249 #endif // SUBZERO_SRC_ICETARGETLOWERINGARM32_H |
OLD | NEW |