| 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 |
| 11 // TargetLowering interface for the ARM 32-bit architecture. | 11 // TargetLowering interface for the ARM 32-bit architecture. |
| 12 // | 12 // |
| 13 //===----------------------------------------------------------------------===// | 13 //===----------------------------------------------------------------------===// |
| 14 | 14 |
| 15 #ifndef SUBZERO_SRC_ICETARGETLOWERINGARM32_H | 15 #ifndef SUBZERO_SRC_ICETARGETLOWERINGARM32_H |
| 16 #define SUBZERO_SRC_ICETARGETLOWERINGARM32_H | 16 #define SUBZERO_SRC_ICETARGETLOWERINGARM32_H |
| 17 | 17 |
| 18 #include "IceDefs.h" | 18 #include "IceDefs.h" |
| 19 #include "IceInstARM32.h" | 19 #include "IceInstARM32.h" |
| 20 #include "IceRegistersARM32.h" | 20 #include "IceRegistersARM32.h" |
| 21 #include "IceTargetLowering.h" | 21 #include "IceTargetLowering.h" |
| 22 | 22 |
| 23 namespace Ice { | 23 namespace Ice { |
| 24 | 24 |
| 25 // Class encapsulating ARM cpu features / instruction set.. |
| 26 class TargetARM32Features { |
| 27 TargetARM32Features() = delete; |
| 28 TargetARM32Features(const TargetARM32Features &) = delete; |
| 29 TargetARM32Features &operator=(const TargetARM32Features &) = delete; |
| 30 |
| 31 public: |
| 32 explicit TargetARM32Features(const ClFlags &Flags); |
| 33 |
| 34 enum ARM32InstructionSet { |
| 35 Begin, |
| 36 // Neon is the PNaCl baseline instruction set. |
| 37 Neon = Begin, |
| 38 HWDivArm, // HW divide in ARM mode (not just Thumb mode). |
| 39 End |
| 40 }; |
| 41 |
| 42 bool hasFeature(ARM32InstructionSet I) const { return I <= InstructionSet; } |
| 43 |
| 44 private: |
| 45 ARM32InstructionSet InstructionSet = ARM32InstructionSet::Begin; |
| 46 }; |
| 47 |
| 48 // The target lowering logic for ARM32. |
| 25 class TargetARM32 : public TargetLowering { | 49 class TargetARM32 : public TargetLowering { |
| 26 TargetARM32() = delete; | 50 TargetARM32() = delete; |
| 27 TargetARM32(const TargetARM32 &) = delete; | 51 TargetARM32(const TargetARM32 &) = delete; |
| 28 TargetARM32 &operator=(const TargetARM32 &) = delete; | 52 TargetARM32 &operator=(const TargetARM32 &) = delete; |
| 29 | 53 |
| 30 public: | 54 public: |
| 31 // TODO(jvoung): return a unique_ptr. | 55 // TODO(jvoung): return a unique_ptr. |
| 32 static TargetARM32 *create(Cfg *Func) { return new TargetARM32(Func); } | 56 static TargetARM32 *create(Cfg *Func) { return new TargetARM32(Func); } |
| 33 | 57 |
| 34 void translateOm1() override; | 58 void translateOm1() override; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 68 | 92 |
| 69 // Ensure that a 64-bit Variable has been split into 2 32-bit | 93 // Ensure that a 64-bit Variable has been split into 2 32-bit |
| 70 // Variables, creating them if necessary. This is needed for all | 94 // Variables, creating them if necessary. This is needed for all |
| 71 // I64 operations. | 95 // I64 operations. |
| 72 void split64(Variable *Var); | 96 void split64(Variable *Var); |
| 73 Operand *loOperand(Operand *Operand); | 97 Operand *loOperand(Operand *Operand); |
| 74 Operand *hiOperand(Operand *Operand); | 98 Operand *hiOperand(Operand *Operand); |
| 75 void finishArgumentLowering(Variable *Arg, Variable *FramePtr, | 99 void finishArgumentLowering(Variable *Arg, Variable *FramePtr, |
| 76 size_t BasicFrameOffset, size_t &InArgsSizeBytes); | 100 size_t BasicFrameOffset, size_t &InArgsSizeBytes); |
| 77 | 101 |
| 78 enum ARM32InstructionSet { | 102 bool hasCPUFeature(TargetARM32Features::ARM32InstructionSet I) const { |
| 79 Begin, | 103 return CPUFeatures.hasFeature(I); |
| 80 // Neon is the PNaCl baseline instruction set. | 104 } |
| 81 Neon = Begin, | |
| 82 HWDivArm, // HW divide in ARM mode (not just Thumb mode). | |
| 83 End | |
| 84 }; | |
| 85 | |
| 86 ARM32InstructionSet getInstructionSet() const { return InstructionSet; } | |
| 87 | 105 |
| 88 protected: | 106 protected: |
| 89 explicit TargetARM32(Cfg *Func); | 107 explicit TargetARM32(Cfg *Func); |
| 90 | 108 |
| 91 void postLower() override; | 109 void postLower() override; |
| 92 | 110 |
| 93 void lowerAlloca(const InstAlloca *Inst) override; | 111 void lowerAlloca(const InstAlloca *Inst) override; |
| 94 void lowerArithmetic(const InstArithmetic *Inst) override; | 112 void lowerArithmetic(const InstArithmetic *Inst) override; |
| 95 void lowerAssign(const InstAssign *Inst) override; | 113 void lowerAssign(const InstAssign *Inst) override; |
| 96 void lowerBr(const InstBr *Inst) override; | 114 void lowerBr(const InstBr *Inst) override; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 108 void lowerStore(const InstStore *Inst) override; | 126 void lowerStore(const InstStore *Inst) override; |
| 109 void lowerSwitch(const InstSwitch *Inst) override; | 127 void lowerSwitch(const InstSwitch *Inst) override; |
| 110 void lowerUnreachable(const InstUnreachable *Inst) override; | 128 void lowerUnreachable(const InstUnreachable *Inst) override; |
| 111 void prelowerPhis() override; | 129 void prelowerPhis() override; |
| 112 void lowerPhiAssignments(CfgNode *Node, | 130 void lowerPhiAssignments(CfgNode *Node, |
| 113 const AssignList &Assignments) override; | 131 const AssignList &Assignments) override; |
| 114 void doAddressOptLoad() override; | 132 void doAddressOptLoad() override; |
| 115 void doAddressOptStore() override; | 133 void doAddressOptStore() override; |
| 116 void randomlyInsertNop(float Probability) override; | 134 void randomlyInsertNop(float Probability) override; |
| 117 | 135 |
| 136 typedef void (TargetARM32::*ExtInstr)(Variable *, Variable *, |
| 137 CondARM32::Cond); |
| 138 typedef void (TargetARM32::*DivInstr)(Variable *, Variable *, Variable *, |
| 139 CondARM32::Cond); |
| 140 void lowerIDivRem(Variable *Dest, Variable *T, Variable *Src0R, Operand *Src1, |
| 141 ExtInstr ExtFunc, DivInstr DivFunc, |
| 142 const char *DivHelperName, bool IsRemainder); |
| 143 |
| 118 enum OperandLegalization { | 144 enum OperandLegalization { |
| 119 Legal_None = 0, | 145 Legal_None = 0, |
| 120 Legal_Reg = 1 << 0, // physical register, not stack location | 146 Legal_Reg = 1 << 0, // physical register, not stack location |
| 121 Legal_Flex = 1 << 1, // A flexible operand2, which can hold rotated | 147 Legal_Flex = 1 << 1, // A flexible operand2, which can hold rotated |
| 122 // small immediates, or shifted registers. | 148 // small immediates, or shifted registers. |
| 123 Legal_Mem = 1 << 2, // includes [r0, r1 lsl #2] as well as [sp, #12] | 149 Legal_Mem = 1 << 2, // includes [r0, r1 lsl #2] as well as [sp, #12] |
| 124 Legal_All = ~Legal_None | 150 Legal_All = ~Legal_None |
| 125 }; | 151 }; |
| 126 typedef uint32_t LegalMask; | 152 typedef uint32_t LegalMask; |
| 127 Operand *legalize(Operand *From, LegalMask Allowed = Legal_All, | 153 Operand *legalize(Operand *From, LegalMask Allowed = Legal_All, |
| 128 int32_t RegNum = Variable::NoRegister); | 154 int32_t RegNum = Variable::NoRegister); |
| 129 Variable *legalizeToVar(Operand *From, int32_t RegNum = Variable::NoRegister); | 155 Variable *legalizeToVar(Operand *From, int32_t RegNum = Variable::NoRegister); |
| 130 OperandARM32Mem *formMemoryOperand(Operand *Ptr, Type Ty); | 156 OperandARM32Mem *formMemoryOperand(Operand *Ptr, Type Ty); |
| 131 | 157 |
| 132 Variable *makeReg(Type Ty, int32_t RegNum = Variable::NoRegister); | 158 Variable *makeReg(Type Ty, int32_t RegNum = Variable::NoRegister); |
| 133 static Type stackSlotType(); | 159 static Type stackSlotType(); |
| 134 Variable *copyToReg(Operand *Src, int32_t RegNum = Variable::NoRegister); | 160 Variable *copyToReg(Operand *Src, int32_t RegNum = Variable::NoRegister); |
| 135 void alignRegisterPow2(Variable *Reg, uint32_t Align); | 161 void alignRegisterPow2(Variable *Reg, uint32_t Align); |
| 136 | 162 |
| 137 // Returns a vector in a register with the given constant entries. | 163 // Returns a vector in a register with the given constant entries. |
| 138 Variable *makeVectorOfZeros(Type Ty, int32_t RegNum = Variable::NoRegister); | 164 Variable *makeVectorOfZeros(Type Ty, int32_t RegNum = Variable::NoRegister); |
| 139 | 165 |
| 140 void makeRandomRegisterPermutation( | 166 void makeRandomRegisterPermutation( |
| 141 llvm::SmallVectorImpl<int32_t> &Permutation, | 167 llvm::SmallVectorImpl<int32_t> &Permutation, |
| 142 const llvm::SmallBitVector &ExcludeRegisters) const override; | 168 const llvm::SmallBitVector &ExcludeRegisters) const override; |
| 143 | 169 |
| 170 // If a divide-by-zero check is needed, inserts the test and branch |
| 171 // then returns the label for the target of the branch. |
| 172 // If no check is needed, returns nullptr. |
| 173 InstARM32Label *beginDiv0Check(Type Ty, Operand *SrcLo, Operand *SrcHi); |
| 174 // If a divide-by-zero check is needed (CheckLabel is non-zero), inserts |
| 175 // a local branch target with a trap as the body. |
| 176 void endDiv0Check(InstARM32Label *CheckLabel); |
| 177 |
| 144 // The following are helpers that insert lowered ARM32 instructions | 178 // The following are helpers that insert lowered ARM32 instructions |
| 145 // with minimal syntactic overhead, so that the lowering code can | 179 // with minimal syntactic overhead, so that the lowering code can |
| 146 // look as close to assembly as practical. | 180 // look as close to assembly as practical. |
| 147 | 181 |
| 148 void _add(Variable *Dest, Variable *Src0, Operand *Src1, | 182 void _add(Variable *Dest, Variable *Src0, Operand *Src1, |
| 149 CondARM32::Cond Pred = CondARM32::AL) { | 183 CondARM32::Cond Pred = CondARM32::AL) { |
| 150 Context.insert(InstARM32Add::create(Func, Dest, Src0, Src1, Pred)); | 184 Context.insert(InstARM32Add::create(Func, Dest, Src0, Src1, Pred)); |
| 151 } | 185 } |
| 152 void _adds(Variable *Dest, Variable *Src0, Operand *Src1, | 186 void _adds(Variable *Dest, Variable *Src0, Operand *Src1, |
| 153 CondARM32::Cond Pred = CondARM32::AL) { | 187 CondARM32::Cond Pred = CondARM32::AL) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 168 Context.insert(InstARM32And::create(Func, Dest, Src0, Src1, Pred)); | 202 Context.insert(InstARM32And::create(Func, Dest, Src0, Src1, Pred)); |
| 169 } | 203 } |
| 170 void _asr(Variable *Dest, Variable *Src0, Operand *Src1, | 204 void _asr(Variable *Dest, Variable *Src0, Operand *Src1, |
| 171 CondARM32::Cond Pred = CondARM32::AL) { | 205 CondARM32::Cond Pred = CondARM32::AL) { |
| 172 Context.insert(InstARM32Asr::create(Func, Dest, Src0, Src1, Pred)); | 206 Context.insert(InstARM32Asr::create(Func, Dest, Src0, Src1, Pred)); |
| 173 } | 207 } |
| 174 void _bic(Variable *Dest, Variable *Src0, Operand *Src1, | 208 void _bic(Variable *Dest, Variable *Src0, Operand *Src1, |
| 175 CondARM32::Cond Pred = CondARM32::AL) { | 209 CondARM32::Cond Pred = CondARM32::AL) { |
| 176 Context.insert(InstARM32Bic::create(Func, Dest, Src0, Src1, Pred)); | 210 Context.insert(InstARM32Bic::create(Func, Dest, Src0, Src1, Pred)); |
| 177 } | 211 } |
| 178 void _br(CondARM32::Cond Condition, CfgNode *TargetTrue, | 212 void _br(CfgNode *TargetTrue, CfgNode *TargetFalse, |
| 179 CfgNode *TargetFalse) { | 213 CondARM32::Cond Condition) { |
| 180 Context.insert( | 214 Context.insert( |
| 181 InstARM32Br::create(Func, TargetTrue, TargetFalse, Condition)); | 215 InstARM32Br::create(Func, TargetTrue, TargetFalse, Condition)); |
| 182 } | 216 } |
| 183 void _br(CfgNode *Target) { | 217 void _br(CfgNode *Target) { |
| 184 Context.insert(InstARM32Br::create(Func, Target)); | 218 Context.insert(InstARM32Br::create(Func, Target)); |
| 185 } | 219 } |
| 186 void _br(CfgNode *Target, CondARM32::Cond Condition) { | 220 void _br(CfgNode *Target, CondARM32::Cond Condition) { |
| 187 Context.insert(InstARM32Br::create(Func, Target, Condition)); | 221 Context.insert(InstARM32Br::create(Func, Target, Condition)); |
| 188 } | 222 } |
| 223 void _br(InstARM32Label *Label, CondARM32::Cond Condition) { |
| 224 Context.insert(InstARM32Br::create(Func, Label, Condition)); |
| 225 } |
| 189 void _cmp(Variable *Src0, Operand *Src1, | 226 void _cmp(Variable *Src0, Operand *Src1, |
| 190 CondARM32::Cond Pred = CondARM32::AL) { | 227 CondARM32::Cond Pred = CondARM32::AL) { |
| 191 Context.insert(InstARM32Cmp::create(Func, Src0, Src1, Pred)); | 228 Context.insert(InstARM32Cmp::create(Func, Src0, Src1, Pred)); |
| 192 } | 229 } |
| 193 void _eor(Variable *Dest, Variable *Src0, Operand *Src1, | 230 void _eor(Variable *Dest, Variable *Src0, Operand *Src1, |
| 194 CondARM32::Cond Pred = CondARM32::AL) { | 231 CondARM32::Cond Pred = CondARM32::AL) { |
| 195 Context.insert(InstARM32Eor::create(Func, Dest, Src0, Src1, Pred)); | 232 Context.insert(InstARM32Eor::create(Func, Dest, Src0, Src1, Pred)); |
| 196 } | 233 } |
| 197 void _ldr(Variable *Dest, OperandARM32Mem *Addr, | 234 void _ldr(Variable *Dest, OperandARM32Mem *Addr, |
| 198 CondARM32::Cond Pred = CondARM32::AL) { | 235 CondARM32::Cond Pred = CondARM32::AL) { |
| 199 Context.insert(InstARM32Ldr::create(Func, Dest, Addr, Pred)); | 236 Context.insert(InstARM32Ldr::create(Func, Dest, Addr, Pred)); |
| 200 } | 237 } |
| 201 void _lsl(Variable *Dest, Variable *Src0, Operand *Src1, | 238 void _lsl(Variable *Dest, Variable *Src0, Operand *Src1, |
| 202 CondARM32::Cond Pred = CondARM32::AL) { | 239 CondARM32::Cond Pred = CondARM32::AL) { |
| 203 Context.insert(InstARM32Lsl::create(Func, Dest, Src0, Src1, Pred)); | 240 Context.insert(InstARM32Lsl::create(Func, Dest, Src0, Src1, Pred)); |
| 204 } | 241 } |
| 205 void _lsr(Variable *Dest, Variable *Src0, Operand *Src1, | 242 void _lsr(Variable *Dest, Variable *Src0, Operand *Src1, |
| 206 CondARM32::Cond Pred = CondARM32::AL) { | 243 CondARM32::Cond Pred = CondARM32::AL) { |
| 207 Context.insert(InstARM32Lsr::create(Func, Dest, Src0, Src1, Pred)); | 244 Context.insert(InstARM32Lsr::create(Func, Dest, Src0, Src1, Pred)); |
| 208 } | 245 } |
| 209 void _mla(Variable *Dest, Variable *Src0, Variable *Src1, Variable *Acc, | 246 void _mla(Variable *Dest, Variable *Src0, Variable *Src1, Variable *Acc, |
| 210 CondARM32::Cond Pred = CondARM32::AL) { | 247 CondARM32::Cond Pred = CondARM32::AL) { |
| 211 Context.insert(InstARM32Mla::create(Func, Dest, Src0, Src1, Acc, Pred)); | 248 Context.insert(InstARM32Mla::create(Func, Dest, Src0, Src1, Acc, Pred)); |
| 212 } | 249 } |
| 250 void _mls(Variable *Dest, Variable *Src0, Variable *Src1, Variable *Acc, |
| 251 CondARM32::Cond Pred = CondARM32::AL) { |
| 252 Context.insert(InstARM32Mls::create(Func, Dest, Src0, Src1, Acc, Pred)); |
| 253 } |
| 213 // If Dest=nullptr is passed in, then a new variable is created, | 254 // If Dest=nullptr is passed in, then a new variable is created, |
| 214 // marked as infinite register allocation weight, and returned | 255 // marked as infinite register allocation weight, and returned |
| 215 // through the in/out Dest argument. | 256 // through the in/out Dest argument. |
| 216 void _mov(Variable *&Dest, Operand *Src0, | 257 void _mov(Variable *&Dest, Operand *Src0, |
| 217 CondARM32::Cond Pred = CondARM32::AL, | 258 CondARM32::Cond Pred = CondARM32::AL, |
| 218 int32_t RegNum = Variable::NoRegister) { | 259 int32_t RegNum = Variable::NoRegister) { |
| 219 if (Dest == nullptr) | 260 if (Dest == nullptr) |
| 220 Dest = makeReg(Src0->getType(), RegNum); | 261 Dest = makeReg(Src0->getType(), RegNum); |
| 221 Context.insert(InstARM32Mov::create(Func, Dest, Src0, Pred)); | 262 Context.insert(InstARM32Mov::create(Func, Dest, Src0, Pred)); |
| 222 } | 263 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 241 Context.insert(InstARM32Mul::create(Func, Dest, Src0, Src1, Pred)); | 282 Context.insert(InstARM32Mul::create(Func, Dest, Src0, Src1, Pred)); |
| 242 } | 283 } |
| 243 void _mvn(Variable *Dest, Operand *Src0, | 284 void _mvn(Variable *Dest, Operand *Src0, |
| 244 CondARM32::Cond Pred = CondARM32::AL) { | 285 CondARM32::Cond Pred = CondARM32::AL) { |
| 245 Context.insert(InstARM32Mvn::create(Func, Dest, Src0, Pred)); | 286 Context.insert(InstARM32Mvn::create(Func, Dest, Src0, Pred)); |
| 246 } | 287 } |
| 247 void _orr(Variable *Dest, Variable *Src0, Operand *Src1, | 288 void _orr(Variable *Dest, Variable *Src0, Operand *Src1, |
| 248 CondARM32::Cond Pred = CondARM32::AL) { | 289 CondARM32::Cond Pred = CondARM32::AL) { |
| 249 Context.insert(InstARM32Orr::create(Func, Dest, Src0, Src1, Pred)); | 290 Context.insert(InstARM32Orr::create(Func, Dest, Src0, Src1, Pred)); |
| 250 } | 291 } |
| 292 void _orrs(Variable *Dest, Variable *Src0, Operand *Src1, |
| 293 CondARM32::Cond Pred = CondARM32::AL) { |
| 294 const bool SetFlags = true; |
| 295 Context.insert( |
| 296 InstARM32Orr::create(Func, Dest, Src0, Src1, Pred, SetFlags)); |
| 297 } |
| 251 void _push(const VarList &Sources) { | 298 void _push(const VarList &Sources) { |
| 252 Context.insert(InstARM32Push::create(Func, Sources)); | 299 Context.insert(InstARM32Push::create(Func, Sources)); |
| 253 } | 300 } |
| 254 void _pop(const VarList &Dests) { | 301 void _pop(const VarList &Dests) { |
| 255 Context.insert(InstARM32Pop::create(Func, Dests)); | 302 Context.insert(InstARM32Pop::create(Func, Dests)); |
| 256 // Mark dests as modified. | 303 // Mark dests as modified. |
| 257 for (Variable *Dest : Dests) | 304 for (Variable *Dest : Dests) |
| 258 Context.insert(InstFakeDef::create(Func, Dest)); | 305 Context.insert(InstFakeDef::create(Func, Dest)); |
| 259 } | 306 } |
| 307 void _ret(Variable *LR, Variable *Src0 = nullptr) { |
| 308 Context.insert(InstARM32Ret::create(Func, LR, Src0)); |
| 309 } |
| 260 void _rsb(Variable *Dest, Variable *Src0, Operand *Src1, | 310 void _rsb(Variable *Dest, Variable *Src0, Operand *Src1, |
| 261 CondARM32::Cond Pred = CondARM32::AL) { | 311 CondARM32::Cond Pred = CondARM32::AL) { |
| 262 Context.insert(InstARM32Rsb::create(Func, Dest, Src0, Src1, Pred)); | 312 Context.insert(InstARM32Rsb::create(Func, Dest, Src0, Src1, Pred)); |
| 263 } | 313 } |
| 264 void _sbc(Variable *Dest, Variable *Src0, Operand *Src1, | 314 void _sbc(Variable *Dest, Variable *Src0, Operand *Src1, |
| 265 CondARM32::Cond Pred = CondARM32::AL) { | 315 CondARM32::Cond Pred = CondARM32::AL) { |
| 266 Context.insert(InstARM32Sbc::create(Func, Dest, Src0, Src1, Pred)); | 316 Context.insert(InstARM32Sbc::create(Func, Dest, Src0, Src1, Pred)); |
| 267 } | 317 } |
| 268 void _sbcs(Variable *Dest, Variable *Src0, Operand *Src1, | 318 void _sbcs(Variable *Dest, Variable *Src0, Operand *Src1, |
| 269 CondARM32::Cond Pred = CondARM32::AL) { | 319 CondARM32::Cond Pred = CondARM32::AL) { |
| 270 const bool SetFlags = true; | 320 const bool SetFlags = true; |
| 271 Context.insert( | 321 Context.insert( |
| 272 InstARM32Sbc::create(Func, Dest, Src0, Src1, Pred, SetFlags)); | 322 InstARM32Sbc::create(Func, Dest, Src0, Src1, Pred, SetFlags)); |
| 273 } | 323 } |
| 324 void _sdiv(Variable *Dest, Variable *Src0, Variable *Src1, |
| 325 CondARM32::Cond Pred = CondARM32::AL) { |
| 326 Context.insert(InstARM32Sdiv::create(Func, Dest, Src0, Src1, Pred)); |
| 327 } |
| 274 void _str(Variable *Value, OperandARM32Mem *Addr, | 328 void _str(Variable *Value, OperandARM32Mem *Addr, |
| 275 CondARM32::Cond Pred = CondARM32::AL) { | 329 CondARM32::Cond Pred = CondARM32::AL) { |
| 276 Context.insert(InstARM32Str::create(Func, Value, Addr, Pred)); | 330 Context.insert(InstARM32Str::create(Func, Value, Addr, Pred)); |
| 277 } | 331 } |
| 278 void _sub(Variable *Dest, Variable *Src0, Operand *Src1, | 332 void _sub(Variable *Dest, Variable *Src0, Operand *Src1, |
| 279 CondARM32::Cond Pred = CondARM32::AL) { | 333 CondARM32::Cond Pred = CondARM32::AL) { |
| 280 Context.insert(InstARM32Sub::create(Func, Dest, Src0, Src1, Pred)); | 334 Context.insert(InstARM32Sub::create(Func, Dest, Src0, Src1, Pred)); |
| 281 } | 335 } |
| 282 void _subs(Variable *Dest, Variable *Src0, Operand *Src1, | 336 void _subs(Variable *Dest, Variable *Src0, Operand *Src1, |
| 283 CondARM32::Cond Pred = CondARM32::AL) { | 337 CondARM32::Cond Pred = CondARM32::AL) { |
| 284 const bool SetFlags = true; | 338 const bool SetFlags = true; |
| 285 Context.insert( | 339 Context.insert( |
| 286 InstARM32Sub::create(Func, Dest, Src0, Src1, Pred, SetFlags)); | 340 InstARM32Sub::create(Func, Dest, Src0, Src1, Pred, SetFlags)); |
| 287 } | 341 } |
| 288 void _sxt(Variable *Dest, Variable *Src0, | 342 void _sxt(Variable *Dest, Variable *Src0, |
| 289 CondARM32::Cond Pred = CondARM32::AL) { | 343 CondARM32::Cond Pred = CondARM32::AL) { |
| 290 Context.insert(InstARM32Sxt::create(Func, Dest, Src0, Pred)); | 344 Context.insert(InstARM32Sxt::create(Func, Dest, Src0, Pred)); |
| 291 } | 345 } |
| 292 void _ret(Variable *LR, Variable *Src0 = nullptr) { | 346 void _tst(Variable *Src0, Operand *Src1, |
| 293 Context.insert(InstARM32Ret::create(Func, LR, Src0)); | 347 CondARM32::Cond Pred = CondARM32::AL) { |
| 348 Context.insert(InstARM32Tst::create(Func, Src0, Src1, Pred)); |
| 349 } |
| 350 void _trap() { Context.insert(InstARM32Trap::create(Func)); } |
| 351 void _udiv(Variable *Dest, Variable *Src0, Variable *Src1, |
| 352 CondARM32::Cond Pred = CondARM32::AL) { |
| 353 Context.insert(InstARM32Udiv::create(Func, Dest, Src0, Src1, Pred)); |
| 294 } | 354 } |
| 295 void _umull(Variable *DestLo, Variable *DestHi, Variable *Src0, | 355 void _umull(Variable *DestLo, Variable *DestHi, Variable *Src0, |
| 296 Variable *Src1, CondARM32::Cond Pred = CondARM32::AL) { | 356 Variable *Src1, CondARM32::Cond Pred = CondARM32::AL) { |
| 297 Context.insert( | 357 Context.insert( |
| 298 InstARM32Umull::create(Func, DestLo, DestHi, Src0, Src1, Pred)); | 358 InstARM32Umull::create(Func, DestLo, DestHi, Src0, Src1, Pred)); |
| 299 // Model the modification to the second dest as a fake def. | 359 // Model the modification to the second dest as a fake def. |
| 300 // Note that the def is not predicated. | 360 // Note that the def is not predicated. |
| 301 Context.insert(InstFakeDef::create(Func, DestHi, DestLo)); | 361 Context.insert(InstFakeDef::create(Func, DestHi, DestLo)); |
| 302 } | 362 } |
| 303 void _uxt(Variable *Dest, Variable *Src0, | 363 void _uxt(Variable *Dest, Variable *Src0, |
| 304 CondARM32::Cond Pred = CondARM32::AL) { | 364 CondARM32::Cond Pred = CondARM32::AL) { |
| 305 Context.insert(InstARM32Uxt::create(Func, Dest, Src0, Pred)); | 365 Context.insert(InstARM32Uxt::create(Func, Dest, Src0, Pred)); |
| 306 } | 366 } |
| 307 | 367 |
| 308 ARM32InstructionSet InstructionSet = ARM32InstructionSet::Begin; | 368 TargetARM32Features CPUFeatures; |
| 309 bool UsesFramePointer = false; | 369 bool UsesFramePointer = false; |
| 310 bool NeedsStackAlignment = false; | 370 bool NeedsStackAlignment = false; |
| 311 bool MaybeLeafFunc = true; | 371 bool MaybeLeafFunc = true; |
| 312 size_t SpillAreaSizeBytes = 0; | 372 size_t SpillAreaSizeBytes = 0; |
| 313 llvm::SmallBitVector TypeToRegisterSet[IceType_NUM]; | 373 llvm::SmallBitVector TypeToRegisterSet[IceType_NUM]; |
| 314 llvm::SmallBitVector ScratchRegs; | 374 llvm::SmallBitVector ScratchRegs; |
| 315 llvm::SmallBitVector RegsUsed; | 375 llvm::SmallBitVector RegsUsed; |
| 316 VarList PhysicalRegisters[IceType_NUM]; | 376 VarList PhysicalRegisters[IceType_NUM]; |
| 317 static IceString RegNames[]; | 377 static IceString RegNames[]; |
| 318 | 378 |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 379 return std::unique_ptr<TargetHeaderLowering>(new TargetHeaderARM32(Ctx)); | 439 return std::unique_ptr<TargetHeaderLowering>(new TargetHeaderARM32(Ctx)); |
| 380 } | 440 } |
| 381 | 441 |
| 382 void lower() override; | 442 void lower() override; |
| 383 | 443 |
| 384 protected: | 444 protected: |
| 385 explicit TargetHeaderARM32(GlobalContext *Ctx); | 445 explicit TargetHeaderARM32(GlobalContext *Ctx); |
| 386 | 446 |
| 387 private: | 447 private: |
| 388 ~TargetHeaderARM32() = default; | 448 ~TargetHeaderARM32() = default; |
| 449 |
| 450 TargetARM32Features CPUFeatures; |
| 389 }; | 451 }; |
| 390 | 452 |
| 391 } // end of namespace Ice | 453 } // end of namespace Ice |
| 392 | 454 |
| 393 #endif // SUBZERO_SRC_ICETARGETLOWERINGARM32_H | 455 #endif // SUBZERO_SRC_ICETARGETLOWERINGARM32_H |
| OLD | NEW |