Thumb1RegisterInfo.cpp revision 5a54516adf2b15fa337445d327ec3ad9bd1e3648
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::tLDRpci))
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
354/// convertToNonSPOpcode - Change the opcode to the non-SP version, because
355/// we're replacing the frame index with a non-SP register.
356static unsigned convertToNonSPOpcode(unsigned Opcode) {
357  switch (Opcode) {
358  case ARM::tLDRspi:
359  case ARM::tRestore:           // FIXME: Should this opcode be here?
360    return ARM::tLDRi;
361
362  case ARM::tSTRspi:
363  case ARM::tSpill:             // FIXME: Should this opcode be here?
364    return ARM::tSTRi;
365  }
366
367  return Opcode;
368}
369
370bool Thumb1RegisterInfo::
371rewriteFrameIndex(MachineBasicBlock::iterator II, unsigned FrameRegIdx,
372                  unsigned FrameReg, int &Offset,
373                  const ARMBaseInstrInfo &TII) const {
374  MachineInstr &MI = *II;
375  MachineBasicBlock &MBB = *MI.getParent();
376  DebugLoc dl = MI.getDebugLoc();
377  unsigned Opcode = MI.getOpcode();
378  const TargetInstrDesc &Desc = MI.getDesc();
379  unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
380
381  if (Opcode == ARM::tADDrSPi) {
382    Offset += MI.getOperand(FrameRegIdx+1).getImm();
383
384    // Can't use tADDrSPi if it's based off the frame pointer.
385    unsigned NumBits = 0;
386    unsigned Scale = 1;
387    if (FrameReg != ARM::SP) {
388      Opcode = ARM::tADDi3;
389      MI.setDesc(TII.get(Opcode));
390      NumBits = 3;
391    } else {
392      NumBits = 8;
393      Scale = 4;
394      assert((Offset & 3) == 0 &&
395             "Thumb add/sub sp, #imm immediate must be multiple of 4!");
396    }
397
398    unsigned PredReg;
399    if (Offset == 0 && getInstrPredicate(&MI, PredReg) == ARMCC::AL) {
400      // Turn it into a move.
401      MI.setDesc(TII.get(ARM::tMOVgpr2tgpr));
402      MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
403      // Remove offset and remaining explicit predicate operands.
404      do MI.RemoveOperand(FrameRegIdx+1);
405      while (MI.getNumOperands() > FrameRegIdx+1 &&
406             (!MI.getOperand(FrameRegIdx+1).isReg() ||
407              !MI.getOperand(FrameRegIdx+1).isImm()));
408      return true;
409    }
410
411    // Common case: small offset, fits into instruction.
412    unsigned Mask = (1 << NumBits) - 1;
413    if (((Offset / Scale) & ~Mask) == 0) {
414      // Replace the FrameIndex with sp / fp
415      if (Opcode == ARM::tADDi3) {
416        removeOperands(MI, FrameRegIdx);
417        MachineInstrBuilder MIB(&MI);
418        AddDefaultPred(AddDefaultT1CC(MIB).addReg(FrameReg)
419                       .addImm(Offset / Scale));
420      } else {
421        MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
422        MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset / Scale);
423      }
424      return true;
425    }
426
427    unsigned DestReg = MI.getOperand(0).getReg();
428    unsigned Bytes = (Offset > 0) ? Offset : -Offset;
429    unsigned NumMIs = calcNumMI(Opcode, 0, Bytes, NumBits, Scale);
430    // MI would expand into a large number of instructions. Don't try to
431    // simplify the immediate.
432    if (NumMIs > 2) {
433      emitThumbRegPlusImmediate(MBB, II, DestReg, FrameReg, Offset, TII,
434                                *this, dl);
435      MBB.erase(II);
436      return true;
437    }
438
439    if (Offset > 0) {
440      // Translate r0 = add sp, imm to
441      // r0 = add sp, 255*4
442      // r0 = add r0, (imm - 255*4)
443      if (Opcode == ARM::tADDi3) {
444        removeOperands(MI, FrameRegIdx);
445        MachineInstrBuilder MIB(&MI);
446        AddDefaultPred(AddDefaultT1CC(MIB).addReg(FrameReg).addImm(Mask));
447      } else {
448        MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
449        MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Mask);
450      }
451      Offset = (Offset - Mask * Scale);
452      MachineBasicBlock::iterator NII = llvm::next(II);
453      emitThumbRegPlusImmediate(MBB, NII, DestReg, DestReg, Offset, TII,
454                                *this, dl);
455    } else {
456      // Translate r0 = add sp, -imm to
457      // r0 = -imm (this is then translated into a series of instructons)
458      // r0 = add r0, sp
459      emitThumbConstant(MBB, II, DestReg, Offset, TII, *this, dl);
460
461      MI.setDesc(TII.get(ARM::tADDhirr));
462      MI.getOperand(FrameRegIdx).ChangeToRegister(DestReg, false, false, true);
463      MI.getOperand(FrameRegIdx+1).ChangeToRegister(FrameReg, false);
464      if (Opcode == ARM::tADDi3) {
465        MachineInstrBuilder MIB(&MI);
466        AddDefaultPred(MIB);
467      }
468    }
469    return true;
470  } else {
471    if (AddrMode != ARMII::AddrModeT1_s)
472      llvm_unreachable("Unsupported addressing mode!");
473
474    unsigned ImmIdx = FrameRegIdx + 1;
475    int InstrOffs = MI.getOperand(ImmIdx).getImm();
476    unsigned NumBits = (FrameReg == ARM::SP) ? 8 : 5;
477    unsigned Scale = 4;
478
479    Offset += InstrOffs * Scale;
480    assert((Offset & (Scale - 1)) == 0 && "Can't encode this offset!");
481
482    // Common case: small offset, fits into instruction.
483    MachineOperand &ImmOp = MI.getOperand(ImmIdx);
484    int ImmedOffset = Offset / Scale;
485    unsigned Mask = (1 << NumBits) - 1;
486
487    if ((unsigned)Offset <= Mask * Scale) {
488      // Replace the FrameIndex with the frame register (e.g., sp).
489      MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
490      ImmOp.ChangeToImmediate(ImmedOffset);
491
492      // If we're using a register where sp was stored, convert the instruction
493      // to the non-SP version.
494      unsigned NewOpc = convertToNonSPOpcode(Opcode);
495      if (NewOpc != Opcode && FrameReg != ARM::SP)
496        MI.setDesc(TII.get(NewOpc));
497
498      return true;
499    }
500
501    NumBits = 5;
502    Mask = (1 << NumBits) - 1;
503
504    // If this is a thumb spill / restore, we will be using a constpool load to
505    // materialize the offset.
506    if (Opcode == ARM::tRestore || Opcode == ARM::tSpill) {
507      ImmOp.ChangeToImmediate(0);
508    } else {
509      // Otherwise, it didn't fit. Pull in what we can to simplify the immed.
510      ImmedOffset = ImmedOffset & Mask;
511      ImmOp.ChangeToImmediate(ImmedOffset);
512      Offset &= ~(Mask * Scale);
513    }
514  }
515
516  return Offset == 0;
517}
518
519void
520Thumb1RegisterInfo::resolveFrameIndex(MachineBasicBlock::iterator I,
521                                      unsigned BaseReg, int64_t Offset) const {
522  MachineInstr &MI = *I;
523  int Off = Offset; // ARM doesn't need the general 64-bit offsets
524  unsigned i = 0;
525
526  while (!MI.getOperand(i).isFI()) {
527    ++i;
528    assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
529  }
530  bool Done = false;
531  Done = rewriteFrameIndex(MI, i, BaseReg, Off, TII);
532  assert (Done && "Unable to resolve frame index!");
533}
534
535/// saveScavengerRegister - Spill the register so it can be used by the
536/// register scavenger. Return true.
537bool
538Thumb1RegisterInfo::saveScavengerRegister(MachineBasicBlock &MBB,
539                                          MachineBasicBlock::iterator I,
540                                          MachineBasicBlock::iterator &UseMI,
541                                          const TargetRegisterClass *RC,
542                                          unsigned Reg) const {
543  // Thumb1 can't use the emergency spill slot on the stack because
544  // ldr/str immediate offsets must be positive, and if we're referencing
545  // off the frame pointer (if, for example, there are alloca() calls in
546  // the function, the offset will be negative. Use R12 instead since that's
547  // a call clobbered register that we know won't be used in Thumb1 mode.
548  DebugLoc DL;
549  BuildMI(MBB, I, DL, TII.get(ARM::tMOVtgpr2gpr)).
550    addReg(ARM::R12, RegState::Define).addReg(Reg, RegState::Kill);
551
552  // The UseMI is where we would like to restore the register. If there's
553  // interference with R12 before then, however, we'll need to restore it
554  // before that instead and adjust the UseMI.
555  bool done = false;
556  for (MachineBasicBlock::iterator II = I; !done && II != UseMI ; ++II) {
557    if (II->isDebugValue())
558      continue;
559    // If this instruction affects R12, adjust our restore point.
560    for (unsigned i = 0, e = II->getNumOperands(); i != e; ++i) {
561      const MachineOperand &MO = II->getOperand(i);
562      if (!MO.isReg() || MO.isUndef() || !MO.getReg() ||
563          TargetRegisterInfo::isVirtualRegister(MO.getReg()))
564        continue;
565      if (MO.getReg() == ARM::R12) {
566        UseMI = II;
567        done = true;
568        break;
569      }
570    }
571  }
572  // Restore the register from R12
573  BuildMI(MBB, UseMI, DL, TII.get(ARM::tMOVgpr2tgpr)).
574    addReg(Reg, RegState::Define).addReg(ARM::R12, RegState::Kill);
575
576  return true;
577}
578
579void
580Thumb1RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
581                                        int SPAdj, RegScavenger *RS) const {
582  unsigned VReg = 0;
583  unsigned i = 0;
584  MachineInstr &MI = *II;
585  MachineBasicBlock &MBB = *MI.getParent();
586  MachineFunction &MF = *MBB.getParent();
587  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
588  DebugLoc dl = MI.getDebugLoc();
589
590  while (!MI.getOperand(i).isFI()) {
591    ++i;
592    assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
593  }
594
595  unsigned FrameReg = ARM::SP;
596  int FrameIndex = MI.getOperand(i).getIndex();
597  int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) +
598               MF.getFrameInfo()->getStackSize() + SPAdj;
599
600  if (AFI->isGPRCalleeSavedArea1Frame(FrameIndex))
601    Offset -= AFI->getGPRCalleeSavedArea1Offset();
602  else if (AFI->isGPRCalleeSavedArea2Frame(FrameIndex))
603    Offset -= AFI->getGPRCalleeSavedArea2Offset();
604  else if (MF.getFrameInfo()->hasVarSizedObjects()) {
605    assert(SPAdj == 0 && MF.getTarget().getFrameInfo()->hasFP(MF) &&
606           "Unexpected");
607    // There are alloca()'s in this function, must reference off the frame
608    // pointer or base pointer instead.
609    if (!hasBasePointer(MF)) {
610      FrameReg = getFrameRegister(MF);
611      Offset -= AFI->getFramePtrSpillOffset();
612    } else
613      FrameReg = BasePtr;
614  }
615
616  // Special handling of dbg_value instructions.
617  if (MI.isDebugValue()) {
618    MI.getOperand(i).  ChangeToRegister(FrameReg, false /*isDef*/);
619    MI.getOperand(i+1).ChangeToImmediate(Offset);
620    return;
621  }
622
623  // Modify MI as necessary to handle as much of 'Offset' as possible
624  assert(AFI->isThumbFunction() &&
625         "This eliminateFrameIndex only supports Thumb1!");
626  if (rewriteFrameIndex(MI, i, FrameReg, Offset, TII))
627    return;
628
629  // If we get here, the immediate doesn't fit into the instruction.  We folded
630  // as much as possible above, handle the rest, providing a register that is
631  // SP+LargeImm.
632  assert(Offset && "This code isn't needed if offset already handled!");
633
634  unsigned Opcode = MI.getOpcode();
635  const TargetInstrDesc &Desc = MI.getDesc();
636
637  // Remove predicate first.
638  int PIdx = MI.findFirstPredOperandIdx();
639  if (PIdx != -1)
640    removeOperands(MI, PIdx);
641
642  if (Desc.mayLoad()) {
643    // Use the destination register to materialize sp + offset.
644    unsigned TmpReg = MI.getOperand(0).getReg();
645    bool UseRR = false;
646    if (Opcode == ARM::tRestore) {
647      if (FrameReg == ARM::SP)
648        emitThumbRegPlusImmInReg(MBB, II, TmpReg, FrameReg,
649                                 Offset, false, TII, *this, dl);
650      else {
651        emitLoadConstPool(MBB, II, dl, TmpReg, 0, Offset);
652        UseRR = true;
653      }
654    } else {
655      emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg, Offset, TII,
656                                *this, dl);
657    }
658
659    MI.setDesc(TII.get(ARM::tLDRr));
660    MI.getOperand(i).ChangeToRegister(TmpReg, false, false, true);
661    if (UseRR)
662      // Use [reg, reg] addrmode.
663      MI.addOperand(MachineOperand::CreateReg(FrameReg, false));
664  } else if (Desc.mayStore()) {
665      VReg = MF.getRegInfo().createVirtualRegister(ARM::tGPRRegisterClass);
666      bool UseRR = false;
667
668      if (Opcode == ARM::tSpill) {
669        if (FrameReg == ARM::SP)
670          emitThumbRegPlusImmInReg(MBB, II, VReg, FrameReg,
671                                   Offset, false, TII, *this, dl);
672        else {
673          emitLoadConstPool(MBB, II, dl, VReg, 0, Offset);
674          UseRR = true;
675        }
676      } else
677        emitThumbRegPlusImmediate(MBB, II, VReg, FrameReg, Offset, TII,
678                                  *this, dl);
679      MI.setDesc(TII.get(ARM::tSTRr));
680      MI.getOperand(i).ChangeToRegister(VReg, false, false, true);
681      if (UseRR)  // Use [reg, reg] addrmode.
682        MI.addOperand(MachineOperand::CreateReg(FrameReg, false));
683  } else {
684    assert(false && "Unexpected opcode!");
685  }
686
687  // Add predicate back if it's needed.
688  if (MI.getDesc().isPredicable()) {
689    MachineInstrBuilder MIB(&MI);
690    AddDefaultPred(MIB);
691  }
692}
693