| 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 |