Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(145)

Side by Side Diff: src/IceTargetLoweringARM32.h

Issue 1214693004: ARM lowering integer divide and remainder, with div by 0 checks. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: rebase, refactor, and fix switch MINIMAL=1 Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698