1 //===- Thumb1RegisterInfo.cpp - Thumb-1 Register Information ----*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file contains the Thumb-1 implementation of the TargetRegisterInfo
13 //===----------------------------------------------------------------------===//
16 #include "ARMAddressingModes.h"
17 #include "ARMBaseInstrInfo.h"
18 #include "ARMMachineFunctionInfo.h"
19 #include "ARMSubtarget.h"
20 #include "Thumb1InstrInfo.h"
21 #include "Thumb1RegisterInfo.h"
22 #include "llvm/Constants.h"
23 #include "llvm/DerivedTypes.h"
24 #include "llvm/Function.h"
25 #include "llvm/LLVMContext.h"
26 #include "llvm/CodeGen/MachineConstantPool.h"
27 #include "llvm/CodeGen/MachineFrameInfo.h"
28 #include "llvm/CodeGen/MachineFunction.h"
29 #include "llvm/CodeGen/MachineInstrBuilder.h"
30 #include "llvm/CodeGen/MachineLocation.h"
31 #include "llvm/CodeGen/MachineRegisterInfo.h"
32 #include "llvm/Target/TargetFrameLowering.h"
33 #include "llvm/Target/TargetMachine.h"
34 #include "llvm/Support/CommandLine.h"
35 #include "llvm/Support/ErrorHandling.h"
36 #include "llvm/Support/raw_ostream.h"
39 extern cl::opt
<bool> ReuseFrameIndexVals
;
44 Thumb1RegisterInfo::Thumb1RegisterInfo(const ARMBaseInstrInfo
&tii
,
45 const ARMSubtarget
&sti
)
46 : ARMBaseRegisterInfo(tii
, sti
) {
49 const TargetRegisterClass
*
50 Thumb1RegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass
*RC
)
52 if (ARM::tGPRRegClass
.hasSubClassEq(RC
))
53 return ARM::tGPRRegisterClass
;
54 return ARMBaseRegisterInfo::getLargestLegalSuperClass(RC
);
57 const TargetRegisterClass
*
58 Thumb1RegisterInfo::getPointerRegClass(unsigned Kind
) const {
59 return ARM::tGPRRegisterClass
;
62 /// emitLoadConstPool - Emits a load from constpool to materialize the
63 /// specified immediate.
65 Thumb1RegisterInfo::emitLoadConstPool(MachineBasicBlock
&MBB
,
66 MachineBasicBlock::iterator
&MBBI
,
68 unsigned DestReg
, unsigned SubIdx
,
70 ARMCC::CondCodes Pred
, unsigned PredReg
,
71 unsigned MIFlags
) const {
72 MachineFunction
&MF
= *MBB
.getParent();
73 MachineConstantPool
*ConstantPool
= MF
.getConstantPool();
74 const Constant
*C
= ConstantInt::get(
75 Type::getInt32Ty(MBB
.getParent()->getFunction()->getContext()), Val
);
76 unsigned Idx
= ConstantPool
->getConstantPoolIndex(C
, 4);
78 BuildMI(MBB
, MBBI
, dl
, TII
.get(ARM::tLDRpci
))
79 .addReg(DestReg
, getDefRegState(true), SubIdx
)
80 .addConstantPoolIndex(Idx
).addImm(Pred
).addReg(PredReg
)
85 /// emitThumbRegPlusImmInReg - Emits a series of instructions to materialize
86 /// a destreg = basereg + immediate in Thumb code. Materialize the immediate
87 /// in a register using mov / mvn sequences or load the immediate from a
90 void emitThumbRegPlusImmInReg(MachineBasicBlock
&MBB
,
91 MachineBasicBlock::iterator
&MBBI
,
93 unsigned DestReg
, unsigned BaseReg
,
94 int NumBytes
, bool CanChangeCC
,
95 const TargetInstrInfo
&TII
,
96 const ARMBaseRegisterInfo
& MRI
,
97 unsigned MIFlags
= MachineInstr::NoFlags
) {
98 MachineFunction
&MF
= *MBB
.getParent();
99 bool isHigh
= !isARMLowRegister(DestReg
) ||
100 (BaseReg
!= 0 && !isARMLowRegister(BaseReg
));
102 // Subtract doesn't have high register version. Load the negative value
103 // if either base or dest register is a high register. Also, if do not
104 // issue sub as part of the sequence if condition register is to be
106 if (NumBytes
< 0 && !isHigh
&& CanChangeCC
) {
108 NumBytes
= -NumBytes
;
110 unsigned LdReg
= DestReg
;
111 if (DestReg
== ARM::SP
) {
112 assert(BaseReg
== ARM::SP
&& "Unexpected!");
113 LdReg
= MF
.getRegInfo().createVirtualRegister(ARM::tGPRRegisterClass
);
116 if (NumBytes
<= 255 && NumBytes
>= 0)
117 AddDefaultT1CC(BuildMI(MBB
, MBBI
, dl
, TII
.get(ARM::tMOVi8
), LdReg
))
118 .addImm(NumBytes
).setMIFlags(MIFlags
);
119 else if (NumBytes
< 0 && NumBytes
>= -255) {
120 AddDefaultT1CC(BuildMI(MBB
, MBBI
, dl
, TII
.get(ARM::tMOVi8
), LdReg
))
121 .addImm(NumBytes
).setMIFlags(MIFlags
);
122 AddDefaultT1CC(BuildMI(MBB
, MBBI
, dl
, TII
.get(ARM::tRSB
), LdReg
))
123 .addReg(LdReg
, RegState::Kill
).setMIFlags(MIFlags
);
125 MRI
.emitLoadConstPool(MBB
, MBBI
, dl
, LdReg
, 0, NumBytes
,
126 ARMCC::AL
, 0, MIFlags
);
129 int Opc
= (isSub
) ? ARM::tSUBrr
: (isHigh
? ARM::tADDhirr
: ARM::tADDrr
);
130 MachineInstrBuilder MIB
=
131 BuildMI(MBB
, MBBI
, dl
, TII
.get(Opc
), DestReg
);
132 if (Opc
!= ARM::tADDhirr
)
133 MIB
= AddDefaultT1CC(MIB
);
134 if (DestReg
== ARM::SP
|| isSub
)
135 MIB
.addReg(BaseReg
).addReg(LdReg
, RegState::Kill
);
137 MIB
.addReg(LdReg
).addReg(BaseReg
, RegState::Kill
);
141 /// calcNumMI - Returns the number of instructions required to materialize
142 /// the specific add / sub r, c instruction.
143 static unsigned calcNumMI(int Opc
, int ExtraOpc
, unsigned Bytes
,
144 unsigned NumBits
, unsigned Scale
) {
146 unsigned Chunk
= ((1 << NumBits
) - 1) * Scale
;
148 if (Opc
== ARM::tADDrSPi
) {
149 unsigned ThisVal
= (Bytes
> Chunk
) ? Chunk
: Bytes
;
153 Scale
= 1; // Followed by a number of tADDi8.
154 Chunk
= ((1 << NumBits
) - 1) * Scale
;
157 NumMIs
+= Bytes
/ Chunk
;
158 if ((Bytes
% Chunk
) != 0)
165 /// emitThumbRegPlusImmediate - Emits a series of instructions to materialize
166 /// a destreg = basereg + immediate in Thumb code.
167 void llvm::emitThumbRegPlusImmediate(MachineBasicBlock
&MBB
,
168 MachineBasicBlock::iterator
&MBBI
,
170 unsigned DestReg
, unsigned BaseReg
,
171 int NumBytes
, const TargetInstrInfo
&TII
,
172 const ARMBaseRegisterInfo
& MRI
,
174 bool isSub
= NumBytes
< 0;
175 unsigned Bytes
= (unsigned)NumBytes
;
176 if (isSub
) Bytes
= -NumBytes
;
177 bool isMul4
= (Bytes
& 3) == 0;
178 bool isTwoAddr
= false;
179 bool DstNotEqBase
= false;
180 unsigned NumBits
= 1;
185 bool NeedPred
= false;
187 if (DestReg
== BaseReg
&& BaseReg
== ARM::SP
) {
188 assert(isMul4
&& "Thumb sp inc / dec size must be multiple of 4!");
191 Opc
= isSub
? ARM::tSUBspi
: ARM::tADDspi
;
193 } else if (!isSub
&& BaseReg
== ARM::SP
) {
196 // r1 = add sp, 100 * 4
200 ExtraOpc
= ARM::tADDi3
;
209 if (DestReg
!= BaseReg
)
212 if (DestReg
== ARM::SP
) {
213 Opc
= isSub
? ARM::tSUBspi
: ARM::tADDspi
;
214 assert(isMul4
&& "Thumb sp inc / dec size must be multiple of 4!");
218 Opc
= isSub
? ARM::tSUBi8
: ARM::tADDi8
;
220 NeedPred
= NeedCC
= true;
225 unsigned NumMIs
= calcNumMI(Opc
, ExtraOpc
, Bytes
, NumBits
, Scale
);
226 unsigned Threshold
= (DestReg
== ARM::SP
) ? 3 : 2;
227 if (NumMIs
> Threshold
) {
228 // This will expand into too many instructions. Load the immediate from a
230 emitThumbRegPlusImmInReg(MBB
, MBBI
, dl
,
231 DestReg
, BaseReg
, NumBytes
, true,
237 if (isARMLowRegister(DestReg
) && isARMLowRegister(BaseReg
)) {
238 // If both are low registers, emit DestReg = add BaseReg, max(Imm, 7)
239 unsigned Chunk
= (1 << 3) - 1;
240 unsigned ThisVal
= (Bytes
> Chunk
) ? Chunk
: Bytes
;
242 const MCInstrDesc
&MCID
= TII
.get(isSub
? ARM::tSUBi3
: ARM::tADDi3
);
243 const MachineInstrBuilder MIB
=
244 AddDefaultT1CC(BuildMI(MBB
, MBBI
, dl
, MCID
, DestReg
).setMIFlags(MIFlags
));
245 AddDefaultPred(MIB
.addReg(BaseReg
, RegState::Kill
).addImm(ThisVal
));
247 AddDefaultPred(BuildMI(MBB
, MBBI
, dl
, TII
.get(ARM::tMOVr
), DestReg
)
248 .addReg(BaseReg
, RegState::Kill
))
249 .setMIFlags(MIFlags
);
254 unsigned Chunk
= ((1 << NumBits
) - 1) * Scale
;
256 unsigned ThisVal
= (Bytes
> Chunk
) ? Chunk
: Bytes
;
259 // Build the new tADD / tSUB.
261 MachineInstrBuilder MIB
= BuildMI(MBB
, MBBI
, dl
, TII
.get(Opc
), DestReg
);
263 MIB
= AddDefaultT1CC(MIB
);
264 MIB
.addReg(DestReg
).addImm(ThisVal
);
266 MIB
= AddDefaultPred(MIB
);
267 MIB
.setMIFlags(MIFlags
);
270 bool isKill
= BaseReg
!= ARM::SP
;
271 MachineInstrBuilder MIB
= BuildMI(MBB
, MBBI
, dl
, TII
.get(Opc
), DestReg
);
273 MIB
= AddDefaultT1CC(MIB
);
274 MIB
.addReg(BaseReg
, getKillRegState(isKill
)).addImm(ThisVal
);
276 MIB
= AddDefaultPred(MIB
);
277 MIB
.setMIFlags(MIFlags
);
280 if (Opc
== ARM::tADDrSPi
) {
286 Chunk
= ((1 << NumBits
) - 1) * Scale
;
287 Opc
= isSub
? ARM::tSUBi8
: ARM::tADDi8
;
288 NeedPred
= NeedCC
= isTwoAddr
= true;
294 const MCInstrDesc
&MCID
= TII
.get(ExtraOpc
);
295 AddDefaultPred(AddDefaultT1CC(BuildMI(MBB
, MBBI
, dl
, MCID
, DestReg
))
296 .addReg(DestReg
, RegState::Kill
)
297 .addImm(((unsigned)NumBytes
) & 3)
298 .setMIFlags(MIFlags
));
302 static void emitSPUpdate(MachineBasicBlock
&MBB
,
303 MachineBasicBlock::iterator
&MBBI
,
304 const TargetInstrInfo
&TII
, DebugLoc dl
,
305 const Thumb1RegisterInfo
&MRI
,
307 emitThumbRegPlusImmediate(MBB
, MBBI
, dl
, ARM::SP
, ARM::SP
, NumBytes
, TII
,
311 void Thumb1RegisterInfo::
312 eliminateCallFramePseudoInstr(MachineFunction
&MF
, MachineBasicBlock
&MBB
,
313 MachineBasicBlock::iterator I
) const {
314 const TargetFrameLowering
*TFI
= MF
.getTarget().getFrameLowering();
316 if (!TFI
->hasReservedCallFrame(MF
)) {
317 // If we have alloca, convert as follows:
318 // ADJCALLSTACKDOWN -> sub, sp, sp, amount
319 // ADJCALLSTACKUP -> add, sp, sp, amount
320 MachineInstr
*Old
= I
;
321 DebugLoc dl
= Old
->getDebugLoc();
322 unsigned Amount
= Old
->getOperand(0).getImm();
324 // We need to keep the stack aligned properly. To do this, we round the
325 // amount of space needed for the outgoing arguments up to the next
326 // alignment boundary.
327 unsigned Align
= TFI
->getStackAlignment();
328 Amount
= (Amount
+Align
-1)/Align
*Align
;
330 // Replace the pseudo instruction with a new instruction...
331 unsigned Opc
= Old
->getOpcode();
332 if (Opc
== ARM::ADJCALLSTACKDOWN
|| Opc
== ARM::tADJCALLSTACKDOWN
) {
333 emitSPUpdate(MBB
, I
, TII
, dl
, *this, -Amount
);
335 assert(Opc
== ARM::ADJCALLSTACKUP
|| Opc
== ARM::tADJCALLSTACKUP
);
336 emitSPUpdate(MBB
, I
, TII
, dl
, *this, Amount
);
343 /// emitThumbConstant - Emit a series of instructions to materialize a
345 static void emitThumbConstant(MachineBasicBlock
&MBB
,
346 MachineBasicBlock::iterator
&MBBI
,
347 unsigned DestReg
, int Imm
,
348 const TargetInstrInfo
&TII
,
349 const Thumb1RegisterInfo
& MRI
,
351 bool isSub
= Imm
< 0;
352 if (isSub
) Imm
= -Imm
;
354 int Chunk
= (1 << 8) - 1;
355 int ThisVal
= (Imm
> Chunk
) ? Chunk
: Imm
;
357 AddDefaultPred(AddDefaultT1CC(BuildMI(MBB
, MBBI
, dl
, TII
.get(ARM::tMOVi8
),
361 emitThumbRegPlusImmediate(MBB
, MBBI
, dl
, DestReg
, DestReg
, Imm
, TII
, MRI
);
363 const MCInstrDesc
&MCID
= TII
.get(ARM::tRSB
);
364 AddDefaultPred(AddDefaultT1CC(BuildMI(MBB
, MBBI
, dl
, MCID
, DestReg
))
365 .addReg(DestReg
, RegState::Kill
));
369 static void removeOperands(MachineInstr
&MI
, unsigned i
) {
371 for (unsigned e
= MI
.getNumOperands(); i
!= e
; ++i
)
372 MI
.RemoveOperand(Op
);
375 /// convertToNonSPOpcode - Change the opcode to the non-SP version, because
376 /// we're replacing the frame index with a non-SP register.
377 static unsigned convertToNonSPOpcode(unsigned Opcode
) {
389 bool Thumb1RegisterInfo::
390 rewriteFrameIndex(MachineBasicBlock::iterator II
, unsigned FrameRegIdx
,
391 unsigned FrameReg
, int &Offset
,
392 const ARMBaseInstrInfo
&TII
) const {
393 MachineInstr
&MI
= *II
;
394 MachineBasicBlock
&MBB
= *MI
.getParent();
395 DebugLoc dl
= MI
.getDebugLoc();
396 unsigned Opcode
= MI
.getOpcode();
397 const MCInstrDesc
&Desc
= MI
.getDesc();
398 unsigned AddrMode
= (Desc
.TSFlags
& ARMII::AddrModeMask
);
400 if (Opcode
== ARM::tADDrSPi
) {
401 Offset
+= MI
.getOperand(FrameRegIdx
+1).getImm();
403 // Can't use tADDrSPi if it's based off the frame pointer.
404 unsigned NumBits
= 0;
406 if (FrameReg
!= ARM::SP
) {
407 Opcode
= ARM::tADDi3
;
408 MI
.setDesc(TII
.get(Opcode
));
413 assert((Offset
& 3) == 0 &&
414 "Thumb add/sub sp, #imm immediate must be multiple of 4!");
418 if (Offset
== 0 && getInstrPredicate(&MI
, PredReg
) == ARMCC::AL
) {
419 // Turn it into a move.
420 MI
.setDesc(TII
.get(ARM::tMOVr
));
421 MI
.getOperand(FrameRegIdx
).ChangeToRegister(FrameReg
, false);
422 // Remove offset and add predicate operands.
423 MI
.RemoveOperand(FrameRegIdx
+1);
424 MachineInstrBuilder
MIB(&MI
);
429 // Common case: small offset, fits into instruction.
430 unsigned Mask
= (1 << NumBits
) - 1;
431 if (((Offset
/ Scale
) & ~Mask
) == 0) {
432 // Replace the FrameIndex with sp / fp
433 if (Opcode
== ARM::tADDi3
) {
434 removeOperands(MI
, FrameRegIdx
);
435 MachineInstrBuilder
MIB(&MI
);
436 AddDefaultPred(AddDefaultT1CC(MIB
).addReg(FrameReg
)
437 .addImm(Offset
/ Scale
));
439 MI
.getOperand(FrameRegIdx
).ChangeToRegister(FrameReg
, false);
440 MI
.getOperand(FrameRegIdx
+1).ChangeToImmediate(Offset
/ Scale
);
445 unsigned DestReg
= MI
.getOperand(0).getReg();
446 unsigned Bytes
= (Offset
> 0) ? Offset
: -Offset
;
447 unsigned NumMIs
= calcNumMI(Opcode
, 0, Bytes
, NumBits
, Scale
);
448 // MI would expand into a large number of instructions. Don't try to
449 // simplify the immediate.
451 emitThumbRegPlusImmediate(MBB
, II
, dl
, DestReg
, FrameReg
, Offset
, TII
,
458 // Translate r0 = add sp, imm to
459 // r0 = add sp, 255*4
460 // r0 = add r0, (imm - 255*4)
461 if (Opcode
== ARM::tADDi3
) {
462 removeOperands(MI
, FrameRegIdx
);
463 MachineInstrBuilder
MIB(&MI
);
464 AddDefaultPred(AddDefaultT1CC(MIB
).addReg(FrameReg
).addImm(Mask
));
466 MI
.getOperand(FrameRegIdx
).ChangeToRegister(FrameReg
, false);
467 MI
.getOperand(FrameRegIdx
+1).ChangeToImmediate(Mask
);
469 Offset
= (Offset
- Mask
* Scale
);
470 MachineBasicBlock::iterator NII
= llvm::next(II
);
471 emitThumbRegPlusImmediate(MBB
, NII
, dl
, DestReg
, DestReg
, Offset
, TII
,
474 // Translate r0 = add sp, -imm to
475 // r0 = -imm (this is then translated into a series of instructons)
477 emitThumbConstant(MBB
, II
, DestReg
, Offset
, TII
, *this, dl
);
479 MI
.setDesc(TII
.get(ARM::tADDhirr
));
480 MI
.getOperand(FrameRegIdx
).ChangeToRegister(DestReg
, false, false, true);
481 MI
.getOperand(FrameRegIdx
+1).ChangeToRegister(FrameReg
, false);
482 if (Opcode
== ARM::tADDi3
) {
483 MachineInstrBuilder
MIB(&MI
);
489 if (AddrMode
!= ARMII::AddrModeT1_s
)
490 llvm_unreachable("Unsupported addressing mode!");
492 unsigned ImmIdx
= FrameRegIdx
+ 1;
493 int InstrOffs
= MI
.getOperand(ImmIdx
).getImm();
494 unsigned NumBits
= (FrameReg
== ARM::SP
) ? 8 : 5;
497 Offset
+= InstrOffs
* Scale
;
498 assert((Offset
& (Scale
- 1)) == 0 && "Can't encode this offset!");
500 // Common case: small offset, fits into instruction.
501 MachineOperand
&ImmOp
= MI
.getOperand(ImmIdx
);
502 int ImmedOffset
= Offset
/ Scale
;
503 unsigned Mask
= (1 << NumBits
) - 1;
505 if ((unsigned)Offset
<= Mask
* Scale
) {
506 // Replace the FrameIndex with the frame register (e.g., sp).
507 MI
.getOperand(FrameRegIdx
).ChangeToRegister(FrameReg
, false);
508 ImmOp
.ChangeToImmediate(ImmedOffset
);
510 // If we're using a register where sp was stored, convert the instruction
511 // to the non-SP version.
512 unsigned NewOpc
= convertToNonSPOpcode(Opcode
);
513 if (NewOpc
!= Opcode
&& FrameReg
!= ARM::SP
)
514 MI
.setDesc(TII
.get(NewOpc
));
520 Mask
= (1 << NumBits
) - 1;
522 // If this is a thumb spill / restore, we will be using a constpool load to
523 // materialize the offset.
524 if (Opcode
== ARM::tLDRspi
|| Opcode
== ARM::tSTRspi
) {
525 ImmOp
.ChangeToImmediate(0);
527 // Otherwise, it didn't fit. Pull in what we can to simplify the immed.
528 ImmedOffset
= ImmedOffset
& Mask
;
529 ImmOp
.ChangeToImmediate(ImmedOffset
);
530 Offset
&= ~(Mask
* Scale
);
538 Thumb1RegisterInfo::resolveFrameIndex(MachineBasicBlock::iterator I
,
539 unsigned BaseReg
, int64_t Offset
) const {
540 MachineInstr
&MI
= *I
;
541 int Off
= Offset
; // ARM doesn't need the general 64-bit offsets
544 while (!MI
.getOperand(i
).isFI()) {
546 assert(i
< MI
.getNumOperands() && "Instr doesn't have FrameIndex operand!");
549 Done
= rewriteFrameIndex(MI
, i
, BaseReg
, Off
, TII
);
550 assert (Done
&& "Unable to resolve frame index!");
553 /// saveScavengerRegister - Spill the register so it can be used by the
554 /// register scavenger. Return true.
556 Thumb1RegisterInfo::saveScavengerRegister(MachineBasicBlock
&MBB
,
557 MachineBasicBlock::iterator I
,
558 MachineBasicBlock::iterator
&UseMI
,
559 const TargetRegisterClass
*RC
,
560 unsigned Reg
) const {
561 // Thumb1 can't use the emergency spill slot on the stack because
562 // ldr/str immediate offsets must be positive, and if we're referencing
563 // off the frame pointer (if, for example, there are alloca() calls in
564 // the function, the offset will be negative. Use R12 instead since that's
565 // a call clobbered register that we know won't be used in Thumb1 mode.
567 AddDefaultPred(BuildMI(MBB
, I
, DL
, TII
.get(ARM::tMOVr
))
568 .addReg(ARM::R12
, RegState::Define
)
569 .addReg(Reg
, RegState::Kill
));
571 // The UseMI is where we would like to restore the register. If there's
572 // interference with R12 before then, however, we'll need to restore it
573 // before that instead and adjust the UseMI.
575 for (MachineBasicBlock::iterator II
= I
; !done
&& II
!= UseMI
; ++II
) {
576 if (II
->isDebugValue())
578 // If this instruction affects R12, adjust our restore point.
579 for (unsigned i
= 0, e
= II
->getNumOperands(); i
!= e
; ++i
) {
580 const MachineOperand
&MO
= II
->getOperand(i
);
581 if (!MO
.isReg() || MO
.isUndef() || !MO
.getReg() ||
582 TargetRegisterInfo::isVirtualRegister(MO
.getReg()))
584 if (MO
.getReg() == ARM::R12
) {
591 // Restore the register from R12
592 AddDefaultPred(BuildMI(MBB
, UseMI
, DL
, TII
.get(ARM::tMOVr
)).
593 addReg(Reg
, RegState::Define
).addReg(ARM::R12
, RegState::Kill
));
599 Thumb1RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II
,
600 int SPAdj
, RegScavenger
*RS
) const {
603 MachineInstr
&MI
= *II
;
604 MachineBasicBlock
&MBB
= *MI
.getParent();
605 MachineFunction
&MF
= *MBB
.getParent();
606 ARMFunctionInfo
*AFI
= MF
.getInfo
<ARMFunctionInfo
>();
607 DebugLoc dl
= MI
.getDebugLoc();
609 while (!MI
.getOperand(i
).isFI()) {
611 assert(i
< MI
.getNumOperands() && "Instr doesn't have FrameIndex operand!");
614 unsigned FrameReg
= ARM::SP
;
615 int FrameIndex
= MI
.getOperand(i
).getIndex();
616 int Offset
= MF
.getFrameInfo()->getObjectOffset(FrameIndex
) +
617 MF
.getFrameInfo()->getStackSize() + SPAdj
;
619 if (AFI
->isGPRCalleeSavedArea1Frame(FrameIndex
))
620 Offset
-= AFI
->getGPRCalleeSavedArea1Offset();
621 else if (AFI
->isGPRCalleeSavedArea2Frame(FrameIndex
))
622 Offset
-= AFI
->getGPRCalleeSavedArea2Offset();
623 else if (MF
.getFrameInfo()->hasVarSizedObjects()) {
624 assert(SPAdj
== 0 && MF
.getTarget().getFrameLowering()->hasFP(MF
) &&
626 // There are alloca()'s in this function, must reference off the frame
627 // pointer or base pointer instead.
628 if (!hasBasePointer(MF
)) {
629 FrameReg
= getFrameRegister(MF
);
630 Offset
-= AFI
->getFramePtrSpillOffset();
635 // Special handling of dbg_value instructions.
636 if (MI
.isDebugValue()) {
637 MI
.getOperand(i
). ChangeToRegister(FrameReg
, false /*isDef*/);
638 MI
.getOperand(i
+1).ChangeToImmediate(Offset
);
642 // Modify MI as necessary to handle as much of 'Offset' as possible
643 assert(AFI
->isThumbFunction() &&
644 "This eliminateFrameIndex only supports Thumb1!");
645 if (rewriteFrameIndex(MI
, i
, FrameReg
, Offset
, TII
))
648 // If we get here, the immediate doesn't fit into the instruction. We folded
649 // as much as possible above, handle the rest, providing a register that is
651 assert(Offset
&& "This code isn't needed if offset already handled!");
653 unsigned Opcode
= MI
.getOpcode();
654 const MCInstrDesc
&Desc
= MI
.getDesc();
656 // Remove predicate first.
657 int PIdx
= MI
.findFirstPredOperandIdx();
659 removeOperands(MI
, PIdx
);
661 if (Desc
.mayLoad()) {
662 // Use the destination register to materialize sp + offset.
663 unsigned TmpReg
= MI
.getOperand(0).getReg();
665 if (Opcode
== ARM::tLDRspi
) {
666 if (FrameReg
== ARM::SP
)
667 emitThumbRegPlusImmInReg(MBB
, II
, dl
, TmpReg
, FrameReg
,
668 Offset
, false, TII
, *this);
670 emitLoadConstPool(MBB
, II
, dl
, TmpReg
, 0, Offset
);
674 emitThumbRegPlusImmediate(MBB
, II
, dl
, TmpReg
, FrameReg
, Offset
, TII
,
678 MI
.setDesc(TII
.get(UseRR
? ARM::tLDRr
: ARM::tLDRi
));
679 MI
.getOperand(i
).ChangeToRegister(TmpReg
, false, false, true);
681 // Use [reg, reg] addrmode. Replace the immediate operand w/ the frame
682 // register. The offset is already handled in the vreg value.
683 MI
.getOperand(i
+1).ChangeToRegister(FrameReg
, false, false, false);
684 } else if (Desc
.mayStore()) {
685 VReg
= MF
.getRegInfo().createVirtualRegister(ARM::tGPRRegisterClass
);
688 if (Opcode
== ARM::tSTRspi
) {
689 if (FrameReg
== ARM::SP
)
690 emitThumbRegPlusImmInReg(MBB
, II
, dl
, VReg
, FrameReg
,
691 Offset
, false, TII
, *this);
693 emitLoadConstPool(MBB
, II
, dl
, VReg
, 0, Offset
);
697 emitThumbRegPlusImmediate(MBB
, II
, dl
, VReg
, FrameReg
, Offset
, TII
,
699 MI
.setDesc(TII
.get(UseRR
? ARM::tSTRr
: ARM::tSTRi
));
700 MI
.getOperand(i
).ChangeToRegister(VReg
, false, false, true);
702 // Use [reg, reg] addrmode. Replace the immediate operand w/ the frame
703 // register. The offset is already handled in the vreg value.
704 MI
.getOperand(i
+1).ChangeToRegister(FrameReg
, false, false, false);
706 assert(false && "Unexpected opcode!");
709 // Add predicate back if it's needed.
710 if (MI
.getDesc().isPredicable()) {
711 MachineInstrBuilder
MIB(&MI
);