| 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 // This file declares the TargetLoweringARM32 class, which implements the |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 59 void emit(const ConstantUndef *C) const final; | 59 void emit(const ConstantUndef *C) const final; |
| 60 void emit(const ConstantInteger32 *C) const final; | 60 void emit(const ConstantInteger32 *C) const final; |
| 61 void emit(const ConstantInteger64 *C) const final; | 61 void emit(const ConstantInteger64 *C) const final; |
| 62 void emit(const ConstantFloat *C) const final; | 62 void emit(const ConstantFloat *C) const final; |
| 63 void emit(const ConstantDouble *C) const final; | 63 void emit(const ConstantDouble *C) const final; |
| 64 | 64 |
| 65 void lowerArguments() override; | 65 void lowerArguments() override; |
| 66 void addProlog(CfgNode *Node) override; | 66 void addProlog(CfgNode *Node) override; |
| 67 void addEpilog(CfgNode *Node) override; | 67 void addEpilog(CfgNode *Node) override; |
| 68 | 68 |
| 69 // Ensure that a 64-bit Variable has been split into 2 32-bit | 69 /// Ensure that a 64-bit Variable has been split into 2 32-bit |
| 70 // Variables, creating them if necessary. This is needed for all | 70 /// Variables, creating them if necessary. This is needed for all |
| 71 // I64 operations. | 71 /// I64 operations. |
| 72 void split64(Variable *Var); | 72 void split64(Variable *Var); |
| 73 Operand *loOperand(Operand *Operand); | 73 Operand *loOperand(Operand *Operand); |
| 74 Operand *hiOperand(Operand *Operand); | 74 Operand *hiOperand(Operand *Operand); |
| 75 void finishArgumentLowering(Variable *Arg, Variable *FramePtr, | 75 void finishArgumentLowering(Variable *Arg, Variable *FramePtr, |
| 76 size_t BasicFrameOffset, size_t &InArgsSizeBytes); | 76 size_t BasicFrameOffset, size_t &InArgsSizeBytes); |
| 77 | 77 |
| 78 enum ARM32InstructionSet { | 78 enum ARM32InstructionSet { |
| 79 Begin, | 79 Begin, |
| 80 // Neon is the PNaCl baseline instruction set. | 80 // Neon is the PNaCl baseline instruction set. |
| 81 Neon = Begin, | 81 Neon = Begin, |
| (...skipping 28 matching lines...) Expand all Loading... |
| 110 void lowerUnreachable(const InstUnreachable *Inst) override; | 110 void lowerUnreachable(const InstUnreachable *Inst) override; |
| 111 void prelowerPhis() override; | 111 void prelowerPhis() override; |
| 112 void lowerPhiAssignments(CfgNode *Node, | 112 void lowerPhiAssignments(CfgNode *Node, |
| 113 const AssignList &Assignments) override; | 113 const AssignList &Assignments) override; |
| 114 void doAddressOptLoad() override; | 114 void doAddressOptLoad() override; |
| 115 void doAddressOptStore() override; | 115 void doAddressOptStore() override; |
| 116 void randomlyInsertNop(float Probability) override; | 116 void randomlyInsertNop(float Probability) override; |
| 117 | 117 |
| 118 enum OperandLegalization { | 118 enum OperandLegalization { |
| 119 Legal_None = 0, | 119 Legal_None = 0, |
| 120 Legal_Reg = 1 << 0, // physical register, not stack location | 120 Legal_Reg = 1 << 0, /// physical register, not stack location |
| 121 Legal_Flex = 1 << 1, // A flexible operand2, which can hold rotated | 121 Legal_Flex = 1 << 1, /// A flexible operand2, which can hold rotated |
| 122 // small immediates, or shifted registers. | 122 /// small immediates, or shifted registers. |
| 123 Legal_Mem = 1 << 2, // includes [r0, r1 lsl #2] as well as [sp, #12] | 123 Legal_Mem = 1 << 2, /// includes [r0, r1 lsl #2] as well as [sp, #12] |
| 124 Legal_All = ~Legal_None | 124 Legal_All = ~Legal_None |
| 125 }; | 125 }; |
| 126 typedef uint32_t LegalMask; | 126 typedef uint32_t LegalMask; |
| 127 Operand *legalize(Operand *From, LegalMask Allowed = Legal_All, | 127 Operand *legalize(Operand *From, LegalMask Allowed = Legal_All, |
| 128 int32_t RegNum = Variable::NoRegister); | 128 int32_t RegNum = Variable::NoRegister); |
| 129 Variable *legalizeToVar(Operand *From, int32_t RegNum = Variable::NoRegister); | 129 Variable *legalizeToVar(Operand *From, int32_t RegNum = Variable::NoRegister); |
| 130 OperandARM32Mem *formMemoryOperand(Operand *Ptr, Type Ty); | 130 OperandARM32Mem *formMemoryOperand(Operand *Ptr, Type Ty); |
| 131 | 131 |
| 132 Variable *makeReg(Type Ty, int32_t RegNum = Variable::NoRegister); | 132 Variable *makeReg(Type Ty, int32_t RegNum = Variable::NoRegister); |
| 133 static Type stackSlotType(); | 133 static Type stackSlotType(); |
| 134 Variable *copyToReg(Operand *Src, int32_t RegNum = Variable::NoRegister); | 134 Variable *copyToReg(Operand *Src, int32_t RegNum = Variable::NoRegister); |
| 135 void alignRegisterPow2(Variable *Reg, uint32_t Align); | 135 void alignRegisterPow2(Variable *Reg, uint32_t Align); |
| 136 | 136 |
| 137 // Returns a vector in a register with the given constant entries. | 137 /// Returns a vector in a register with the given constant entries. |
| 138 Variable *makeVectorOfZeros(Type Ty, int32_t RegNum = Variable::NoRegister); | 138 Variable *makeVectorOfZeros(Type Ty, int32_t RegNum = Variable::NoRegister); |
| 139 | 139 |
| 140 void makeRandomRegisterPermutation( | 140 void makeRandomRegisterPermutation( |
| 141 llvm::SmallVectorImpl<int32_t> &Permutation, | 141 llvm::SmallVectorImpl<int32_t> &Permutation, |
| 142 const llvm::SmallBitVector &ExcludeRegisters) const override; | 142 const llvm::SmallBitVector &ExcludeRegisters) const override; |
| 143 | 143 |
| 144 // The following are helpers that insert lowered ARM32 instructions | 144 // The following are helpers that insert lowered ARM32 instructions |
| 145 // with minimal syntactic overhead, so that the lowering code can | 145 // with minimal syntactic overhead, so that the lowering code can |
| 146 // look as close to assembly as practical. | 146 // look as close to assembly as practical. |
| 147 | 147 |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 200 Context.insert(InstARM32Lsl::create(Func, Dest, Src0, Src1, Pred)); | 200 Context.insert(InstARM32Lsl::create(Func, Dest, Src0, Src1, Pred)); |
| 201 } | 201 } |
| 202 void _lsr(Variable *Dest, Variable *Src0, Operand *Src1, | 202 void _lsr(Variable *Dest, Variable *Src0, Operand *Src1, |
| 203 CondARM32::Cond Pred = CondARM32::AL) { | 203 CondARM32::Cond Pred = CondARM32::AL) { |
| 204 Context.insert(InstARM32Lsr::create(Func, Dest, Src0, Src1, Pred)); | 204 Context.insert(InstARM32Lsr::create(Func, Dest, Src0, Src1, Pred)); |
| 205 } | 205 } |
| 206 void _mla(Variable *Dest, Variable *Src0, Variable *Src1, Variable *Acc, | 206 void _mla(Variable *Dest, Variable *Src0, Variable *Src1, Variable *Acc, |
| 207 CondARM32::Cond Pred = CondARM32::AL) { | 207 CondARM32::Cond Pred = CondARM32::AL) { |
| 208 Context.insert(InstARM32Mla::create(Func, Dest, Src0, Src1, Acc, Pred)); | 208 Context.insert(InstARM32Mla::create(Func, Dest, Src0, Src1, Acc, Pred)); |
| 209 } | 209 } |
| 210 // If Dest=nullptr is passed in, then a new variable is created, | 210 /// If Dest=nullptr is passed in, then a new variable is created, |
| 211 // marked as infinite register allocation weight, and returned | 211 /// marked as infinite register allocation weight, and returned |
| 212 // through the in/out Dest argument. | 212 /// through the in/out Dest argument. |
| 213 void _mov(Variable *&Dest, Operand *Src0, | 213 void _mov(Variable *&Dest, Operand *Src0, |
| 214 CondARM32::Cond Pred = CondARM32::AL, | 214 CondARM32::Cond Pred = CondARM32::AL, |
| 215 int32_t RegNum = Variable::NoRegister) { | 215 int32_t RegNum = Variable::NoRegister) { |
| 216 if (Dest == nullptr) | 216 if (Dest == nullptr) |
| 217 Dest = makeReg(Src0->getType(), RegNum); | 217 Dest = makeReg(Src0->getType(), RegNum); |
| 218 Context.insert(InstARM32Mov::create(Func, Dest, Src0, Pred)); | 218 Context.insert(InstARM32Mov::create(Func, Dest, Src0, Pred)); |
| 219 } | 219 } |
| 220 void _mov_nonkillable(Variable *Dest, Operand *Src0, | 220 void _mov_nonkillable(Variable *Dest, Operand *Src0, |
| 221 CondARM32::Cond Pred = CondARM32::AL) { | 221 CondARM32::Cond Pred = CondARM32::AL) { |
| 222 Inst *NewInst = InstARM32Mov::create(Func, Dest, Src0, Pred); | 222 Inst *NewInst = InstARM32Mov::create(Func, Dest, Src0, Pred); |
| 223 NewInst->setDestNonKillable(); | 223 NewInst->setDestNonKillable(); |
| 224 Context.insert(NewInst); | 224 Context.insert(NewInst); |
| 225 } | 225 } |
| 226 // The Operand can only be a 16-bit immediate or a ConstantRelocatable | 226 /// The Operand can only be a 16-bit immediate or a ConstantRelocatable |
| 227 // (with an upper16 relocation). | 227 /// (with an upper16 relocation). |
| 228 void _movt(Variable *Dest, Operand *Src0, | 228 void _movt(Variable *Dest, Operand *Src0, |
| 229 CondARM32::Cond Pred = CondARM32::AL) { | 229 CondARM32::Cond Pred = CondARM32::AL) { |
| 230 Context.insert(InstARM32Movt::create(Func, Dest, Src0, Pred)); | 230 Context.insert(InstARM32Movt::create(Func, Dest, Src0, Pred)); |
| 231 } | 231 } |
| 232 void _movw(Variable *Dest, Operand *Src0, | 232 void _movw(Variable *Dest, Operand *Src0, |
| 233 CondARM32::Cond Pred = CondARM32::AL) { | 233 CondARM32::Cond Pred = CondARM32::AL) { |
| 234 Context.insert(InstARM32Movw::create(Func, Dest, Src0, Pred)); | 234 Context.insert(InstARM32Movw::create(Func, Dest, Src0, Pred)); |
| 235 } | 235 } |
| 236 void _mul(Variable *Dest, Variable *Src0, Variable *Src1, | 236 void _mul(Variable *Dest, Variable *Src0, Variable *Src1, |
| 237 CondARM32::Cond Pred = CondARM32::AL) { | 237 CondARM32::Cond Pred = CondARM32::AL) { |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 306 bool UsesFramePointer = false; | 306 bool UsesFramePointer = false; |
| 307 bool NeedsStackAlignment = false; | 307 bool NeedsStackAlignment = false; |
| 308 bool MaybeLeafFunc = true; | 308 bool MaybeLeafFunc = true; |
| 309 size_t SpillAreaSizeBytes = 0; | 309 size_t SpillAreaSizeBytes = 0; |
| 310 llvm::SmallBitVector TypeToRegisterSet[IceType_NUM]; | 310 llvm::SmallBitVector TypeToRegisterSet[IceType_NUM]; |
| 311 llvm::SmallBitVector ScratchRegs; | 311 llvm::SmallBitVector ScratchRegs; |
| 312 llvm::SmallBitVector RegsUsed; | 312 llvm::SmallBitVector RegsUsed; |
| 313 VarList PhysicalRegisters[IceType_NUM]; | 313 VarList PhysicalRegisters[IceType_NUM]; |
| 314 static IceString RegNames[]; | 314 static IceString RegNames[]; |
| 315 | 315 |
| 316 // Helper class that understands the Calling Convention and register | 316 /// Helper class that understands the Calling Convention and register |
| 317 // assignments. The first few integer type parameters can use r0-r3, | 317 /// assignments. The first few integer type parameters can use r0-r3, |
| 318 // regardless of their position relative to the floating-point/vector | 318 /// regardless of their position relative to the floating-point/vector |
| 319 // arguments in the argument list. Floating-point and vector arguments | 319 /// arguments in the argument list. Floating-point and vector arguments |
| 320 // can use q0-q3 (aka d0-d7, s0-s15). Technically, arguments that can | 320 /// can use q0-q3 (aka d0-d7, s0-s15). Technically, arguments that can |
| 321 // start with registers but extend beyond the available registers can be | 321 /// start with registers but extend beyond the available registers can be |
| 322 // split between the registers and the stack. However, this is typically | 322 /// split between the registers and the stack. However, this is typically |
| 323 // for passing GPR structs by value, and PNaCl transforms expand this out. | 323 /// for passing GPR structs by value, and PNaCl transforms expand this out. |
| 324 // | 324 /// |
| 325 // Also, at the point before the call, the stack must be aligned. | 325 /// Also, at the point before the call, the stack must be aligned. |
| 326 class CallingConv { | 326 class CallingConv { |
| 327 CallingConv(const CallingConv &) = delete; | 327 CallingConv(const CallingConv &) = delete; |
| 328 CallingConv &operator=(const CallingConv &) = delete; | 328 CallingConv &operator=(const CallingConv &) = delete; |
| 329 | 329 |
| 330 public: | 330 public: |
| 331 CallingConv() : NumGPRRegsUsed(0) {} | 331 CallingConv() : NumGPRRegsUsed(0) {} |
| 332 ~CallingConv() = default; | 332 ~CallingConv() = default; |
| 333 | 333 |
| 334 bool I64InRegs(std::pair<int32_t, int32_t> *Regs); | 334 bool I64InRegs(std::pair<int32_t, int32_t> *Regs); |
| 335 bool I32InReg(int32_t *Reg); | 335 bool I32InReg(int32_t *Reg); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 381 protected: | 381 protected: |
| 382 explicit TargetHeaderARM32(GlobalContext *Ctx); | 382 explicit TargetHeaderARM32(GlobalContext *Ctx); |
| 383 | 383 |
| 384 private: | 384 private: |
| 385 ~TargetHeaderARM32() = default; | 385 ~TargetHeaderARM32() = default; |
| 386 }; | 386 }; |
| 387 | 387 |
| 388 } // end of namespace Ice | 388 } // end of namespace Ice |
| 389 | 389 |
| 390 #endif // SUBZERO_SRC_ICETARGETLOWERINGARM32_H | 390 #endif // SUBZERO_SRC_ICETARGETLOWERINGARM32_H |
| OLD | NEW |