LLVM API Documentation

Thumb1RegisterInfo.cpp
Go to the documentation of this file.
00001 //===-- Thumb1RegisterInfo.cpp - Thumb-1 Register Information -------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file contains the Thumb-1 implementation of the TargetRegisterInfo
00011 // class.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 
00015 #include "Thumb1RegisterInfo.h"
00016 #include "ARM.h"
00017 #include "ARMBaseInstrInfo.h"
00018 #include "ARMMachineFunctionInfo.h"
00019 #include "ARMSubtarget.h"
00020 #include "MCTargetDesc/ARMAddressingModes.h"
00021 #include "llvm/CodeGen/MachineConstantPool.h"
00022 #include "llvm/CodeGen/MachineFrameInfo.h"
00023 #include "llvm/CodeGen/MachineFunction.h"
00024 #include "llvm/CodeGen/MachineInstrBuilder.h"
00025 #include "llvm/CodeGen/MachineRegisterInfo.h"
00026 #include "llvm/CodeGen/RegisterScavenging.h"
00027 #include "llvm/IR/Constants.h"
00028 #include "llvm/IR/DerivedTypes.h"
00029 #include "llvm/IR/Function.h"
00030 #include "llvm/IR/LLVMContext.h"
00031 #include "llvm/Support/CommandLine.h"
00032 #include "llvm/Support/ErrorHandling.h"
00033 #include "llvm/Support/raw_ostream.h"
00034 #include "llvm/Target/TargetFrameLowering.h"
00035 #include "llvm/Target/TargetMachine.h"
00036 
00037 namespace llvm {
00038 extern cl::opt<bool> ReuseFrameIndexVals;
00039 }
00040 
00041 using namespace llvm;
00042 
00043 Thumb1RegisterInfo::Thumb1RegisterInfo(const ARMBaseInstrInfo &tii,
00044                                        const ARMSubtarget &sti)
00045   : ARMBaseRegisterInfo(tii, sti) {
00046 }
00047 
00048 const TargetRegisterClass*
00049 Thumb1RegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC)
00050                                                                          const {
00051   if (ARM::tGPRRegClass.hasSubClassEq(RC))
00052     return &ARM::tGPRRegClass;
00053   return ARMBaseRegisterInfo::getLargestLegalSuperClass(RC);
00054 }
00055 
00056 const TargetRegisterClass *
00057 Thumb1RegisterInfo::getPointerRegClass(const MachineFunction &MF, unsigned Kind)
00058                                                                          const {
00059   return &ARM::tGPRRegClass;
00060 }
00061 
00062 /// emitLoadConstPool - Emits a load from constpool to materialize the
00063 /// specified immediate.
00064 void
00065 Thumb1RegisterInfo::emitLoadConstPool(MachineBasicBlock &MBB,
00066                                       MachineBasicBlock::iterator &MBBI,
00067                                       DebugLoc dl,
00068                                       unsigned DestReg, unsigned SubIdx,
00069                                       int Val,
00070                                       ARMCC::CondCodes Pred, unsigned PredReg,
00071                                       unsigned MIFlags) const {
00072   MachineFunction &MF = *MBB.getParent();
00073   MachineConstantPool *ConstantPool = MF.getConstantPool();
00074   const Constant *C = ConstantInt::get(
00075           Type::getInt32Ty(MBB.getParent()->getFunction()->getContext()), Val);
00076   unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4);
00077 
00078   BuildMI(MBB, MBBI, dl, TII.get(ARM::tLDRpci))
00079     .addReg(DestReg, getDefRegState(true), SubIdx)
00080     .addConstantPoolIndex(Idx).addImm(Pred).addReg(PredReg)
00081     .setMIFlags(MIFlags);
00082 }
00083 
00084 
00085 /// emitThumbRegPlusImmInReg - Emits a series of instructions to materialize
00086 /// a destreg = basereg + immediate in Thumb code. Materialize the immediate
00087 /// in a register using mov / mvn sequences or load the immediate from a
00088 /// constpool entry.
00089 static
00090 void emitThumbRegPlusImmInReg(MachineBasicBlock &MBB,
00091                               MachineBasicBlock::iterator &MBBI,
00092                               DebugLoc dl,
00093                               unsigned DestReg, unsigned BaseReg,
00094                               int NumBytes, bool CanChangeCC,
00095                               const TargetInstrInfo &TII,
00096                               const ARMBaseRegisterInfo& MRI,
00097                               unsigned MIFlags = MachineInstr::NoFlags) {
00098     MachineFunction &MF = *MBB.getParent();
00099     bool isHigh = !isARMLowRegister(DestReg) ||
00100                   (BaseReg != 0 && !isARMLowRegister(BaseReg));
00101     bool isSub = false;
00102     // Subtract doesn't have high register version. Load the negative value
00103     // if either base or dest register is a high register. Also, if do not
00104     // issue sub as part of the sequence if condition register is to be
00105     // preserved.
00106     if (NumBytes < 0 && !isHigh && CanChangeCC) {
00107       isSub = true;
00108       NumBytes = -NumBytes;
00109     }
00110     unsigned LdReg = DestReg;
00111     if (DestReg == ARM::SP) {
00112       assert(BaseReg == ARM::SP && "Unexpected!");
00113       LdReg = MF.getRegInfo().createVirtualRegister(&ARM::tGPRRegClass);
00114     }
00115 
00116     if (NumBytes <= 255 && NumBytes >= 0)
00117       AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg))
00118         .addImm(NumBytes).setMIFlags(MIFlags);
00119     else if (NumBytes < 0 && NumBytes >= -255) {
00120       AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg))
00121         .addImm(NumBytes).setMIFlags(MIFlags);
00122       AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tRSB), LdReg))
00123         .addReg(LdReg, RegState::Kill).setMIFlags(MIFlags);
00124     } else
00125       MRI.emitLoadConstPool(MBB, MBBI, dl, LdReg, 0, NumBytes,
00126                             ARMCC::AL, 0, MIFlags);
00127 
00128     // Emit add / sub.
00129     int Opc = (isSub) ? ARM::tSUBrr : (isHigh ? ARM::tADDhirr : ARM::tADDrr);
00130     MachineInstrBuilder MIB =
00131       BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg);
00132     if (Opc != ARM::tADDhirr)
00133       MIB = AddDefaultT1CC(MIB);
00134     if (DestReg == ARM::SP || isSub)
00135       MIB.addReg(BaseReg).addReg(LdReg, RegState::Kill);
00136     else
00137       MIB.addReg(LdReg).addReg(BaseReg, RegState::Kill);
00138     AddDefaultPred(MIB);
00139 }
00140 
00141 /// calcNumMI - Returns the number of instructions required to materialize
00142 /// the specific add / sub r, c instruction.
00143 static unsigned calcNumMI(int Opc, int ExtraOpc, unsigned Bytes,
00144                           unsigned NumBits, unsigned Scale) {
00145   unsigned NumMIs = 0;
00146   unsigned Chunk = ((1 << NumBits) - 1) * Scale;
00147 
00148   if (Opc == ARM::tADDrSPi) {
00149     unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes;
00150     Bytes -= ThisVal;
00151     NumMIs++;
00152     NumBits = 8;
00153     Scale = 1;  // Followed by a number of tADDi8.
00154     Chunk = ((1 << NumBits) - 1) * Scale;
00155   }
00156 
00157   NumMIs += Bytes / Chunk;
00158   if ((Bytes % Chunk) != 0)
00159     NumMIs++;
00160   if (ExtraOpc)
00161     NumMIs++;
00162   return NumMIs;
00163 }
00164 
00165 /// emitThumbRegPlusImmediate - Emits a series of instructions to materialize
00166 /// a destreg = basereg + immediate in Thumb code.
00167 void llvm::emitThumbRegPlusImmediate(MachineBasicBlock &MBB,
00168                                      MachineBasicBlock::iterator &MBBI,
00169                                      DebugLoc dl,
00170                                      unsigned DestReg, unsigned BaseReg,
00171                                      int NumBytes, const TargetInstrInfo &TII,
00172                                      const ARMBaseRegisterInfo& MRI,
00173                                      unsigned MIFlags) {
00174   bool isSub = NumBytes < 0;
00175   unsigned Bytes = (unsigned)NumBytes;
00176   if (isSub) Bytes = -NumBytes;
00177   bool isMul4 = (Bytes & 3) == 0;
00178   bool isTwoAddr = false;
00179   bool DstNotEqBase = false;
00180   unsigned NumBits = 1;
00181   unsigned Scale = 1;
00182   int Opc = 0;
00183   int ExtraOpc = 0;
00184   bool NeedCC = false;
00185 
00186   if (DestReg == BaseReg && BaseReg == ARM::SP) {
00187     assert(isMul4 && "Thumb sp inc / dec size must be multiple of 4!");
00188     NumBits = 7;
00189     Scale = 4;
00190     Opc = isSub ? ARM::tSUBspi : ARM::tADDspi;
00191     isTwoAddr = true;
00192   } else if (!isSub && BaseReg == ARM::SP) {
00193     // r1 = add sp, 403
00194     // =>
00195     // r1 = add sp, 100 * 4
00196     // r1 = add r1, 3
00197     if (!isMul4) {
00198       Bytes &= ~3;
00199       ExtraOpc = ARM::tADDi3;
00200     }
00201     NumBits = 8;
00202     Scale = 4;
00203     Opc = ARM::tADDrSPi;
00204   } else {
00205     // sp = sub sp, c
00206     // r1 = sub sp, c
00207     // r8 = sub sp, c
00208     if (DestReg != BaseReg)
00209       DstNotEqBase = true;
00210     NumBits = 8;
00211     if (DestReg == ARM::SP) {
00212       Opc = isSub ? ARM::tSUBspi : ARM::tADDspi;
00213       assert(isMul4 && "Thumb sp inc / dec size must be multiple of 4!");
00214       NumBits = 7;
00215       Scale = 4;
00216     } else {
00217       Opc = isSub ? ARM::tSUBi8 : ARM::tADDi8;
00218       NumBits = 8;
00219       NeedCC = true;
00220     }
00221     isTwoAddr = true;
00222   }
00223 
00224   unsigned NumMIs = calcNumMI(Opc, ExtraOpc, Bytes, NumBits, Scale);
00225   unsigned Threshold = (DestReg == ARM::SP) ? 3 : 2;
00226   if (NumMIs > Threshold) {
00227     // This will expand into too many instructions. Load the immediate from a
00228     // constpool entry.
00229     emitThumbRegPlusImmInReg(MBB, MBBI, dl,
00230                              DestReg, BaseReg, NumBytes, true,
00231                              TII, MRI, MIFlags);
00232     return;
00233   }
00234 
00235   if (DstNotEqBase) {
00236     if (isARMLowRegister(DestReg) && isARMLowRegister(BaseReg)) {
00237       // If both are low registers, emit DestReg = add BaseReg, max(Imm, 7)
00238       unsigned Chunk = (1 << 3) - 1;
00239       unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes;
00240       Bytes -= ThisVal;
00241       const MCInstrDesc &MCID = TII.get(isSub ? ARM::tSUBi3 : ARM::tADDi3);
00242       const MachineInstrBuilder MIB =
00243         AddDefaultT1CC(BuildMI(MBB, MBBI, dl, MCID, DestReg)
00244                          .setMIFlags(MIFlags));
00245       AddDefaultPred(MIB.addReg(BaseReg, RegState::Kill).addImm(ThisVal));
00246     } else {
00247       AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), DestReg)
00248         .addReg(BaseReg, RegState::Kill))
00249         .setMIFlags(MIFlags);
00250     }
00251     BaseReg = DestReg;
00252   }
00253 
00254   unsigned Chunk = ((1 << NumBits) - 1) * Scale;
00255   while (Bytes) {
00256     unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes;
00257     Bytes -= ThisVal;
00258     ThisVal /= Scale;
00259     // Build the new tADD / tSUB.
00260     if (isTwoAddr) {
00261       MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg);
00262       if (NeedCC)
00263         MIB = AddDefaultT1CC(MIB);
00264       MIB.addReg(DestReg).addImm(ThisVal);
00265       MIB = AddDefaultPred(MIB);
00266       MIB.setMIFlags(MIFlags);
00267     } else {
00268       bool isKill = BaseReg != ARM::SP;
00269       MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg);
00270       if (NeedCC)
00271         MIB = AddDefaultT1CC(MIB);
00272       MIB.addReg(BaseReg, getKillRegState(isKill)).addImm(ThisVal);
00273       MIB = AddDefaultPred(MIB);
00274       MIB.setMIFlags(MIFlags);
00275 
00276       BaseReg = DestReg;
00277       if (Opc == ARM::tADDrSPi) {
00278         // r4 = add sp, imm
00279         // r4 = add r4, imm
00280         // ...
00281         NumBits = 8;
00282         Scale = 1;
00283         Chunk = ((1 << NumBits) - 1) * Scale;
00284         Opc = isSub ? ARM::tSUBi8 : ARM::tADDi8;
00285         NeedCC = isTwoAddr = true;
00286       }
00287     }
00288   }
00289 
00290   if (ExtraOpc) {
00291     const MCInstrDesc &MCID = TII.get(ExtraOpc);
00292     AddDefaultPred(AddDefaultT1CC(BuildMI(MBB, MBBI, dl, MCID, DestReg))
00293                    .addReg(DestReg, RegState::Kill)
00294                    .addImm(((unsigned)NumBytes) & 3)
00295                    .setMIFlags(MIFlags));
00296   }
00297 }
00298 
00299 /// emitThumbConstant - Emit a series of instructions to materialize a
00300 /// constant.
00301 static void emitThumbConstant(MachineBasicBlock &MBB,
00302                               MachineBasicBlock::iterator &MBBI,
00303                               unsigned DestReg, int Imm,
00304                               const TargetInstrInfo &TII,
00305                               const Thumb1RegisterInfo& MRI,
00306                               DebugLoc dl) {
00307   bool isSub = Imm < 0;
00308   if (isSub) Imm = -Imm;
00309 
00310   int Chunk = (1 << 8) - 1;
00311   int ThisVal = (Imm > Chunk) ? Chunk : Imm;
00312   Imm -= ThisVal;
00313   AddDefaultPred(AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8),
00314                                         DestReg))
00315                  .addImm(ThisVal));
00316   if (Imm > 0)
00317     emitThumbRegPlusImmediate(MBB, MBBI, dl, DestReg, DestReg, Imm, TII, MRI);
00318   if (isSub) {
00319     const MCInstrDesc &MCID = TII.get(ARM::tRSB);
00320     AddDefaultPred(AddDefaultT1CC(BuildMI(MBB, MBBI, dl, MCID, DestReg))
00321                    .addReg(DestReg, RegState::Kill));
00322   }
00323 }
00324 
00325 static void removeOperands(MachineInstr &MI, unsigned i) {
00326   unsigned Op = i;
00327   for (unsigned e = MI.getNumOperands(); i != e; ++i)
00328     MI.RemoveOperand(Op);
00329 }
00330 
00331 /// convertToNonSPOpcode - Change the opcode to the non-SP version, because
00332 /// we're replacing the frame index with a non-SP register.
00333 static unsigned convertToNonSPOpcode(unsigned Opcode) {
00334   switch (Opcode) {
00335   case ARM::tLDRspi:
00336     return ARM::tLDRi;
00337 
00338   case ARM::tSTRspi:
00339     return ARM::tSTRi;
00340   }
00341 
00342   return Opcode;
00343 }
00344 
00345 bool Thumb1RegisterInfo::
00346 rewriteFrameIndex(MachineBasicBlock::iterator II, unsigned FrameRegIdx,
00347                   unsigned FrameReg, int &Offset,
00348                   const ARMBaseInstrInfo &TII) const {
00349   MachineInstr &MI = *II;
00350   MachineBasicBlock &MBB = *MI.getParent();
00351   DebugLoc dl = MI.getDebugLoc();
00352   MachineInstrBuilder MIB(*MBB.getParent(), &MI);
00353   unsigned Opcode = MI.getOpcode();
00354   const MCInstrDesc &Desc = MI.getDesc();
00355   unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
00356 
00357   if (Opcode == ARM::tADDrSPi) {
00358     Offset += MI.getOperand(FrameRegIdx+1).getImm();
00359 
00360     // Can't use tADDrSPi if it's based off the frame pointer.
00361     unsigned NumBits = 0;
00362     unsigned Scale = 1;
00363     if (FrameReg != ARM::SP) {
00364       Opcode = ARM::tADDi3;
00365       NumBits = 3;
00366     } else {
00367       NumBits = 8;
00368       Scale = 4;
00369       assert((Offset & 3) == 0 &&
00370              "Thumb add/sub sp, #imm immediate must be multiple of 4!");
00371     }
00372 
00373     unsigned PredReg;
00374     if (Offset == 0 && getInstrPredicate(&MI, PredReg) == ARMCC::AL) {
00375       // Turn it into a move.
00376       MI.setDesc(TII.get(ARM::tMOVr));
00377       MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
00378       // Remove offset
00379       MI.RemoveOperand(FrameRegIdx+1);
00380       return true;
00381     }
00382 
00383     // Common case: small offset, fits into instruction.
00384     unsigned Mask = (1 << NumBits) - 1;
00385     if (((Offset / Scale) & ~Mask) == 0) {
00386       // Replace the FrameIndex with sp / fp
00387       if (Opcode == ARM::tADDi3) {
00388         MI.setDesc(TII.get(Opcode));
00389         removeOperands(MI, FrameRegIdx);
00390         AddDefaultPred(AddDefaultT1CC(MIB).addReg(FrameReg)
00391                        .addImm(Offset / Scale));
00392       } else {
00393         MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
00394         MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset / Scale);
00395       }
00396       return true;
00397     }
00398 
00399     unsigned DestReg = MI.getOperand(0).getReg();
00400     unsigned Bytes = (Offset > 0) ? Offset : -Offset;
00401     unsigned NumMIs = calcNumMI(Opcode, 0, Bytes, NumBits, Scale);
00402     // MI would expand into a large number of instructions. Don't try to
00403     // simplify the immediate.
00404     if (NumMIs > 2) {
00405       emitThumbRegPlusImmediate(MBB, II, dl, DestReg, FrameReg, Offset, TII,
00406                                 *this);
00407       MBB.erase(II);
00408       return true;
00409     }
00410 
00411     if (Offset > 0) {
00412       // Translate r0 = add sp, imm to
00413       // r0 = add sp, 255*4
00414       // r0 = add r0, (imm - 255*4)
00415       if (Opcode == ARM::tADDi3) {
00416         MI.setDesc(TII.get(Opcode));
00417         removeOperands(MI, FrameRegIdx);
00418         AddDefaultPred(AddDefaultT1CC(MIB).addReg(FrameReg).addImm(Mask));
00419       } else {
00420         MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
00421         MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Mask);
00422       }
00423       Offset = (Offset - Mask * Scale);
00424       MachineBasicBlock::iterator NII = llvm::next(II);
00425       emitThumbRegPlusImmediate(MBB, NII, dl, DestReg, DestReg, Offset, TII,
00426                                 *this);
00427     } else {
00428       // Translate r0 = add sp, -imm to
00429       // r0 = -imm (this is then translated into a series of instructons)
00430       // r0 = add r0, sp
00431       emitThumbConstant(MBB, II, DestReg, Offset, TII, *this, dl);
00432 
00433       MI.setDesc(TII.get(ARM::tADDhirr));
00434       MI.getOperand(FrameRegIdx).ChangeToRegister(DestReg, false, false, true);
00435       MI.getOperand(FrameRegIdx+1).ChangeToRegister(FrameReg, false);
00436     }
00437     return true;
00438   } else {
00439     if (AddrMode != ARMII::AddrModeT1_s)
00440       llvm_unreachable("Unsupported addressing mode!");
00441 
00442     unsigned ImmIdx = FrameRegIdx + 1;
00443     int InstrOffs = MI.getOperand(ImmIdx).getImm();
00444     unsigned NumBits = (FrameReg == ARM::SP) ? 8 : 5;
00445     unsigned Scale = 4;
00446 
00447     Offset += InstrOffs * Scale;
00448     assert((Offset & (Scale - 1)) == 0 && "Can't encode this offset!");
00449 
00450     // Common case: small offset, fits into instruction.
00451     MachineOperand &ImmOp = MI.getOperand(ImmIdx);
00452     int ImmedOffset = Offset / Scale;
00453     unsigned Mask = (1 << NumBits) - 1;
00454 
00455     if ((unsigned)Offset <= Mask * Scale) {
00456       // Replace the FrameIndex with the frame register (e.g., sp).
00457       MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
00458       ImmOp.ChangeToImmediate(ImmedOffset);
00459 
00460       // If we're using a register where sp was stored, convert the instruction
00461       // to the non-SP version.
00462       unsigned NewOpc = convertToNonSPOpcode(Opcode);
00463       if (NewOpc != Opcode && FrameReg != ARM::SP)
00464         MI.setDesc(TII.get(NewOpc));
00465 
00466       return true;
00467     }
00468 
00469     NumBits = 5;
00470     Mask = (1 << NumBits) - 1;
00471 
00472     // If this is a thumb spill / restore, we will be using a constpool load to
00473     // materialize the offset.
00474     if (Opcode == ARM::tLDRspi || Opcode == ARM::tSTRspi) {
00475       ImmOp.ChangeToImmediate(0);
00476     } else {
00477       // Otherwise, it didn't fit. Pull in what we can to simplify the immed.
00478       ImmedOffset = ImmedOffset & Mask;
00479       ImmOp.ChangeToImmediate(ImmedOffset);
00480       Offset &= ~(Mask * Scale);
00481     }
00482   }
00483 
00484   return Offset == 0;
00485 }
00486 
00487 void
00488 Thumb1RegisterInfo::resolveFrameIndex(MachineBasicBlock::iterator I,
00489                                       unsigned BaseReg, int64_t Offset) const {
00490   MachineInstr &MI = *I;
00491   int Off = Offset; // ARM doesn't need the general 64-bit offsets
00492   unsigned i = 0;
00493 
00494   while (!MI.getOperand(i).isFI()) {
00495     ++i;
00496     assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
00497   }
00498   bool Done = rewriteFrameIndex(MI, i, BaseReg, Off, TII);
00499   assert (Done && "Unable to resolve frame index!");
00500   (void)Done;
00501 }
00502 
00503 /// saveScavengerRegister - Spill the register so it can be used by the
00504 /// register scavenger. Return true.
00505 bool
00506 Thumb1RegisterInfo::saveScavengerRegister(MachineBasicBlock &MBB,
00507                                           MachineBasicBlock::iterator I,
00508                                           MachineBasicBlock::iterator &UseMI,
00509                                           const TargetRegisterClass *RC,
00510                                           unsigned Reg) const {
00511   // Thumb1 can't use the emergency spill slot on the stack because
00512   // ldr/str immediate offsets must be positive, and if we're referencing
00513   // off the frame pointer (if, for example, there are alloca() calls in
00514   // the function, the offset will be negative. Use R12 instead since that's
00515   // a call clobbered register that we know won't be used in Thumb1 mode.
00516   DebugLoc DL;
00517   AddDefaultPred(BuildMI(MBB, I, DL, TII.get(ARM::tMOVr))
00518     .addReg(ARM::R12, RegState::Define)
00519     .addReg(Reg, RegState::Kill));
00520 
00521   // The UseMI is where we would like to restore the register. If there's
00522   // interference with R12 before then, however, we'll need to restore it
00523   // before that instead and adjust the UseMI.
00524   bool done = false;
00525   for (MachineBasicBlock::iterator II = I; !done && II != UseMI ; ++II) {
00526     if (II->isDebugValue())
00527       continue;
00528     // If this instruction affects R12, adjust our restore point.
00529     for (unsigned i = 0, e = II->getNumOperands(); i != e; ++i) {
00530       const MachineOperand &MO = II->getOperand(i);
00531       if (MO.isRegMask() && MO.clobbersPhysReg(ARM::R12)) {
00532         UseMI = II;
00533         done = true;
00534         break;
00535       }
00536       if (!MO.isReg() || MO.isUndef() || !MO.getReg() ||
00537           TargetRegisterInfo::isVirtualRegister(MO.getReg()))
00538         continue;
00539       if (MO.getReg() == ARM::R12) {
00540         UseMI = II;
00541         done = true;
00542         break;
00543       }
00544     }
00545   }
00546   // Restore the register from R12
00547   AddDefaultPred(BuildMI(MBB, UseMI, DL, TII.get(ARM::tMOVr)).
00548     addReg(Reg, RegState::Define).addReg(ARM::R12, RegState::Kill));
00549 
00550   return true;
00551 }
00552 
00553 void
00554 Thumb1RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
00555                                         int SPAdj, unsigned FIOperandNum,
00556                                         RegScavenger *RS) const {
00557   unsigned VReg = 0;
00558   MachineInstr &MI = *II;
00559   MachineBasicBlock &MBB = *MI.getParent();
00560   MachineFunction &MF = *MBB.getParent();
00561   ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
00562   DebugLoc dl = MI.getDebugLoc();
00563   MachineInstrBuilder MIB(*MBB.getParent(), &MI);
00564 
00565   unsigned FrameReg = ARM::SP;
00566   int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
00567   int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) +
00568                MF.getFrameInfo()->getStackSize() + SPAdj;
00569 
00570   if (AFI->isGPRCalleeSavedArea1Frame(FrameIndex))
00571     Offset -= AFI->getGPRCalleeSavedArea1Offset();
00572   else if (AFI->isGPRCalleeSavedArea2Frame(FrameIndex))
00573     Offset -= AFI->getGPRCalleeSavedArea2Offset();
00574   else if (MF.getFrameInfo()->hasVarSizedObjects()) {
00575     assert(SPAdj == 0 && MF.getTarget().getFrameLowering()->hasFP(MF) &&
00576            "Unexpected");
00577     // There are alloca()'s in this function, must reference off the frame
00578     // pointer or base pointer instead.
00579     if (!hasBasePointer(MF)) {
00580       FrameReg = getFrameRegister(MF);
00581       Offset -= AFI->getFramePtrSpillOffset();
00582     } else
00583       FrameReg = BasePtr;
00584   }
00585 
00586   // PEI::scavengeFrameVirtualRegs() cannot accurately track SPAdj because the
00587   // call frame setup/destroy instructions have already been eliminated.  That
00588   // means the stack pointer cannot be used to access the emergency spill slot
00589   // when !hasReservedCallFrame().
00590 #ifndef NDEBUG
00591   if (RS && FrameReg == ARM::SP && RS->isScavengingFrameIndex(FrameIndex)){
00592     assert(MF.getTarget().getFrameLowering()->hasReservedCallFrame(MF) &&
00593            "Cannot use SP to access the emergency spill slot in "
00594            "functions without a reserved call frame");
00595     assert(!MF.getFrameInfo()->hasVarSizedObjects() &&
00596            "Cannot use SP to access the emergency spill slot in "
00597            "functions with variable sized frame objects");
00598   }
00599 #endif // NDEBUG
00600 
00601   // Special handling of dbg_value instructions.
00602   if (MI.isDebugValue()) {
00603     MI.getOperand(FIOperandNum).  ChangeToRegister(FrameReg, false /*isDef*/);
00604     MI.getOperand(FIOperandNum+1).ChangeToImmediate(Offset);
00605     return;
00606   }
00607 
00608   // Modify MI as necessary to handle as much of 'Offset' as possible
00609   assert(AFI->isThumbFunction() &&
00610          "This eliminateFrameIndex only supports Thumb1!");
00611   if (rewriteFrameIndex(MI, FIOperandNum, FrameReg, Offset, TII))
00612     return;
00613 
00614   // If we get here, the immediate doesn't fit into the instruction.  We folded
00615   // as much as possible above, handle the rest, providing a register that is
00616   // SP+LargeImm.
00617   assert(Offset && "This code isn't needed if offset already handled!");
00618 
00619   unsigned Opcode = MI.getOpcode();
00620 
00621   // Remove predicate first.
00622   int PIdx = MI.findFirstPredOperandIdx();
00623   if (PIdx != -1)
00624     removeOperands(MI, PIdx);
00625 
00626   if (MI.mayLoad()) {
00627     // Use the destination register to materialize sp + offset.
00628     unsigned TmpReg = MI.getOperand(0).getReg();
00629     bool UseRR = false;
00630     if (Opcode == ARM::tLDRspi) {
00631       if (FrameReg == ARM::SP)
00632         emitThumbRegPlusImmInReg(MBB, II, dl, TmpReg, FrameReg,
00633                                  Offset, false, TII, *this);
00634       else {
00635         emitLoadConstPool(MBB, II, dl, TmpReg, 0, Offset);
00636         UseRR = true;
00637       }
00638     } else {
00639       emitThumbRegPlusImmediate(MBB, II, dl, TmpReg, FrameReg, Offset, TII,
00640                                 *this);
00641     }
00642 
00643     MI.setDesc(TII.get(UseRR ? ARM::tLDRr : ARM::tLDRi));
00644     MI.getOperand(FIOperandNum).ChangeToRegister(TmpReg, false, false, true);
00645     if (UseRR)
00646       // Use [reg, reg] addrmode. Replace the immediate operand w/ the frame
00647       // register. The offset is already handled in the vreg value.
00648       MI.getOperand(FIOperandNum+1).ChangeToRegister(FrameReg, false, false,
00649                                                      false);
00650   } else if (MI.mayStore()) {
00651       VReg = MF.getRegInfo().createVirtualRegister(&ARM::tGPRRegClass);
00652       bool UseRR = false;
00653 
00654       if (Opcode == ARM::tSTRspi) {
00655         if (FrameReg == ARM::SP)
00656           emitThumbRegPlusImmInReg(MBB, II, dl, VReg, FrameReg,
00657                                    Offset, false, TII, *this);
00658         else {
00659           emitLoadConstPool(MBB, II, dl, VReg, 0, Offset);
00660           UseRR = true;
00661         }
00662       } else
00663         emitThumbRegPlusImmediate(MBB, II, dl, VReg, FrameReg, Offset, TII,
00664                                   *this);
00665       MI.setDesc(TII.get(UseRR ? ARM::tSTRr : ARM::tSTRi));
00666       MI.getOperand(FIOperandNum).ChangeToRegister(VReg, false, false, true);
00667       if (UseRR)
00668         // Use [reg, reg] addrmode. Replace the immediate operand w/ the frame
00669         // register. The offset is already handled in the vreg value.
00670         MI.getOperand(FIOperandNum+1).ChangeToRegister(FrameReg, false, false,
00671                                                        false);
00672   } else {
00673     llvm_unreachable("Unexpected opcode!");
00674   }
00675 
00676   // Add predicate back if it's needed.
00677   if (MI.isPredicable())
00678     AddDefaultPred(MIB);
00679 }