| 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 // This file declares the TargetLoweringARM32 class, which implements the | 10 /// \file |
| 11 // TargetLowering interface for the ARM 32-bit architecture. | 11 /// This file declares the TargetLoweringARM32 class, which implements the |
| 12 // | 12 /// TargetLowering interface for the ARM 32-bit architecture. |
| 13 /// |
| 13 //===----------------------------------------------------------------------===// | 14 //===----------------------------------------------------------------------===// |
| 14 | 15 |
| 15 #ifndef SUBZERO_SRC_ICETARGETLOWERINGARM32_H | 16 #ifndef SUBZERO_SRC_ICETARGETLOWERINGARM32_H |
| 16 #define SUBZERO_SRC_ICETARGETLOWERINGARM32_H | 17 #define SUBZERO_SRC_ICETARGETLOWERINGARM32_H |
| 17 | 18 |
| 18 #include "IceDefs.h" | 19 #include "IceDefs.h" |
| 19 #include "IceInstARM32.h" | 20 #include "IceInstARM32.h" |
| 20 #include "IceRegistersARM32.h" | 21 #include "IceRegistersARM32.h" |
| 21 #include "IceTargetLowering.h" | 22 #include "IceTargetLowering.h" |
| 22 | 23 |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 83 void emit(const ConstantUndef *C) const final; | 84 void emit(const ConstantUndef *C) const final; |
| 84 void emit(const ConstantInteger32 *C) const final; | 85 void emit(const ConstantInteger32 *C) const final; |
| 85 void emit(const ConstantInteger64 *C) const final; | 86 void emit(const ConstantInteger64 *C) const final; |
| 86 void emit(const ConstantFloat *C) const final; | 87 void emit(const ConstantFloat *C) const final; |
| 87 void emit(const ConstantDouble *C) const final; | 88 void emit(const ConstantDouble *C) const final; |
| 88 | 89 |
| 89 void lowerArguments() override; | 90 void lowerArguments() override; |
| 90 void addProlog(CfgNode *Node) override; | 91 void addProlog(CfgNode *Node) override; |
| 91 void addEpilog(CfgNode *Node) override; | 92 void addEpilog(CfgNode *Node) override; |
| 92 | 93 |
| 93 // Ensure that a 64-bit Variable has been split into 2 32-bit | 94 /// Ensure that a 64-bit Variable has been split into 2 32-bit |
| 94 // Variables, creating them if necessary. This is needed for all | 95 /// Variables, creating them if necessary. This is needed for all |
| 95 // I64 operations. | 96 /// I64 operations. |
| 96 void split64(Variable *Var); | 97 void split64(Variable *Var); |
| 97 Operand *loOperand(Operand *Operand); | 98 Operand *loOperand(Operand *Operand); |
| 98 Operand *hiOperand(Operand *Operand); | 99 Operand *hiOperand(Operand *Operand); |
| 99 void finishArgumentLowering(Variable *Arg, Variable *FramePtr, | 100 void finishArgumentLowering(Variable *Arg, Variable *FramePtr, |
| 100 size_t BasicFrameOffset, size_t &InArgsSizeBytes); | 101 size_t BasicFrameOffset, size_t &InArgsSizeBytes); |
| 101 | 102 |
| 102 bool hasCPUFeature(TargetARM32Features::ARM32InstructionSet I) const { | 103 bool hasCPUFeature(TargetARM32Features::ARM32InstructionSet I) const { |
| 103 return CPUFeatures.hasFeature(I); | 104 return CPUFeatures.hasFeature(I); |
| 104 } | 105 } |
| 105 | 106 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 128 void lowerUnreachable(const InstUnreachable *Inst) override; | 129 void lowerUnreachable(const InstUnreachable *Inst) override; |
| 129 void prelowerPhis() override; | 130 void prelowerPhis() override; |
| 130 void lowerPhiAssignments(CfgNode *Node, | 131 void lowerPhiAssignments(CfgNode *Node, |
| 131 const AssignList &Assignments) override; | 132 const AssignList &Assignments) override; |
| 132 void doAddressOptLoad() override; | 133 void doAddressOptLoad() override; |
| 133 void doAddressOptStore() override; | 134 void doAddressOptStore() override; |
| 134 void randomlyInsertNop(float Probability) override; | 135 void randomlyInsertNop(float Probability) override; |
| 135 | 136 |
| 136 enum OperandLegalization { | 137 enum OperandLegalization { |
| 137 Legal_None = 0, | 138 Legal_None = 0, |
| 138 Legal_Reg = 1 << 0, // physical register, not stack location | 139 Legal_Reg = 1 << 0, /// physical register, not stack location |
| 139 Legal_Flex = 1 << 1, // A flexible operand2, which can hold rotated | 140 Legal_Flex = 1 << 1, /// A flexible operand2, which can hold rotated |
| 140 // small immediates, or shifted registers. | 141 /// small immediates, or shifted registers. |
| 141 Legal_Mem = 1 << 2, // includes [r0, r1 lsl #2] as well as [sp, #12] | 142 Legal_Mem = 1 << 2, /// includes [r0, r1 lsl #2] as well as [sp, #12] |
| 142 Legal_All = ~Legal_None | 143 Legal_All = ~Legal_None |
| 143 }; | 144 }; |
| 144 typedef uint32_t LegalMask; | 145 typedef uint32_t LegalMask; |
| 145 Operand *legalize(Operand *From, LegalMask Allowed = Legal_All, | 146 Operand *legalize(Operand *From, LegalMask Allowed = Legal_All, |
| 146 int32_t RegNum = Variable::NoRegister); | 147 int32_t RegNum = Variable::NoRegister); |
| 147 Variable *legalizeToVar(Operand *From, int32_t RegNum = Variable::NoRegister); | 148 Variable *legalizeToVar(Operand *From, int32_t RegNum = Variable::NoRegister); |
| 148 OperandARM32Mem *formMemoryOperand(Operand *Ptr, Type Ty); | 149 OperandARM32Mem *formMemoryOperand(Operand *Ptr, Type Ty); |
| 149 | 150 |
| 150 Variable *makeReg(Type Ty, int32_t RegNum = Variable::NoRegister); | 151 Variable *makeReg(Type Ty, int32_t RegNum = Variable::NoRegister); |
| 151 static Type stackSlotType(); | 152 static Type stackSlotType(); |
| 152 Variable *copyToReg(Operand *Src, int32_t RegNum = Variable::NoRegister); | 153 Variable *copyToReg(Operand *Src, int32_t RegNum = Variable::NoRegister); |
| 153 void alignRegisterPow2(Variable *Reg, uint32_t Align); | 154 void alignRegisterPow2(Variable *Reg, uint32_t Align); |
| 154 | 155 |
| 155 // Returns a vector in a register with the given constant entries. | 156 /// Returns a vector in a register with the given constant entries. |
| 156 Variable *makeVectorOfZeros(Type Ty, int32_t RegNum = Variable::NoRegister); | 157 Variable *makeVectorOfZeros(Type Ty, int32_t RegNum = Variable::NoRegister); |
| 157 | 158 |
| 158 void makeRandomRegisterPermutation( | 159 void makeRandomRegisterPermutation( |
| 159 llvm::SmallVectorImpl<int32_t> &Permutation, | 160 llvm::SmallVectorImpl<int32_t> &Permutation, |
| 160 const llvm::SmallBitVector &ExcludeRegisters) const override; | 161 const llvm::SmallBitVector &ExcludeRegisters) const override; |
| 161 | 162 |
| 162 // If a divide-by-zero check is needed, inserts a: | 163 // If a divide-by-zero check is needed, inserts a: |
| 163 // test; branch .LSKIP; trap; .LSKIP: <continuation>. | 164 // test; branch .LSKIP; trap; .LSKIP: <continuation>. |
| 164 // If no check is needed nothing is inserted. | 165 // If no check is needed nothing is inserted. |
| 165 void div0Check(Type Ty, Operand *SrcLo, Operand *SrcHi); | 166 void div0Check(Type Ty, Operand *SrcLo, Operand *SrcHi); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 240 Context.insert(InstARM32Lsr::create(Func, Dest, Src0, Src1, Pred)); | 241 Context.insert(InstARM32Lsr::create(Func, Dest, Src0, Src1, Pred)); |
| 241 } | 242 } |
| 242 void _mla(Variable *Dest, Variable *Src0, Variable *Src1, Variable *Acc, | 243 void _mla(Variable *Dest, Variable *Src0, Variable *Src1, Variable *Acc, |
| 243 CondARM32::Cond Pred = CondARM32::AL) { | 244 CondARM32::Cond Pred = CondARM32::AL) { |
| 244 Context.insert(InstARM32Mla::create(Func, Dest, Src0, Src1, Acc, Pred)); | 245 Context.insert(InstARM32Mla::create(Func, Dest, Src0, Src1, Acc, Pred)); |
| 245 } | 246 } |
| 246 void _mls(Variable *Dest, Variable *Src0, Variable *Src1, Variable *Acc, | 247 void _mls(Variable *Dest, Variable *Src0, Variable *Src1, Variable *Acc, |
| 247 CondARM32::Cond Pred = CondARM32::AL) { | 248 CondARM32::Cond Pred = CondARM32::AL) { |
| 248 Context.insert(InstARM32Mls::create(Func, Dest, Src0, Src1, Acc, Pred)); | 249 Context.insert(InstARM32Mls::create(Func, Dest, Src0, Src1, Acc, Pred)); |
| 249 } | 250 } |
| 250 // If Dest=nullptr is passed in, then a new variable is created, | 251 /// If Dest=nullptr is passed in, then a new variable is created, |
| 251 // marked as infinite register allocation weight, and returned | 252 /// marked as infinite register allocation weight, and returned |
| 252 // through the in/out Dest argument. | 253 /// through the in/out Dest argument. |
| 253 void _mov(Variable *&Dest, Operand *Src0, | 254 void _mov(Variable *&Dest, Operand *Src0, |
| 254 CondARM32::Cond Pred = CondARM32::AL, | 255 CondARM32::Cond Pred = CondARM32::AL, |
| 255 int32_t RegNum = Variable::NoRegister) { | 256 int32_t RegNum = Variable::NoRegister) { |
| 256 if (Dest == nullptr) | 257 if (Dest == nullptr) |
| 257 Dest = makeReg(Src0->getType(), RegNum); | 258 Dest = makeReg(Src0->getType(), RegNum); |
| 258 Context.insert(InstARM32Mov::create(Func, Dest, Src0, Pred)); | 259 Context.insert(InstARM32Mov::create(Func, Dest, Src0, Pred)); |
| 259 } | 260 } |
| 260 void _mov_nonkillable(Variable *Dest, Operand *Src0, | 261 void _mov_nonkillable(Variable *Dest, Operand *Src0, |
| 261 CondARM32::Cond Pred = CondARM32::AL) { | 262 CondARM32::Cond Pred = CondARM32::AL) { |
| 262 Inst *NewInst = InstARM32Mov::create(Func, Dest, Src0, Pred); | 263 Inst *NewInst = InstARM32Mov::create(Func, Dest, Src0, Pred); |
| 263 NewInst->setDestNonKillable(); | 264 NewInst->setDestNonKillable(); |
| 264 Context.insert(NewInst); | 265 Context.insert(NewInst); |
| 265 } | 266 } |
| 266 // The Operand can only be a 16-bit immediate or a ConstantRelocatable | 267 /// The Operand can only be a 16-bit immediate or a ConstantRelocatable |
| 267 // (with an upper16 relocation). | 268 /// (with an upper16 relocation). |
| 268 void _movt(Variable *Dest, Operand *Src0, | 269 void _movt(Variable *Dest, Operand *Src0, |
| 269 CondARM32::Cond Pred = CondARM32::AL) { | 270 CondARM32::Cond Pred = CondARM32::AL) { |
| 270 Context.insert(InstARM32Movt::create(Func, Dest, Src0, Pred)); | 271 Context.insert(InstARM32Movt::create(Func, Dest, Src0, Pred)); |
| 271 } | 272 } |
| 272 void _movw(Variable *Dest, Operand *Src0, | 273 void _movw(Variable *Dest, Operand *Src0, |
| 273 CondARM32::Cond Pred = CondARM32::AL) { | 274 CondARM32::Cond Pred = CondARM32::AL) { |
| 274 Context.insert(InstARM32Movw::create(Func, Dest, Src0, Pred)); | 275 Context.insert(InstARM32Movw::create(Func, Dest, Src0, Pred)); |
| 275 } | 276 } |
| 276 void _mul(Variable *Dest, Variable *Src0, Variable *Src1, | 277 void _mul(Variable *Dest, Variable *Src0, Variable *Src1, |
| 277 CondARM32::Cond Pred = CondARM32::AL) { | 278 CondARM32::Cond Pred = CondARM32::AL) { |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 365 bool UsesFramePointer = false; | 366 bool UsesFramePointer = false; |
| 366 bool NeedsStackAlignment = false; | 367 bool NeedsStackAlignment = false; |
| 367 bool MaybeLeafFunc = true; | 368 bool MaybeLeafFunc = true; |
| 368 size_t SpillAreaSizeBytes = 0; | 369 size_t SpillAreaSizeBytes = 0; |
| 369 llvm::SmallBitVector TypeToRegisterSet[IceType_NUM]; | 370 llvm::SmallBitVector TypeToRegisterSet[IceType_NUM]; |
| 370 llvm::SmallBitVector ScratchRegs; | 371 llvm::SmallBitVector ScratchRegs; |
| 371 llvm::SmallBitVector RegsUsed; | 372 llvm::SmallBitVector RegsUsed; |
| 372 VarList PhysicalRegisters[IceType_NUM]; | 373 VarList PhysicalRegisters[IceType_NUM]; |
| 373 static IceString RegNames[]; | 374 static IceString RegNames[]; |
| 374 | 375 |
| 375 // Helper class that understands the Calling Convention and register | 376 /// Helper class that understands the Calling Convention and register |
| 376 // assignments. The first few integer type parameters can use r0-r3, | 377 /// assignments. The first few integer type parameters can use r0-r3, |
| 377 // regardless of their position relative to the floating-point/vector | 378 /// regardless of their position relative to the floating-point/vector |
| 378 // arguments in the argument list. Floating-point and vector arguments | 379 /// arguments in the argument list. Floating-point and vector arguments |
| 379 // can use q0-q3 (aka d0-d7, s0-s15). Technically, arguments that can | 380 /// can use q0-q3 (aka d0-d7, s0-s15). Technically, arguments that can |
| 380 // start with registers but extend beyond the available registers can be | 381 /// start with registers but extend beyond the available registers can be |
| 381 // split between the registers and the stack. However, this is typically | 382 /// split between the registers and the stack. However, this is typically |
| 382 // for passing GPR structs by value, and PNaCl transforms expand this out. | 383 /// for passing GPR structs by value, and PNaCl transforms expand this out. |
| 383 // | 384 /// |
| 384 // Also, at the point before the call, the stack must be aligned. | 385 /// Also, at the point before the call, the stack must be aligned. |
| 385 class CallingConv { | 386 class CallingConv { |
| 386 CallingConv(const CallingConv &) = delete; | 387 CallingConv(const CallingConv &) = delete; |
| 387 CallingConv &operator=(const CallingConv &) = delete; | 388 CallingConv &operator=(const CallingConv &) = delete; |
| 388 | 389 |
| 389 public: | 390 public: |
| 390 CallingConv() : NumGPRRegsUsed(0) {} | 391 CallingConv() : NumGPRRegsUsed(0) {} |
| 391 ~CallingConv() = default; | 392 ~CallingConv() = default; |
| 392 | 393 |
| 393 bool I64InRegs(std::pair<int32_t, int32_t> *Regs); | 394 bool I64InRegs(std::pair<int32_t, int32_t> *Regs); |
| 394 bool I32InReg(int32_t *Reg); | 395 bool I32InReg(int32_t *Reg); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 442 | 443 |
| 443 private: | 444 private: |
| 444 ~TargetHeaderARM32() = default; | 445 ~TargetHeaderARM32() = default; |
| 445 | 446 |
| 446 TargetARM32Features CPUFeatures; | 447 TargetARM32Features CPUFeatures; |
| 447 }; | 448 }; |
| 448 | 449 |
| 449 } // end of namespace Ice | 450 } // end of namespace Ice |
| 450 | 451 |
| 451 #endif // SUBZERO_SRC_ICETARGETLOWERINGARM32_H | 452 #endif // SUBZERO_SRC_ICETARGETLOWERINGARM32_H |
| OLD | NEW |