| 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<SizeT> *Regs); |
| 1071 llvm::SmallBitVector GPRegsUsed; | 1073 llvm::SmallBitVector GPRegsUsed; |
| 1072 CfgVector<SizeT> GPRArgs; | 1074 CfgVector<SizeT> GPRArgs; |
| 1073 CfgVector<SizeT> I64Args; | 1075 CfgVector<SizeT> I64Args; |
| 1074 | 1076 |
| 1075 void discardUnavailableVFPRegs(CfgVector<SizeT> *Regs); | 1077 void discardUnavailableVFPRegs(CfgVector<SizeT> *Regs); |
| 1076 llvm::SmallBitVector VFPRegsUsed; | 1078 llvm::SmallBitVector VFPRegsUsed; |
| 1077 CfgVector<SizeT> FP32Args; | 1079 CfgVector<SizeT> FP32Args; |
| (...skipping 139 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 |