Deleted Added
full compact
ARMRegisterInfo.cpp (194710) ARMRegisterInfo.cpp (195340)
1//===- ARMRegisterInfo.cpp - ARM Register Information -----------*- C++ -*-===//
2//
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//===----------------------------------------------------------------------===//

--- 17 unchanged lines hidden (view full) ---

26#include "llvm/CodeGen/MachineLocation.h"
27#include "llvm/CodeGen/MachineRegisterInfo.h"
28#include "llvm/CodeGen/RegisterScavenging.h"
29#include "llvm/Target/TargetFrameInfo.h"
30#include "llvm/Target/TargetMachine.h"
31#include "llvm/Target/TargetOptions.h"
32#include "llvm/ADT/BitVector.h"
33#include "llvm/ADT/SmallVector.h"
1//===- ARMRegisterInfo.cpp - ARM Register Information -----------*- C++ -*-===//
2//
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//===----------------------------------------------------------------------===//

--- 17 unchanged lines hidden (view full) ---

26#include "llvm/CodeGen/MachineLocation.h"
27#include "llvm/CodeGen/MachineRegisterInfo.h"
28#include "llvm/CodeGen/RegisterScavenging.h"
29#include "llvm/Target/TargetFrameInfo.h"
30#include "llvm/Target/TargetMachine.h"
31#include "llvm/Target/TargetOptions.h"
32#include "llvm/ADT/BitVector.h"
33#include "llvm/ADT/SmallVector.h"
34#include "llvm/ADT/STLExtras.h"
35#include "llvm/Support/CommandLine.h"
36#include <algorithm>
37using namespace llvm;
38
34using namespace llvm;
35
39static cl::opt<bool> ThumbRegScavenging("enable-thumb-reg-scavenging",
40 cl::Hidden,
41 cl::desc("Enable register scavenging on Thumb"));
42
43unsigned ARMRegisterInfo::getRegisterNumbering(unsigned RegEnum) {
36unsigned ARMBaseRegisterInfo::getRegisterNumbering(unsigned RegEnum) {
44 using namespace ARM;
45 switch (RegEnum) {
46 case R0: case S0: case D0: return 0;
47 case R1: case S1: case D1: return 1;
48 case R2: case S2: case D2: return 2;
49 case R3: case S3: case D3: return 3;
50 case R4: case S4: case D4: return 4;
51 case R5: case S5: case D5: return 5;

--- 24 unchanged lines hidden (view full) ---

76 case S30: return 30;
77 case S31: return 31;
78 default:
79 assert(0 && "Unknown ARM register!");
80 abort();
81 }
82}
83
37 using namespace ARM;
38 switch (RegEnum) {
39 case R0: case S0: case D0: return 0;
40 case R1: case S1: case D1: return 1;
41 case R2: case S2: case D2: return 2;
42 case R3: case S3: case D3: return 3;
43 case R4: case S4: case D4: return 4;
44 case R5: case S5: case D5: return 5;

--- 24 unchanged lines hidden (view full) ---

69 case S30: return 30;
70 case S31: return 31;
71 default:
72 assert(0 && "Unknown ARM register!");
73 abort();
74 }
75}
76
84unsigned ARMRegisterInfo::getRegisterNumbering(unsigned RegEnum,
85 bool &isSPVFP) {
77unsigned ARMBaseRegisterInfo::getRegisterNumbering(unsigned RegEnum,
78 bool &isSPVFP) {
86 isSPVFP = false;
87
88 using namespace ARM;
89 switch (RegEnum) {
90 default:
91 assert(0 && "Unknown ARM register!");
92 abort();
93 case R0: case D0: return 0;

--- 9 unchanged lines hidden (view full) ---

103 case R10: case D10: return 10;
104 case R11: case D11: return 11;
105 case R12: case D12: return 12;
106 case SP: case D13: return 13;
107 case LR: case D14: return 14;
108 case PC: case D15: return 15;
109
110 case S0: case S1: case S2: case S3:
79 isSPVFP = false;
80
81 using namespace ARM;
82 switch (RegEnum) {
83 default:
84 assert(0 && "Unknown ARM register!");
85 abort();
86 case R0: case D0: return 0;

--- 9 unchanged lines hidden (view full) ---

96 case R10: case D10: return 10;
97 case R11: case D11: return 11;
98 case R12: case D12: return 12;
99 case SP: case D13: return 13;
100 case LR: case D14: return 14;
101 case PC: case D15: return 15;
102
103 case S0: case S1: case S2: case S3:
111 case S4: case S5: case S6: case S7:
112 case S8: case S9: case S10: case S11:
113 case S12: case S13: case S14: case S15:
114 case S16: case S17: case S18: case S19:
115 case S20: case S21: case S22: case S23:
116 case S24: case S25: case S26: case S27:
104 case S4: case S5: case S6: case S7:
105 case S8: case S9: case S10: case S11:
106 case S12: case S13: case S14: case S15:
107 case S16: case S17: case S18: case S19:
108 case S20: case S21: case S22: case S23:
109 case S24: case S25: case S26: case S27:
117 case S28: case S29: case S30: case S31: {
118 isSPVFP = true;
119 switch (RegEnum) {
120 default: return 0; // Avoid compile time warning.
121 case S0: return 0;
122 case S1: return 1;
123 case S2: return 2;
124 case S3: return 3;

--- 25 unchanged lines hidden (view full) ---

150 case S29: return 29;
151 case S30: return 30;
152 case S31: return 31;
153 }
154 }
155 }
156}
157
110 case S28: case S29: case S30: case S31: {
111 isSPVFP = true;
112 switch (RegEnum) {
113 default: return 0; // Avoid compile time warning.
114 case S0: return 0;
115 case S1: return 1;
116 case S2: return 2;
117 case S3: return 3;

--- 25 unchanged lines hidden (view full) ---

143 case S29: return 29;
144 case S30: return 30;
145 case S31: return 31;
146 }
147 }
148 }
149}
150
158ARMRegisterInfo::ARMRegisterInfo(const TargetInstrInfo &tii,
159 const ARMSubtarget &sti)
151ARMBaseRegisterInfo::ARMBaseRegisterInfo(const TargetInstrInfo &tii,
152 const ARMSubtarget &sti)
160 : ARMGenRegisterInfo(ARM::ADJCALLSTACKDOWN, ARM::ADJCALLSTACKUP),
161 TII(tii), STI(sti),
162 FramePtr((STI.isTargetDarwin() || STI.isThumb()) ? ARM::R7 : ARM::R11) {
163}
164
153 : ARMGenRegisterInfo(ARM::ADJCALLSTACKDOWN, ARM::ADJCALLSTACKUP),
154 TII(tii), STI(sti),
155 FramePtr((STI.isTargetDarwin() || STI.isThumb()) ? ARM::R7 : ARM::R11) {
156}
157
158ARMRegisterInfo::ARMRegisterInfo(const TargetInstrInfo &tii,
159 const ARMSubtarget &sti)
160 : ARMBaseRegisterInfo(tii, sti) {
161}
162
165static inline
166const MachineInstrBuilder &AddDefaultPred(const MachineInstrBuilder &MIB) {
167 return MIB.addImm((int64_t)ARMCC::AL).addReg(0);
168}
169
170static inline
171const MachineInstrBuilder &AddDefaultCC(const MachineInstrBuilder &MIB) {
172 return MIB.addReg(0);
173}
174
175/// emitLoadConstPool - Emits a load from constpool to materialize the
176/// specified immediate.
177void ARMRegisterInfo::emitLoadConstPool(MachineBasicBlock &MBB,
178 MachineBasicBlock::iterator &MBBI,
163static inline
164const MachineInstrBuilder &AddDefaultPred(const MachineInstrBuilder &MIB) {
165 return MIB.addImm((int64_t)ARMCC::AL).addReg(0);
166}
167
168static inline
169const MachineInstrBuilder &AddDefaultCC(const MachineInstrBuilder &MIB) {
170 return MIB.addReg(0);
171}
172
173/// emitLoadConstPool - Emits a load from constpool to materialize the
174/// specified immediate.
175void ARMRegisterInfo::emitLoadConstPool(MachineBasicBlock &MBB,
176 MachineBasicBlock::iterator &MBBI,
177 const TargetInstrInfo *TII, DebugLoc dl,
179 unsigned DestReg, int Val,
178 unsigned DestReg, int Val,
180 unsigned Pred, unsigned PredReg,
181 const TargetInstrInfo *TII,
182 bool isThumb,
183 DebugLoc dl) const {
179 ARMCC::CondCodes Pred,
180 unsigned PredReg) const {
184 MachineFunction &MF = *MBB.getParent();
185 MachineConstantPool *ConstantPool = MF.getConstantPool();
186 Constant *C = ConstantInt::get(Type::Int32Ty, Val);
187 unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4);
181 MachineFunction &MF = *MBB.getParent();
182 MachineConstantPool *ConstantPool = MF.getConstantPool();
183 Constant *C = ConstantInt::get(Type::Int32Ty, Val);
184 unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4);
188 if (isThumb)
189 BuildMI(MBB, MBBI, dl,
190 TII->get(ARM::tLDRcp),DestReg).addConstantPoolIndex(Idx);
191 else
192 BuildMI(MBB, MBBI, dl, TII->get(ARM::LDRcp), DestReg)
193 .addConstantPoolIndex(Idx)
194 .addReg(0).addImm(0).addImm(Pred).addReg(PredReg);
195}
196
185
197/// isLowRegister - Returns true if the register is low register r0-r7.
198///
199bool ARMRegisterInfo::isLowRegister(unsigned Reg) const {
200 using namespace ARM;
201 switch (Reg) {
202 case R0: case R1: case R2: case R3:
203 case R4: case R5: case R6: case R7:
204 return true;
205 default:
206 return false;
207 }
186 BuildMI(MBB, MBBI, dl, TII->get(ARM::LDRcp), DestReg)
187 .addConstantPoolIndex(Idx)
188 .addReg(0).addImm(0).addImm(Pred).addReg(PredReg);
208}
209
189}
190
210const TargetRegisterClass*
211ARMRegisterInfo::getPhysicalRegisterRegClass(unsigned Reg, MVT VT) const {
212 if (STI.isThumb()) {
213 if (isLowRegister(Reg))
214 return ARM::tGPRRegisterClass;
215 switch (Reg) {
216 default:
217 break;
218 case ARM::R8: case ARM::R9: case ARM::R10: case ARM::R11:
219 case ARM::R12: case ARM::SP: case ARM::LR: case ARM::PC:
220 return ARM::GPRRegisterClass;
221 }
222 }
223 return TargetRegisterInfo::getPhysicalRegisterRegClass(Reg, VT);
224}
225
226const unsigned*
191const unsigned*
227ARMRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
192ARMBaseRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
228 static const unsigned CalleeSavedRegs[] = {
229 ARM::LR, ARM::R11, ARM::R10, ARM::R9, ARM::R8,
230 ARM::R7, ARM::R6, ARM::R5, ARM::R4,
231
232 ARM::D15, ARM::D14, ARM::D13, ARM::D12,
233 ARM::D11, ARM::D10, ARM::D9, ARM::D8,
234 0
235 };

--- 7 unchanged lines hidden (view full) ---

243 ARM::D15, ARM::D14, ARM::D13, ARM::D12,
244 ARM::D11, ARM::D10, ARM::D9, ARM::D8,
245 0
246 };
247 return STI.isTargetDarwin() ? DarwinCalleeSavedRegs : CalleeSavedRegs;
248}
249
250const TargetRegisterClass* const *
193 static const unsigned CalleeSavedRegs[] = {
194 ARM::LR, ARM::R11, ARM::R10, ARM::R9, ARM::R8,
195 ARM::R7, ARM::R6, ARM::R5, ARM::R4,
196
197 ARM::D15, ARM::D14, ARM::D13, ARM::D12,
198 ARM::D11, ARM::D10, ARM::D9, ARM::D8,
199 0
200 };

--- 7 unchanged lines hidden (view full) ---

208 ARM::D15, ARM::D14, ARM::D13, ARM::D12,
209 ARM::D11, ARM::D10, ARM::D9, ARM::D8,
210 0
211 };
212 return STI.isTargetDarwin() ? DarwinCalleeSavedRegs : CalleeSavedRegs;
213}
214
215const TargetRegisterClass* const *
251ARMRegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const {
216ARMBaseRegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const {
252 static const TargetRegisterClass * const CalleeSavedRegClasses[] = {
253 &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::GPRRegClass,
254 &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::GPRRegClass,
255 &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::GPRRegClass,
256
257 &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass,
258 &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass,
259 0

--- 32 unchanged lines hidden (view full) ---

292 if (STI.isThumb()) {
293 return STI.isTargetDarwin()
294 ? DarwinThumbCalleeSavedRegClasses : ThumbCalleeSavedRegClasses;
295 }
296 return STI.isTargetDarwin()
297 ? DarwinCalleeSavedRegClasses : CalleeSavedRegClasses;
298}
299
217 static const TargetRegisterClass * const CalleeSavedRegClasses[] = {
218 &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::GPRRegClass,
219 &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::GPRRegClass,
220 &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::GPRRegClass,
221
222 &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass,
223 &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass,
224 0

--- 32 unchanged lines hidden (view full) ---

257 if (STI.isThumb()) {
258 return STI.isTargetDarwin()
259 ? DarwinThumbCalleeSavedRegClasses : ThumbCalleeSavedRegClasses;
260 }
261 return STI.isTargetDarwin()
262 ? DarwinCalleeSavedRegClasses : CalleeSavedRegClasses;
263}
264
300BitVector ARMRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
265BitVector ARMBaseRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
301 // FIXME: avoid re-calculating this everytime.
302 BitVector Reserved(getNumRegs());
303 Reserved.set(ARM::SP);
304 Reserved.set(ARM::PC);
305 if (STI.isTargetDarwin() || hasFP(MF))
306 Reserved.set(FramePtr);
307 // Some targets reserve R9.
308 if (STI.isR9Reserved())
309 Reserved.set(ARM::R9);
310 return Reserved;
311}
312
313bool
266 // FIXME: avoid re-calculating this everytime.
267 BitVector Reserved(getNumRegs());
268 Reserved.set(ARM::SP);
269 Reserved.set(ARM::PC);
270 if (STI.isTargetDarwin() || hasFP(MF))
271 Reserved.set(FramePtr);
272 // Some targets reserve R9.
273 if (STI.isR9Reserved())
274 Reserved.set(ARM::R9);
275 return Reserved;
276}
277
278bool
314ARMRegisterInfo::isReservedReg(const MachineFunction &MF, unsigned Reg) const {
279ARMBaseRegisterInfo::isReservedReg(const MachineFunction &MF, unsigned Reg) const {
315 switch (Reg) {
316 default: break;
317 case ARM::SP:
318 case ARM::PC:
319 return true;
320 case ARM::R7:
321 case ARM::R11:
322 if (FramePtr == Reg && (STI.isTargetDarwin() || hasFP(MF)))
323 return true;
324 break;
325 case ARM::R9:
326 return STI.isR9Reserved();
327 }
328
329 return false;
330}
331
280 switch (Reg) {
281 default: break;
282 case ARM::SP:
283 case ARM::PC:
284 return true;
285 case ARM::R7:
286 case ARM::R11:
287 if (FramePtr == Reg && (STI.isTargetDarwin() || hasFP(MF)))
288 return true;
289 break;
290 case ARM::R9:
291 return STI.isR9Reserved();
292 }
293
294 return false;
295}
296
332const TargetRegisterClass *ARMRegisterInfo::getPointerRegClass() const {
297const TargetRegisterClass *ARMBaseRegisterInfo::getPointerRegClass() const {
333 return &ARM::GPRRegClass;
334}
335
336/// getAllocationOrder - Returns the register allocation order for a specified
337/// register class in the form of a pair of TargetRegisterClass iterators.
338std::pair<TargetRegisterClass::iterator,TargetRegisterClass::iterator>
298 return &ARM::GPRRegClass;
299}
300
301/// getAllocationOrder - Returns the register allocation order for a specified
302/// register class in the form of a pair of TargetRegisterClass iterators.
303std::pair<TargetRegisterClass::iterator,TargetRegisterClass::iterator>
339ARMRegisterInfo::getAllocationOrder(const TargetRegisterClass *RC,
340 unsigned HintType, unsigned HintReg,
341 const MachineFunction &MF) const {
304ARMBaseRegisterInfo::getAllocationOrder(const TargetRegisterClass *RC,
305 unsigned HintType, unsigned HintReg,
306 const MachineFunction &MF) const {
342 // Alternative register allocation orders when favoring even / odd registers
343 // of register pairs.
344
345 // No FP, R9 is available.
346 static const unsigned GPREven1[] = {
347 ARM::R0, ARM::R2, ARM::R4, ARM::R6, ARM::R8, ARM::R10,
348 ARM::R1, ARM::R3, ARM::R12,ARM::LR, ARM::R5, ARM::R7,
349 ARM::R9, ARM::R11

--- 124 unchanged lines hidden (view full) ---

474 }
475 return std::make_pair(RC->allocation_order_begin(MF),
476 RC->allocation_order_end(MF));
477}
478
479/// ResolveRegAllocHint - Resolves the specified register allocation hint
480/// to a physical register. Returns the physical register if it is successful.
481unsigned
307 // Alternative register allocation orders when favoring even / odd registers
308 // of register pairs.
309
310 // No FP, R9 is available.
311 static const unsigned GPREven1[] = {
312 ARM::R0, ARM::R2, ARM::R4, ARM::R6, ARM::R8, ARM::R10,
313 ARM::R1, ARM::R3, ARM::R12,ARM::LR, ARM::R5, ARM::R7,
314 ARM::R9, ARM::R11

--- 124 unchanged lines hidden (view full) ---

439 }
440 return std::make_pair(RC->allocation_order_begin(MF),
441 RC->allocation_order_end(MF));
442}
443
444/// ResolveRegAllocHint - Resolves the specified register allocation hint
445/// to a physical register. Returns the physical register if it is successful.
446unsigned
482ARMRegisterInfo::ResolveRegAllocHint(unsigned Type, unsigned Reg,
483 const MachineFunction &MF) const {
447ARMBaseRegisterInfo::ResolveRegAllocHint(unsigned Type, unsigned Reg,
448 const MachineFunction &MF) const {
484 if (Reg == 0 || !isPhysicalRegister(Reg))
485 return 0;
486 if (Type == 0)
487 return Reg;
488 else if (Type == (unsigned)ARMRI::RegPairOdd)
489 // Odd register.
490 return getRegisterPairOdd(Reg, MF);
491 else if (Type == (unsigned)ARMRI::RegPairEven)
492 // Even register.
493 return getRegisterPairEven(Reg, MF);
494 return 0;
495}
496
497void
449 if (Reg == 0 || !isPhysicalRegister(Reg))
450 return 0;
451 if (Type == 0)
452 return Reg;
453 else if (Type == (unsigned)ARMRI::RegPairOdd)
454 // Odd register.
455 return getRegisterPairOdd(Reg, MF);
456 else if (Type == (unsigned)ARMRI::RegPairEven)
457 // Even register.
458 return getRegisterPairEven(Reg, MF);
459 return 0;
460}
461
462void
498ARMRegisterInfo::UpdateRegAllocHint(unsigned Reg, unsigned NewReg,
499 MachineFunction &MF) const {
463ARMBaseRegisterInfo::UpdateRegAllocHint(unsigned Reg, unsigned NewReg,
464 MachineFunction &MF) const {
500 MachineRegisterInfo *MRI = &MF.getRegInfo();
501 std::pair<unsigned, unsigned> Hint = MRI->getRegAllocationHint(Reg);
502 if ((Hint.first == (unsigned)ARMRI::RegPairOdd ||
503 Hint.first == (unsigned)ARMRI::RegPairEven) &&
504 Hint.second && TargetRegisterInfo::isVirtualRegister(Hint.second)) {
505 // If 'Reg' is one of the even / odd register pair and it's now changed
506 // (e.g. coalesced) into a different register. The other register of the
507 // pair allocation hint must be updated to reflect the relationship
508 // change.
509 unsigned OtherReg = Hint.second;
510 Hint = MRI->getRegAllocationHint(OtherReg);
511 if (Hint.second == Reg)
512 // Make sure the pair has not already divorced.
513 MRI->setRegAllocationHint(OtherReg, Hint.first, NewReg);
514 }
515}
516
517bool
518ARMRegisterInfo::requiresRegisterScavenging(const MachineFunction &MF) const {
465 MachineRegisterInfo *MRI = &MF.getRegInfo();
466 std::pair<unsigned, unsigned> Hint = MRI->getRegAllocationHint(Reg);
467 if ((Hint.first == (unsigned)ARMRI::RegPairOdd ||
468 Hint.first == (unsigned)ARMRI::RegPairEven) &&
469 Hint.second && TargetRegisterInfo::isVirtualRegister(Hint.second)) {
470 // If 'Reg' is one of the even / odd register pair and it's now changed
471 // (e.g. coalesced) into a different register. The other register of the
472 // pair allocation hint must be updated to reflect the relationship
473 // change.
474 unsigned OtherReg = Hint.second;
475 Hint = MRI->getRegAllocationHint(OtherReg);
476 if (Hint.second == Reg)
477 // Make sure the pair has not already divorced.
478 MRI->setRegAllocationHint(OtherReg, Hint.first, NewReg);
479 }
480}
481
482bool
483ARMRegisterInfo::requiresRegisterScavenging(const MachineFunction &MF) const {
519 const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
520 return ThumbRegScavenging || !AFI->isThumbFunction();
484 return true;
521}
522
523/// hasFP - Return true if the specified function should have a dedicated frame
524/// pointer register. This is true if the function has variable sized allocas
525/// or if frame pointer elimination is disabled.
526///
485}
486
487/// hasFP - Return true if the specified function should have a dedicated frame
488/// pointer register. This is true if the function has variable sized allocas
489/// or if frame pointer elimination is disabled.
490///
527bool ARMRegisterInfo::hasFP(const MachineFunction &MF) const {
491bool ARMBaseRegisterInfo::hasFP(const MachineFunction &MF) const {
528 const MachineFrameInfo *MFI = MF.getFrameInfo();
529 return (NoFramePointerElim ||
530 MFI->hasVarSizedObjects() ||
531 MFI->isFrameAddressTaken());
532}
533
534// hasReservedCallFrame - Under normal circumstances, when a frame pointer is
535// not required, we reserve argument space for call sites in the function
536// immediately on entry to the current function. This eliminates the need for
537// add/sub sp brackets around call sites. Returns true if the call frame is
538// included as part of the stack frame.
539bool ARMRegisterInfo::hasReservedCallFrame(MachineFunction &MF) const {
540 const MachineFrameInfo *FFI = MF.getFrameInfo();
541 unsigned CFSize = FFI->getMaxCallFrameSize();
492 const MachineFrameInfo *MFI = MF.getFrameInfo();
493 return (NoFramePointerElim ||
494 MFI->hasVarSizedObjects() ||
495 MFI->isFrameAddressTaken());
496}
497
498// hasReservedCallFrame - Under normal circumstances, when a frame pointer is
499// not required, we reserve argument space for call sites in the function
500// immediately on entry to the current function. This eliminates the need for
501// add/sub sp brackets around call sites. Returns true if the call frame is
502// included as part of the stack frame.
503bool ARMRegisterInfo::hasReservedCallFrame(MachineFunction &MF) const {
504 const MachineFrameInfo *FFI = MF.getFrameInfo();
505 unsigned CFSize = FFI->getMaxCallFrameSize();
542 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
543 // It's not always a good idea to include the call frame as part of the
544 // stack frame. ARM (especially Thumb) has small immediate offset to
545 // address the stack frame. So a large call frame can cause poor codegen
546 // and may even makes it impossible to scavenge a register.
506 // It's not always a good idea to include the call frame as part of the
507 // stack frame. ARM (especially Thumb) has small immediate offset to
508 // address the stack frame. So a large call frame can cause poor codegen
509 // and may even makes it impossible to scavenge a register.
547 if (AFI->isThumbFunction()) {
548 if (CFSize >= ((1 << 8) - 1) * 4 / 2) // Half of imm8 * 4
549 return false;
550 } else {
551 if (CFSize >= ((1 << 12) - 1) / 2) // Half of imm12
552 return false;
553 }
510 if (CFSize >= ((1 << 12) - 1) / 2) // Half of imm12
511 return false;
512
554 return !MF.getFrameInfo()->hasVarSizedObjects();
555}
556
557/// emitARMRegPlusImmediate - Emits a series of instructions to materialize
558/// a destreg = basereg + immediate in ARM code.
559static
560void emitARMRegPlusImmediate(MachineBasicBlock &MBB,
561 MachineBasicBlock::iterator &MBBI,
562 unsigned DestReg, unsigned BaseReg, int NumBytes,
563 ARMCC::CondCodes Pred, unsigned PredReg,
564 const TargetInstrInfo &TII,
565 DebugLoc dl) {
566 bool isSub = NumBytes < 0;
567 if (isSub) NumBytes = -NumBytes;
568
569 while (NumBytes) {
570 unsigned RotAmt = ARM_AM::getSOImmValRotate(NumBytes);
571 unsigned ThisVal = NumBytes & ARM_AM::rotr32(0xFF, RotAmt);
572 assert(ThisVal && "Didn't extract field correctly");
513 return !MF.getFrameInfo()->hasVarSizedObjects();
514}
515
516/// emitARMRegPlusImmediate - Emits a series of instructions to materialize
517/// a destreg = basereg + immediate in ARM code.
518static
519void emitARMRegPlusImmediate(MachineBasicBlock &MBB,
520 MachineBasicBlock::iterator &MBBI,
521 unsigned DestReg, unsigned BaseReg, int NumBytes,
522 ARMCC::CondCodes Pred, unsigned PredReg,
523 const TargetInstrInfo &TII,
524 DebugLoc dl) {
525 bool isSub = NumBytes < 0;
526 if (isSub) NumBytes = -NumBytes;
527
528 while (NumBytes) {
529 unsigned RotAmt = ARM_AM::getSOImmValRotate(NumBytes);
530 unsigned ThisVal = NumBytes & ARM_AM::rotr32(0xFF, RotAmt);
531 assert(ThisVal && "Didn't extract field correctly");
573
532
574 // We will handle these bits from offset, clear them.
575 NumBytes &= ~ThisVal;
533 // We will handle these bits from offset, clear them.
534 NumBytes &= ~ThisVal;
576
535
577 // Get the properly encoded SOImmVal field.
578 int SOImmVal = ARM_AM::getSOImmVal(ThisVal);
579 assert(SOImmVal != -1 && "Bit extraction didn't work?");
536 // Get the properly encoded SOImmVal field.
537 int SOImmVal = ARM_AM::getSOImmVal(ThisVal);
538 assert(SOImmVal != -1 && "Bit extraction didn't work?");
580
539
581 // Build the new ADD / SUB.
582 BuildMI(MBB, MBBI, dl, TII.get(isSub ? ARM::SUBri : ARM::ADDri), DestReg)
583 .addReg(BaseReg, RegState::Kill).addImm(SOImmVal)
584 .addImm((unsigned)Pred).addReg(PredReg).addReg(0);
585 BaseReg = DestReg;
586 }
587}
588
540 // Build the new ADD / SUB.
541 BuildMI(MBB, MBBI, dl, TII.get(isSub ? ARM::SUBri : ARM::ADDri), DestReg)
542 .addReg(BaseReg, RegState::Kill).addImm(SOImmVal)
543 .addImm((unsigned)Pred).addReg(PredReg).addReg(0);
544 BaseReg = DestReg;
545 }
546}
547
589/// calcNumMI - Returns the number of instructions required to materialize
590/// the specific add / sub r, c instruction.
591static unsigned calcNumMI(int Opc, int ExtraOpc, unsigned Bytes,
592 unsigned NumBits, unsigned Scale) {
593 unsigned NumMIs = 0;
594 unsigned Chunk = ((1 << NumBits) - 1) * Scale;
595
596 if (Opc == ARM::tADDrSPi) {
597 unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes;
598 Bytes -= ThisVal;
599 NumMIs++;
600 NumBits = 8;
601 Scale = 1; // Followed by a number of tADDi8.
602 Chunk = ((1 << NumBits) - 1) * Scale;
603 }
604
605 NumMIs += Bytes / Chunk;
606 if ((Bytes % Chunk) != 0)
607 NumMIs++;
608 if (ExtraOpc)
609 NumMIs++;
610 return NumMIs;
548static void
549emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
550 const TargetInstrInfo &TII, DebugLoc dl,
551 int NumBytes,
552 ARMCC::CondCodes Pred = ARMCC::AL, unsigned PredReg = 0) {
553 emitARMRegPlusImmediate(MBB, MBBI, ARM::SP, ARM::SP, NumBytes,
554 Pred, PredReg, TII, dl);
611}
612
555}
556
613/// emitThumbRegPlusImmInReg - Emits a series of instructions to materialize
614/// a destreg = basereg + immediate in Thumb code. Materialize the immediate
615/// in a register using mov / mvn sequences or load the immediate from a
616/// constpool entry.
617static
618void emitThumbRegPlusImmInReg(MachineBasicBlock &MBB,
619 MachineBasicBlock::iterator &MBBI,
620 unsigned DestReg, unsigned BaseReg,
621 int NumBytes, bool CanChangeCC,
622 const TargetInstrInfo &TII,
623 const ARMRegisterInfo& MRI,
624 DebugLoc dl) {
625 bool isHigh = !MRI.isLowRegister(DestReg) ||
626 (BaseReg != 0 && !MRI.isLowRegister(BaseReg));
627 bool isSub = false;
628 // Subtract doesn't have high register version. Load the negative value
629 // if either base or dest register is a high register. Also, if do not
630 // issue sub as part of the sequence if condition register is to be
631 // preserved.
632 if (NumBytes < 0 && !isHigh && CanChangeCC) {
633 isSub = true;
634 NumBytes = -NumBytes;
635 }
636 unsigned LdReg = DestReg;
637 if (DestReg == ARM::SP) {
638 assert(BaseReg == ARM::SP && "Unexpected!");
639 LdReg = ARM::R3;
640 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVlor2hir), ARM::R12)
641 .addReg(ARM::R3, RegState::Kill);
642 }
643
644 if (NumBytes <= 255 && NumBytes >= 0)
645 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg).addImm(NumBytes);
646 else if (NumBytes < 0 && NumBytes >= -255) {
647 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg).addImm(NumBytes);
648 BuildMI(MBB, MBBI, dl, TII.get(ARM::tNEG), LdReg)
649 .addReg(LdReg, RegState::Kill);
650 } else
651 MRI.emitLoadConstPool(MBB, MBBI, LdReg, NumBytes, ARMCC::AL, 0, &TII,
652 true, dl);
653
654 // Emit add / sub.
655 int Opc = (isSub) ? ARM::tSUBrr : (isHigh ? ARM::tADDhirr : ARM::tADDrr);
656 const MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl,
657 TII.get(Opc), DestReg);
658 if (DestReg == ARM::SP || isSub)
659 MIB.addReg(BaseReg).addReg(LdReg, RegState::Kill);
660 else
661 MIB.addReg(LdReg).addReg(BaseReg, RegState::Kill);
662 if (DestReg == ARM::SP)
663 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVhir2lor), ARM::R3)
664 .addReg(ARM::R12, RegState::Kill);
665}
666
667/// emitThumbRegPlusImmediate - Emits a series of instructions to materialize
668/// a destreg = basereg + immediate in Thumb code.
669static
670void emitThumbRegPlusImmediate(MachineBasicBlock &MBB,
671 MachineBasicBlock::iterator &MBBI,
672 unsigned DestReg, unsigned BaseReg,
673 int NumBytes, const TargetInstrInfo &TII,
674 const ARMRegisterInfo& MRI,
675 DebugLoc dl) {
676 bool isSub = NumBytes < 0;
677 unsigned Bytes = (unsigned)NumBytes;
678 if (isSub) Bytes = -NumBytes;
679 bool isMul4 = (Bytes & 3) == 0;
680 bool isTwoAddr = false;
681 bool DstNotEqBase = false;
682 unsigned NumBits = 1;
683 unsigned Scale = 1;
684 int Opc = 0;
685 int ExtraOpc = 0;
686
687 if (DestReg == BaseReg && BaseReg == ARM::SP) {
688 assert(isMul4 && "Thumb sp inc / dec size must be multiple of 4!");
689 NumBits = 7;
690 Scale = 4;
691 Opc = isSub ? ARM::tSUBspi : ARM::tADDspi;
692 isTwoAddr = true;
693 } else if (!isSub && BaseReg == ARM::SP) {
694 // r1 = add sp, 403
695 // =>
696 // r1 = add sp, 100 * 4
697 // r1 = add r1, 3
698 if (!isMul4) {
699 Bytes &= ~3;
700 ExtraOpc = ARM::tADDi3;
701 }
702 NumBits = 8;
703 Scale = 4;
704 Opc = ARM::tADDrSPi;
705 } else {
706 // sp = sub sp, c
707 // r1 = sub sp, c
708 // r8 = sub sp, c
709 if (DestReg != BaseReg)
710 DstNotEqBase = true;
711 NumBits = 8;
712 Opc = isSub ? ARM::tSUBi8 : ARM::tADDi8;
713 isTwoAddr = true;
714 }
715
716 unsigned NumMIs = calcNumMI(Opc, ExtraOpc, Bytes, NumBits, Scale);
717 unsigned Threshold = (DestReg == ARM::SP) ? 3 : 2;
718 if (NumMIs > Threshold) {
719 // This will expand into too many instructions. Load the immediate from a
720 // constpool entry.
721 emitThumbRegPlusImmInReg(MBB, MBBI, DestReg, BaseReg, NumBytes, true, TII,
722 MRI, dl);
723 return;
724 }
725
726 if (DstNotEqBase) {
727 if (MRI.isLowRegister(DestReg) && MRI.isLowRegister(BaseReg)) {
728 // If both are low registers, emit DestReg = add BaseReg, max(Imm, 7)
729 unsigned Chunk = (1 << 3) - 1;
730 unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes;
731 Bytes -= ThisVal;
732 BuildMI(MBB, MBBI, dl,TII.get(isSub ? ARM::tSUBi3 : ARM::tADDi3), DestReg)
733 .addReg(BaseReg, RegState::Kill).addImm(ThisVal);
734 } else {
735 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), DestReg)
736 .addReg(BaseReg, RegState::Kill);
737 }
738 BaseReg = DestReg;
739 }
740
741 unsigned Chunk = ((1 << NumBits) - 1) * Scale;
742 while (Bytes) {
743 unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes;
744 Bytes -= ThisVal;
745 ThisVal /= Scale;
746 // Build the new tADD / tSUB.
747 if (isTwoAddr)
748 BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
749 .addReg(DestReg).addImm(ThisVal);
750 else {
751 bool isKill = BaseReg != ARM::SP;
752 BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
753 .addReg(BaseReg, getKillRegState(isKill)).addImm(ThisVal);
754 BaseReg = DestReg;
755
756 if (Opc == ARM::tADDrSPi) {
757 // r4 = add sp, imm
758 // r4 = add r4, imm
759 // ...
760 NumBits = 8;
761 Scale = 1;
762 Chunk = ((1 << NumBits) - 1) * Scale;
763 Opc = isSub ? ARM::tSUBi8 : ARM::tADDi8;
764 isTwoAddr = true;
765 }
766 }
767 }
768
769 if (ExtraOpc)
770 BuildMI(MBB, MBBI, dl, TII.get(ExtraOpc), DestReg)
771 .addReg(DestReg, RegState::Kill)
772 .addImm(((unsigned)NumBytes) & 3);
773}
774
775static
776void emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
777 int NumBytes, ARMCC::CondCodes Pred, unsigned PredReg,
778 bool isThumb, const TargetInstrInfo &TII,
779 const ARMRegisterInfo& MRI,
780 DebugLoc dl) {
781 if (isThumb)
782 emitThumbRegPlusImmediate(MBB, MBBI, ARM::SP, ARM::SP, NumBytes, TII,
783 MRI, dl);
784 else
785 emitARMRegPlusImmediate(MBB, MBBI, ARM::SP, ARM::SP, NumBytes,
786 Pred, PredReg, TII, dl);
787}
788
789void ARMRegisterInfo::
790eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
791 MachineBasicBlock::iterator I) const {
792 if (!hasReservedCallFrame(MF)) {
793 // If we have alloca, convert as follows:
794 // ADJCALLSTACKDOWN -> sub, sp, sp, amount
795 // ADJCALLSTACKUP -> add, sp, sp, amount
796 MachineInstr *Old = I;
797 DebugLoc dl = Old->getDebugLoc();
798 unsigned Amount = Old->getOperand(0).getImm();
799 if (Amount != 0) {
557void ARMRegisterInfo::
558eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
559 MachineBasicBlock::iterator I) const {
560 if (!hasReservedCallFrame(MF)) {
561 // If we have alloca, convert as follows:
562 // ADJCALLSTACKDOWN -> sub, sp, sp, amount
563 // ADJCALLSTACKUP -> add, sp, sp, amount
564 MachineInstr *Old = I;
565 DebugLoc dl = Old->getDebugLoc();
566 unsigned Amount = Old->getOperand(0).getImm();
567 if (Amount != 0) {
800 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
801 // We need to keep the stack aligned properly. To do this, we round the
802 // amount of space needed for the outgoing arguments up to the next
803 // alignment boundary.
804 unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment();
805 Amount = (Amount+Align-1)/Align*Align;
806
807 // Replace the pseudo instruction with a new instruction...
808 unsigned Opc = Old->getOpcode();
568 // We need to keep the stack aligned properly. To do this, we round the
569 // amount of space needed for the outgoing arguments up to the next
570 // alignment boundary.
571 unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment();
572 Amount = (Amount+Align-1)/Align*Align;
573
574 // Replace the pseudo instruction with a new instruction...
575 unsigned Opc = Old->getOpcode();
809 bool isThumb = AFI->isThumbFunction();
810 ARMCC::CondCodes Pred = isThumb
811 ? ARMCC::AL : (ARMCC::CondCodes)Old->getOperand(1).getImm();
576 ARMCC::CondCodes Pred = (ARMCC::CondCodes)Old->getOperand(1).getImm();
812 if (Opc == ARM::ADJCALLSTACKDOWN || Opc == ARM::tADJCALLSTACKDOWN) {
813 // Note: PredReg is operand 2 for ADJCALLSTACKDOWN.
577 if (Opc == ARM::ADJCALLSTACKDOWN || Opc == ARM::tADJCALLSTACKDOWN) {
578 // Note: PredReg is operand 2 for ADJCALLSTACKDOWN.
814 unsigned PredReg = isThumb ? 0 : Old->getOperand(2).getReg();
815 emitSPUpdate(MBB, I, -Amount, Pred, PredReg, isThumb, TII, *this, dl);
579 unsigned PredReg = Old->getOperand(2).getReg();
580 emitSPUpdate(MBB, I, TII, dl, -Amount, Pred, PredReg);
816 } else {
817 // Note: PredReg is operand 3 for ADJCALLSTACKUP.
581 } else {
582 // Note: PredReg is operand 3 for ADJCALLSTACKUP.
818 unsigned PredReg = isThumb ? 0 : Old->getOperand(3).getReg();
583 unsigned PredReg = Old->getOperand(3).getReg();
819 assert(Opc == ARM::ADJCALLSTACKUP || Opc == ARM::tADJCALLSTACKUP);
584 assert(Opc == ARM::ADJCALLSTACKUP || Opc == ARM::tADJCALLSTACKUP);
820 emitSPUpdate(MBB, I, Amount, Pred, PredReg, isThumb, TII, *this, dl);
585 emitSPUpdate(MBB, I, TII, dl, Amount, Pred, PredReg);
821 }
822 }
823 }
824 MBB.erase(I);
825}
826
586 }
587 }
588 }
589 MBB.erase(I);
590}
591
827/// emitThumbConstant - Emit a series of instructions to materialize a
828/// constant.
829static void emitThumbConstant(MachineBasicBlock &MBB,
830 MachineBasicBlock::iterator &MBBI,
831 unsigned DestReg, int Imm,
832 const TargetInstrInfo &TII,
833 const ARMRegisterInfo& MRI,
834 DebugLoc dl) {
835 bool isSub = Imm < 0;
836 if (isSub) Imm = -Imm;
837
838 int Chunk = (1 << 8) - 1;
839 int ThisVal = (Imm > Chunk) ? Chunk : Imm;
840 Imm -= ThisVal;
841 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), DestReg).addImm(ThisVal);
842 if (Imm > 0)
843 emitThumbRegPlusImmediate(MBB, MBBI, DestReg, DestReg, Imm, TII, MRI, dl);
844 if (isSub)
845 BuildMI(MBB, MBBI, dl, TII.get(ARM::tNEG), DestReg)
846 .addReg(DestReg, RegState::Kill);
847}
848
849/// findScratchRegister - Find a 'free' ARM register. If register scavenger
850/// is not being used, R12 is available. Otherwise, try for a call-clobbered
851/// register first and then a spilled callee-saved register if that fails.
852static
853unsigned findScratchRegister(RegScavenger *RS, const TargetRegisterClass *RC,
854 ARMFunctionInfo *AFI) {
855 unsigned Reg = RS ? RS->FindUnusedReg(RC, true) : (unsigned) ARM::R12;
856 assert (!AFI->isThumbFunction());

--- 6 unchanged lines hidden (view full) ---

863
864void ARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
865 int SPAdj, RegScavenger *RS) const{
866 unsigned i = 0;
867 MachineInstr &MI = *II;
868 MachineBasicBlock &MBB = *MI.getParent();
869 MachineFunction &MF = *MBB.getParent();
870 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
592/// findScratchRegister - Find a 'free' ARM register. If register scavenger
593/// is not being used, R12 is available. Otherwise, try for a call-clobbered
594/// register first and then a spilled callee-saved register if that fails.
595static
596unsigned findScratchRegister(RegScavenger *RS, const TargetRegisterClass *RC,
597 ARMFunctionInfo *AFI) {
598 unsigned Reg = RS ? RS->FindUnusedReg(RC, true) : (unsigned) ARM::R12;
599 assert (!AFI->isThumbFunction());

--- 6 unchanged lines hidden (view full) ---

606
607void ARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
608 int SPAdj, RegScavenger *RS) const{
609 unsigned i = 0;
610 MachineInstr &MI = *II;
611 MachineBasicBlock &MBB = *MI.getParent();
612 MachineFunction &MF = *MBB.getParent();
613 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
871 bool isThumb = AFI->isThumbFunction();
872 DebugLoc dl = MI.getDebugLoc();
873
874 while (!MI.getOperand(i).isFI()) {
875 ++i;
876 assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
877 }
614 DebugLoc dl = MI.getDebugLoc();
615
616 while (!MI.getOperand(i).isFI()) {
617 ++i;
618 assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
619 }
878
620
879 unsigned FrameReg = ARM::SP;
880 int FrameIndex = MI.getOperand(i).getIndex();
621 unsigned FrameReg = ARM::SP;
622 int FrameIndex = MI.getOperand(i).getIndex();
881 int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) +
623 int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) +
882 MF.getFrameInfo()->getStackSize() + SPAdj;
883
884 if (AFI->isGPRCalleeSavedArea1Frame(FrameIndex))
885 Offset -= AFI->getGPRCalleeSavedArea1Offset();
886 else if (AFI->isGPRCalleeSavedArea2Frame(FrameIndex))
887 Offset -= AFI->getGPRCalleeSavedArea2Offset();
888 else if (AFI->isDPRCalleeSavedAreaFrame(FrameIndex))
889 Offset -= AFI->getDPRCalleeSavedAreaOffset();

--- 31 unchanged lines hidden (view full) ---

921 // Common case: small offset, fits into instruction.
922 int ImmedOffset = ARM_AM::getSOImmVal(Offset);
923 if (ImmedOffset != -1) {
924 // Replace the FrameIndex with sp / fp
925 MI.getOperand(i).ChangeToRegister(FrameReg, false);
926 MI.getOperand(i+1).ChangeToImmediate(ImmedOffset);
927 return;
928 }
624 MF.getFrameInfo()->getStackSize() + SPAdj;
625
626 if (AFI->isGPRCalleeSavedArea1Frame(FrameIndex))
627 Offset -= AFI->getGPRCalleeSavedArea1Offset();
628 else if (AFI->isGPRCalleeSavedArea2Frame(FrameIndex))
629 Offset -= AFI->getGPRCalleeSavedArea2Offset();
630 else if (AFI->isDPRCalleeSavedAreaFrame(FrameIndex))
631 Offset -= AFI->getDPRCalleeSavedAreaOffset();

--- 31 unchanged lines hidden (view full) ---

663 // Common case: small offset, fits into instruction.
664 int ImmedOffset = ARM_AM::getSOImmVal(Offset);
665 if (ImmedOffset != -1) {
666 // Replace the FrameIndex with sp / fp
667 MI.getOperand(i).ChangeToRegister(FrameReg, false);
668 MI.getOperand(i+1).ChangeToImmediate(ImmedOffset);
669 return;
670 }
929
671
930 // Otherwise, we fallback to common code below to form the imm offset with
931 // a sequence of ADDri instructions. First though, pull as much of the imm
932 // into this ADDri as possible.
933 unsigned RotAmt = ARM_AM::getSOImmValRotate(Offset);
934 unsigned ThisImmVal = Offset & ARM_AM::rotr32(0xFF, RotAmt);
672 // Otherwise, we fallback to common code below to form the imm offset with
673 // a sequence of ADDri instructions. First though, pull as much of the imm
674 // into this ADDri as possible.
675 unsigned RotAmt = ARM_AM::getSOImmValRotate(Offset);
676 unsigned ThisImmVal = Offset & ARM_AM::rotr32(0xFF, RotAmt);
935
677
936 // We will handle these bits from offset, clear them.
937 Offset &= ~ThisImmVal;
678 // We will handle these bits from offset, clear them.
679 Offset &= ~ThisImmVal;
938
680
939 // Get the properly encoded SOImmVal field.
940 int ThisSOImmVal = ARM_AM::getSOImmVal(ThisImmVal);
681 // Get the properly encoded SOImmVal field.
682 int ThisSOImmVal = ARM_AM::getSOImmVal(ThisImmVal);
941 assert(ThisSOImmVal != -1 && "Bit extraction didn't work?");
683 assert(ThisSOImmVal != -1 && "Bit extraction didn't work?");
942 MI.getOperand(i+1).ChangeToImmediate(ThisSOImmVal);
684 MI.getOperand(i+1).ChangeToImmediate(ThisSOImmVal);
943 } else if (Opcode == ARM::tADDrSPi) {
944 Offset += MI.getOperand(i+1).getImm();
945
946 // Can't use tADDrSPi if it's based off the frame pointer.
947 unsigned NumBits = 0;
948 unsigned Scale = 1;
949 if (FrameReg != ARM::SP) {
950 Opcode = ARM::tADDi3;
951 MI.setDesc(TII.get(ARM::tADDi3));
952 NumBits = 3;
953 } else {
954 NumBits = 8;
955 Scale = 4;
956 assert((Offset & 3) == 0 &&
957 "Thumb add/sub sp, #imm immediate must be multiple of 4!");
958 }
959
960 if (Offset == 0) {
961 // Turn it into a move.
962 MI.setDesc(TII.get(ARM::tMOVhir2lor));
963 MI.getOperand(i).ChangeToRegister(FrameReg, false);
964 MI.RemoveOperand(i+1);
965 return;
966 }
967
968 // Common case: small offset, fits into instruction.
969 unsigned Mask = (1 << NumBits) - 1;
970 if (((Offset / Scale) & ~Mask) == 0) {
971 // Replace the FrameIndex with sp / fp
972 MI.getOperand(i).ChangeToRegister(FrameReg, false);
973 MI.getOperand(i+1).ChangeToImmediate(Offset / Scale);
974 return;
975 }
976
977 unsigned DestReg = MI.getOperand(0).getReg();
978 unsigned Bytes = (Offset > 0) ? Offset : -Offset;
979 unsigned NumMIs = calcNumMI(Opcode, 0, Bytes, NumBits, Scale);
980 // MI would expand into a large number of instructions. Don't try to
981 // simplify the immediate.
982 if (NumMIs > 2) {
983 emitThumbRegPlusImmediate(MBB, II, DestReg, FrameReg, Offset, TII,
984 *this, dl);
985 MBB.erase(II);
986 return;
987 }
988
989 if (Offset > 0) {
990 // Translate r0 = add sp, imm to
991 // r0 = add sp, 255*4
992 // r0 = add r0, (imm - 255*4)
993 MI.getOperand(i).ChangeToRegister(FrameReg, false);
994 MI.getOperand(i+1).ChangeToImmediate(Mask);
995 Offset = (Offset - Mask * Scale);
996 MachineBasicBlock::iterator NII = next(II);
997 emitThumbRegPlusImmediate(MBB, NII, DestReg, DestReg, Offset, TII,
998 *this, dl);
999 } else {
1000 // Translate r0 = add sp, -imm to
1001 // r0 = -imm (this is then translated into a series of instructons)
1002 // r0 = add r0, sp
1003 emitThumbConstant(MBB, II, DestReg, Offset, TII, *this, dl);
1004 MI.setDesc(TII.get(ARM::tADDhirr));
1005 MI.getOperand(i).ChangeToRegister(DestReg, false, false, true);
1006 MI.getOperand(i+1).ChangeToRegister(FrameReg, false);
1007 }
1008 return;
1009 } else {
1010 unsigned ImmIdx = 0;
1011 int InstrOffs = 0;
1012 unsigned NumBits = 0;
1013 unsigned Scale = 1;
1014 switch (AddrMode) {
1015 case ARMII::AddrMode2: {
1016 ImmIdx = i+2;

--- 15 unchanged lines hidden (view full) ---

1032 ImmIdx = i+1;
1033 InstrOffs = ARM_AM::getAM5Offset(MI.getOperand(ImmIdx).getImm());
1034 if (ARM_AM::getAM5Op(MI.getOperand(ImmIdx).getImm()) == ARM_AM::sub)
1035 InstrOffs *= -1;
1036 NumBits = 8;
1037 Scale = 4;
1038 break;
1039 }
685 } else {
686 unsigned ImmIdx = 0;
687 int InstrOffs = 0;
688 unsigned NumBits = 0;
689 unsigned Scale = 1;
690 switch (AddrMode) {
691 case ARMII::AddrMode2: {
692 ImmIdx = i+2;

--- 15 unchanged lines hidden (view full) ---

708 ImmIdx = i+1;
709 InstrOffs = ARM_AM::getAM5Offset(MI.getOperand(ImmIdx).getImm());
710 if (ARM_AM::getAM5Op(MI.getOperand(ImmIdx).getImm()) == ARM_AM::sub)
711 InstrOffs *= -1;
712 NumBits = 8;
713 Scale = 4;
714 break;
715 }
1040 case ARMII::AddrModeTs: {
1041 ImmIdx = i+1;
1042 InstrOffs = MI.getOperand(ImmIdx).getImm();
1043 NumBits = (FrameReg == ARM::SP) ? 8 : 5;
1044 Scale = 4;
1045 break;
1046 }
1047 default:
1048 assert(0 && "Unsupported addressing mode!");
1049 abort();
1050 break;
1051 }
1052
1053 Offset += InstrOffs * Scale;
1054 assert((Offset & (Scale-1)) == 0 && "Can't encode this offset!");
716 default:
717 assert(0 && "Unsupported addressing mode!");
718 abort();
719 break;
720 }
721
722 Offset += InstrOffs * Scale;
723 assert((Offset & (Scale-1)) == 0 && "Can't encode this offset!");
1055 if (Offset < 0 && !isThumb) {
724 if (Offset < 0) {
1056 Offset = -Offset;
1057 isSub = true;
1058 }
1059
1060 // Common case: small offset, fits into instruction.
1061 MachineOperand &ImmOp = MI.getOperand(ImmIdx);
1062 int ImmedOffset = Offset / Scale;
1063 unsigned Mask = (1 << NumBits) - 1;
1064 if ((unsigned)Offset <= Mask * Scale) {
1065 // Replace the FrameIndex with sp
1066 MI.getOperand(i).ChangeToRegister(FrameReg, false);
1067 if (isSub)
1068 ImmedOffset |= 1 << NumBits;
1069 ImmOp.ChangeToImmediate(ImmedOffset);
1070 return;
1071 }
1072
725 Offset = -Offset;
726 isSub = true;
727 }
728
729 // Common case: small offset, fits into instruction.
730 MachineOperand &ImmOp = MI.getOperand(ImmIdx);
731 int ImmedOffset = Offset / Scale;
732 unsigned Mask = (1 << NumBits) - 1;
733 if ((unsigned)Offset <= Mask * Scale) {
734 // Replace the FrameIndex with sp
735 MI.getOperand(i).ChangeToRegister(FrameReg, false);
736 if (isSub)
737 ImmedOffset |= 1 << NumBits;
738 ImmOp.ChangeToImmediate(ImmedOffset);
739 return;
740 }
741
1073 bool isThumSpillRestore = Opcode == ARM::tRestore || Opcode == ARM::tSpill;
1074 if (AddrMode == ARMII::AddrModeTs) {
1075 // Thumb tLDRspi, tSTRspi. These will change to instructions that use
1076 // a different base register.
1077 NumBits = 5;
1078 Mask = (1 << NumBits) - 1;
1079 }
1080 // If this is a thumb spill / restore, we will be using a constpool load to
1081 // materialize the offset.
1082 if (AddrMode == ARMII::AddrModeTs && isThumSpillRestore)
1083 ImmOp.ChangeToImmediate(0);
1084 else {
1085 // Otherwise, it didn't fit. Pull in what we can to simplify the immed.
1086 ImmedOffset = ImmedOffset & Mask;
1087 if (isSub)
1088 ImmedOffset |= 1 << NumBits;
1089 ImmOp.ChangeToImmediate(ImmedOffset);
1090 Offset &= ~(Mask*Scale);
1091 }
742 // Otherwise, it didn't fit. Pull in what we can to simplify the immed.
743 ImmedOffset = ImmedOffset & Mask;
744 if (isSub)
745 ImmedOffset |= 1 << NumBits;
746 ImmOp.ChangeToImmediate(ImmedOffset);
747 Offset &= ~(Mask*Scale);
1092 }
748 }
1093
749
1094 // If we get here, the immediate doesn't fit into the instruction. We folded
1095 // as much as possible above, handle the rest, providing a register that is
1096 // SP+LargeImm.
1097 assert(Offset && "This code isn't needed if offset already handled!");
1098
750 // If we get here, the immediate doesn't fit into the instruction. We folded
751 // as much as possible above, handle the rest, providing a register that is
752 // SP+LargeImm.
753 assert(Offset && "This code isn't needed if offset already handled!");
754
1099 if (isThumb) {
1100 if (Desc.mayLoad()) {
1101 // Use the destination register to materialize sp + offset.
1102 unsigned TmpReg = MI.getOperand(0).getReg();
1103 bool UseRR = false;
1104 if (Opcode == ARM::tRestore) {
1105 if (FrameReg == ARM::SP)
1106 emitThumbRegPlusImmInReg(MBB, II, TmpReg, FrameReg,
1107 Offset, false, TII, *this, dl);
1108 else {
1109 emitLoadConstPool(MBB, II, TmpReg, Offset, ARMCC::AL, 0, &TII,
1110 true, dl);
1111 UseRR = true;
1112 }
1113 } else
1114 emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg, Offset, TII,
1115 *this, dl);
1116 MI.setDesc(TII.get(ARM::tLDR));
1117 MI.getOperand(i).ChangeToRegister(TmpReg, false, false, true);
1118 if (UseRR)
1119 // Use [reg, reg] addrmode.
1120 MI.addOperand(MachineOperand::CreateReg(FrameReg, false));
1121 else // tLDR has an extra register operand.
1122 MI.addOperand(MachineOperand::CreateReg(0, false));
1123 } else if (Desc.mayStore()) {
1124 // FIXME! This is horrific!!! We need register scavenging.
1125 // Our temporary workaround has marked r3 unavailable. Of course, r3 is
1126 // also a ABI register so it's possible that is is the register that is
1127 // being storing here. If that's the case, we do the following:
1128 // r12 = r2
1129 // Use r2 to materialize sp + offset
1130 // str r3, r2
1131 // r2 = r12
1132 unsigned ValReg = MI.getOperand(0).getReg();
1133 unsigned TmpReg = ARM::R3;
1134 bool UseRR = false;
1135 if (ValReg == ARM::R3) {
1136 BuildMI(MBB, II, dl, TII.get(ARM::tMOVlor2hir), ARM::R12)
1137 .addReg(ARM::R2, RegState::Kill);
1138 TmpReg = ARM::R2;
1139 }
1140 if (TmpReg == ARM::R3 && AFI->isR3LiveIn())
1141 BuildMI(MBB, II, dl, TII.get(ARM::tMOVlor2hir), ARM::R12)
1142 .addReg(ARM::R3, RegState::Kill);
1143 if (Opcode == ARM::tSpill) {
1144 if (FrameReg == ARM::SP)
1145 emitThumbRegPlusImmInReg(MBB, II, TmpReg, FrameReg,
1146 Offset, false, TII, *this, dl);
1147 else {
1148 emitLoadConstPool(MBB, II, TmpReg, Offset, ARMCC::AL, 0, &TII,
1149 true, dl);
1150 UseRR = true;
1151 }
1152 } else
1153 emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg, Offset, TII,
1154 *this, dl);
1155 MI.setDesc(TII.get(ARM::tSTR));
1156 MI.getOperand(i).ChangeToRegister(TmpReg, false, false, true);
1157 if (UseRR) // Use [reg, reg] addrmode.
1158 MI.addOperand(MachineOperand::CreateReg(FrameReg, false));
1159 else // tSTR has an extra register operand.
1160 MI.addOperand(MachineOperand::CreateReg(0, false));
1161
1162 MachineBasicBlock::iterator NII = next(II);
1163 if (ValReg == ARM::R3)
1164 BuildMI(MBB, NII, dl, TII.get(ARM::tMOVhir2lor), ARM::R2)
1165 .addReg(ARM::R12, RegState::Kill);
1166 if (TmpReg == ARM::R3 && AFI->isR3LiveIn())
1167 BuildMI(MBB, NII, dl, TII.get(ARM::tMOVhir2lor), ARM::R3)
1168 .addReg(ARM::R12, RegState::Kill);
1169 } else
1170 assert(false && "Unexpected opcode!");
1171 } else {
1172 // Insert a set of r12 with the full address: r12 = sp + offset
1173 // If the offset we have is too large to fit into the instruction, we need
1174 // to form it with a series of ADDri's. Do this by taking 8-bit chunks
1175 // out of 'Offset'.
1176 unsigned ScratchReg = findScratchRegister(RS, &ARM::GPRRegClass, AFI);
1177 if (ScratchReg == 0)
1178 // No register is "free". Scavenge a register.
1179 ScratchReg = RS->scavengeRegister(&ARM::GPRRegClass, II, SPAdj);
1180 int PIdx = MI.findFirstPredOperandIdx();
1181 ARMCC::CondCodes Pred = (PIdx == -1)
1182 ? ARMCC::AL : (ARMCC::CondCodes)MI.getOperand(PIdx).getImm();
1183 unsigned PredReg = (PIdx == -1) ? 0 : MI.getOperand(PIdx+1).getReg();
1184 emitARMRegPlusImmediate(MBB, II, ScratchReg, FrameReg,
1185 isSub ? -Offset : Offset, Pred, PredReg, TII, dl);
1186 MI.getOperand(i).ChangeToRegister(ScratchReg, false, false, true);
1187 }
755 // Insert a set of r12 with the full address: r12 = sp + offset
756 // If the offset we have is too large to fit into the instruction, we need
757 // to form it with a series of ADDri's. Do this by taking 8-bit chunks
758 // out of 'Offset'.
759 unsigned ScratchReg = findScratchRegister(RS, &ARM::GPRRegClass, AFI);
760 if (ScratchReg == 0)
761 // No register is "free". Scavenge a register.
762 ScratchReg = RS->scavengeRegister(&ARM::GPRRegClass, II, SPAdj);
763 int PIdx = MI.findFirstPredOperandIdx();
764 ARMCC::CondCodes Pred = (PIdx == -1)
765 ? ARMCC::AL : (ARMCC::CondCodes)MI.getOperand(PIdx).getImm();
766 unsigned PredReg = (PIdx == -1) ? 0 : MI.getOperand(PIdx+1).getReg();
767 emitARMRegPlusImmediate(MBB, II, ScratchReg, FrameReg,
768 isSub ? -Offset : Offset, Pred, PredReg, TII, dl);
769 MI.getOperand(i).ChangeToRegister(ScratchReg, false, false, true);
1188}
1189
1190static unsigned estimateStackSize(MachineFunction &MF, MachineFrameInfo *MFI) {
1191 const MachineFrameInfo *FFI = MF.getFrameInfo();
1192 int Offset = 0;
1193 for (int i = FFI->getObjectIndexBegin(); i != 0; ++i) {
1194 int FixedOff = -FFI->getObjectOffset(i);
1195 if (FixedOff > Offset) Offset = FixedOff;

--- 5 unchanged lines hidden (view full) ---

1201 unsigned Align = FFI->getObjectAlignment(i);
1202 // Adjust to alignment boundary
1203 Offset = (Offset+Align-1)/Align*Align;
1204 }
1205 return (unsigned)Offset;
1206}
1207
1208void
770}
771
772static unsigned estimateStackSize(MachineFunction &MF, MachineFrameInfo *MFI) {
773 const MachineFrameInfo *FFI = MF.getFrameInfo();
774 int Offset = 0;
775 for (int i = FFI->getObjectIndexBegin(); i != 0; ++i) {
776 int FixedOff = -FFI->getObjectOffset(i);
777 if (FixedOff > Offset) Offset = FixedOff;

--- 5 unchanged lines hidden (view full) ---

783 unsigned Align = FFI->getObjectAlignment(i);
784 // Adjust to alignment boundary
785 Offset = (Offset+Align-1)/Align*Align;
786 }
787 return (unsigned)Offset;
788}
789
790void
1209ARMRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
1210 RegScavenger *RS) const {
791ARMBaseRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
792 RegScavenger *RS) const {
1211 // This tells PEI to spill the FP as if it is any other callee-save register
1212 // to take advantage the eliminateFrameIndex machinery. This also ensures it
1213 // is spilled in the order specified by getCalleeSavedRegs() to make it easier
1214 // to combine multiple loads / stores.
1215 bool CanEliminateFrame = true;
1216 bool CS1Spilled = false;
1217 bool LRSpilled = false;
1218 unsigned NumGPRSpills = 0;

--- 42 unchanged lines hidden (view full) ---

1261 case ARM::R5:
1262 case ARM::R6:
1263 case ARM::R7:
1264 CS1Spilled = true;
1265 break;
1266 default:
1267 break;
1268 }
793 // This tells PEI to spill the FP as if it is any other callee-save register
794 // to take advantage the eliminateFrameIndex machinery. This also ensures it
795 // is spilled in the order specified by getCalleeSavedRegs() to make it easier
796 // to combine multiple loads / stores.
797 bool CanEliminateFrame = true;
798 bool CS1Spilled = false;
799 bool LRSpilled = false;
800 unsigned NumGPRSpills = 0;

--- 42 unchanged lines hidden (view full) ---

843 case ARM::R5:
844 case ARM::R6:
845 case ARM::R7:
846 CS1Spilled = true;
847 break;
848 default:
849 break;
850 }
1269 } else {
851 } else {
1270 if (!STI.isTargetDarwin()) {
1271 UnspilledCS1GPRs.push_back(Reg);
1272 continue;
1273 }
1274
1275 switch (Reg) {
1276 case ARM::R4:
1277 case ARM::R5:

--- 49 unchanged lines hidden (view full) ---

1327 // of GPRs. Spill one extra callee save GPR so we won't have to pad between
1328 // the integer and double callee save areas.
1329 unsigned TargetAlign = MF.getTarget().getFrameInfo()->getStackAlignment();
1330 if (TargetAlign == 8 && (NumGPRSpills & 1)) {
1331 if (CS1Spilled && !UnspilledCS1GPRs.empty()) {
1332 for (unsigned i = 0, e = UnspilledCS1GPRs.size(); i != e; ++i) {
1333 unsigned Reg = UnspilledCS1GPRs[i];
1334 // Don't spiil high register if the function is thumb
852 if (!STI.isTargetDarwin()) {
853 UnspilledCS1GPRs.push_back(Reg);
854 continue;
855 }
856
857 switch (Reg) {
858 case ARM::R4:
859 case ARM::R5:

--- 49 unchanged lines hidden (view full) ---

909 // of GPRs. Spill one extra callee save GPR so we won't have to pad between
910 // the integer and double callee save areas.
911 unsigned TargetAlign = MF.getTarget().getFrameInfo()->getStackAlignment();
912 if (TargetAlign == 8 && (NumGPRSpills & 1)) {
913 if (CS1Spilled && !UnspilledCS1GPRs.empty()) {
914 for (unsigned i = 0, e = UnspilledCS1GPRs.size(); i != e; ++i) {
915 unsigned Reg = UnspilledCS1GPRs[i];
916 // Don't spiil high register if the function is thumb
1335 if (!AFI->isThumbFunction() || isLowRegister(Reg) || Reg == ARM::LR) {
917 if (!AFI->isThumbFunction() ||
918 isARMLowRegister(Reg) || Reg == ARM::LR) {
1336 MF.getRegInfo().setPhysRegUsed(Reg);
1337 AFI->setCSRegisterIsSpilled(Reg);
1338 if (!isReservedReg(MF, Reg))
1339 ExtraCSSpill = true;
1340 break;
1341 }
1342 }
1343 } else if (!UnspilledCS2GPRs.empty() &&
1344 !AFI->isThumbFunction()) {
1345 unsigned Reg = UnspilledCS2GPRs.front();
1346 MF.getRegInfo().setPhysRegUsed(Reg);
1347 AFI->setCSRegisterIsSpilled(Reg);
1348 if (!isReservedReg(MF, Reg))
1349 ExtraCSSpill = true;
1350 }
1351 }
1352
1353 // Estimate if we might need to scavenge a register at some point in order
919 MF.getRegInfo().setPhysRegUsed(Reg);
920 AFI->setCSRegisterIsSpilled(Reg);
921 if (!isReservedReg(MF, Reg))
922 ExtraCSSpill = true;
923 break;
924 }
925 }
926 } else if (!UnspilledCS2GPRs.empty() &&
927 !AFI->isThumbFunction()) {
928 unsigned Reg = UnspilledCS2GPRs.front();
929 MF.getRegInfo().setPhysRegUsed(Reg);
930 AFI->setCSRegisterIsSpilled(Reg);
931 if (!isReservedReg(MF, Reg))
932 ExtraCSSpill = true;
933 }
934 }
935
936 // Estimate if we might need to scavenge a register at some point in order
1354 // to materialize a stack offset. If so, either spill one additiona
937 // to materialize a stack offset. If so, either spill one additional
1355 // callee-saved register or reserve a special spill slot to facilitate
1356 // register scavenging.
1357 if (RS && !ExtraCSSpill && !AFI->isThumbFunction()) {
1358 MachineFrameInfo *MFI = MF.getFrameInfo();
1359 unsigned Size = estimateStackSize(MF, MFI);
1360 unsigned Limit = (1 << 12) - 1;
1361 for (MachineFunction::iterator BB = MF.begin(),E = MF.end();BB != E; ++BB)
1362 for (MachineBasicBlock::iterator I= BB->begin(); I != BB->end(); ++I) {

--- 92 unchanged lines hidden (view full) ---

1455 }
1456}
1457
1458void ARMRegisterInfo::emitPrologue(MachineFunction &MF) const {
1459 MachineBasicBlock &MBB = MF.front();
1460 MachineBasicBlock::iterator MBBI = MBB.begin();
1461 MachineFrameInfo *MFI = MF.getFrameInfo();
1462 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
938 // callee-saved register or reserve a special spill slot to facilitate
939 // register scavenging.
940 if (RS && !ExtraCSSpill && !AFI->isThumbFunction()) {
941 MachineFrameInfo *MFI = MF.getFrameInfo();
942 unsigned Size = estimateStackSize(MF, MFI);
943 unsigned Limit = (1 << 12) - 1;
944 for (MachineFunction::iterator BB = MF.begin(),E = MF.end();BB != E; ++BB)
945 for (MachineBasicBlock::iterator I= BB->begin(); I != BB->end(); ++I) {

--- 92 unchanged lines hidden (view full) ---

1038 }
1039}
1040
1041void ARMRegisterInfo::emitPrologue(MachineFunction &MF) const {
1042 MachineBasicBlock &MBB = MF.front();
1043 MachineBasicBlock::iterator MBBI = MBB.begin();
1044 MachineFrameInfo *MFI = MF.getFrameInfo();
1045 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
1463 bool isThumb = AFI->isThumbFunction();
1464 unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize();
1465 unsigned NumBytes = MFI->getStackSize();
1466 const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
1467 DebugLoc dl = (MBBI != MBB.end() ?
1468 MBBI->getDebugLoc() : DebugLoc::getUnknownLoc());
1469
1046 unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize();
1047 unsigned NumBytes = MFI->getStackSize();
1048 const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
1049 DebugLoc dl = (MBBI != MBB.end() ?
1050 MBBI->getDebugLoc() : DebugLoc::getUnknownLoc());
1051
1470 if (isThumb) {
1471 // Check if R3 is live in. It might have to be used as a scratch register.
1472 for (MachineRegisterInfo::livein_iterator I =MF.getRegInfo().livein_begin(),
1473 E = MF.getRegInfo().livein_end(); I != E; ++I) {
1474 if (I->first == ARM::R3) {
1475 AFI->setR3IsLiveIn(true);
1476 break;
1477 }
1478 }
1479
1480 // Thumb add/sub sp, imm8 instructions implicitly multiply the offset by 4.
1481 NumBytes = (NumBytes + 3) & ~3;
1482 MFI->setStackSize(NumBytes);
1483 }
1484
1485 // Determine the sizes of each callee-save spill areas and record which frame
1486 // belongs to which callee-save spill areas.
1487 unsigned GPRCS1Size = 0, GPRCS2Size = 0, DPRCSSize = 0;
1488 int FramePtrSpillFI = 0;
1489
1490 if (VARegSaveSize)
1052 // Determine the sizes of each callee-save spill areas and record which frame
1053 // belongs to which callee-save spill areas.
1054 unsigned GPRCS1Size = 0, GPRCS2Size = 0, DPRCSSize = 0;
1055 int FramePtrSpillFI = 0;
1056
1057 if (VARegSaveSize)
1491 emitSPUpdate(MBB, MBBI, -VARegSaveSize, ARMCC::AL, 0, isThumb, TII,
1492 *this, dl);
1058 emitSPUpdate(MBB, MBBI, TII, dl, -VARegSaveSize);
1493
1494 if (!AFI->hasStackFrame()) {
1495 if (NumBytes != 0)
1059
1060 if (!AFI->hasStackFrame()) {
1061 if (NumBytes != 0)
1496 emitSPUpdate(MBB, MBBI, -NumBytes, ARMCC::AL, 0, isThumb, TII, *this, dl);
1062 emitSPUpdate(MBB, MBBI, TII, dl, -NumBytes);
1497 return;
1498 }
1499
1500 for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
1501 unsigned Reg = CSI[i].getReg();
1502 int FI = CSI[i].getFrameIdx();
1503 switch (Reg) {
1504 case ARM::R4:

--- 21 unchanged lines hidden (view full) ---

1526 }
1527 break;
1528 default:
1529 AFI->addDPRCalleeSavedAreaFrame(FI);
1530 DPRCSSize += 8;
1531 }
1532 }
1533
1063 return;
1064 }
1065
1066 for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
1067 unsigned Reg = CSI[i].getReg();
1068 int FI = CSI[i].getFrameIdx();
1069 switch (Reg) {
1070 case ARM::R4:

--- 21 unchanged lines hidden (view full) ---

1092 }
1093 break;
1094 default:
1095 AFI->addDPRCalleeSavedAreaFrame(FI);
1096 DPRCSSize += 8;
1097 }
1098 }
1099
1534 if (!isThumb) {
1535 // Build the new SUBri to adjust SP for integer callee-save spill area 1.
1536 emitSPUpdate(MBB, MBBI, -GPRCS1Size, ARMCC::AL, 0, isThumb, TII, *this, dl);
1537 movePastCSLoadStoreOps(MBB, MBBI, ARM::STR, 1, STI);
1538 } else if (MBBI != MBB.end() && MBBI->getOpcode() == ARM::tPUSH) {
1539 ++MBBI;
1540 if (MBBI != MBB.end())
1541 dl = MBBI->getDebugLoc();
1542 }
1100 // Build the new SUBri to adjust SP for integer callee-save spill area 1.
1101 emitSPUpdate(MBB, MBBI, TII, dl, -GPRCS1Size);
1102 movePastCSLoadStoreOps(MBB, MBBI, ARM::STR, 1, STI);
1543
1544 // Darwin ABI requires FP to point to the stack slot that contains the
1545 // previous FP.
1546 if (STI.isTargetDarwin() || hasFP(MF)) {
1547 MachineInstrBuilder MIB =
1103
1104 // Darwin ABI requires FP to point to the stack slot that contains the
1105 // previous FP.
1106 if (STI.isTargetDarwin() || hasFP(MF)) {
1107 MachineInstrBuilder MIB =
1548 BuildMI(MBB, MBBI, dl, TII.get(isThumb ? ARM::tADDrSPi : ARM::ADDri),
1549 FramePtr)
1108 BuildMI(MBB, MBBI, dl, TII.get(ARM::ADDri), FramePtr)
1550 .addFrameIndex(FramePtrSpillFI).addImm(0);
1109 .addFrameIndex(FramePtrSpillFI).addImm(0);
1551 if (!isThumb) AddDefaultCC(AddDefaultPred(MIB));
1110 AddDefaultCC(AddDefaultPred(MIB));
1552 }
1553
1111 }
1112
1554 if (!isThumb) {
1555 // Build the new SUBri to adjust SP for integer callee-save spill area 2.
1556 emitSPUpdate(MBB, MBBI, -GPRCS2Size, ARMCC::AL, 0, false, TII, *this, dl);
1113 // Build the new SUBri to adjust SP for integer callee-save spill area 2.
1114 emitSPUpdate(MBB, MBBI, TII, dl, -GPRCS2Size);
1557
1115
1558 // Build the new SUBri to adjust SP for FP callee-save spill area.
1559 movePastCSLoadStoreOps(MBB, MBBI, ARM::STR, 2, STI);
1560 emitSPUpdate(MBB, MBBI, -DPRCSSize, ARMCC::AL, 0, false, TII, *this, dl);
1561 }
1116 // Build the new SUBri to adjust SP for FP callee-save spill area.
1117 movePastCSLoadStoreOps(MBB, MBBI, ARM::STR, 2, STI);
1118 emitSPUpdate(MBB, MBBI, TII, dl, -DPRCSSize);
1562
1563 // Determine starting offsets of spill areas.
1564 unsigned DPRCSOffset = NumBytes - (GPRCS1Size + GPRCS2Size + DPRCSSize);
1565 unsigned GPRCS2Offset = DPRCSOffset + DPRCSSize;
1566 unsigned GPRCS1Offset = GPRCS2Offset + GPRCS2Size;
1567 AFI->setFramePtrSpillOffset(MFI->getObjectOffset(FramePtrSpillFI) + NumBytes);
1568 AFI->setGPRCalleeSavedArea1Offset(GPRCS1Offset);
1569 AFI->setGPRCalleeSavedArea2Offset(GPRCS2Offset);
1570 AFI->setDPRCalleeSavedAreaOffset(DPRCSOffset);
1119
1120 // Determine starting offsets of spill areas.
1121 unsigned DPRCSOffset = NumBytes - (GPRCS1Size + GPRCS2Size + DPRCSSize);
1122 unsigned GPRCS2Offset = DPRCSOffset + DPRCSSize;
1123 unsigned GPRCS1Offset = GPRCS2Offset + GPRCS2Size;
1124 AFI->setFramePtrSpillOffset(MFI->getObjectOffset(FramePtrSpillFI) + NumBytes);
1125 AFI->setGPRCalleeSavedArea1Offset(GPRCS1Offset);
1126 AFI->setGPRCalleeSavedArea2Offset(GPRCS2Offset);
1127 AFI->setDPRCalleeSavedAreaOffset(DPRCSOffset);
1571
1128
1572 NumBytes = DPRCSOffset;
1573 if (NumBytes) {
1574 // Insert it after all the callee-save spills.
1129 NumBytes = DPRCSOffset;
1130 if (NumBytes) {
1131 // Insert it after all the callee-save spills.
1575 if (!isThumb)
1576 movePastCSLoadStoreOps(MBB, MBBI, ARM::FSTD, 3, STI);
1577 emitSPUpdate(MBB, MBBI, -NumBytes, ARMCC::AL, 0, isThumb, TII, *this, dl);
1132 movePastCSLoadStoreOps(MBB, MBBI, ARM::FSTD, 3, STI);
1133 emitSPUpdate(MBB, MBBI, TII, dl, -NumBytes);
1578 }
1579
1134 }
1135
1580 if(STI.isTargetELF() && hasFP(MF)) {
1136 if (STI.isTargetELF() && hasFP(MF)) {
1581 MFI->setOffsetAdjustment(MFI->getOffsetAdjustment() -
1582 AFI->getFramePtrSpillOffset());
1583 }
1584
1585 AFI->setGPRCalleeSavedArea1Size(GPRCS1Size);
1586 AFI->setGPRCalleeSavedArea2Size(GPRCS2Size);
1587 AFI->setDPRCalleeSavedAreaSize(DPRCSSize);
1588}
1589
1590static bool isCalleeSavedRegister(unsigned Reg, const unsigned *CSRegs) {
1591 for (unsigned i = 0; CSRegs[i]; ++i)
1592 if (Reg == CSRegs[i])
1593 return true;
1594 return false;
1595}
1596
1597static bool isCSRestore(MachineInstr *MI, const unsigned *CSRegs) {
1598 return ((MI->getOpcode() == ARM::FLDD ||
1137 MFI->setOffsetAdjustment(MFI->getOffsetAdjustment() -
1138 AFI->getFramePtrSpillOffset());
1139 }
1140
1141 AFI->setGPRCalleeSavedArea1Size(GPRCS1Size);
1142 AFI->setGPRCalleeSavedArea2Size(GPRCS2Size);
1143 AFI->setDPRCalleeSavedAreaSize(DPRCSSize);
1144}
1145
1146static bool isCalleeSavedRegister(unsigned Reg, const unsigned *CSRegs) {
1147 for (unsigned i = 0; CSRegs[i]; ++i)
1148 if (Reg == CSRegs[i])
1149 return true;
1150 return false;
1151}
1152
1153static bool isCSRestore(MachineInstr *MI, const unsigned *CSRegs) {
1154 return ((MI->getOpcode() == ARM::FLDD ||
1599 MI->getOpcode() == ARM::LDR ||
1600 MI->getOpcode() == ARM::tRestore) &&
1155 MI->getOpcode() == ARM::LDR) &&
1601 MI->getOperand(1).isFI() &&
1602 isCalleeSavedRegister(MI->getOperand(0).getReg(), CSRegs));
1603}
1604
1605void ARMRegisterInfo::emitEpilogue(MachineFunction &MF,
1606 MachineBasicBlock &MBB) const {
1607 MachineBasicBlock::iterator MBBI = prior(MBB.end());
1156 MI->getOperand(1).isFI() &&
1157 isCalleeSavedRegister(MI->getOperand(0).getReg(), CSRegs));
1158}
1159
1160void ARMRegisterInfo::emitEpilogue(MachineFunction &MF,
1161 MachineBasicBlock &MBB) const {
1162 MachineBasicBlock::iterator MBBI = prior(MBB.end());
1608 assert((MBBI->getOpcode() == ARM::BX_RET ||
1609 MBBI->getOpcode() == ARM::tBX_RET ||
1610 MBBI->getOpcode() == ARM::tPOP_RET) &&
1163 assert(MBBI->getOpcode() == ARM::BX_RET &&
1611 "Can only insert epilog into returning blocks");
1612 DebugLoc dl = MBBI->getDebugLoc();
1613 MachineFrameInfo *MFI = MF.getFrameInfo();
1614 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
1164 "Can only insert epilog into returning blocks");
1165 DebugLoc dl = MBBI->getDebugLoc();
1166 MachineFrameInfo *MFI = MF.getFrameInfo();
1167 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
1615 bool isThumb = AFI->isThumbFunction();
1616 unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize();
1617 int NumBytes = (int)MFI->getStackSize();
1618
1619 if (!AFI->hasStackFrame()) {
1620 if (NumBytes != 0)
1168 unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize();
1169 int NumBytes = (int)MFI->getStackSize();
1170
1171 if (!AFI->hasStackFrame()) {
1172 if (NumBytes != 0)
1621 emitSPUpdate(MBB, MBBI, NumBytes, ARMCC::AL, 0, isThumb, TII, *this, dl);
1173 emitSPUpdate(MBB, MBBI, TII, dl, NumBytes);
1622 } else {
1623 // Unwind MBBI to point to first LDR / FLDD.
1624 const unsigned *CSRegs = getCalleeSavedRegs();
1625 if (MBBI != MBB.begin()) {
1626 do
1627 --MBBI;
1628 while (MBBI != MBB.begin() && isCSRestore(MBBI, CSRegs));
1629 if (!isCSRestore(MBBI, CSRegs))
1630 ++MBBI;
1631 }
1632
1633 // Move SP to start of FP callee save spill area.
1634 NumBytes -= (AFI->getGPRCalleeSavedArea1Size() +
1635 AFI->getGPRCalleeSavedArea2Size() +
1636 AFI->getDPRCalleeSavedAreaSize());
1174 } else {
1175 // Unwind MBBI to point to first LDR / FLDD.
1176 const unsigned *CSRegs = getCalleeSavedRegs();
1177 if (MBBI != MBB.begin()) {
1178 do
1179 --MBBI;
1180 while (MBBI != MBB.begin() && isCSRestore(MBBI, CSRegs));
1181 if (!isCSRestore(MBBI, CSRegs))
1182 ++MBBI;
1183 }
1184
1185 // Move SP to start of FP callee save spill area.
1186 NumBytes -= (AFI->getGPRCalleeSavedArea1Size() +
1187 AFI->getGPRCalleeSavedArea2Size() +
1188 AFI->getDPRCalleeSavedAreaSize());
1637 if (isThumb) {
1638 if (hasFP(MF)) {
1639 NumBytes = AFI->getFramePtrSpillOffset() - NumBytes;
1640 // Reset SP based on frame pointer only if the stack frame extends beyond
1641 // frame pointer stack slot or target is ELF and the function has FP.
1189
1190 // Darwin ABI requires FP to point to the stack slot that contains the
1191 // previous FP.
1192 if ((STI.isTargetDarwin() && NumBytes) || hasFP(MF)) {
1193 NumBytes = AFI->getFramePtrSpillOffset() - NumBytes;
1194 // Reset SP based on frame pointer only if the stack frame extends beyond
1195 // frame pointer stack slot or target is ELF and the function has FP.
1196 if (AFI->getGPRCalleeSavedArea2Size() ||
1197 AFI->getDPRCalleeSavedAreaSize() ||
1198 AFI->getDPRCalleeSavedAreaOffset()||
1199 hasFP(MF)) {
1642 if (NumBytes)
1200 if (NumBytes)
1643 emitThumbRegPlusImmediate(MBB, MBBI, ARM::SP, FramePtr, -NumBytes,
1644 TII, *this, dl);
1201 BuildMI(MBB, MBBI, dl, TII.get(ARM::SUBri), ARM::SP).addReg(FramePtr)
1202 .addImm(NumBytes)
1203 .addImm((unsigned)ARMCC::AL).addReg(0).addReg(0);
1645 else
1204 else
1646 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVlor2hir), ARM::SP)
1647 .addReg(FramePtr);
1648 } else {
1649 if (MBBI->getOpcode() == ARM::tBX_RET &&
1650 &MBB.front() != MBBI &&
1651 prior(MBBI)->getOpcode() == ARM::tPOP) {
1652 MachineBasicBlock::iterator PMBBI = prior(MBBI);
1653 emitSPUpdate(MBB, PMBBI, NumBytes, ARMCC::AL, 0, isThumb, TII,
1654 *this, dl);
1655 } else
1656 emitSPUpdate(MBB, MBBI, NumBytes, ARMCC::AL, 0, isThumb, TII,
1657 *this, dl);
1205 BuildMI(MBB, MBBI, dl, TII.get(ARM::MOVr), ARM::SP).addReg(FramePtr)
1206 .addImm((unsigned)ARMCC::AL).addReg(0).addReg(0);
1658 }
1207 }
1659 } else {
1660 // Darwin ABI requires FP to point to the stack slot that contains the
1661 // previous FP.
1662 if ((STI.isTargetDarwin() && NumBytes) || hasFP(MF)) {
1663 NumBytes = AFI->getFramePtrSpillOffset() - NumBytes;
1664 // Reset SP based on frame pointer only if the stack frame extends beyond
1665 // frame pointer stack slot or target is ELF and the function has FP.
1666 if (AFI->getGPRCalleeSavedArea2Size() ||
1667 AFI->getDPRCalleeSavedAreaSize() ||
1668 AFI->getDPRCalleeSavedAreaOffset()||
1669 hasFP(MF)) {
1670 if (NumBytes)
1671 BuildMI(MBB, MBBI, dl, TII.get(ARM::SUBri), ARM::SP).addReg(FramePtr)
1672 .addImm(NumBytes)
1673 .addImm((unsigned)ARMCC::AL).addReg(0).addReg(0);
1674 else
1675 BuildMI(MBB, MBBI, dl, TII.get(ARM::MOVr), ARM::SP).addReg(FramePtr)
1676 .addImm((unsigned)ARMCC::AL).addReg(0).addReg(0);
1677 }
1678 } else if (NumBytes) {
1679 emitSPUpdate(MBB, MBBI, NumBytes, ARMCC::AL, 0, false, TII, *this, dl);
1680 }
1208 } else if (NumBytes) {
1209 emitSPUpdate(MBB, MBBI, TII, dl, NumBytes);
1210 }
1681
1211
1682 // Move SP to start of integer callee save spill area 2.
1683 movePastCSLoadStoreOps(MBB, MBBI, ARM::FLDD, 3, STI);
1684 emitSPUpdate(MBB, MBBI, AFI->getDPRCalleeSavedAreaSize(), ARMCC::AL, 0,
1685 false, TII, *this, dl);
1212 // Move SP to start of integer callee save spill area 2.
1213 movePastCSLoadStoreOps(MBB, MBBI, ARM::FLDD, 3, STI);
1214 emitSPUpdate(MBB, MBBI, TII, dl, AFI->getDPRCalleeSavedAreaSize());
1686
1215
1687 // Move SP to start of integer callee save spill area 1.
1688 movePastCSLoadStoreOps(MBB, MBBI, ARM::LDR, 2, STI);
1689 emitSPUpdate(MBB, MBBI, AFI->getGPRCalleeSavedArea2Size(), ARMCC::AL, 0,
1690 false, TII, *this, dl);
1216 // Move SP to start of integer callee save spill area 1.
1217 movePastCSLoadStoreOps(MBB, MBBI, ARM::LDR, 2, STI);
1218 emitSPUpdate(MBB, MBBI, TII, dl, AFI->getGPRCalleeSavedArea2Size());
1691
1219
1692 // Move SP to SP upon entry to the function.
1693 movePastCSLoadStoreOps(MBB, MBBI, ARM::LDR, 1, STI);
1694 emitSPUpdate(MBB, MBBI, AFI->getGPRCalleeSavedArea1Size(), ARMCC::AL, 0,
1695 false, TII, *this, dl);
1696 }
1220 // Move SP to SP upon entry to the function.
1221 movePastCSLoadStoreOps(MBB, MBBI, ARM::LDR, 1, STI);
1222 emitSPUpdate(MBB, MBBI, TII, dl, AFI->getGPRCalleeSavedArea1Size());
1697 }
1698
1223 }
1224
1699 if (VARegSaveSize) {
1700 if (isThumb)
1701 // Epilogue for vararg functions: pop LR to R3 and branch off it.
1702 // FIXME: Verify this is still ok when R3 is no longer being reserved.
1703 BuildMI(MBB, MBBI, dl, TII.get(ARM::tPOP)).addReg(ARM::R3);
1225 if (VARegSaveSize)
1226 emitSPUpdate(MBB, MBBI, TII, dl, VARegSaveSize);
1704
1227
1705 emitSPUpdate(MBB, MBBI, VARegSaveSize, ARMCC::AL, 0, isThumb, TII,
1706 *this, dl);
1707
1708 if (isThumb) {
1709 BuildMI(MBB, MBBI, dl, TII.get(ARM::tBX_RET_vararg)).addReg(ARM::R3);
1710 MBB.erase(MBBI);
1711 }
1712 }
1713}
1714
1228}
1229
1715unsigned ARMRegisterInfo::getRARegister() const {
1230unsigned ARMBaseRegisterInfo::getRARegister() const {
1716 return ARM::LR;
1717}
1718
1231 return ARM::LR;
1232}
1233
1719unsigned ARMRegisterInfo::getFrameRegister(MachineFunction &MF) const {
1234unsigned ARMBaseRegisterInfo::getFrameRegister(MachineFunction &MF) const {
1720 if (STI.isTargetDarwin() || hasFP(MF))
1721 return FramePtr;
1722 return ARM::SP;
1723}
1724
1235 if (STI.isTargetDarwin() || hasFP(MF))
1236 return FramePtr;
1237 return ARM::SP;
1238}
1239
1725unsigned ARMRegisterInfo::getEHExceptionRegister() const {
1240unsigned ARMBaseRegisterInfo::getEHExceptionRegister() const {
1726 assert(0 && "What is the exception register");
1727 return 0;
1728}
1729
1241 assert(0 && "What is the exception register");
1242 return 0;
1243}
1244
1730unsigned ARMRegisterInfo::getEHHandlerRegister() const {
1245unsigned ARMBaseRegisterInfo::getEHHandlerRegister() const {
1731 assert(0 && "What is the exception handler register");
1732 return 0;
1733}
1734
1246 assert(0 && "What is the exception handler register");
1247 return 0;
1248}
1249
1735int ARMRegisterInfo::getDwarfRegNum(unsigned RegNum, bool isEH) const {
1250int ARMBaseRegisterInfo::getDwarfRegNum(unsigned RegNum, bool isEH) const {
1736 return ARMGenRegisterInfo::getDwarfRegNumFull(RegNum, 0);
1737}
1738
1251 return ARMGenRegisterInfo::getDwarfRegNumFull(RegNum, 0);
1252}
1253
1739unsigned ARMRegisterInfo::getRegisterPairEven(unsigned Reg,
1740 const MachineFunction &MF) const {
1254unsigned ARMBaseRegisterInfo::getRegisterPairEven(unsigned Reg,
1255 const MachineFunction &MF) const {
1741 switch (Reg) {
1742 default: break;
1743 // Return 0 if either register of the pair is a special register.
1744 // So no R12, etc.
1745 case ARM::R1:
1746 return ARM::R0;
1747 case ARM::R3:
1748 // FIXME!

--- 56 unchanged lines hidden (view full) ---

1805 return ARM::D12;
1806 case ARM::D15:
1807 return ARM::D14;
1808 }
1809
1810 return 0;
1811}
1812
1256 switch (Reg) {
1257 default: break;
1258 // Return 0 if either register of the pair is a special register.
1259 // So no R12, etc.
1260 case ARM::R1:
1261 return ARM::R0;
1262 case ARM::R3:
1263 // FIXME!

--- 56 unchanged lines hidden (view full) ---

1320 return ARM::D12;
1321 case ARM::D15:
1322 return ARM::D14;
1323 }
1324
1325 return 0;
1326}
1327
1813unsigned ARMRegisterInfo::getRegisterPairOdd(unsigned Reg,
1328unsigned ARMBaseRegisterInfo::getRegisterPairOdd(unsigned Reg,
1814 const MachineFunction &MF) const {
1815 switch (Reg) {
1816 default: break;
1817 // Return 0 if either register of the pair is a special register.
1818 // So no R12, etc.
1819 case ARM::R0:
1820 return ARM::R1;
1821 case ARM::R2:

--- 66 unchanged lines hidden ---
1329 const MachineFunction &MF) const {
1330 switch (Reg) {
1331 default: break;
1332 // Return 0 if either register of the pair is a special register.
1333 // So no R12, etc.
1334 case ARM::R0:
1335 return ARM::R1;
1336 case ARM::R2:

--- 66 unchanged lines hidden ---