blob: f5223760ddea986f7352638ca22c56035591dd37 [file] [log] [blame]
Chris Lattner2cfd52c2009-07-29 20:31:52 +00001//===- ARMBaseRegisterInfo.cpp - ARM Register Information -------*- C++ -*-===//
David Goodwinc140c482009-07-08 17:28:55 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file contains the base ARM implementation of TargetRegisterInfo class.
11//
12//===----------------------------------------------------------------------===//
13
14#include "ARM.h"
15#include "ARMAddressingModes.h"
David Goodwindb5a71a2009-07-08 18:31:39 +000016#include "ARMBaseInstrInfo.h"
David Goodwinc140c482009-07-08 17:28:55 +000017#include "ARMBaseRegisterInfo.h"
18#include "ARMInstrInfo.h"
19#include "ARMMachineFunctionInfo.h"
20#include "ARMSubtarget.h"
21#include "llvm/Constants.h"
22#include "llvm/DerivedTypes.h"
Owen Anderson9adc0ab2009-07-14 23:09:55 +000023#include "llvm/Function.h"
24#include "llvm/LLVMContext.h"
David Goodwinc140c482009-07-08 17:28:55 +000025#include "llvm/CodeGen/MachineConstantPool.h"
26#include "llvm/CodeGen/MachineFrameInfo.h"
27#include "llvm/CodeGen/MachineFunction.h"
28#include "llvm/CodeGen/MachineInstrBuilder.h"
29#include "llvm/CodeGen/MachineLocation.h"
30#include "llvm/CodeGen/MachineRegisterInfo.h"
31#include "llvm/CodeGen/RegisterScavenging.h"
Torok Edwinab7c09b2009-07-08 18:01:40 +000032#include "llvm/Support/ErrorHandling.h"
Torok Edwindac237e2009-07-08 20:53:28 +000033#include "llvm/Support/raw_ostream.h"
David Goodwinc140c482009-07-08 17:28:55 +000034#include "llvm/Target/TargetFrameInfo.h"
35#include "llvm/Target/TargetMachine.h"
36#include "llvm/Target/TargetOptions.h"
37#include "llvm/ADT/BitVector.h"
38#include "llvm/ADT/SmallVector.h"
Jim Grosbach18ed9c92009-10-20 20:19:50 +000039#include "llvm/Support/CommandLine.h"
David Goodwinc140c482009-07-08 17:28:55 +000040using namespace llvm;
41
Jim Grosbach18ed9c92009-10-20 20:19:50 +000042static cl::opt<bool>
43ReuseFrameIndexVals("arm-reuse-frame-index-vals", cl::Hidden, cl::init(true),
44 cl::desc("Reuse repeated frame index values"));
45
David Goodwinc140c482009-07-08 17:28:55 +000046unsigned ARMBaseRegisterInfo::getRegisterNumbering(unsigned RegEnum,
Evan Cheng8295d992009-07-22 05:55:18 +000047 bool *isSPVFP) {
48 if (isSPVFP)
49 *isSPVFP = false;
David Goodwinc140c482009-07-08 17:28:55 +000050
51 using namespace ARM;
52 switch (RegEnum) {
53 default:
Torok Edwinc23197a2009-07-14 16:55:14 +000054 llvm_unreachable("Unknown ARM register!");
Evan Cheng8295d992009-07-22 05:55:18 +000055 case R0: case D0: case Q0: return 0;
56 case R1: case D1: case Q1: return 1;
57 case R2: case D2: case Q2: return 2;
58 case R3: case D3: case Q3: return 3;
59 case R4: case D4: case Q4: return 4;
60 case R5: case D5: case Q5: return 5;
61 case R6: case D6: case Q6: return 6;
62 case R7: case D7: case Q7: return 7;
63 case R8: case D8: case Q8: return 8;
64 case R9: case D9: case Q9: return 9;
65 case R10: case D10: case Q10: return 10;
66 case R11: case D11: case Q11: return 11;
67 case R12: case D12: case Q12: return 12;
68 case SP: case D13: case Q13: return 13;
69 case LR: case D14: case Q14: return 14;
70 case PC: case D15: case Q15: return 15;
71
72 case D16: return 16;
73 case D17: return 17;
74 case D18: return 18;
75 case D19: return 19;
76 case D20: return 20;
77 case D21: return 21;
78 case D22: return 22;
79 case D23: return 23;
80 case D24: return 24;
81 case D25: return 25;
82 case D26: return 27;
83 case D27: return 27;
84 case D28: return 28;
85 case D29: return 29;
86 case D30: return 30;
87 case D31: return 31;
David Goodwinc140c482009-07-08 17:28:55 +000088
89 case S0: case S1: case S2: case S3:
90 case S4: case S5: case S6: case S7:
91 case S8: case S9: case S10: case S11:
92 case S12: case S13: case S14: case S15:
93 case S16: case S17: case S18: case S19:
94 case S20: case S21: case S22: case S23:
95 case S24: case S25: case S26: case S27:
Evan Cheng8295d992009-07-22 05:55:18 +000096 case S28: case S29: case S30: case S31: {
97 if (isSPVFP)
98 *isSPVFP = true;
David Goodwinc140c482009-07-08 17:28:55 +000099 switch (RegEnum) {
100 default: return 0; // Avoid compile time warning.
101 case S0: return 0;
102 case S1: return 1;
103 case S2: return 2;
104 case S3: return 3;
105 case S4: return 4;
106 case S5: return 5;
107 case S6: return 6;
108 case S7: return 7;
109 case S8: return 8;
110 case S9: return 9;
111 case S10: return 10;
112 case S11: return 11;
113 case S12: return 12;
114 case S13: return 13;
115 case S14: return 14;
116 case S15: return 15;
117 case S16: return 16;
118 case S17: return 17;
119 case S18: return 18;
120 case S19: return 19;
121 case S20: return 20;
122 case S21: return 21;
123 case S22: return 22;
124 case S23: return 23;
125 case S24: return 24;
126 case S25: return 25;
127 case S26: return 26;
128 case S27: return 27;
129 case S28: return 28;
130 case S29: return 29;
131 case S30: return 30;
132 case S31: return 31;
133 }
134 }
135 }
136}
137
David Goodwindb5a71a2009-07-08 18:31:39 +0000138ARMBaseRegisterInfo::ARMBaseRegisterInfo(const ARMBaseInstrInfo &tii,
David Goodwinc140c482009-07-08 17:28:55 +0000139 const ARMSubtarget &sti)
140 : ARMGenRegisterInfo(ARM::ADJCALLSTACKDOWN, ARM::ADJCALLSTACKUP),
141 TII(tii), STI(sti),
142 FramePtr((STI.isTargetDarwin() || STI.isThumb()) ? ARM::R7 : ARM::R11) {
143}
144
145const unsigned*
146ARMBaseRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
147 static const unsigned CalleeSavedRegs[] = {
148 ARM::LR, ARM::R11, ARM::R10, ARM::R9, ARM::R8,
149 ARM::R7, ARM::R6, ARM::R5, ARM::R4,
150
151 ARM::D15, ARM::D14, ARM::D13, ARM::D12,
152 ARM::D11, ARM::D10, ARM::D9, ARM::D8,
153 0
154 };
155
156 static const unsigned DarwinCalleeSavedRegs[] = {
157 // Darwin ABI deviates from ARM standard ABI. R9 is not a callee-saved
158 // register.
159 ARM::LR, ARM::R7, ARM::R6, ARM::R5, ARM::R4,
160 ARM::R11, ARM::R10, ARM::R8,
161
162 ARM::D15, ARM::D14, ARM::D13, ARM::D12,
163 ARM::D11, ARM::D10, ARM::D9, ARM::D8,
164 0
165 };
166 return STI.isTargetDarwin() ? DarwinCalleeSavedRegs : CalleeSavedRegs;
167}
168
169const TargetRegisterClass* const *
170ARMBaseRegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const {
171 static const TargetRegisterClass * const CalleeSavedRegClasses[] = {
Jim Grosbach82b3c2e2009-09-11 20:13:17 +0000172 &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::GPRRegClass,
173 &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::GPRRegClass,
174 &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::GPRRegClass,
David Goodwinc140c482009-07-08 17:28:55 +0000175
Jim Grosbach82b3c2e2009-09-11 20:13:17 +0000176 &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass,
177 &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass,
David Goodwinc140c482009-07-08 17:28:55 +0000178 0
179 };
180
181 static const TargetRegisterClass * const ThumbCalleeSavedRegClasses[] = {
Jim Grosbach82b3c2e2009-09-11 20:13:17 +0000182 &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::GPRRegClass,
183 &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::tGPRRegClass,
184 &ARM::tGPRRegClass,&ARM::tGPRRegClass,&ARM::tGPRRegClass,
David Goodwinc140c482009-07-08 17:28:55 +0000185
Jim Grosbach82b3c2e2009-09-11 20:13:17 +0000186 &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass,
187 &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass,
David Goodwinc140c482009-07-08 17:28:55 +0000188 0
189 };
190
191 static const TargetRegisterClass * const DarwinCalleeSavedRegClasses[] = {
Jim Grosbach82b3c2e2009-09-11 20:13:17 +0000192 &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::GPRRegClass,
193 &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::GPRRegClass,
194 &ARM::GPRRegClass, &ARM::GPRRegClass,
David Goodwinc140c482009-07-08 17:28:55 +0000195
Jim Grosbach82b3c2e2009-09-11 20:13:17 +0000196 &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass,
197 &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass,
David Goodwinc140c482009-07-08 17:28:55 +0000198 0
199 };
200
201 static const TargetRegisterClass * const DarwinThumbCalleeSavedRegClasses[] ={
Jim Grosbach82b3c2e2009-09-11 20:13:17 +0000202 &ARM::GPRRegClass, &ARM::tGPRRegClass, &ARM::tGPRRegClass,
203 &ARM::tGPRRegClass, &ARM::tGPRRegClass, &ARM::GPRRegClass,
204 &ARM::GPRRegClass, &ARM::GPRRegClass,
David Goodwinc140c482009-07-08 17:28:55 +0000205
Jim Grosbach82b3c2e2009-09-11 20:13:17 +0000206 &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass,
207 &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass,
David Goodwinc140c482009-07-08 17:28:55 +0000208 0
209 };
210
David Goodwinf1daf7d2009-07-08 23:10:31 +0000211 if (STI.isThumb1Only()) {
David Goodwinc140c482009-07-08 17:28:55 +0000212 return STI.isTargetDarwin()
213 ? DarwinThumbCalleeSavedRegClasses : ThumbCalleeSavedRegClasses;
214 }
215 return STI.isTargetDarwin()
216 ? DarwinCalleeSavedRegClasses : CalleeSavedRegClasses;
217}
218
219BitVector ARMBaseRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
220 // FIXME: avoid re-calculating this everytime.
221 BitVector Reserved(getNumRegs());
222 Reserved.set(ARM::SP);
223 Reserved.set(ARM::PC);
224 if (STI.isTargetDarwin() || hasFP(MF))
225 Reserved.set(FramePtr);
226 // Some targets reserve R9.
227 if (STI.isR9Reserved())
228 Reserved.set(ARM::R9);
229 return Reserved;
230}
231
Chris Lattner2cfd52c2009-07-29 20:31:52 +0000232bool ARMBaseRegisterInfo::isReservedReg(const MachineFunction &MF,
233 unsigned Reg) const {
David Goodwinc140c482009-07-08 17:28:55 +0000234 switch (Reg) {
235 default: break;
236 case ARM::SP:
237 case ARM::PC:
238 return true;
239 case ARM::R7:
240 case ARM::R11:
241 if (FramePtr == Reg && (STI.isTargetDarwin() || hasFP(MF)))
242 return true;
243 break;
244 case ARM::R9:
245 return STI.isR9Reserved();
246 }
247
248 return false;
249}
250
Chris Lattner2cfd52c2009-07-29 20:31:52 +0000251const TargetRegisterClass *
252ARMBaseRegisterInfo::getPointerRegClass(unsigned Kind) const {
Jim Grosbache11a8f52009-09-11 19:49:06 +0000253 return ARM::GPRRegisterClass;
David Goodwinc140c482009-07-08 17:28:55 +0000254}
255
256/// getAllocationOrder - Returns the register allocation order for a specified
257/// register class in the form of a pair of TargetRegisterClass iterators.
258std::pair<TargetRegisterClass::iterator,TargetRegisterClass::iterator>
259ARMBaseRegisterInfo::getAllocationOrder(const TargetRegisterClass *RC,
260 unsigned HintType, unsigned HintReg,
261 const MachineFunction &MF) const {
262 // Alternative register allocation orders when favoring even / odd registers
263 // of register pairs.
264
265 // No FP, R9 is available.
266 static const unsigned GPREven1[] = {
267 ARM::R0, ARM::R2, ARM::R4, ARM::R6, ARM::R8, ARM::R10,
268 ARM::R1, ARM::R3, ARM::R12,ARM::LR, ARM::R5, ARM::R7,
269 ARM::R9, ARM::R11
270 };
271 static const unsigned GPROdd1[] = {
272 ARM::R1, ARM::R3, ARM::R5, ARM::R7, ARM::R9, ARM::R11,
273 ARM::R0, ARM::R2, ARM::R12,ARM::LR, ARM::R4, ARM::R6,
274 ARM::R8, ARM::R10
275 };
276
277 // FP is R7, R9 is available.
278 static const unsigned GPREven2[] = {
279 ARM::R0, ARM::R2, ARM::R4, ARM::R8, ARM::R10,
280 ARM::R1, ARM::R3, ARM::R12,ARM::LR, ARM::R5, ARM::R6,
281 ARM::R9, ARM::R11
282 };
283 static const unsigned GPROdd2[] = {
284 ARM::R1, ARM::R3, ARM::R5, ARM::R9, ARM::R11,
285 ARM::R0, ARM::R2, ARM::R12,ARM::LR, ARM::R4, ARM::R6,
286 ARM::R8, ARM::R10
287 };
288
289 // FP is R11, R9 is available.
290 static const unsigned GPREven3[] = {
291 ARM::R0, ARM::R2, ARM::R4, ARM::R6, ARM::R8,
292 ARM::R1, ARM::R3, ARM::R10,ARM::R12,ARM::LR, ARM::R5, ARM::R7,
293 ARM::R9
294 };
295 static const unsigned GPROdd3[] = {
296 ARM::R1, ARM::R3, ARM::R5, ARM::R6, ARM::R9,
297 ARM::R0, ARM::R2, ARM::R10,ARM::R12,ARM::LR, ARM::R4, ARM::R7,
298 ARM::R8
299 };
300
301 // No FP, R9 is not available.
302 static const unsigned GPREven4[] = {
303 ARM::R0, ARM::R2, ARM::R4, ARM::R6, ARM::R10,
304 ARM::R1, ARM::R3, ARM::R12,ARM::LR, ARM::R5, ARM::R7, ARM::R8,
305 ARM::R11
306 };
307 static const unsigned GPROdd4[] = {
308 ARM::R1, ARM::R3, ARM::R5, ARM::R7, ARM::R11,
309 ARM::R0, ARM::R2, ARM::R12,ARM::LR, ARM::R4, ARM::R6, ARM::R8,
310 ARM::R10
311 };
312
313 // FP is R7, R9 is not available.
314 static const unsigned GPREven5[] = {
315 ARM::R0, ARM::R2, ARM::R4, ARM::R10,
316 ARM::R1, ARM::R3, ARM::R12,ARM::LR, ARM::R5, ARM::R6, ARM::R8,
317 ARM::R11
318 };
319 static const unsigned GPROdd5[] = {
320 ARM::R1, ARM::R3, ARM::R5, ARM::R11,
321 ARM::R0, ARM::R2, ARM::R12,ARM::LR, ARM::R4, ARM::R6, ARM::R8,
322 ARM::R10
323 };
324
325 // FP is R11, R9 is not available.
326 static const unsigned GPREven6[] = {
327 ARM::R0, ARM::R2, ARM::R4, ARM::R6,
328 ARM::R1, ARM::R3, ARM::R10,ARM::R12,ARM::LR, ARM::R5, ARM::R7, ARM::R8
329 };
330 static const unsigned GPROdd6[] = {
331 ARM::R1, ARM::R3, ARM::R5, ARM::R7,
332 ARM::R0, ARM::R2, ARM::R10,ARM::R12,ARM::LR, ARM::R4, ARM::R6, ARM::R8
333 };
334
335
336 if (HintType == ARMRI::RegPairEven) {
337 if (isPhysicalRegister(HintReg) && getRegisterPairEven(HintReg, MF) == 0)
338 // It's no longer possible to fulfill this hint. Return the default
339 // allocation order.
340 return std::make_pair(RC->allocation_order_begin(MF),
341 RC->allocation_order_end(MF));
342
343 if (!STI.isTargetDarwin() && !hasFP(MF)) {
344 if (!STI.isR9Reserved())
345 return std::make_pair(GPREven1,
346 GPREven1 + (sizeof(GPREven1)/sizeof(unsigned)));
347 else
348 return std::make_pair(GPREven4,
349 GPREven4 + (sizeof(GPREven4)/sizeof(unsigned)));
350 } else if (FramePtr == ARM::R7) {
351 if (!STI.isR9Reserved())
352 return std::make_pair(GPREven2,
353 GPREven2 + (sizeof(GPREven2)/sizeof(unsigned)));
354 else
355 return std::make_pair(GPREven5,
356 GPREven5 + (sizeof(GPREven5)/sizeof(unsigned)));
357 } else { // FramePtr == ARM::R11
358 if (!STI.isR9Reserved())
359 return std::make_pair(GPREven3,
360 GPREven3 + (sizeof(GPREven3)/sizeof(unsigned)));
361 else
362 return std::make_pair(GPREven6,
363 GPREven6 + (sizeof(GPREven6)/sizeof(unsigned)));
364 }
365 } else if (HintType == ARMRI::RegPairOdd) {
366 if (isPhysicalRegister(HintReg) && getRegisterPairOdd(HintReg, MF) == 0)
367 // It's no longer possible to fulfill this hint. Return the default
368 // allocation order.
369 return std::make_pair(RC->allocation_order_begin(MF),
370 RC->allocation_order_end(MF));
371
372 if (!STI.isTargetDarwin() && !hasFP(MF)) {
373 if (!STI.isR9Reserved())
374 return std::make_pair(GPROdd1,
375 GPROdd1 + (sizeof(GPROdd1)/sizeof(unsigned)));
376 else
377 return std::make_pair(GPROdd4,
378 GPROdd4 + (sizeof(GPROdd4)/sizeof(unsigned)));
379 } else if (FramePtr == ARM::R7) {
380 if (!STI.isR9Reserved())
381 return std::make_pair(GPROdd2,
382 GPROdd2 + (sizeof(GPROdd2)/sizeof(unsigned)));
383 else
384 return std::make_pair(GPROdd5,
385 GPROdd5 + (sizeof(GPROdd5)/sizeof(unsigned)));
386 } else { // FramePtr == ARM::R11
387 if (!STI.isR9Reserved())
388 return std::make_pair(GPROdd3,
389 GPROdd3 + (sizeof(GPROdd3)/sizeof(unsigned)));
390 else
391 return std::make_pair(GPROdd6,
392 GPROdd6 + (sizeof(GPROdd6)/sizeof(unsigned)));
393 }
394 }
395 return std::make_pair(RC->allocation_order_begin(MF),
396 RC->allocation_order_end(MF));
397}
398
399/// ResolveRegAllocHint - Resolves the specified register allocation hint
400/// to a physical register. Returns the physical register if it is successful.
401unsigned
402ARMBaseRegisterInfo::ResolveRegAllocHint(unsigned Type, unsigned Reg,
403 const MachineFunction &MF) const {
404 if (Reg == 0 || !isPhysicalRegister(Reg))
405 return 0;
406 if (Type == 0)
407 return Reg;
408 else if (Type == (unsigned)ARMRI::RegPairOdd)
409 // Odd register.
410 return getRegisterPairOdd(Reg, MF);
411 else if (Type == (unsigned)ARMRI::RegPairEven)
412 // Even register.
413 return getRegisterPairEven(Reg, MF);
414 return 0;
415}
416
417void
418ARMBaseRegisterInfo::UpdateRegAllocHint(unsigned Reg, unsigned NewReg,
419 MachineFunction &MF) const {
420 MachineRegisterInfo *MRI = &MF.getRegInfo();
421 std::pair<unsigned, unsigned> Hint = MRI->getRegAllocationHint(Reg);
422 if ((Hint.first == (unsigned)ARMRI::RegPairOdd ||
423 Hint.first == (unsigned)ARMRI::RegPairEven) &&
424 Hint.second && TargetRegisterInfo::isVirtualRegister(Hint.second)) {
425 // If 'Reg' is one of the even / odd register pair and it's now changed
426 // (e.g. coalesced) into a different register. The other register of the
427 // pair allocation hint must be updated to reflect the relationship
428 // change.
429 unsigned OtherReg = Hint.second;
430 Hint = MRI->getRegAllocationHint(OtherReg);
431 if (Hint.second == Reg)
432 // Make sure the pair has not already divorced.
433 MRI->setRegAllocationHint(OtherReg, Hint.first, NewReg);
434 }
435}
436
437/// hasFP - Return true if the specified function should have a dedicated frame
438/// pointer register. This is true if the function has variable sized allocas
439/// or if frame pointer elimination is disabled.
440///
441bool ARMBaseRegisterInfo::hasFP(const MachineFunction &MF) const {
442 const MachineFrameInfo *MFI = MF.getFrameInfo();
443 return (NoFramePointerElim ||
444 MFI->hasVarSizedObjects() ||
445 MFI->isFrameAddressTaken());
446}
447
Evan Cheng010b1b92009-08-15 02:05:35 +0000448bool ARMBaseRegisterInfo::cannotEliminateFrame(const MachineFunction &MF) const {
Evan Cheng98a01042009-08-14 20:48:13 +0000449 const MachineFrameInfo *MFI = MF.getFrameInfo();
450 if (NoFramePointerElim && MFI->hasCalls())
451 return true;
452 return MFI->hasVarSizedObjects() || MFI->isFrameAddressTaken();
453}
454
Evan Cheng542383d2009-07-28 06:24:12 +0000455/// estimateStackSize - Estimate and return the size of the frame.
David Goodwinc140c482009-07-08 17:28:55 +0000456static unsigned estimateStackSize(MachineFunction &MF, MachineFrameInfo *MFI) {
457 const MachineFrameInfo *FFI = MF.getFrameInfo();
458 int Offset = 0;
459 for (int i = FFI->getObjectIndexBegin(); i != 0; ++i) {
460 int FixedOff = -FFI->getObjectOffset(i);
461 if (FixedOff > Offset) Offset = FixedOff;
462 }
463 for (unsigned i = 0, e = FFI->getObjectIndexEnd(); i != e; ++i) {
464 if (FFI->isDeadObjectIndex(i))
465 continue;
466 Offset += FFI->getObjectSize(i);
467 unsigned Align = FFI->getObjectAlignment(i);
468 // Adjust to alignment boundary
469 Offset = (Offset+Align-1)/Align*Align;
470 }
471 return (unsigned)Offset;
472}
473
Evan Cheng542383d2009-07-28 06:24:12 +0000474/// estimateRSStackSizeLimit - Look at each instruction that references stack
475/// frames and return the stack size limit beyond which some of these
476/// instructions will require scratch register during their expansion later.
Evan Chengee42fd32009-07-30 23:29:25 +0000477unsigned
478ARMBaseRegisterInfo::estimateRSStackSizeLimit(MachineFunction &MF) const {
Evan Cheng542383d2009-07-28 06:24:12 +0000479 unsigned Limit = (1 << 12) - 1;
Chris Lattnerb180d992009-07-28 18:48:43 +0000480 for (MachineFunction::iterator BB = MF.begin(),E = MF.end(); BB != E; ++BB) {
481 for (MachineBasicBlock::iterator I = BB->begin(), E = BB->end();
482 I != E; ++I) {
483 for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
484 if (!I->getOperand(i).isFI()) continue;
Jim Grosbach764ab522009-08-11 15:33:49 +0000485
Chris Lattnerb180d992009-07-28 18:48:43 +0000486 const TargetInstrDesc &Desc = TII.get(I->getOpcode());
487 unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
488 if (AddrMode == ARMII::AddrMode3 ||
489 AddrMode == ARMII::AddrModeT2_i8)
490 return (1 << 8) - 1;
Jim Grosbach764ab522009-08-11 15:33:49 +0000491
Chris Lattnerb180d992009-07-28 18:48:43 +0000492 if (AddrMode == ARMII::AddrMode5 ||
493 AddrMode == ARMII::AddrModeT2_i8s4)
494 Limit = std::min(Limit, ((1U << 8) - 1) * 4);
Evan Chengee42fd32009-07-30 23:29:25 +0000495
496 if (AddrMode == ARMII::AddrModeT2_i12 && hasFP(MF))
497 // When the stack offset is negative, we will end up using
498 // the i8 instructions instead.
499 return (1 << 8) - 1;
Chris Lattnerb180d992009-07-28 18:48:43 +0000500 break; // At most one FI per instruction
501 }
Evan Cheng542383d2009-07-28 06:24:12 +0000502 }
503 }
504
505 return Limit;
506}
507
David Goodwinc140c482009-07-08 17:28:55 +0000508void
509ARMBaseRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
510 RegScavenger *RS) const {
511 // This tells PEI to spill the FP as if it is any other callee-save register
512 // to take advantage the eliminateFrameIndex machinery. This also ensures it
513 // is spilled in the order specified by getCalleeSavedRegs() to make it easier
514 // to combine multiple loads / stores.
515 bool CanEliminateFrame = true;
516 bool CS1Spilled = false;
517 bool LRSpilled = false;
518 unsigned NumGPRSpills = 0;
519 SmallVector<unsigned, 4> UnspilledCS1GPRs;
520 SmallVector<unsigned, 4> UnspilledCS2GPRs;
521 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
522
523 // Don't spill FP if the frame can be eliminated. This is determined
524 // by scanning the callee-save registers to see if any is used.
525 const unsigned *CSRegs = getCalleeSavedRegs();
526 const TargetRegisterClass* const *CSRegClasses = getCalleeSavedRegClasses();
527 for (unsigned i = 0; CSRegs[i]; ++i) {
528 unsigned Reg = CSRegs[i];
529 bool Spilled = false;
530 if (MF.getRegInfo().isPhysRegUsed(Reg)) {
531 AFI->setCSRegisterIsSpilled(Reg);
532 Spilled = true;
533 CanEliminateFrame = false;
534 } else {
535 // Check alias registers too.
536 for (const unsigned *Aliases = getAliasSet(Reg); *Aliases; ++Aliases) {
537 if (MF.getRegInfo().isPhysRegUsed(*Aliases)) {
538 Spilled = true;
539 CanEliminateFrame = false;
540 }
541 }
542 }
543
Jim Grosbachec9eef42009-09-28 22:08:06 +0000544 if (CSRegClasses[i] == ARM::GPRRegisterClass ||
545 CSRegClasses[i] == ARM::tGPRRegisterClass) {
David Goodwinc140c482009-07-08 17:28:55 +0000546 if (Spilled) {
547 NumGPRSpills++;
548
549 if (!STI.isTargetDarwin()) {
550 if (Reg == ARM::LR)
551 LRSpilled = true;
552 CS1Spilled = true;
553 continue;
554 }
555
556 // Keep track if LR and any of R4, R5, R6, and R7 is spilled.
557 switch (Reg) {
558 case ARM::LR:
559 LRSpilled = true;
560 // Fallthrough
561 case ARM::R4:
562 case ARM::R5:
563 case ARM::R6:
564 case ARM::R7:
565 CS1Spilled = true;
566 break;
567 default:
568 break;
569 }
570 } else {
571 if (!STI.isTargetDarwin()) {
572 UnspilledCS1GPRs.push_back(Reg);
573 continue;
574 }
575
576 switch (Reg) {
577 case ARM::R4:
578 case ARM::R5:
579 case ARM::R6:
580 case ARM::R7:
581 case ARM::LR:
582 UnspilledCS1GPRs.push_back(Reg);
583 break;
584 default:
585 UnspilledCS2GPRs.push_back(Reg);
586 break;
587 }
588 }
589 }
590 }
591
592 bool ForceLRSpill = false;
David Goodwinf1daf7d2009-07-08 23:10:31 +0000593 if (!LRSpilled && AFI->isThumb1OnlyFunction()) {
David Goodwinc140c482009-07-08 17:28:55 +0000594 unsigned FnSize = TII.GetFunctionSizeInBytes(MF);
595 // Force LR to be spilled if the Thumb function size is > 2048. This enables
596 // use of BL to implement far jump. If it turns out that it's not needed
597 // then the branch fix up path will undo it.
598 if (FnSize >= (1 << 11)) {
599 CanEliminateFrame = false;
600 ForceLRSpill = true;
601 }
602 }
603
604 bool ExtraCSSpill = false;
Evan Cheng010b1b92009-08-15 02:05:35 +0000605 if (!CanEliminateFrame || cannotEliminateFrame(MF)) {
David Goodwinc140c482009-07-08 17:28:55 +0000606 AFI->setHasStackFrame(true);
607
608 // If LR is not spilled, but at least one of R4, R5, R6, and R7 is spilled.
609 // Spill LR as well so we can fold BX_RET to the registers restore (LDM).
610 if (!LRSpilled && CS1Spilled) {
611 MF.getRegInfo().setPhysRegUsed(ARM::LR);
612 AFI->setCSRegisterIsSpilled(ARM::LR);
613 NumGPRSpills++;
614 UnspilledCS1GPRs.erase(std::find(UnspilledCS1GPRs.begin(),
615 UnspilledCS1GPRs.end(), (unsigned)ARM::LR));
616 ForceLRSpill = false;
617 ExtraCSSpill = true;
618 }
619
620 // Darwin ABI requires FP to point to the stack slot that contains the
621 // previous FP.
622 if (STI.isTargetDarwin() || hasFP(MF)) {
623 MF.getRegInfo().setPhysRegUsed(FramePtr);
624 NumGPRSpills++;
625 }
626
627 // If stack and double are 8-byte aligned and we are spilling an odd number
628 // of GPRs. Spill one extra callee save GPR so we won't have to pad between
629 // the integer and double callee save areas.
630 unsigned TargetAlign = MF.getTarget().getFrameInfo()->getStackAlignment();
631 if (TargetAlign == 8 && (NumGPRSpills & 1)) {
632 if (CS1Spilled && !UnspilledCS1GPRs.empty()) {
633 for (unsigned i = 0, e = UnspilledCS1GPRs.size(); i != e; ++i) {
634 unsigned Reg = UnspilledCS1GPRs[i];
David Goodwinf1daf7d2009-07-08 23:10:31 +0000635 // Don't spill high register if the function is thumb1
636 if (!AFI->isThumb1OnlyFunction() ||
David Goodwinc140c482009-07-08 17:28:55 +0000637 isARMLowRegister(Reg) || Reg == ARM::LR) {
638 MF.getRegInfo().setPhysRegUsed(Reg);
639 AFI->setCSRegisterIsSpilled(Reg);
640 if (!isReservedReg(MF, Reg))
641 ExtraCSSpill = true;
642 break;
643 }
644 }
645 } else if (!UnspilledCS2GPRs.empty() &&
David Goodwinf1daf7d2009-07-08 23:10:31 +0000646 !AFI->isThumb1OnlyFunction()) {
David Goodwinc140c482009-07-08 17:28:55 +0000647 unsigned Reg = UnspilledCS2GPRs.front();
648 MF.getRegInfo().setPhysRegUsed(Reg);
649 AFI->setCSRegisterIsSpilled(Reg);
650 if (!isReservedReg(MF, Reg))
651 ExtraCSSpill = true;
652 }
653 }
654
655 // Estimate if we might need to scavenge a register at some point in order
656 // to materialize a stack offset. If so, either spill one additional
657 // callee-saved register or reserve a special spill slot to facilitate
Jim Grosbach3d6cb882009-09-24 23:52:18 +0000658 // register scavenging. Thumb1 needs a spill slot for stack pointer
659 // adjustments also, even when the frame itself is small.
660 if (RS && !ExtraCSSpill) {
David Goodwinc140c482009-07-08 17:28:55 +0000661 MachineFrameInfo *MFI = MF.getFrameInfo();
Jim Grosbachd1a5ca62009-09-30 01:43:29 +0000662 // If any of the stack slot references may be out of range of an
663 // immediate offset, make sure a register (or a spill slot) is
664 // available for the register scavenger. Note that if we're indexing
665 // off the frame pointer, the effective stack size is 4 bytes larger
Jim Grosbach460c4822009-09-30 15:23:38 +0000666 // since the FP points to the stack slot of the previous FP.
Jim Grosbachd1a5ca62009-09-30 01:43:29 +0000667 if (estimateStackSize(MF, MFI) + (hasFP(MF) ? 4 : 0)
Jim Grosbach540b05d2009-10-05 22:30:23 +0000668 >= estimateRSStackSizeLimit(MF)) {
David Goodwinc140c482009-07-08 17:28:55 +0000669 // If any non-reserved CS register isn't spilled, just spill one or two
670 // extra. That should take care of it!
671 unsigned NumExtras = TargetAlign / 4;
672 SmallVector<unsigned, 2> Extras;
673 while (NumExtras && !UnspilledCS1GPRs.empty()) {
674 unsigned Reg = UnspilledCS1GPRs.back();
675 UnspilledCS1GPRs.pop_back();
676 if (!isReservedReg(MF, Reg)) {
677 Extras.push_back(Reg);
678 NumExtras--;
679 }
680 }
Jim Grosbach17487ba2009-09-29 23:17:20 +0000681 // For non-Thumb1 functions, also check for hi-reg CS registers
682 if (!AFI->isThumb1OnlyFunction()) {
683 while (NumExtras && !UnspilledCS2GPRs.empty()) {
684 unsigned Reg = UnspilledCS2GPRs.back();
685 UnspilledCS2GPRs.pop_back();
686 if (!isReservedReg(MF, Reg)) {
687 Extras.push_back(Reg);
688 NumExtras--;
689 }
David Goodwinc140c482009-07-08 17:28:55 +0000690 }
691 }
692 if (Extras.size() && NumExtras == 0) {
693 for (unsigned i = 0, e = Extras.size(); i != e; ++i) {
694 MF.getRegInfo().setPhysRegUsed(Extras[i]);
695 AFI->setCSRegisterIsSpilled(Extras[i]);
696 }
Jim Grosbach540b05d2009-10-05 22:30:23 +0000697 } else if (!AFI->isThumb1OnlyFunction()) {
698 // note: Thumb1 functions spill to R12, not the stack.
David Goodwinc140c482009-07-08 17:28:55 +0000699 // Reserve a slot closest to SP or frame pointer.
Jim Grosbache11a8f52009-09-11 19:49:06 +0000700 const TargetRegisterClass *RC = ARM::GPRRegisterClass;
David Goodwinc140c482009-07-08 17:28:55 +0000701 RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(),
702 RC->getAlignment()));
703 }
704 }
705 }
706 }
707
708 if (ForceLRSpill) {
709 MF.getRegInfo().setPhysRegUsed(ARM::LR);
710 AFI->setCSRegisterIsSpilled(ARM::LR);
711 AFI->setLRIsSpilledForFarJump(true);
712 }
713}
714
715unsigned ARMBaseRegisterInfo::getRARegister() const {
716 return ARM::LR;
717}
718
719unsigned ARMBaseRegisterInfo::getFrameRegister(MachineFunction &MF) const {
720 if (STI.isTargetDarwin() || hasFP(MF))
721 return FramePtr;
722 return ARM::SP;
723}
724
725unsigned ARMBaseRegisterInfo::getEHExceptionRegister() const {
Torok Edwinc23197a2009-07-14 16:55:14 +0000726 llvm_unreachable("What is the exception register");
David Goodwinc140c482009-07-08 17:28:55 +0000727 return 0;
728}
729
730unsigned ARMBaseRegisterInfo::getEHHandlerRegister() const {
Torok Edwinc23197a2009-07-14 16:55:14 +0000731 llvm_unreachable("What is the exception handler register");
David Goodwinc140c482009-07-08 17:28:55 +0000732 return 0;
733}
734
735int ARMBaseRegisterInfo::getDwarfRegNum(unsigned RegNum, bool isEH) const {
736 return ARMGenRegisterInfo::getDwarfRegNumFull(RegNum, 0);
737}
738
739unsigned ARMBaseRegisterInfo::getRegisterPairEven(unsigned Reg,
740 const MachineFunction &MF) const {
741 switch (Reg) {
742 default: break;
743 // Return 0 if either register of the pair is a special register.
744 // So no R12, etc.
745 case ARM::R1:
746 return ARM::R0;
747 case ARM::R3:
Jim Grosbach60097512009-10-19 22:57:03 +0000748 return ARM::R2;
David Goodwinc140c482009-07-08 17:28:55 +0000749 case ARM::R5:
750 return ARM::R4;
751 case ARM::R7:
752 return isReservedReg(MF, ARM::R7) ? 0 : ARM::R6;
753 case ARM::R9:
754 return isReservedReg(MF, ARM::R9) ? 0 :ARM::R8;
755 case ARM::R11:
756 return isReservedReg(MF, ARM::R11) ? 0 : ARM::R10;
757
758 case ARM::S1:
759 return ARM::S0;
760 case ARM::S3:
761 return ARM::S2;
762 case ARM::S5:
763 return ARM::S4;
764 case ARM::S7:
765 return ARM::S6;
766 case ARM::S9:
767 return ARM::S8;
768 case ARM::S11:
769 return ARM::S10;
770 case ARM::S13:
771 return ARM::S12;
772 case ARM::S15:
773 return ARM::S14;
774 case ARM::S17:
775 return ARM::S16;
776 case ARM::S19:
777 return ARM::S18;
778 case ARM::S21:
779 return ARM::S20;
780 case ARM::S23:
781 return ARM::S22;
782 case ARM::S25:
783 return ARM::S24;
784 case ARM::S27:
785 return ARM::S26;
786 case ARM::S29:
787 return ARM::S28;
788 case ARM::S31:
789 return ARM::S30;
790
791 case ARM::D1:
792 return ARM::D0;
793 case ARM::D3:
794 return ARM::D2;
795 case ARM::D5:
796 return ARM::D4;
797 case ARM::D7:
798 return ARM::D6;
799 case ARM::D9:
800 return ARM::D8;
801 case ARM::D11:
802 return ARM::D10;
803 case ARM::D13:
804 return ARM::D12;
805 case ARM::D15:
806 return ARM::D14;
Evan Cheng8295d992009-07-22 05:55:18 +0000807 case ARM::D17:
808 return ARM::D16;
809 case ARM::D19:
810 return ARM::D18;
811 case ARM::D21:
812 return ARM::D20;
813 case ARM::D23:
814 return ARM::D22;
815 case ARM::D25:
816 return ARM::D24;
817 case ARM::D27:
818 return ARM::D26;
819 case ARM::D29:
820 return ARM::D28;
821 case ARM::D31:
822 return ARM::D30;
David Goodwinc140c482009-07-08 17:28:55 +0000823 }
824
825 return 0;
826}
827
828unsigned ARMBaseRegisterInfo::getRegisterPairOdd(unsigned Reg,
829 const MachineFunction &MF) const {
830 switch (Reg) {
831 default: break;
832 // Return 0 if either register of the pair is a special register.
833 // So no R12, etc.
834 case ARM::R0:
835 return ARM::R1;
836 case ARM::R2:
Jim Grosbach60097512009-10-19 22:57:03 +0000837 return ARM::R3;
David Goodwinc140c482009-07-08 17:28:55 +0000838 case ARM::R4:
839 return ARM::R5;
840 case ARM::R6:
841 return isReservedReg(MF, ARM::R7) ? 0 : ARM::R7;
842 case ARM::R8:
843 return isReservedReg(MF, ARM::R9) ? 0 :ARM::R9;
844 case ARM::R10:
845 return isReservedReg(MF, ARM::R11) ? 0 : ARM::R11;
846
847 case ARM::S0:
848 return ARM::S1;
849 case ARM::S2:
850 return ARM::S3;
851 case ARM::S4:
852 return ARM::S5;
853 case ARM::S6:
854 return ARM::S7;
855 case ARM::S8:
856 return ARM::S9;
857 case ARM::S10:
858 return ARM::S11;
859 case ARM::S12:
860 return ARM::S13;
861 case ARM::S14:
862 return ARM::S15;
863 case ARM::S16:
864 return ARM::S17;
865 case ARM::S18:
866 return ARM::S19;
867 case ARM::S20:
868 return ARM::S21;
869 case ARM::S22:
870 return ARM::S23;
871 case ARM::S24:
872 return ARM::S25;
873 case ARM::S26:
874 return ARM::S27;
875 case ARM::S28:
876 return ARM::S29;
877 case ARM::S30:
878 return ARM::S31;
879
880 case ARM::D0:
881 return ARM::D1;
882 case ARM::D2:
883 return ARM::D3;
884 case ARM::D4:
885 return ARM::D5;
886 case ARM::D6:
887 return ARM::D7;
888 case ARM::D8:
889 return ARM::D9;
890 case ARM::D10:
891 return ARM::D11;
892 case ARM::D12:
893 return ARM::D13;
894 case ARM::D14:
895 return ARM::D15;
Evan Cheng8295d992009-07-22 05:55:18 +0000896 case ARM::D16:
897 return ARM::D17;
898 case ARM::D18:
899 return ARM::D19;
900 case ARM::D20:
901 return ARM::D21;
902 case ARM::D22:
903 return ARM::D23;
904 case ARM::D24:
905 return ARM::D25;
906 case ARM::D26:
907 return ARM::D27;
908 case ARM::D28:
909 return ARM::D29;
910 case ARM::D30:
911 return ARM::D31;
David Goodwinc140c482009-07-08 17:28:55 +0000912 }
913
914 return 0;
915}
916
David Goodwindb5a71a2009-07-08 18:31:39 +0000917/// emitLoadConstPool - Emits a load from constpool to materialize the
918/// specified immediate.
919void ARMBaseRegisterInfo::
920emitLoadConstPool(MachineBasicBlock &MBB,
921 MachineBasicBlock::iterator &MBBI,
David Goodwin77521f52009-07-08 20:28:28 +0000922 DebugLoc dl,
Evan Cheng37844532009-07-16 09:20:10 +0000923 unsigned DestReg, unsigned SubIdx, int Val,
David Goodwindb5a71a2009-07-08 18:31:39 +0000924 ARMCC::CondCodes Pred,
925 unsigned PredReg) const {
926 MachineFunction &MF = *MBB.getParent();
927 MachineConstantPool *ConstantPool = MF.getConstantPool();
Owen Anderson1d0be152009-08-13 21:58:54 +0000928 Constant *C =
929 ConstantInt::get(Type::getInt32Ty(MF.getFunction()->getContext()), Val);
David Goodwindb5a71a2009-07-08 18:31:39 +0000930 unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4);
931
Evan Cheng37844532009-07-16 09:20:10 +0000932 BuildMI(MBB, MBBI, dl, TII.get(ARM::LDRcp))
933 .addReg(DestReg, getDefRegState(true), SubIdx)
David Goodwindb5a71a2009-07-08 18:31:39 +0000934 .addConstantPoolIndex(Idx)
935 .addReg(0).addImm(0).addImm(Pred).addReg(PredReg);
936}
937
938bool ARMBaseRegisterInfo::
939requiresRegisterScavenging(const MachineFunction &MF) const {
940 return true;
941}
Jim Grosbach7e831db2009-10-20 01:26:58 +0000942bool ARMBaseRegisterInfo::
943requiresFrameIndexScavenging(const MachineFunction &MF) const {
944 return true;
945}
David Goodwindb5a71a2009-07-08 18:31:39 +0000946
947// hasReservedCallFrame - Under normal circumstances, when a frame pointer is
948// not required, we reserve argument space for call sites in the function
949// immediately on entry to the current function. This eliminates the need for
950// add/sub sp brackets around call sites. Returns true if the call frame is
951// included as part of the stack frame.
952bool ARMBaseRegisterInfo::
953hasReservedCallFrame(MachineFunction &MF) const {
954 const MachineFrameInfo *FFI = MF.getFrameInfo();
955 unsigned CFSize = FFI->getMaxCallFrameSize();
956 // It's not always a good idea to include the call frame as part of the
957 // stack frame. ARM (especially Thumb) has small immediate offset to
958 // address the stack frame. So a large call frame can cause poor codegen
959 // and may even makes it impossible to scavenge a register.
960 if (CFSize >= ((1 << 12) - 1) / 2) // Half of imm12
961 return false;
962
963 return !MF.getFrameInfo()->hasVarSizedObjects();
964}
965
David Goodwindb5a71a2009-07-08 18:31:39 +0000966static void
Evan Cheng6495f632009-07-28 05:48:47 +0000967emitSPUpdate(bool isARM,
968 MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
969 DebugLoc dl, const ARMBaseInstrInfo &TII,
David Goodwindb5a71a2009-07-08 18:31:39 +0000970 int NumBytes,
971 ARMCC::CondCodes Pred = ARMCC::AL, unsigned PredReg = 0) {
Evan Cheng6495f632009-07-28 05:48:47 +0000972 if (isARM)
973 emitARMRegPlusImmediate(MBB, MBBI, dl, ARM::SP, ARM::SP, NumBytes,
974 Pred, PredReg, TII);
975 else
976 emitT2RegPlusImmediate(MBB, MBBI, dl, ARM::SP, ARM::SP, NumBytes,
977 Pred, PredReg, TII);
David Goodwindb5a71a2009-07-08 18:31:39 +0000978}
979
Evan Cheng6495f632009-07-28 05:48:47 +0000980
David Goodwindb5a71a2009-07-08 18:31:39 +0000981void ARMBaseRegisterInfo::
982eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
983 MachineBasicBlock::iterator I) const {
984 if (!hasReservedCallFrame(MF)) {
985 // If we have alloca, convert as follows:
986 // ADJCALLSTACKDOWN -> sub, sp, sp, amount
987 // ADJCALLSTACKUP -> add, sp, sp, amount
988 MachineInstr *Old = I;
989 DebugLoc dl = Old->getDebugLoc();
990 unsigned Amount = Old->getOperand(0).getImm();
991 if (Amount != 0) {
992 // We need to keep the stack aligned properly. To do this, we round the
993 // amount of space needed for the outgoing arguments up to the next
994 // alignment boundary.
995 unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment();
996 Amount = (Amount+Align-1)/Align*Align;
997
Evan Cheng6495f632009-07-28 05:48:47 +0000998 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
999 assert(!AFI->isThumb1OnlyFunction() &&
1000 "This eliminateCallFramePseudoInstr does not suppor Thumb1!");
1001 bool isARM = !AFI->isThumbFunction();
1002
David Goodwindb5a71a2009-07-08 18:31:39 +00001003 // Replace the pseudo instruction with a new instruction...
1004 unsigned Opc = Old->getOpcode();
1005 ARMCC::CondCodes Pred = (ARMCC::CondCodes)Old->getOperand(1).getImm();
Evan Cheng6495f632009-07-28 05:48:47 +00001006 // FIXME: Thumb2 version of ADJCALLSTACKUP and ADJCALLSTACKDOWN?
David Goodwindb5a71a2009-07-08 18:31:39 +00001007 if (Opc == ARM::ADJCALLSTACKDOWN || Opc == ARM::tADJCALLSTACKDOWN) {
1008 // Note: PredReg is operand 2 for ADJCALLSTACKDOWN.
1009 unsigned PredReg = Old->getOperand(2).getReg();
Evan Cheng6495f632009-07-28 05:48:47 +00001010 emitSPUpdate(isARM, MBB, I, dl, TII, -Amount, Pred, PredReg);
David Goodwindb5a71a2009-07-08 18:31:39 +00001011 } else {
1012 // Note: PredReg is operand 3 for ADJCALLSTACKUP.
1013 unsigned PredReg = Old->getOperand(3).getReg();
1014 assert(Opc == ARM::ADJCALLSTACKUP || Opc == ARM::tADJCALLSTACKUP);
Evan Cheng6495f632009-07-28 05:48:47 +00001015 emitSPUpdate(isARM, MBB, I, dl, TII, Amount, Pred, PredReg);
David Goodwindb5a71a2009-07-08 18:31:39 +00001016 }
1017 }
1018 }
1019 MBB.erase(I);
1020}
1021
Jim Grosbachb58f4982009-10-07 17:12:56 +00001022unsigned
Evan Cheng6495f632009-07-28 05:48:47 +00001023ARMBaseRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
Jim Grosbachb58f4982009-10-07 17:12:56 +00001024 int SPAdj, int *Value,
1025 RegScavenger *RS) const {
David Goodwindb5a71a2009-07-08 18:31:39 +00001026 unsigned i = 0;
1027 MachineInstr &MI = *II;
1028 MachineBasicBlock &MBB = *MI.getParent();
1029 MachineFunction &MF = *MBB.getParent();
Evan Cheng010b1b92009-08-15 02:05:35 +00001030 const MachineFrameInfo *MFI = MF.getFrameInfo();
David Goodwindb5a71a2009-07-08 18:31:39 +00001031 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
Evan Cheng6495f632009-07-28 05:48:47 +00001032 assert(!AFI->isThumb1OnlyFunction() &&
Bob Wilsona15de002009-09-18 21:42:44 +00001033 "This eliminateFrameIndex does not support Thumb1!");
David Goodwindb5a71a2009-07-08 18:31:39 +00001034
1035 while (!MI.getOperand(i).isFI()) {
1036 ++i;
1037 assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
1038 }
1039
1040 unsigned FrameReg = ARM::SP;
1041 int FrameIndex = MI.getOperand(i).getIndex();
Evan Cheng010b1b92009-08-15 02:05:35 +00001042 int Offset = MFI->getObjectOffset(FrameIndex) + MFI->getStackSize() + SPAdj;
David Goodwindb5a71a2009-07-08 18:31:39 +00001043
1044 if (AFI->isGPRCalleeSavedArea1Frame(FrameIndex))
1045 Offset -= AFI->getGPRCalleeSavedArea1Offset();
1046 else if (AFI->isGPRCalleeSavedArea2Frame(FrameIndex))
1047 Offset -= AFI->getGPRCalleeSavedArea2Offset();
1048 else if (AFI->isDPRCalleeSavedAreaFrame(FrameIndex))
1049 Offset -= AFI->getDPRCalleeSavedAreaOffset();
Evan Cheng010b1b92009-08-15 02:05:35 +00001050 else if (hasFP(MF) && AFI->hasStackFrame()) {
1051 assert(SPAdj == 0 && "Unexpected stack offset!");
1052 // Use frame pointer to reference fixed objects unless this is a
1053 // frameless function,
David Goodwindb5a71a2009-07-08 18:31:39 +00001054 FrameReg = getFrameRegister(MF);
1055 Offset -= AFI->getFramePtrSpillOffset();
1056 }
1057
David Goodwin5ff58b52009-07-24 00:16:18 +00001058 // modify MI as necessary to handle as much of 'Offset' as possible
Evan Chengcdbb3f52009-08-27 01:23:50 +00001059 bool Done = false;
Evan Cheng6495f632009-07-28 05:48:47 +00001060 if (!AFI->isThumbFunction())
Evan Chengcdbb3f52009-08-27 01:23:50 +00001061 Done = rewriteARMFrameIndex(MI, i, FrameReg, Offset, TII);
Evan Cheng6495f632009-07-28 05:48:47 +00001062 else {
1063 assert(AFI->isThumb2Function());
Evan Chengcdbb3f52009-08-27 01:23:50 +00001064 Done = rewriteT2FrameIndex(MI, i, FrameReg, Offset, TII);
Evan Cheng6495f632009-07-28 05:48:47 +00001065 }
Evan Chengcdbb3f52009-08-27 01:23:50 +00001066 if (Done)
Jim Grosbachb58f4982009-10-07 17:12:56 +00001067 return 0;
David Goodwindb5a71a2009-07-08 18:31:39 +00001068
1069 // If we get here, the immediate doesn't fit into the instruction. We folded
1070 // as much as possible above, handle the rest, providing a register that is
1071 // SP+LargeImm.
Daniel Dunbar19bb87d2009-08-28 08:08:22 +00001072 assert((Offset ||
1073 (MI.getDesc().TSFlags & ARMII::AddrModeMask) == ARMII::AddrMode4) &&
Evan Chengcdbb3f52009-08-27 01:23:50 +00001074 "This code isn't needed if offset already handled!");
David Goodwindb5a71a2009-07-08 18:31:39 +00001075
Jim Grosbach7e831db2009-10-20 01:26:58 +00001076 unsigned ScratchReg = 0;
David Goodwindb5a71a2009-07-08 18:31:39 +00001077 int PIdx = MI.findFirstPredOperandIdx();
1078 ARMCC::CondCodes Pred = (PIdx == -1)
1079 ? ARMCC::AL : (ARMCC::CondCodes)MI.getOperand(PIdx).getImm();
1080 unsigned PredReg = (PIdx == -1) ? 0 : MI.getOperand(PIdx+1).getReg();
Evan Chengcdbb3f52009-08-27 01:23:50 +00001081 if (Offset == 0)
1082 // Must be addrmode4.
1083 MI.getOperand(i).ChangeToRegister(FrameReg, false, false, false);
Evan Cheng6495f632009-07-28 05:48:47 +00001084 else {
Jim Grosbach7e831db2009-10-20 01:26:58 +00001085 ScratchReg = MF.getRegInfo().createVirtualRegister(ARM::GPRRegisterClass);
1086 *Value = Offset;
Evan Chengcdbb3f52009-08-27 01:23:50 +00001087 if (!AFI->isThumbFunction())
1088 emitARMRegPlusImmediate(MBB, II, MI.getDebugLoc(), ScratchReg, FrameReg,
1089 Offset, Pred, PredReg, TII);
1090 else {
1091 assert(AFI->isThumb2Function());
1092 emitT2RegPlusImmediate(MBB, II, MI.getDebugLoc(), ScratchReg, FrameReg,
1093 Offset, Pred, PredReg, TII);
1094 }
1095 MI.getOperand(i).ChangeToRegister(ScratchReg, false, false, true);
Jim Grosbach18ed9c92009-10-20 20:19:50 +00001096 if (!ReuseFrameIndexVals)
1097 ScratchReg = 0;
Evan Cheng6495f632009-07-28 05:48:47 +00001098 }
Jim Grosbach7e831db2009-10-20 01:26:58 +00001099 return ScratchReg;
David Goodwindb5a71a2009-07-08 18:31:39 +00001100}
1101
1102/// Move iterator pass the next bunch of callee save load / store ops for
1103/// the particular spill area (1: integer area 1, 2: integer area 2,
1104/// 3: fp area, 0: don't care).
1105static void movePastCSLoadStoreOps(MachineBasicBlock &MBB,
1106 MachineBasicBlock::iterator &MBBI,
David Goodwin5ff58b52009-07-24 00:16:18 +00001107 int Opc1, int Opc2, unsigned Area,
David Goodwindb5a71a2009-07-08 18:31:39 +00001108 const ARMSubtarget &STI) {
1109 while (MBBI != MBB.end() &&
David Goodwin5ff58b52009-07-24 00:16:18 +00001110 ((MBBI->getOpcode() == Opc1) || (MBBI->getOpcode() == Opc2)) &&
1111 MBBI->getOperand(1).isFI()) {
David Goodwindb5a71a2009-07-08 18:31:39 +00001112 if (Area != 0) {
1113 bool Done = false;
1114 unsigned Category = 0;
1115 switch (MBBI->getOperand(0).getReg()) {
1116 case ARM::R4: case ARM::R5: case ARM::R6: case ARM::R7:
1117 case ARM::LR:
1118 Category = 1;
1119 break;
1120 case ARM::R8: case ARM::R9: case ARM::R10: case ARM::R11:
1121 Category = STI.isTargetDarwin() ? 2 : 1;
1122 break;
1123 case ARM::D8: case ARM::D9: case ARM::D10: case ARM::D11:
1124 case ARM::D12: case ARM::D13: case ARM::D14: case ARM::D15:
1125 Category = 3;
1126 break;
1127 default:
1128 Done = true;
1129 break;
1130 }
1131 if (Done || Category != Area)
1132 break;
1133 }
1134
1135 ++MBBI;
1136 }
1137}
1138
1139void ARMBaseRegisterInfo::
1140emitPrologue(MachineFunction &MF) const {
1141 MachineBasicBlock &MBB = MF.front();
1142 MachineBasicBlock::iterator MBBI = MBB.begin();
1143 MachineFrameInfo *MFI = MF.getFrameInfo();
1144 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
Evan Cheng6495f632009-07-28 05:48:47 +00001145 assert(!AFI->isThumb1OnlyFunction() &&
1146 "This emitPrologue does not suppor Thumb1!");
1147 bool isARM = !AFI->isThumbFunction();
David Goodwindb5a71a2009-07-08 18:31:39 +00001148 unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize();
1149 unsigned NumBytes = MFI->getStackSize();
1150 const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
1151 DebugLoc dl = (MBBI != MBB.end() ?
1152 MBBI->getDebugLoc() : DebugLoc::getUnknownLoc());
1153
1154 // Determine the sizes of each callee-save spill areas and record which frame
1155 // belongs to which callee-save spill areas.
1156 unsigned GPRCS1Size = 0, GPRCS2Size = 0, DPRCSSize = 0;
1157 int FramePtrSpillFI = 0;
1158
Bob Wilsonc8ce2d42009-09-25 16:34:46 +00001159 // Allocate the vararg register save area. This is not counted in NumBytes.
David Goodwindb5a71a2009-07-08 18:31:39 +00001160 if (VARegSaveSize)
Evan Cheng6495f632009-07-28 05:48:47 +00001161 emitSPUpdate(isARM, MBB, MBBI, dl, TII, -VARegSaveSize);
David Goodwindb5a71a2009-07-08 18:31:39 +00001162
1163 if (!AFI->hasStackFrame()) {
1164 if (NumBytes != 0)
Evan Cheng6495f632009-07-28 05:48:47 +00001165 emitSPUpdate(isARM, MBB, MBBI, dl, TII, -NumBytes);
David Goodwindb5a71a2009-07-08 18:31:39 +00001166 return;
1167 }
1168
1169 for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
1170 unsigned Reg = CSI[i].getReg();
1171 int FI = CSI[i].getFrameIdx();
1172 switch (Reg) {
1173 case ARM::R4:
1174 case ARM::R5:
1175 case ARM::R6:
1176 case ARM::R7:
1177 case ARM::LR:
1178 if (Reg == FramePtr)
1179 FramePtrSpillFI = FI;
1180 AFI->addGPRCalleeSavedArea1Frame(FI);
1181 GPRCS1Size += 4;
1182 break;
1183 case ARM::R8:
1184 case ARM::R9:
1185 case ARM::R10:
1186 case ARM::R11:
1187 if (Reg == FramePtr)
1188 FramePtrSpillFI = FI;
1189 if (STI.isTargetDarwin()) {
1190 AFI->addGPRCalleeSavedArea2Frame(FI);
1191 GPRCS2Size += 4;
1192 } else {
1193 AFI->addGPRCalleeSavedArea1Frame(FI);
1194 GPRCS1Size += 4;
1195 }
1196 break;
1197 default:
1198 AFI->addDPRCalleeSavedAreaFrame(FI);
1199 DPRCSSize += 8;
1200 }
1201 }
1202
1203 // Build the new SUBri to adjust SP for integer callee-save spill area 1.
Evan Cheng6495f632009-07-28 05:48:47 +00001204 emitSPUpdate(isARM, MBB, MBBI, dl, TII, -GPRCS1Size);
Evan Cheng5732ca02009-07-27 03:14:20 +00001205 movePastCSLoadStoreOps(MBB, MBBI, ARM::STR, ARM::t2STRi12, 1, STI);
David Goodwindb5a71a2009-07-08 18:31:39 +00001206
Bob Wilsonc8ce2d42009-09-25 16:34:46 +00001207 // Set FP to point to the stack slot that contains the previous FP.
1208 // For Darwin, FP is R7, which has now been stored in spill area 1.
1209 // Otherwise, if this is not Darwin, all the callee-saved registers go
1210 // into spill area 1, including the FP in R11. In either case, it is
1211 // now safe to emit this assignment.
David Goodwindb5a71a2009-07-08 18:31:39 +00001212 if (STI.isTargetDarwin() || hasFP(MF)) {
Evan Cheng6495f632009-07-28 05:48:47 +00001213 unsigned ADDriOpc = !AFI->isThumbFunction() ? ARM::ADDri : ARM::t2ADDri;
David Goodwindb5a71a2009-07-08 18:31:39 +00001214 MachineInstrBuilder MIB =
Evan Cheng6495f632009-07-28 05:48:47 +00001215 BuildMI(MBB, MBBI, dl, TII.get(ADDriOpc), FramePtr)
David Goodwindb5a71a2009-07-08 18:31:39 +00001216 .addFrameIndex(FramePtrSpillFI).addImm(0);
1217 AddDefaultCC(AddDefaultPred(MIB));
1218 }
1219
1220 // Build the new SUBri to adjust SP for integer callee-save spill area 2.
Evan Cheng6495f632009-07-28 05:48:47 +00001221 emitSPUpdate(isARM, MBB, MBBI, dl, TII, -GPRCS2Size);
David Goodwindb5a71a2009-07-08 18:31:39 +00001222
1223 // Build the new SUBri to adjust SP for FP callee-save spill area.
Evan Cheng5732ca02009-07-27 03:14:20 +00001224 movePastCSLoadStoreOps(MBB, MBBI, ARM::STR, ARM::t2STRi12, 2, STI);
Evan Cheng6495f632009-07-28 05:48:47 +00001225 emitSPUpdate(isARM, MBB, MBBI, dl, TII, -DPRCSSize);
David Goodwindb5a71a2009-07-08 18:31:39 +00001226
1227 // Determine starting offsets of spill areas.
1228 unsigned DPRCSOffset = NumBytes - (GPRCS1Size + GPRCS2Size + DPRCSSize);
1229 unsigned GPRCS2Offset = DPRCSOffset + DPRCSSize;
1230 unsigned GPRCS1Offset = GPRCS2Offset + GPRCS2Size;
1231 AFI->setFramePtrSpillOffset(MFI->getObjectOffset(FramePtrSpillFI) + NumBytes);
1232 AFI->setGPRCalleeSavedArea1Offset(GPRCS1Offset);
1233 AFI->setGPRCalleeSavedArea2Offset(GPRCS2Offset);
1234 AFI->setDPRCalleeSavedAreaOffset(DPRCSOffset);
1235
1236 NumBytes = DPRCSOffset;
1237 if (NumBytes) {
1238 // Insert it after all the callee-save spills.
Evan Chengb74bb1a2009-07-24 00:53:56 +00001239 movePastCSLoadStoreOps(MBB, MBBI, ARM::FSTD, 0, 3, STI);
Evan Cheng6495f632009-07-28 05:48:47 +00001240 emitSPUpdate(isARM, MBB, MBBI, dl, TII, -NumBytes);
David Goodwindb5a71a2009-07-08 18:31:39 +00001241 }
1242
1243 if (STI.isTargetELF() && hasFP(MF)) {
1244 MFI->setOffsetAdjustment(MFI->getOffsetAdjustment() -
1245 AFI->getFramePtrSpillOffset());
1246 }
1247
1248 AFI->setGPRCalleeSavedArea1Size(GPRCS1Size);
1249 AFI->setGPRCalleeSavedArea2Size(GPRCS2Size);
1250 AFI->setDPRCalleeSavedAreaSize(DPRCSSize);
1251}
1252
1253static bool isCalleeSavedRegister(unsigned Reg, const unsigned *CSRegs) {
1254 for (unsigned i = 0; CSRegs[i]; ++i)
1255 if (Reg == CSRegs[i])
1256 return true;
1257 return false;
1258}
1259
David Goodwin77521f52009-07-08 20:28:28 +00001260static bool isCSRestore(MachineInstr *MI,
Jim Grosbach764ab522009-08-11 15:33:49 +00001261 const ARMBaseInstrInfo &TII,
David Goodwin77521f52009-07-08 20:28:28 +00001262 const unsigned *CSRegs) {
Evan Chengb74bb1a2009-07-24 00:53:56 +00001263 return ((MI->getOpcode() == (int)ARM::FLDD ||
Evan Cheng5732ca02009-07-27 03:14:20 +00001264 MI->getOpcode() == (int)ARM::LDR ||
1265 MI->getOpcode() == (int)ARM::t2LDRi12) &&
David Goodwindb5a71a2009-07-08 18:31:39 +00001266 MI->getOperand(1).isFI() &&
1267 isCalleeSavedRegister(MI->getOperand(0).getReg(), CSRegs));
1268}
1269
1270void ARMBaseRegisterInfo::
Evan Cheng293f8d92009-07-27 18:31:40 +00001271emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const {
David Goodwindb5a71a2009-07-08 18:31:39 +00001272 MachineBasicBlock::iterator MBBI = prior(MBB.end());
Evan Cheng5ca53a72009-07-27 18:20:05 +00001273 assert(MBBI->getDesc().isReturn() &&
David Goodwindb5a71a2009-07-08 18:31:39 +00001274 "Can only insert epilog into returning blocks");
1275 DebugLoc dl = MBBI->getDebugLoc();
1276 MachineFrameInfo *MFI = MF.getFrameInfo();
1277 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
Evan Cheng6495f632009-07-28 05:48:47 +00001278 assert(!AFI->isThumb1OnlyFunction() &&
1279 "This emitEpilogue does not suppor Thumb1!");
1280 bool isARM = !AFI->isThumbFunction();
1281
David Goodwindb5a71a2009-07-08 18:31:39 +00001282 unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize();
1283 int NumBytes = (int)MFI->getStackSize();
1284
1285 if (!AFI->hasStackFrame()) {
1286 if (NumBytes != 0)
Evan Cheng6495f632009-07-28 05:48:47 +00001287 emitSPUpdate(isARM, MBB, MBBI, dl, TII, NumBytes);
David Goodwindb5a71a2009-07-08 18:31:39 +00001288 } else {
1289 // Unwind MBBI to point to first LDR / FLDD.
1290 const unsigned *CSRegs = getCalleeSavedRegs();
1291 if (MBBI != MBB.begin()) {
1292 do
1293 --MBBI;
David Goodwin77521f52009-07-08 20:28:28 +00001294 while (MBBI != MBB.begin() && isCSRestore(MBBI, TII, CSRegs));
1295 if (!isCSRestore(MBBI, TII, CSRegs))
David Goodwindb5a71a2009-07-08 18:31:39 +00001296 ++MBBI;
1297 }
1298
1299 // Move SP to start of FP callee save spill area.
1300 NumBytes -= (AFI->getGPRCalleeSavedArea1Size() +
1301 AFI->getGPRCalleeSavedArea2Size() +
1302 AFI->getDPRCalleeSavedAreaSize());
1303
1304 // Darwin ABI requires FP to point to the stack slot that contains the
1305 // previous FP.
Evan Cheng010b1b92009-08-15 02:05:35 +00001306 bool HasFP = hasFP(MF);
1307 if ((STI.isTargetDarwin() && NumBytes) || HasFP) {
David Goodwindb5a71a2009-07-08 18:31:39 +00001308 NumBytes = AFI->getFramePtrSpillOffset() - NumBytes;
1309 // Reset SP based on frame pointer only if the stack frame extends beyond
1310 // frame pointer stack slot or target is ELF and the function has FP.
Evan Cheng010b1b92009-08-15 02:05:35 +00001311 if (HasFP ||
1312 AFI->getGPRCalleeSavedArea2Size() ||
David Goodwindb5a71a2009-07-08 18:31:39 +00001313 AFI->getDPRCalleeSavedAreaSize() ||
Evan Cheng010b1b92009-08-15 02:05:35 +00001314 AFI->getDPRCalleeSavedAreaOffset()) {
Evan Cheng6495f632009-07-28 05:48:47 +00001315 if (NumBytes) {
Evan Cheng86198642009-08-07 00:34:42 +00001316 if (isARM)
1317 emitARMRegPlusImmediate(MBB, MBBI, dl, ARM::SP, FramePtr, -NumBytes,
1318 ARMCC::AL, 0, TII);
1319 else
1320 emitT2RegPlusImmediate(MBB, MBBI, dl, ARM::SP, FramePtr, -NumBytes,
1321 ARMCC::AL, 0, TII);
Evan Cheng6495f632009-07-28 05:48:47 +00001322 } else {
1323 // Thumb2 or ARM.
Jim Grosbach764ab522009-08-11 15:33:49 +00001324 if (isARM)
Evan Cheng052053b2009-08-10 05:49:43 +00001325 BuildMI(MBB, MBBI, dl, TII.get(ARM::MOVr), ARM::SP)
1326 .addReg(FramePtr)
1327 .addImm((unsigned)ARMCC::AL).addReg(0).addReg(0);
1328 else
1329 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVgpr2gpr), ARM::SP)
1330 .addReg(FramePtr);
Evan Cheng6495f632009-07-28 05:48:47 +00001331 }
David Goodwindb5a71a2009-07-08 18:31:39 +00001332 }
Evan Cheng6495f632009-07-28 05:48:47 +00001333 } else if (NumBytes)
1334 emitSPUpdate(isARM, MBB, MBBI, dl, TII, NumBytes);
David Goodwindb5a71a2009-07-08 18:31:39 +00001335
1336 // Move SP to start of integer callee save spill area 2.
Evan Chengb74bb1a2009-07-24 00:53:56 +00001337 movePastCSLoadStoreOps(MBB, MBBI, ARM::FLDD, 0, 3, STI);
Evan Cheng6495f632009-07-28 05:48:47 +00001338 emitSPUpdate(isARM, MBB, MBBI, dl, TII, AFI->getDPRCalleeSavedAreaSize());
David Goodwindb5a71a2009-07-08 18:31:39 +00001339
1340 // Move SP to start of integer callee save spill area 1.
Evan Cheng5732ca02009-07-27 03:14:20 +00001341 movePastCSLoadStoreOps(MBB, MBBI, ARM::LDR, ARM::t2LDRi12, 2, STI);
Evan Cheng6495f632009-07-28 05:48:47 +00001342 emitSPUpdate(isARM, MBB, MBBI, dl, TII, AFI->getGPRCalleeSavedArea2Size());
David Goodwindb5a71a2009-07-08 18:31:39 +00001343
1344 // Move SP to SP upon entry to the function.
Evan Cheng5732ca02009-07-27 03:14:20 +00001345 movePastCSLoadStoreOps(MBB, MBBI, ARM::LDR, ARM::t2LDRi12, 1, STI);
Evan Cheng6495f632009-07-28 05:48:47 +00001346 emitSPUpdate(isARM, MBB, MBBI, dl, TII, AFI->getGPRCalleeSavedArea1Size());
David Goodwindb5a71a2009-07-08 18:31:39 +00001347 }
1348
1349 if (VARegSaveSize)
Evan Cheng6495f632009-07-28 05:48:47 +00001350 emitSPUpdate(isARM, MBB, MBBI, dl, TII, VARegSaveSize);
David Goodwindb5a71a2009-07-08 18:31:39 +00001351}
1352
David Goodwinc140c482009-07-08 17:28:55 +00001353#include "ARMGenRegisterInfo.inc"