Thumb1RegisterInfo.cpp revision d0c38176690e9602a93a20a43f1bd084564a8116
1//===- Thumb1RegisterInfo.cpp - Thumb-1 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//===----------------------------------------------------------------------===//
9//
10// This file contains the Thumb-1 implementation of the TargetRegisterInfo
11// class.
12//
13//===----------------------------------------------------------------------===//
14
15#include "ARM.h"
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/TargetFrameInfo.h"
33#include "llvm/Target/TargetMachine.h"
34#include "llvm/ADT/BitVector.h"
35#include "llvm/ADT/SmallVector.h"
36#include "llvm/Support/CommandLine.h"
37#include "llvm/Support/ErrorHandling.h"
38#include "llvm/Support/raw_ostream.h"
39
40namespace llvm {
41extern cl::opt<bool> ReuseFrameIndexVals;
42}
43
44using namespace llvm;
45
46Thumb1RegisterInfo::Thumb1RegisterInfo(const ARMBaseInstrInfo &tii,
47                                       const ARMSubtarget &sti)
48  : ARMBaseRegisterInfo(tii, sti) {
49}
50
51/// emitLoadConstPool - Emits a load from constpool to materialize the
52/// specified immediate.
53void Thumb1RegisterInfo::emitLoadConstPool(MachineBasicBlock &MBB,
54                                           MachineBasicBlock::iterator &MBBI,
55                                           DebugLoc dl,
56                                           unsigned DestReg, unsigned SubIdx,
57                                           int Val,
58                                           ARMCC::CondCodes Pred,
59                                           unsigned PredReg) const {
60  MachineFunction &MF = *MBB.getParent();
61  MachineConstantPool *ConstantPool = MF.getConstantPool();
62  const Constant *C = ConstantInt::get(
63          Type::getInt32Ty(MBB.getParent()->getFunction()->getContext()), Val);
64  unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4);
65
66  BuildMI(MBB, MBBI, dl, TII.get(ARM::tLDRcp))
67          .addReg(DestReg, getDefRegState(true), SubIdx)
68          .addConstantPoolIndex(Idx).addImm(Pred).addReg(PredReg);
69}
70
71
72/// emitThumbRegPlusImmInReg - Emits a series of instructions to materialize
73/// a destreg = basereg + immediate in Thumb code. Materialize the immediate
74/// in a register using mov / mvn sequences or load the immediate from a
75/// constpool entry.
76static
77void emitThumbRegPlusImmInReg(MachineBasicBlock &MBB,
78                              MachineBasicBlock::iterator &MBBI,
79                              unsigned DestReg, unsigned BaseReg,
80                              int NumBytes, bool CanChangeCC,
81                              const TargetInstrInfo &TII,
82                              const ARMBaseRegisterInfo& MRI,
83                              DebugLoc dl) {
84    MachineFunction &MF = *MBB.getParent();
85    bool isHigh = !isARMLowRegister(DestReg) ||
86                  (BaseReg != 0 && !isARMLowRegister(BaseReg));
87    bool isSub = false;
88    // Subtract doesn't have high register version. Load the negative value
89    // if either base or dest register is a high register. Also, if do not
90    // issue sub as part of the sequence if condition register is to be
91    // preserved.
92    if (NumBytes < 0 && !isHigh && CanChangeCC) {
93      isSub = true;
94      NumBytes = -NumBytes;
95    }
96    unsigned LdReg = DestReg;
97    if (DestReg == ARM::SP) {
98      assert(BaseReg == ARM::SP && "Unexpected!");
99      LdReg = MF.getRegInfo().createVirtualRegister(ARM::tGPRRegisterClass);
100    }
101
102    if (NumBytes <= 255 && NumBytes >= 0)
103      AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg))
104        .addImm(NumBytes);
105    else if (NumBytes < 0 && NumBytes >= -255) {
106      AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg))
107        .addImm(NumBytes);
108      AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tRSB), LdReg))
109        .addReg(LdReg, RegState::Kill);
110    } else
111      MRI.emitLoadConstPool(MBB, MBBI, dl, LdReg, 0, NumBytes);
112
113    // Emit add / sub.
114    int Opc = (isSub) ? ARM::tSUBrr : (isHigh ? ARM::tADDhirr : ARM::tADDrr);
115    MachineInstrBuilder MIB =
116      BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg);
117    if (Opc != ARM::tADDhirr)
118      MIB = AddDefaultT1CC(MIB);
119    if (DestReg == ARM::SP || isSub)
120      MIB.addReg(BaseReg).addReg(LdReg, RegState::Kill);
121    else
122      MIB.addReg(LdReg).addReg(BaseReg, RegState::Kill);
123    AddDefaultPred(MIB);
124}
125
126/// calcNumMI - Returns the number of instructions required to materialize
127/// the specific add / sub r, c instruction.
128static unsigned calcNumMI(int Opc, int ExtraOpc, unsigned Bytes,
129                          unsigned NumBits, unsigned Scale) {
130  unsigned NumMIs = 0;
131  unsigned Chunk = ((1 << NumBits) - 1) * Scale;
132
133  if (Opc == ARM::tADDrSPi) {
134    unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes;
135    Bytes -= ThisVal;
136    NumMIs++;
137    NumBits = 8;
138    Scale = 1;  // Followed by a number of tADDi8.
139    Chunk = ((1 << NumBits) - 1) * Scale;
140  }
141
142  NumMIs += Bytes / Chunk;
143  if ((Bytes % Chunk) != 0)
144    NumMIs++;
145  if (ExtraOpc)
146    NumMIs++;
147  return NumMIs;
148}
149
150/// emitThumbRegPlusImmediate - Emits a series of instructions to materialize
151/// a destreg = basereg + immediate in Thumb code.
152void llvm::emitThumbRegPlusImmediate(MachineBasicBlock &MBB,
153                                     MachineBasicBlock::iterator &MBBI,
154                                     unsigned DestReg, unsigned BaseReg,
155                                     int NumBytes, const TargetInstrInfo &TII,
156                                     const ARMBaseRegisterInfo& MRI,
157                                     DebugLoc dl) {
158  bool isSub = NumBytes < 0;
159  unsigned Bytes = (unsigned)NumBytes;
160  if (isSub) Bytes = -NumBytes;
161  bool isMul4 = (Bytes & 3) == 0;
162  bool isTwoAddr = false;
163  bool DstNotEqBase = false;
164  unsigned NumBits = 1;
165  unsigned Scale = 1;
166  int Opc = 0;
167  int ExtraOpc = 0;
168  bool NeedCC = false;
169  bool NeedPred = false;
170
171  if (DestReg == BaseReg && BaseReg == ARM::SP) {
172    assert(isMul4 && "Thumb sp inc / dec size must be multiple of 4!");
173    NumBits = 7;
174    Scale = 4;
175    Opc = isSub ? ARM::tSUBspi : ARM::tADDspi;
176    isTwoAddr = true;
177  } else if (!isSub && BaseReg == ARM::SP) {
178    // r1 = add sp, 403
179    // =>
180    // r1 = add sp, 100 * 4
181    // r1 = add r1, 3
182    if (!isMul4) {
183      Bytes &= ~3;
184      ExtraOpc = ARM::tADDi3;
185    }
186    NumBits = 8;
187    Scale = 4;
188    Opc = ARM::tADDrSPi;
189  } else {
190    // sp = sub sp, c
191    // r1 = sub sp, c
192    // r8 = sub sp, c
193    if (DestReg != BaseReg)
194      DstNotEqBase = true;
195    NumBits = 8;
196    if (DestReg == ARM::SP) {
197      Opc = isSub ? ARM::tSUBspi : ARM::tADDspi;
198      assert(isMul4 && "Thumb sp inc / dec size must be multiple of 4!");
199      NumBits = 7;
200      Scale = 4;
201    } else {
202      Opc = isSub ? ARM::tSUBi8 : ARM::tADDi8;
203      NumBits = 8;
204      NeedPred = NeedCC = true;
205    }
206    isTwoAddr = true;
207  }
208
209  unsigned NumMIs = calcNumMI(Opc, ExtraOpc, Bytes, NumBits, Scale);
210  unsigned Threshold = (DestReg == ARM::SP) ? 3 : 2;
211  if (NumMIs > Threshold) {
212    // This will expand into too many instructions. Load the immediate from a
213    // constpool entry.
214    emitThumbRegPlusImmInReg(MBB, MBBI, DestReg, BaseReg, NumBytes, true, TII,
215                             MRI, dl);
216    return;
217  }
218
219  if (DstNotEqBase) {
220    if (isARMLowRegister(DestReg) && isARMLowRegister(BaseReg)) {
221      // If both are low registers, emit DestReg = add BaseReg, max(Imm, 7)
222      unsigned Chunk = (1 << 3) - 1;
223      unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes;
224      Bytes -= ThisVal;
225      const TargetInstrDesc &TID = TII.get(isSub ? ARM::tSUBi3 : ARM::tADDi3);
226      const MachineInstrBuilder MIB =
227        AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TID, DestReg));
228      AddDefaultPred(MIB.addReg(BaseReg, RegState::Kill).addImm(ThisVal));
229    } else {
230      BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), DestReg)
231        .addReg(BaseReg, RegState::Kill);
232    }
233    BaseReg = DestReg;
234  }
235
236  unsigned Chunk = ((1 << NumBits) - 1) * Scale;
237  while (Bytes) {
238    unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes;
239    Bytes -= ThisVal;
240    ThisVal /= Scale;
241    // Build the new tADD / tSUB.
242    if (isTwoAddr) {
243      MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg);
244      if (NeedCC)
245        MIB = AddDefaultT1CC(MIB);
246      MIB .addReg(DestReg).addImm(ThisVal);
247      if (NeedPred)
248        MIB = AddDefaultPred(MIB);
249    }
250    else {
251      bool isKill = BaseReg != ARM::SP;
252      MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg);
253      if (NeedCC)
254        MIB = AddDefaultT1CC(MIB);
255      MIB.addReg(BaseReg, getKillRegState(isKill)).addImm(ThisVal);
256      if (NeedPred)
257        MIB = AddDefaultPred(MIB);
258      BaseReg = DestReg;
259
260      if (Opc == ARM::tADDrSPi) {
261        // r4 = add sp, imm
262        // r4 = add r4, imm
263        // ...
264        NumBits = 8;
265        Scale = 1;
266        Chunk = ((1 << NumBits) - 1) * Scale;
267        Opc = isSub ? ARM::tSUBi8 : ARM::tADDi8;
268        NeedPred = NeedCC = isTwoAddr = true;
269      }
270    }
271  }
272
273  if (ExtraOpc) {
274    const TargetInstrDesc &TID = TII.get(ExtraOpc);
275    AddDefaultPred(AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TID, DestReg))
276                   .addReg(DestReg, RegState::Kill)
277                   .addImm(((unsigned)NumBytes) & 3));
278  }
279}
280
281static void emitSPUpdate(MachineBasicBlock &MBB,
282                         MachineBasicBlock::iterator &MBBI,
283                         const TargetInstrInfo &TII, DebugLoc dl,
284                         const Thumb1RegisterInfo &MRI,
285                         int NumBytes) {
286  emitThumbRegPlusImmediate(MBB, MBBI, ARM::SP, ARM::SP, NumBytes, TII,
287                            MRI, dl);
288}
289
290void Thumb1RegisterInfo::
291eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
292                              MachineBasicBlock::iterator I) const {
293  const TargetFrameInfo *TFI = MF.getTarget().getFrameInfo();
294
295  if (!TFI->hasReservedCallFrame(MF)) {
296    // If we have alloca, convert as follows:
297    // ADJCALLSTACKDOWN -> sub, sp, sp, amount
298    // ADJCALLSTACKUP   -> add, sp, sp, amount
299    MachineInstr *Old = I;
300    DebugLoc dl = Old->getDebugLoc();
301    unsigned Amount = Old->getOperand(0).getImm();
302    if (Amount != 0) {
303      // We need to keep the stack aligned properly.  To do this, we round the
304      // amount of space needed for the outgoing arguments up to the next
305      // alignment boundary.
306      unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment();
307      Amount = (Amount+Align-1)/Align*Align;
308
309      // Replace the pseudo instruction with a new instruction...
310      unsigned Opc = Old->getOpcode();
311      if (Opc == ARM::ADJCALLSTACKDOWN || Opc == ARM::tADJCALLSTACKDOWN) {
312        emitSPUpdate(MBB, I, TII, dl, *this, -Amount);
313      } else {
314        assert(Opc == ARM::ADJCALLSTACKUP || Opc == ARM::tADJCALLSTACKUP);
315        emitSPUpdate(MBB, I, TII, dl, *this, Amount);
316      }
317    }
318  }
319  MBB.erase(I);
320}
321
322/// emitThumbConstant - Emit a series of instructions to materialize a
323/// constant.
324static void emitThumbConstant(MachineBasicBlock &MBB,
325                              MachineBasicBlock::iterator &MBBI,
326                              unsigned DestReg, int Imm,
327                              const TargetInstrInfo &TII,
328                              const Thumb1RegisterInfo& MRI,
329                              DebugLoc dl) {
330  bool isSub = Imm < 0;
331  if (isSub) Imm = -Imm;
332
333  int Chunk = (1 << 8) - 1;
334  int ThisVal = (Imm > Chunk) ? Chunk : Imm;
335  Imm -= ThisVal;
336  AddDefaultPred(AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8),
337                                        DestReg))
338                 .addImm(ThisVal));
339  if (Imm > 0)
340    emitThumbRegPlusImmediate(MBB, MBBI, DestReg, DestReg, Imm, TII, MRI, dl);
341  if (isSub) {
342    const TargetInstrDesc &TID = TII.get(ARM::tRSB);
343    AddDefaultPred(AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TID, DestReg))
344                   .addReg(DestReg, RegState::Kill));
345  }
346}
347
348static void removeOperands(MachineInstr &MI, unsigned i) {
349  unsigned Op = i;
350  for (unsigned e = MI.getNumOperands(); i != e; ++i)
351    MI.RemoveOperand(Op);
352}
353
354bool Thumb1RegisterInfo::
355rewriteFrameIndex(MachineBasicBlock::iterator II, unsigned FrameRegIdx,
356                  unsigned FrameReg, int &Offset,
357                  const ARMBaseInstrInfo &TII) const {
358  MachineInstr &MI = *II;
359  MachineBasicBlock &MBB = *MI.getParent();
360  DebugLoc dl = MI.getDebugLoc();
361  unsigned Opcode = MI.getOpcode();
362  const TargetInstrDesc &Desc = MI.getDesc();
363  unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
364
365  if (Opcode == ARM::tADDrSPi) {
366    Offset += MI.getOperand(FrameRegIdx+1).getImm();
367
368    // Can't use tADDrSPi if it's based off the frame pointer.
369    unsigned NumBits = 0;
370    unsigned Scale = 1;
371    if (FrameReg != ARM::SP) {
372      Opcode = ARM::tADDi3;
373      MI.setDesc(TII.get(Opcode));
374      NumBits = 3;
375    } else {
376      NumBits = 8;
377      Scale = 4;
378      assert((Offset & 3) == 0 &&
379             "Thumb add/sub sp, #imm immediate must be multiple of 4!");
380    }
381
382    unsigned PredReg;
383    if (Offset == 0 && getInstrPredicate(&MI, PredReg) == ARMCC::AL) {
384      // Turn it into a move.
385      MI.setDesc(TII.get(ARM::tMOVgpr2tgpr));
386      MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
387      // Remove offset and remaining explicit predicate operands.
388      do MI.RemoveOperand(FrameRegIdx+1);
389      while (MI.getNumOperands() > FrameRegIdx+1 &&
390             (!MI.getOperand(FrameRegIdx+1).isReg() ||
391              !MI.getOperand(FrameRegIdx+1).isImm()));
392      return true;
393    }
394
395    // Common case: small offset, fits into instruction.
396    unsigned Mask = (1 << NumBits) - 1;
397    if (((Offset / Scale) & ~Mask) == 0) {
398      // Replace the FrameIndex with sp / fp
399      if (Opcode == ARM::tADDi3) {
400        removeOperands(MI, FrameRegIdx);
401        MachineInstrBuilder MIB(&MI);
402        AddDefaultPred(AddDefaultT1CC(MIB).addReg(FrameReg)
403                       .addImm(Offset / Scale));
404      } else {
405        MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
406        MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset / Scale);
407      }
408      return true;
409    }
410
411    unsigned DestReg = MI.getOperand(0).getReg();
412    unsigned Bytes = (Offset > 0) ? Offset : -Offset;
413    unsigned NumMIs = calcNumMI(Opcode, 0, Bytes, NumBits, Scale);
414    // MI would expand into a large number of instructions. Don't try to
415    // simplify the immediate.
416    if (NumMIs > 2) {
417      emitThumbRegPlusImmediate(MBB, II, DestReg, FrameReg, Offset, TII,
418                                *this, dl);
419      MBB.erase(II);
420      return true;
421    }
422
423    if (Offset > 0) {
424      // Translate r0 = add sp, imm to
425      // r0 = add sp, 255*4
426      // r0 = add r0, (imm - 255*4)
427      if (Opcode == ARM::tADDi3) {
428        removeOperands(MI, FrameRegIdx);
429        MachineInstrBuilder MIB(&MI);
430        AddDefaultPred(AddDefaultT1CC(MIB).addReg(FrameReg).addImm(Mask));
431      } else {
432        MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
433        MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Mask);
434      }
435      Offset = (Offset - Mask * Scale);
436      MachineBasicBlock::iterator NII = llvm::next(II);
437      emitThumbRegPlusImmediate(MBB, NII, DestReg, DestReg, Offset, TII,
438                                *this, dl);
439    } else {
440      // Translate r0 = add sp, -imm to
441      // r0 = -imm (this is then translated into a series of instructons)
442      // r0 = add r0, sp
443      emitThumbConstant(MBB, II, DestReg, Offset, TII, *this, dl);
444
445      MI.setDesc(TII.get(ARM::tADDhirr));
446      MI.getOperand(FrameRegIdx).ChangeToRegister(DestReg, false, false, true);
447      MI.getOperand(FrameRegIdx+1).ChangeToRegister(FrameReg, false);
448      if (Opcode == ARM::tADDi3) {
449        MachineInstrBuilder MIB(&MI);
450        AddDefaultPred(MIB);
451      }
452    }
453    return true;
454  } else {
455    unsigned ImmIdx = 0;
456    int InstrOffs = 0;
457    unsigned NumBits = 0;
458    unsigned Scale = 1;
459    switch (AddrMode) {
460    case ARMII::AddrModeT1_s: {
461      ImmIdx = FrameRegIdx+1;
462      InstrOffs = MI.getOperand(ImmIdx).getImm();
463      NumBits = (FrameReg == ARM::SP) ? 8 : 5;
464      Scale = 4;
465      break;
466    }
467    default:
468      llvm_unreachable("Unsupported addressing mode!");
469      break;
470    }
471
472    Offset += InstrOffs * Scale;
473    assert((Offset & (Scale-1)) == 0 && "Can't encode this offset!");
474
475    // Common case: small offset, fits into instruction.
476    MachineOperand &ImmOp = MI.getOperand(ImmIdx);
477    int ImmedOffset = Offset / Scale;
478    unsigned Mask = (1 << NumBits) - 1;
479    if ((unsigned)Offset <= Mask * Scale) {
480      // Replace the FrameIndex with sp
481      MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
482      ImmOp.ChangeToImmediate(ImmedOffset);
483      return true;
484    }
485
486    bool isThumSpillRestore = Opcode == ARM::tRestore || Opcode == ARM::tSpill;
487    if (AddrMode == ARMII::AddrModeT1_s) {
488      // Thumb tLDRspi, tSTRspi. These will change to instructions that use
489      // a different base register.
490      NumBits = 5;
491      Mask = (1 << NumBits) - 1;
492    }
493    // If this is a thumb spill / restore, we will be using a constpool load to
494    // materialize the offset.
495    if (AddrMode == ARMII::AddrModeT1_s && isThumSpillRestore)
496      ImmOp.ChangeToImmediate(0);
497    else {
498      // Otherwise, it didn't fit. Pull in what we can to simplify the immed.
499      ImmedOffset = ImmedOffset & Mask;
500      ImmOp.ChangeToImmediate(ImmedOffset);
501      Offset &= ~(Mask*Scale);
502    }
503  }
504  return Offset == 0;
505}
506
507void
508Thumb1RegisterInfo::resolveFrameIndex(MachineBasicBlock::iterator I,
509                                      unsigned BaseReg, int64_t Offset) const {
510  MachineInstr &MI = *I;
511  int Off = Offset; // ARM doesn't need the general 64-bit offsets
512  unsigned i = 0;
513
514  while (!MI.getOperand(i).isFI()) {
515    ++i;
516    assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
517  }
518  bool Done = false;
519  Done = rewriteFrameIndex(MI, i, BaseReg, Off, TII);
520  assert (Done && "Unable to resolve frame index!");
521}
522
523/// saveScavengerRegister - Spill the register so it can be used by the
524/// register scavenger. Return true.
525bool
526Thumb1RegisterInfo::saveScavengerRegister(MachineBasicBlock &MBB,
527                                          MachineBasicBlock::iterator I,
528                                          MachineBasicBlock::iterator &UseMI,
529                                          const TargetRegisterClass *RC,
530                                          unsigned Reg) const {
531  // Thumb1 can't use the emergency spill slot on the stack because
532  // ldr/str immediate offsets must be positive, and if we're referencing
533  // off the frame pointer (if, for example, there are alloca() calls in
534  // the function, the offset will be negative. Use R12 instead since that's
535  // a call clobbered register that we know won't be used in Thumb1 mode.
536  DebugLoc DL;
537  BuildMI(MBB, I, DL, TII.get(ARM::tMOVtgpr2gpr)).
538    addReg(ARM::R12, RegState::Define).addReg(Reg, RegState::Kill);
539
540  // The UseMI is where we would like to restore the register. If there's
541  // interference with R12 before then, however, we'll need to restore it
542  // before that instead and adjust the UseMI.
543  bool done = false;
544  for (MachineBasicBlock::iterator II = I; !done && II != UseMI ; ++II) {
545    if (II->isDebugValue())
546      continue;
547    // If this instruction affects R12, adjust our restore point.
548    for (unsigned i = 0, e = II->getNumOperands(); i != e; ++i) {
549      const MachineOperand &MO = II->getOperand(i);
550      if (!MO.isReg() || MO.isUndef() || !MO.getReg() ||
551          TargetRegisterInfo::isVirtualRegister(MO.getReg()))
552        continue;
553      if (MO.getReg() == ARM::R12) {
554        UseMI = II;
555        done = true;
556        break;
557      }
558    }
559  }
560  // Restore the register from R12
561  BuildMI(MBB, UseMI, DL, TII.get(ARM::tMOVgpr2tgpr)).
562    addReg(Reg, RegState::Define).addReg(ARM::R12, RegState::Kill);
563
564  return true;
565}
566
567void
568Thumb1RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
569                                        int SPAdj, RegScavenger *RS) const {
570  unsigned VReg = 0;
571  unsigned i = 0;
572  MachineInstr &MI = *II;
573  MachineBasicBlock &MBB = *MI.getParent();
574  MachineFunction &MF = *MBB.getParent();
575  const TargetFrameInfo *TFI = MF.getTarget().getFrameInfo();
576  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
577  DebugLoc dl = MI.getDebugLoc();
578
579  while (!MI.getOperand(i).isFI()) {
580    ++i;
581    assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
582  }
583
584  unsigned FrameReg = ARM::SP;
585  int FrameIndex = MI.getOperand(i).getIndex();
586  int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) +
587               MF.getFrameInfo()->getStackSize() + SPAdj;
588
589  if (AFI->isGPRCalleeSavedArea1Frame(FrameIndex))
590    Offset -= AFI->getGPRCalleeSavedArea1Offset();
591  else if (AFI->isGPRCalleeSavedArea2Frame(FrameIndex))
592    Offset -= AFI->getGPRCalleeSavedArea2Offset();
593  else if (MF.getFrameInfo()->hasVarSizedObjects()) {
594    assert(SPAdj == 0 && TFI->hasFP(MF) && "Unexpected");
595    // There are alloca()'s in this function, must reference off the frame
596    // pointer or base pointer instead.
597    if (!hasBasePointer(MF)) {
598      FrameReg = getFrameRegister(MF);
599      Offset -= AFI->getFramePtrSpillOffset();
600    } else
601      FrameReg = BasePtr;
602  }
603
604  // Special handling of dbg_value instructions.
605  if (MI.isDebugValue()) {
606    MI.getOperand(i).  ChangeToRegister(FrameReg, false /*isDef*/);
607    MI.getOperand(i+1).ChangeToImmediate(Offset);
608    return;
609  }
610
611  // Modify MI as necessary to handle as much of 'Offset' as possible
612  assert(AFI->isThumbFunction() &&
613         "This eliminateFrameIndex only supports Thumb1!");
614  if (rewriteFrameIndex(MI, i, FrameReg, Offset, TII))
615    return;
616
617  // If we get here, the immediate doesn't fit into the instruction.  We folded
618  // as much as possible above, handle the rest, providing a register that is
619  // SP+LargeImm.
620  assert(Offset && "This code isn't needed if offset already handled!");
621
622  unsigned Opcode = MI.getOpcode();
623  const TargetInstrDesc &Desc = MI.getDesc();
624
625  // Remove predicate first.
626  int PIdx = MI.findFirstPredOperandIdx();
627  if (PIdx != -1)
628    removeOperands(MI, PIdx);
629
630  if (Desc.mayLoad()) {
631    // Use the destination register to materialize sp + offset.
632    unsigned TmpReg = MI.getOperand(0).getReg();
633    bool UseRR = false;
634    if (Opcode == ARM::tRestore) {
635      if (FrameReg == ARM::SP)
636        emitThumbRegPlusImmInReg(MBB, II, TmpReg, FrameReg,
637                                 Offset, false, TII, *this, dl);
638      else {
639        emitLoadConstPool(MBB, II, dl, TmpReg, 0, Offset);
640        UseRR = true;
641      }
642    } else {
643      emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg, Offset, TII,
644                                *this, dl);
645    }
646
647    MI.setDesc(TII.get(ARM::tLDR));
648    MI.getOperand(i).ChangeToRegister(TmpReg, false, false, true);
649    if (UseRR)
650      // Use [reg, reg] addrmode.
651      MI.addOperand(MachineOperand::CreateReg(FrameReg, false));
652    else  // tLDR has an extra register operand.
653      MI.addOperand(MachineOperand::CreateReg(0, false));
654  } else if (Desc.mayStore()) {
655      VReg = MF.getRegInfo().createVirtualRegister(ARM::tGPRRegisterClass);
656      bool UseRR = false;
657
658      if (Opcode == ARM::tSpill) {
659        if (FrameReg == ARM::SP)
660          emitThumbRegPlusImmInReg(MBB, II, VReg, FrameReg,
661                                   Offset, false, TII, *this, dl);
662        else {
663          emitLoadConstPool(MBB, II, dl, VReg, 0, Offset);
664          UseRR = true;
665        }
666      } else
667        emitThumbRegPlusImmediate(MBB, II, VReg, FrameReg, Offset, TII,
668                                  *this, dl);
669      MI.setDesc(TII.get(ARM::tSTR));
670      MI.getOperand(i).ChangeToRegister(VReg, false, false, true);
671      if (UseRR)  // Use [reg, reg] addrmode.
672        MI.addOperand(MachineOperand::CreateReg(FrameReg, false));
673      else // tSTR has an extra register operand.
674        MI.addOperand(MachineOperand::CreateReg(0, false));
675  } else
676    assert(false && "Unexpected opcode!");
677
678  // Add predicate back if it's needed.
679  if (MI.getDesc().isPredicable()) {
680    MachineInstrBuilder MIB(&MI);
681    AddDefaultPred(MIB);
682  }
683}
684