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