LCOV - code coverage report
Current view: top level - lib/Target/ARM - ThumbRegisterInfo.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 228 290 78.6 %
Date: 2017-09-14 15:23:50 Functions: 11 12 91.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===-- ThumbRegisterInfo.cpp - Thumb-1 Register Information -------------===//
       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 "ThumbRegisterInfo.h"
      16             : #include "ARMBaseInstrInfo.h"
      17             : #include "ARMMachineFunctionInfo.h"
      18             : #include "ARMSubtarget.h"
      19             : #include "MCTargetDesc/ARMAddressingModes.h"
      20             : #include "llvm/CodeGen/MachineConstantPool.h"
      21             : #include "llvm/CodeGen/MachineFrameInfo.h"
      22             : #include "llvm/CodeGen/MachineFunction.h"
      23             : #include "llvm/CodeGen/MachineInstrBuilder.h"
      24             : #include "llvm/CodeGen/MachineRegisterInfo.h"
      25             : #include "llvm/CodeGen/RegisterScavenging.h"
      26             : #include "llvm/IR/Constants.h"
      27             : #include "llvm/IR/DerivedTypes.h"
      28             : #include "llvm/IR/Function.h"
      29             : #include "llvm/IR/LLVMContext.h"
      30             : #include "llvm/Support/CommandLine.h"
      31             : #include "llvm/Support/ErrorHandling.h"
      32             : #include "llvm/Target/TargetFrameLowering.h"
      33             : #include "llvm/Target/TargetMachine.h"
      34             : 
      35             : namespace llvm {
      36             : extern cl::opt<bool> ReuseFrameIndexVals;
      37             : }
      38             : 
      39             : using namespace llvm;
      40             : 
      41        1753 : ThumbRegisterInfo::ThumbRegisterInfo() : ARMBaseRegisterInfo() {}
      42             : 
      43             : const TargetRegisterClass *
      44        6115 : ThumbRegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC,
      45             :                                               const MachineFunction &MF) const {
      46        6115 :   if (!MF.getSubtarget<ARMSubtarget>().isThumb1Only())
      47        5125 :     return ARMBaseRegisterInfo::getLargestLegalSuperClass(RC, MF);
      48             : 
      49        1980 :   if (ARM::tGPRRegClass.hasSubClassEq(RC))
      50             :     return &ARM::tGPRRegClass;
      51           2 :   return ARMBaseRegisterInfo::getLargestLegalSuperClass(RC, MF);
      52             : }
      53             : 
      54             : const TargetRegisterClass *
      55         165 : ThumbRegisterInfo::getPointerRegClass(const MachineFunction &MF,
      56             :                                       unsigned Kind) const {
      57         165 :   if (!MF.getSubtarget<ARMSubtarget>().isThumb1Only())
      58         155 :     return ARMBaseRegisterInfo::getPointerRegClass(MF, Kind);
      59             :   return &ARM::tGPRRegClass;
      60             : }
      61             : 
      62          81 : static void emitThumb1LoadConstPool(MachineBasicBlock &MBB,
      63             :                                     MachineBasicBlock::iterator &MBBI,
      64             :                                     const DebugLoc &dl, unsigned DestReg,
      65             :                                     unsigned SubIdx, int Val,
      66             :                                     ARMCC::CondCodes Pred, unsigned PredReg,
      67             :                                     unsigned MIFlags) {
      68          81 :   MachineFunction &MF = *MBB.getParent();
      69          81 :   const ARMSubtarget &STI = MF.getSubtarget<ARMSubtarget>();
      70          81 :   const TargetInstrInfo &TII = *STI.getInstrInfo();
      71          81 :   MachineConstantPool *ConstantPool = MF.getConstantPool();
      72          81 :   const Constant *C = ConstantInt::get(
      73          81 :           Type::getInt32Ty(MBB.getParent()->getFunction()->getContext()), Val);
      74          81 :   unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4);
      75             : 
      76         243 :   BuildMI(MBB, MBBI, dl, TII.get(ARM::tLDRpci))
      77          81 :     .addReg(DestReg, getDefRegState(true), SubIdx)
      78         162 :     .addConstantPoolIndex(Idx).addImm(Pred).addReg(PredReg)
      79          81 :     .setMIFlags(MIFlags);
      80          81 : }
      81             : 
      82           0 : static void emitThumb2LoadConstPool(MachineBasicBlock &MBB,
      83             :                                     MachineBasicBlock::iterator &MBBI,
      84             :                                     const DebugLoc &dl, unsigned DestReg,
      85             :                                     unsigned SubIdx, int Val,
      86             :                                     ARMCC::CondCodes Pred, unsigned PredReg,
      87             :                                     unsigned MIFlags) {
      88           0 :   MachineFunction &MF = *MBB.getParent();
      89           0 :   const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
      90           0 :   MachineConstantPool *ConstantPool = MF.getConstantPool();
      91           0 :   const Constant *C = ConstantInt::get(
      92           0 :            Type::getInt32Ty(MBB.getParent()->getFunction()->getContext()), Val);
      93           0 :   unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4);
      94             : 
      95           0 :   BuildMI(MBB, MBBI, dl, TII.get(ARM::t2LDRpci))
      96           0 :       .addReg(DestReg, getDefRegState(true), SubIdx)
      97           0 :       .addConstantPoolIndex(Idx)
      98           0 :       .add(predOps(ARMCC::AL))
      99           0 :       .setMIFlags(MIFlags);
     100           0 : }
     101             : 
     102             : /// emitLoadConstPool - Emits a load from constpool to materialize the
     103             : /// specified immediate.
     104          81 : void ThumbRegisterInfo::emitLoadConstPool(
     105             :     MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
     106             :     const DebugLoc &dl, unsigned DestReg, unsigned SubIdx, int Val,
     107             :     ARMCC::CondCodes Pred, unsigned PredReg, unsigned MIFlags) const {
     108          81 :   MachineFunction &MF = *MBB.getParent();
     109          81 :   const ARMSubtarget &STI = MF.getSubtarget<ARMSubtarget>();
     110             :   if (STI.isThumb1Only()) {
     111             :     assert((isARMLowRegister(DestReg) || isVirtualRegister(DestReg)) &&
     112             :            "Thumb1 does not have ldr to high register");
     113          81 :     return emitThumb1LoadConstPool(MBB, MBBI, dl, DestReg, SubIdx, Val, Pred,
     114          81 :                                    PredReg, MIFlags);
     115             :   }
     116           0 :   return emitThumb2LoadConstPool(MBB, MBBI, dl, DestReg, SubIdx, Val, Pred,
     117           0 :                                  PredReg, MIFlags);
     118             : }
     119             : 
     120             : /// emitThumbRegPlusImmInReg - Emits a series of instructions to materialize
     121             : /// a destreg = basereg + immediate in Thumb code. Materialize the immediate
     122             : /// in a register using mov / mvn sequences or load the immediate from a
     123             : /// constpool entry.
     124          85 : static void emitThumbRegPlusImmInReg(
     125             :     MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
     126             :     const DebugLoc &dl, unsigned DestReg, unsigned BaseReg, int NumBytes,
     127             :     bool CanChangeCC, const TargetInstrInfo &TII,
     128             :     const ARMBaseRegisterInfo &MRI, unsigned MIFlags = MachineInstr::NoFlags) {
     129          85 :   MachineFunction &MF = *MBB.getParent();
     130          85 :   const ARMSubtarget &ST = MF.getSubtarget<ARMSubtarget>();
     131          16 :   bool isHigh = !isARMLowRegister(DestReg) ||
     132          85 :                 (BaseReg != 0 && !isARMLowRegister(BaseReg));
     133          85 :   bool isSub = false;
     134             :   // Subtract doesn't have high register version. Load the negative value
     135             :   // if either base or dest register is a high register. Also, if do not
     136             :   // issue sub as part of the sequence if condition register is to be
     137             :   // preserved.
     138          85 :   if (NumBytes < 0 && !isHigh && CanChangeCC) {
     139           0 :     isSub = true;
     140           0 :     NumBytes = -NumBytes;
     141             :   }
     142          85 :   unsigned LdReg = DestReg;
     143             :   if (DestReg == ARM::SP)
     144             :     assert(BaseReg == ARM::SP && "Unexpected!");
     145         138 :   if (!isARMLowRegister(DestReg) && !MRI.isVirtualRegister(DestReg))
     146          58 :     LdReg = MF.getRegInfo().createVirtualRegister(&ARM::tGPRRegClass);
     147             : 
     148          85 :   if (NumBytes <= 255 && NumBytes >= 0 && CanChangeCC) {
     149           0 :     BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg)
     150           0 :         .add(t1CondCodeOp())
     151           0 :         .addImm(NumBytes)
     152           0 :         .setMIFlags(MIFlags);
     153          85 :   } else if (NumBytes < 0 && NumBytes >= -255 && CanChangeCC) {
     154           0 :     BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg)
     155           0 :         .add(t1CondCodeOp())
     156           0 :         .addImm(NumBytes)
     157           0 :         .setMIFlags(MIFlags);
     158           0 :     BuildMI(MBB, MBBI, dl, TII.get(ARM::tRSB), LdReg)
     159           0 :         .add(t1CondCodeOp())
     160           0 :         .addReg(LdReg, RegState::Kill)
     161           0 :         .setMIFlags(MIFlags);
     162          85 :   } else if (ST.genExecuteOnly()) {
     163          12 :     BuildMI(MBB, MBBI, dl, TII.get(ARM::t2MOVi32imm), LdReg)
     164          12 :       .addImm(NumBytes).setMIFlags(MIFlags);
     165             :   } else
     166          81 :     MRI.emitLoadConstPool(MBB, MBBI, dl, LdReg, 0, NumBytes, ARMCC::AL, 0,
     167          81 :                           MIFlags);
     168             : 
     169             :   // Emit add / sub.
     170         170 :   int Opc = (isSub) ? ARM::tSUBrr
     171          85 :                     : ((isHigh || !CanChangeCC) ? ARM::tADDhirr : ARM::tADDrr);
     172         170 :   MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg);
     173          85 :   if (Opc != ARM::tADDhirr)
     174           0 :     MIB = MIB.add(t1CondCodeOp());
     175          85 :   if (DestReg == ARM::SP || isSub)
     176          58 :     MIB.addReg(BaseReg).addReg(LdReg, RegState::Kill);
     177             :   else
     178          27 :     MIB.addReg(LdReg).addReg(BaseReg, RegState::Kill);
     179         255 :   MIB.add(predOps(ARMCC::AL));
     180          85 : }
     181             : 
     182             : /// emitThumbRegPlusImmediate - Emits a series of instructions to materialize
     183             : /// a destreg = basereg + immediate in Thumb code. Tries a series of ADDs or
     184             : /// SUBs first, and uses a constant pool value if the instruction sequence would
     185             : /// be too long. This is allowed to modify the condition flags.
     186        1344 : void llvm::emitThumbRegPlusImmediate(MachineBasicBlock &MBB,
     187             :                                      MachineBasicBlock::iterator &MBBI,
     188             :                                      const DebugLoc &dl, unsigned DestReg,
     189             :                                      unsigned BaseReg, int NumBytes,
     190             :                                      const TargetInstrInfo &TII,
     191             :                                      const ARMBaseRegisterInfo &MRI,
     192             :                                      unsigned MIFlags) {
     193        1344 :   bool isSub = NumBytes < 0;
     194        1344 :   unsigned Bytes = (unsigned)NumBytes;
     195        1344 :   if (isSub) Bytes = -NumBytes;
     196             : 
     197        1344 :   int CopyOpc = 0;
     198        1344 :   unsigned CopyBits = 0;
     199        1344 :   unsigned CopyScale = 1;
     200        1344 :   bool CopyNeedsCC = false;
     201        1344 :   int ExtraOpc = 0;
     202        1344 :   unsigned ExtraBits = 0;
     203        1344 :   unsigned ExtraScale = 1;
     204        1344 :   bool ExtraNeedsCC = false;
     205             : 
     206             :   // Strategy:
     207             :   // We need to select two types of instruction, maximizing the available
     208             :   // immediate range of each. The instructions we use will depend on whether
     209             :   // DestReg and BaseReg are low, high or the stack pointer.
     210             :   // * CopyOpc  - DestReg = BaseReg + imm
     211             :   //              This will be emitted once if DestReg != BaseReg, and never if
     212             :   //              DestReg == BaseReg.
     213             :   // * ExtraOpc - DestReg = DestReg + imm
     214             :   //              This will be emitted as many times as necessary to add the
     215             :   //              full immediate.
     216             :   // If the immediate ranges of these instructions are not large enough to cover
     217             :   // NumBytes with a reasonable number of instructions, we fall back to using a
     218             :   // value loaded from a constant pool.
     219        1344 :   if (DestReg == ARM::SP) {
     220        1044 :     if (BaseReg == ARM::SP) {
     221             :       // sp -> sp
     222             :       // Already in right reg, no copy needed
     223             :     } else {
     224             :       // low -> sp or high -> sp
     225           0 :       CopyOpc = ARM::tMOVr;
     226           0 :       CopyBits = 0;
     227             :     }
     228        1044 :     ExtraOpc = isSub ? ARM::tSUBspi : ARM::tADDspi;
     229             :     ExtraBits = 7;
     230             :     ExtraScale = 4;
     231         300 :   } else if (isARMLowRegister(DestReg)) {
     232         300 :     if (BaseReg == ARM::SP) {
     233             :       // sp -> low
     234             :       assert(!isSub && "Thumb1 does not have tSUBrSPi");
     235             :       CopyOpc = ARM::tADDrSPi;
     236             :       CopyBits = 8;
     237             :       CopyScale = 4;
     238          41 :     } else if (DestReg == BaseReg) {
     239             :       // low -> same low
     240             :       // Already in right reg, no copy needed
     241          41 :     } else if (isARMLowRegister(BaseReg)) {
     242             :       // low -> different low
     243          41 :       CopyOpc = isSub ? ARM::tSUBi3 : ARM::tADDi3;
     244             :       CopyBits = 3;
     245             :       CopyNeedsCC = true;
     246             :     } else {
     247             :       // high -> low
     248             :       CopyOpc = ARM::tMOVr;
     249             :       CopyBits = 0;
     250             :     }
     251         300 :     ExtraOpc = isSub ? ARM::tSUBi8 : ARM::tADDi8;
     252             :     ExtraBits = 8;
     253             :     ExtraNeedsCC = true;
     254             :   } else /* DestReg is high */ {
     255           0 :     if (DestReg == BaseReg) {
     256             :       // high -> same high
     257             :       // Already in right reg, no copy needed
     258             :     } else {
     259             :       // {low,high,sp} -> high
     260           0 :       CopyOpc = ARM::tMOVr;
     261           0 :       CopyBits = 0;
     262             :     }
     263             :     ExtraOpc = 0;
     264             :   }
     265             : 
     266             :   // We could handle an unaligned immediate with an unaligned copy instruction
     267             :   // and an aligned extra instruction, but this case is not currently needed.
     268             :   assert(((Bytes & 3) == 0 || ExtraScale == 1) &&
     269             :          "Unaligned offset, but all instructions require alignment");
     270             : 
     271        1344 :   unsigned CopyRange = ((1 << CopyBits) - 1) * CopyScale;
     272             :   // If we would emit the copy with an immediate of 0, just use tMOVr.
     273        1344 :   if (CopyOpc && Bytes < CopyScale) {
     274          49 :     CopyOpc = ARM::tMOVr;
     275          49 :     CopyScale = 1;
     276          49 :     CopyNeedsCC = false;
     277          49 :     CopyRange = 0;
     278             :   }
     279        1344 :   unsigned ExtraRange = ((1 << ExtraBits) - 1) * ExtraScale; // per instruction
     280        1344 :   unsigned RequiredCopyInstrs = CopyOpc ? 1 : 0;
     281        1344 :   unsigned RangeAfterCopy = (CopyRange > Bytes) ? 0 : (Bytes - CopyRange);
     282             : 
     283             :   // We could handle this case when the copy instruction does not require an
     284             :   // aligned immediate, but we do not currently do this.
     285             :   assert(RangeAfterCopy % ExtraScale == 0 &&
     286             :          "Extra instruction requires immediate to be aligned");
     287             : 
     288             :   unsigned RequiredExtraInstrs;
     289        1344 :   if (ExtraRange)
     290        2688 :     RequiredExtraInstrs = alignTo(RangeAfterCopy, ExtraRange) / ExtraRange;
     291           0 :   else if (RangeAfterCopy > 0)
     292             :     // We need an extra instruction but none is available
     293             :     RequiredExtraInstrs = 1000000;
     294             :   else
     295           0 :     RequiredExtraInstrs = 0;
     296        1344 :   unsigned RequiredInstrs = RequiredCopyInstrs + RequiredExtraInstrs;
     297        1344 :   unsigned Threshold = (DestReg == ARM::SP) ? 3 : 2;
     298             : 
     299             :   // Use a constant pool, if the sequence of ADDs/SUBs is too expensive.
     300        1344 :   if (RequiredInstrs > Threshold) {
     301          61 :     emitThumbRegPlusImmInReg(MBB, MBBI, dl,
     302             :                              DestReg, BaseReg, NumBytes, true,
     303             :                              TII, MRI, MIFlags);
     304          61 :     return;
     305             :   }
     306             : 
     307             :   // Emit zero or one copy instructions
     308        1283 :   if (CopyOpc) {
     309         297 :     unsigned CopyImm = std::min(Bytes, CopyRange) / CopyScale;
     310         297 :     Bytes -= CopyImm * CopyScale;
     311             : 
     312         594 :     MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(CopyOpc), DestReg);
     313         297 :     if (CopyNeedsCC)
     314          76 :       MIB = MIB.add(t1CondCodeOp());
     315         297 :     MIB.addReg(BaseReg, RegState::Kill);
     316         297 :     if (CopyOpc != ARM::tMOVr) {
     317         248 :       MIB.addImm(CopyImm);
     318             :     }
     319        1188 :     MIB.setMIFlags(MIFlags).add(predOps(ARMCC::AL));
     320             : 
     321         297 :     BaseReg = DestReg;
     322             :   }
     323             : 
     324             :   // Emit zero or more in-place add/sub instructions
     325        2913 :   while (Bytes) {
     326         815 :     unsigned ExtraImm = std::min(Bytes, ExtraRange) / ExtraScale;
     327         815 :     Bytes -= ExtraImm * ExtraScale;
     328             : 
     329        1630 :     MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(ExtraOpc), DestReg);
     330         815 :     if (ExtraNeedsCC)
     331          92 :       MIB = MIB.add(t1CondCodeOp());
     332         815 :     MIB.addReg(BaseReg)
     333        1630 :        .addImm(ExtraImm)
     334        3260 :        .add(predOps(ARMCC::AL))
     335         815 :        .setMIFlags(MIFlags);
     336             :   }
     337             : }
     338             : 
     339             : static void removeOperands(MachineInstr &MI, unsigned i) {
     340          24 :   unsigned Op = i;
     341          72 :   for (unsigned e = MI.getNumOperands(); i != e; ++i)
     342          48 :     MI.RemoveOperand(Op);
     343             : }
     344             : 
     345             : /// convertToNonSPOpcode - Change the opcode to the non-SP version, because
     346             : /// we're replacing the frame index with a non-SP register.
     347             : static unsigned convertToNonSPOpcode(unsigned Opcode) {
     348        1327 :   switch (Opcode) {
     349             :   case ARM::tLDRspi:
     350             :     return ARM::tLDRi;
     351             : 
     352         419 :   case ARM::tSTRspi:
     353             :     return ARM::tSTRi;
     354             :   }
     355             : 
     356             :   return Opcode;
     357             : }
     358             : 
     359        1613 : bool ThumbRegisterInfo::rewriteFrameIndex(MachineBasicBlock::iterator II,
     360             :                                           unsigned FrameRegIdx,
     361             :                                           unsigned FrameReg, int &Offset,
     362             :                                           const ARMBaseInstrInfo &TII) const {
     363        1613 :   MachineInstr &MI = *II;
     364        1613 :   MachineBasicBlock &MBB = *MI.getParent();
     365             :   assert(MBB.getParent()->getSubtarget<ARMSubtarget>().isThumb1Only() &&
     366             :          "This isn't needed for thumb2!");
     367        4839 :   DebugLoc dl = MI.getDebugLoc();
     368        3226 :   MachineInstrBuilder MIB(*MBB.getParent(), &MI);
     369        1613 :   unsigned Opcode = MI.getOpcode();
     370        1613 :   const MCInstrDesc &Desc = MI.getDesc();
     371        1613 :   unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
     372             : 
     373        1613 :   if (Opcode == ARM::tADDframe) {
     374         524 :     Offset += MI.getOperand(FrameRegIdx+1).getImm();
     375         262 :     unsigned DestReg = MI.getOperand(0).getReg();
     376             : 
     377         262 :     emitThumbRegPlusImmediate(MBB, II, dl, DestReg, FrameReg, Offset, TII,
     378             :                               *this);
     379         262 :     MBB.erase(II);
     380         262 :     return true;
     381             :   } else {
     382        1351 :     if (AddrMode != ARMII::AddrModeT1_s)
     383           0 :       llvm_unreachable("Unsupported addressing mode!");
     384             : 
     385        1351 :     unsigned ImmIdx = FrameRegIdx + 1;
     386        2702 :     int InstrOffs = MI.getOperand(ImmIdx).getImm();
     387        1351 :     unsigned NumBits = (FrameReg == ARM::SP) ? 8 : 5;
     388        1351 :     unsigned Scale = 4;
     389             : 
     390        1351 :     Offset += InstrOffs * Scale;
     391             :     assert((Offset & (Scale - 1)) == 0 && "Can't encode this offset!");
     392             : 
     393             :     // Common case: small offset, fits into instruction.
     394        1351 :     MachineOperand &ImmOp = MI.getOperand(ImmIdx);
     395        1351 :     int ImmedOffset = Offset / Scale;
     396        1351 :     unsigned Mask = (1 << NumBits) - 1;
     397             : 
     398        1351 :     if ((unsigned)Offset <= Mask * Scale) {
     399             :       // Replace the FrameIndex with the frame register (e.g., sp).
     400        2654 :       MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
     401        1327 :       ImmOp.ChangeToImmediate(ImmedOffset);
     402             : 
     403             :       // If we're using a register where sp was stored, convert the instruction
     404             :       // to the non-SP version.
     405        1327 :       unsigned NewOpc = convertToNonSPOpcode(Opcode);
     406        1327 :       if (NewOpc != Opcode && FrameReg != ARM::SP)
     407          70 :         MI.setDesc(TII.get(NewOpc));
     408             : 
     409             :       return true;
     410             :     }
     411             : 
     412          24 :     NumBits = 5;
     413          24 :     Mask = (1 << NumBits) - 1;
     414             : 
     415             :     // If this is a thumb spill / restore, we will be using a constpool load to
     416             :     // materialize the offset.
     417          24 :     if (Opcode == ARM::tLDRspi || Opcode == ARM::tSTRspi) {
     418          24 :       ImmOp.ChangeToImmediate(0);
     419             :     } else {
     420             :       // Otherwise, it didn't fit. Pull in what we can to simplify the immed.
     421           0 :       ImmedOffset = ImmedOffset & Mask;
     422           0 :       ImmOp.ChangeToImmediate(ImmedOffset);
     423           0 :       Offset &= ~(Mask * Scale);
     424             :     }
     425             :   }
     426             : 
     427          24 :   return Offset == 0;
     428             : }
     429             : 
     430          25 : void ThumbRegisterInfo::resolveFrameIndex(MachineInstr &MI, unsigned BaseReg,
     431             :                                            int64_t Offset) const {
     432          25 :   const MachineFunction &MF = *MI.getParent()->getParent();
     433          25 :   const ARMSubtarget &STI = MF.getSubtarget<ARMSubtarget>();
     434             :   if (!STI.isThumb1Only())
     435          15 :     return ARMBaseRegisterInfo::resolveFrameIndex(MI, BaseReg, Offset);
     436             : 
     437          10 :   const ARMBaseInstrInfo &TII = *STI.getInstrInfo();
     438          10 :   int Off = Offset; // ARM doesn't need the general 64-bit offsets
     439          10 :   unsigned i = 0;
     440             : 
     441          70 :   while (!MI.getOperand(i).isFI()) {
     442          10 :     ++i;
     443             :     assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
     444             :   }
     445          10 :   bool Done = rewriteFrameIndex(MI, i, BaseReg, Off, TII);
     446             :   assert (Done && "Unable to resolve frame index!");
     447             :   (void)Done;
     448             : }
     449             : 
     450             : /// saveScavengerRegister - Spill the register so it can be used by the
     451             : /// register scavenger. Return true.
     452           3 : bool ThumbRegisterInfo::saveScavengerRegister(
     453             :     MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
     454             :     MachineBasicBlock::iterator &UseMI, const TargetRegisterClass *RC,
     455             :     unsigned Reg) const {
     456             : 
     457           3 :   const ARMSubtarget &STI = MBB.getParent()->getSubtarget<ARMSubtarget>();
     458             :   if (!STI.isThumb1Only())
     459             :     return ARMBaseRegisterInfo::saveScavengerRegister(MBB, I, UseMI, RC, Reg);
     460             : 
     461             :   // Thumb1 can't use the emergency spill slot on the stack because
     462             :   // ldr/str immediate offsets must be positive, and if we're referencing
     463             :   // off the frame pointer (if, for example, there are alloca() calls in
     464             :   // the function, the offset will be negative. Use R12 instead since that's
     465             :   // a call clobbered register that we know won't be used in Thumb1 mode.
     466           2 :   const TargetInstrInfo &TII = *STI.getInstrInfo();
     467           2 :   DebugLoc DL;
     468           6 :   BuildMI(MBB, I, DL, TII.get(ARM::tMOVr))
     469           2 :       .addReg(ARM::R12, RegState::Define)
     470           2 :       .addReg(Reg, RegState::Kill)
     471           6 :       .add(predOps(ARMCC::AL));
     472             : 
     473             :   // The UseMI is where we would like to restore the register. If there's
     474             :   // interference with R12 before then, however, we'll need to restore it
     475             :   // before that instead and adjust the UseMI.
     476           2 :   bool done = false;
     477          28 :   for (MachineBasicBlock::iterator II = I; !done && II != UseMI ; ++II) {
     478          48 :     if (II->isDebugValue())
     479           0 :       continue;
     480             :     // If this instruction affects R12, adjust our restore point.
     481         136 :     for (unsigned i = 0, e = II->getNumOperands(); i != e; ++i) {
     482         176 :       const MachineOperand &MO = II->getOperand(i);
     483          88 :       if (MO.isRegMask() && MO.clobbersPhysReg(ARM::R12)) {
     484           0 :         UseMI = II;
     485           0 :         done = true;
     486           0 :         break;
     487             :       }
     488         272 :       if (!MO.isReg() || MO.isUndef() || !MO.getReg() ||
     489          96 :           TargetRegisterInfo::isVirtualRegister(MO.getReg()))
     490          72 :         continue;
     491          16 :       if (MO.getReg() == ARM::R12) {
     492           0 :         UseMI = II;
     493           0 :         done = true;
     494           0 :         break;
     495             :       }
     496             :     }
     497             :   }
     498             :   // Restore the register from R12
     499           6 :   BuildMI(MBB, UseMI, DL, TII.get(ARM::tMOVr))
     500           2 :       .addReg(Reg, RegState::Define)
     501           2 :       .addReg(ARM::R12, RegState::Kill)
     502           6 :       .add(predOps(ARMCC::AL));
     503             : 
     504           2 :   return true;
     505             : }
     506             : 
     507        6715 : void ThumbRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
     508             :                                             int SPAdj, unsigned FIOperandNum,
     509             :                                             RegScavenger *RS) const {
     510        6715 :   MachineInstr &MI = *II;
     511        6715 :   MachineBasicBlock &MBB = *MI.getParent();
     512        6715 :   MachineFunction &MF = *MBB.getParent();
     513        6715 :   const ARMSubtarget &STI = MF.getSubtarget<ARMSubtarget>();
     514             :   if (!STI.isThumb1Only())
     515        5112 :     return ARMBaseRegisterInfo::eliminateFrameIndex(II, SPAdj, FIOperandNum,
     516       11803 :                                                     RS);
     517             : 
     518        1603 :   unsigned VReg = 0;
     519        1603 :   const ARMBaseInstrInfo &TII = *STI.getInstrInfo();
     520        1603 :   ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
     521        3230 :   DebugLoc dl = MI.getDebugLoc();
     522        3206 :   MachineInstrBuilder MIB(*MBB.getParent(), &MI);
     523             : 
     524        1603 :   unsigned FrameReg = ARM::SP;
     525        3206 :   int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
     526        3206 :   int Offset = MF.getFrameInfo().getObjectOffset(FrameIndex) +
     527        1603 :                MF.getFrameInfo().getStackSize() + SPAdj;
     528             : 
     529        1603 :   if (MF.getFrameInfo().hasVarSizedObjects()) {
     530             :     assert(SPAdj == 0 && STI.getFrameLowering()->hasFP(MF) && "Unexpected");
     531             :     // There are alloca()'s in this function, must reference off the frame
     532             :     // pointer or base pointer instead.
     533          28 :     if (!hasBasePointer(MF)) {
     534           0 :       FrameReg = getFrameRegister(MF);
     535           0 :       Offset -= AFI->getFramePtrSpillOffset();
     536             :     } else
     537          28 :       FrameReg = BasePtr;
     538             :   }
     539             : 
     540             :   // PEI::scavengeFrameVirtualRegs() cannot accurately track SPAdj because the
     541             :   // call frame setup/destroy instructions have already been eliminated.  That
     542             :   // means the stack pointer cannot be used to access the emergency spill slot
     543             :   // when !hasReservedCallFrame().
     544             : #ifndef NDEBUG
     545             :   if (RS && FrameReg == ARM::SP && RS->isScavengingFrameIndex(FrameIndex)){
     546             :     assert(STI.getFrameLowering()->hasReservedCallFrame(MF) &&
     547             :            "Cannot use SP to access the emergency spill slot in "
     548             :            "functions without a reserved call frame");
     549             :     assert(!MF.getFrameInfo().hasVarSizedObjects() &&
     550             :            "Cannot use SP to access the emergency spill slot in "
     551             :            "functions with variable sized frame objects");
     552             :   }
     553             : #endif // NDEBUG
     554             : 
     555             :   // Special handling of dbg_value instructions.
     556        1603 :   if (MI.isDebugValue()) {
     557           0 :     MI.getOperand(FIOperandNum).  ChangeToRegister(FrameReg, false /*isDef*/);
     558           0 :     MI.getOperand(FIOperandNum+1).ChangeToImmediate(Offset);
     559           0 :     return;
     560             :   }
     561             : 
     562             :   // Modify MI as necessary to handle as much of 'Offset' as possible
     563             :   assert(AFI->isThumbFunction() &&
     564             :          "This eliminateFrameIndex only supports Thumb1!");
     565        1603 :   if (rewriteFrameIndex(MI, FIOperandNum, FrameReg, Offset, TII))
     566             :     return;
     567             : 
     568             :   // If we get here, the immediate doesn't fit into the instruction.  We folded
     569             :   // as much as possible above, handle the rest, providing a register that is
     570             :   // SP+LargeImm.
     571             :   assert(Offset && "This code isn't needed if offset already handled!");
     572             : 
     573          24 :   unsigned Opcode = MI.getOpcode();
     574             : 
     575             :   // Remove predicate first.
     576          24 :   int PIdx = MI.findFirstPredOperandIdx();
     577          24 :   if (PIdx != -1)
     578          24 :     removeOperands(MI, PIdx);
     579             : 
     580          24 :   if (MI.mayLoad()) {
     581             :     // Use the destination register to materialize sp + offset.
     582          13 :     unsigned TmpReg = MI.getOperand(0).getReg();
     583          13 :     bool UseRR = false;
     584          13 :     if (Opcode == ARM::tLDRspi) {
     585          13 :       if (FrameReg == ARM::SP || STI.genExecuteOnly())
     586          13 :         emitThumbRegPlusImmInReg(MBB, II, dl, TmpReg, FrameReg,
     587             :                                  Offset, false, TII, *this);
     588             :       else {
     589           0 :         emitLoadConstPool(MBB, II, dl, TmpReg, 0, Offset);
     590           0 :         UseRR = true;
     591             :       }
     592             :     } else {
     593           0 :       emitThumbRegPlusImmediate(MBB, II, dl, TmpReg, FrameReg, Offset, TII,
     594             :                                 *this);
     595             :     }
     596             : 
     597          39 :     MI.setDesc(TII.get(UseRR ? ARM::tLDRr : ARM::tLDRi));
     598          26 :     MI.getOperand(FIOperandNum).ChangeToRegister(TmpReg, false, false, true);
     599          13 :     if (UseRR)
     600             :       // Use [reg, reg] addrmode. Replace the immediate operand w/ the frame
     601             :       // register. The offset is already handled in the vreg value.
     602           0 :       MI.getOperand(FIOperandNum+1).ChangeToRegister(FrameReg, false, false,
     603             :                                                      false);
     604          11 :   } else if (MI.mayStore()) {
     605          11 :       VReg = MF.getRegInfo().createVirtualRegister(&ARM::tGPRRegClass);
     606          11 :       bool UseRR = false;
     607             : 
     608          11 :       if (Opcode == ARM::tSTRspi) {
     609          11 :         if (FrameReg == ARM::SP || STI.genExecuteOnly())
     610          11 :           emitThumbRegPlusImmInReg(MBB, II, dl, VReg, FrameReg,
     611             :                                    Offset, false, TII, *this);
     612             :         else {
     613           0 :           emitLoadConstPool(MBB, II, dl, VReg, 0, Offset);
     614           0 :           UseRR = true;
     615             :         }
     616             :       } else
     617           0 :         emitThumbRegPlusImmediate(MBB, II, dl, VReg, FrameReg, Offset, TII,
     618             :                                   *this);
     619          33 :       MI.setDesc(TII.get(UseRR ? ARM::tSTRr : ARM::tSTRi));
     620          22 :       MI.getOperand(FIOperandNum).ChangeToRegister(VReg, false, false, true);
     621          11 :       if (UseRR)
     622             :         // Use [reg, reg] addrmode. Replace the immediate operand w/ the frame
     623             :         // register. The offset is already handled in the vreg value.
     624           0 :         MI.getOperand(FIOperandNum+1).ChangeToRegister(FrameReg, false, false,
     625             :                                                        false);
     626             :   } else {
     627           0 :     llvm_unreachable("Unexpected opcode!");
     628             :   }
     629             : 
     630             :   // Add predicate back if it's needed.
     631          24 :   if (MI.isPredicable())
     632          72 :     MIB.add(predOps(ARMCC::AL));
     633             : }

Generated by: LCOV version 1.13