131d157ae1ac2cd9c787dc3c1d28e64c682803844Jia Liu//===-- Thumb1RegisterInfo.cpp - Thumb-1 Register Information -------------===//
2a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov//
3a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov//                     The LLVM Compiler Infrastructure
4a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov//
5a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov// This file is distributed under the University of Illinois Open Source
6a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov// License. See LICENSE.TXT for details.
7a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov//
8a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov//===----------------------------------------------------------------------===//
9a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov//
1031c24bf5b39cc8391d4cfdbf8cf5163975fdb81eJim Grosbach// This file contains the Thumb-1 implementation of the TargetRegisterInfo
1131c24bf5b39cc8391d4cfdbf8cf5163975fdb81eJim Grosbach// class.
12a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov//
13a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov//===----------------------------------------------------------------------===//
14a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov
15c1f6f42049696e7357fb4837e1b25dabbaed3fe6Craig Topper#include "Thumb1RegisterInfo.h"
1677521f5232e679aa3de10aaaed2464aa91d7ff55David Goodwin#include "ARMBaseInstrInfo.h"
17a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov#include "ARMMachineFunctionInfo.h"
18a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov#include "ARMSubtarget.h"
19ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMAddressingModes.h"
20a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov#include "llvm/CodeGen/MachineConstantPool.h"
21a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov#include "llvm/CodeGen/MachineFrameInfo.h"
22a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov#include "llvm/CodeGen/MachineFunction.h"
23a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov#include "llvm/CodeGen/MachineInstrBuilder.h"
24a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov#include "llvm/CodeGen/MachineRegisterInfo.h"
250f9d07fb2526c0acdf7ad9fa6e9c1a97a746c0e9Jakob Stoklund Olesen#include "llvm/CodeGen/RegisterScavenging.h"
260b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Constants.h"
270b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DerivedTypes.h"
280b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Function.h"
290b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/LLVMContext.h"
304e501545cd12d903d35096f42eb5fdbe4603d5daJim Grosbach#include "llvm/Support/CommandLine.h"
31ab7c09b6b6f4516a631fd6788918c237c83939afTorok Edwin#include "llvm/Support/ErrorHandling.h"
32d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Target/TargetFrameLowering.h"
33d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Target/TargetMachine.h"
34a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov
358c407d45964fbba19719be555324f247e4fb14e1Dan Gohmannamespace llvm {
364e501545cd12d903d35096f42eb5fdbe4603d5daJim Grosbachextern cl::opt<bool> ReuseFrameIndexVals;
378c407d45964fbba19719be555324f247e4fb14e1Dan Gohman}
388c407d45964fbba19719be555324f247e4fb14e1Dan Gohman
398c407d45964fbba19719be555324f247e4fb14e1Dan Gohmanusing namespace llvm;
404e501545cd12d903d35096f42eb5fdbe4603d5daJim Grosbach
4157148c166ab232191098492633c924fad9c44ef3Bill WendlingThumb1RegisterInfo::Thumb1RegisterInfo(const ARMSubtarget &sti)
4257148c166ab232191098492633c924fad9c44ef3Bill Wendling  : ARMBaseRegisterInfo(sti) {
43a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov}
44a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov
45c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesenconst TargetRegisterClass*
46c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund OlesenThumb1RegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC)
47c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesen                                                                         const {
48fa226bccaa90c520cac154df74069bbabb976eabJakob Stoklund Olesen  if (ARM::tGPRRegClass.hasSubClassEq(RC))
49420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper    return &ARM::tGPRRegClass;
50c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesen  return ARMBaseRegisterInfo::getLargestLegalSuperClass(RC);
51c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesen}
52c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesen
531db952d0c6c93f24619af5de2ea1b0550665479cJakob Stoklund Olesenconst TargetRegisterClass *
54397fc4874efe9c17e737d4c5c50bd19dc3bf27f5Jakob Stoklund OlesenThumb1RegisterInfo::getPointerRegClass(const MachineFunction &MF, unsigned Kind)
55397fc4874efe9c17e737d4c5c50bd19dc3bf27f5Jakob Stoklund Olesen                                                                         const {
56420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper  return &ARM::tGPRRegClass;
571db952d0c6c93f24619af5de2ea1b0550665479cJakob Stoklund Olesen}
581db952d0c6c93f24619af5de2ea1b0550665479cJakob Stoklund Olesen
59a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov/// emitLoadConstPool - Emits a load from constpool to materialize the
60a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov/// specified immediate.
613daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikovvoid
623daccd82d3151fa3629de430b55698a81084fc9eAnton KorobeynikovThumb1RegisterInfo::emitLoadConstPool(MachineBasicBlock &MBB,
633daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov                                      MachineBasicBlock::iterator &MBBI,
643daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov                                      DebugLoc dl,
653daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov                                      unsigned DestReg, unsigned SubIdx,
663daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov                                      int Val,
673daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov                                      ARMCC::CondCodes Pred, unsigned PredReg,
683daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov                                      unsigned MIFlags) const {
69a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov  MachineFunction &MF = *MBB.getParent();
7057148c166ab232191098492633c924fad9c44ef3Bill Wendling  const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
71a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov  MachineConstantPool *ConstantPool = MF.getConstantPool();
7246510a73e977273ec67747eb34cbdb43f815e451Dan Gohman  const Constant *C = ConstantInt::get(
731d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson          Type::getInt32Ty(MBB.getParent()->getFunction()->getContext()), Val);
74a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov  unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4);
75a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov
763e333637f172c30adf5c8333b592fbde17ff9f78Jim Grosbach  BuildMI(MBB, MBBI, dl, TII.get(ARM::tLDRpci))
77b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov    .addReg(DestReg, getDefRegState(true), SubIdx)
78b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov    .addConstantPoolIndex(Idx).addImm(Pred).addReg(PredReg)
79b3fcc06d2124f9d01e3b48097b44cc141309908eAnton Korobeynikov    .setMIFlags(MIFlags);
80a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov}
81a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov
82446c428bf394b7113b0f18cbacb5e87b4efd1e14Evan Cheng
83a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov/// emitThumbRegPlusImmInReg - Emits a series of instructions to materialize
84a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov/// a destreg = basereg + immediate in Thumb code. Materialize the immediate
85a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov/// in a register using mov / mvn sequences or load the immediate from a
86a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov/// constpool entry.
87a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikovstatic
88a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikovvoid emitThumbRegPlusImmInReg(MachineBasicBlock &MBB,
89a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov                              MachineBasicBlock::iterator &MBBI,
903daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov                              DebugLoc dl,
91a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov                              unsigned DestReg, unsigned BaseReg,
92a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov                              int NumBytes, bool CanChangeCC,
93a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov                              const TargetInstrInfo &TII,
94e4ad387a5a88dae20f0f7578e55170bbc8eee2a9Jim Grosbach                              const ARMBaseRegisterInfo& MRI,
953daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov                              unsigned MIFlags = MachineInstr::NoFlags) {
963d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach    MachineFunction &MF = *MBB.getParent();
9755ad1f22b4554be3a9547fe7a8d84ce05b3d5c72Anton Korobeynikov    bool isHigh = !isARMLowRegister(DestReg) ||
9855ad1f22b4554be3a9547fe7a8d84ce05b3d5c72Anton Korobeynikov                  (BaseReg != 0 && !isARMLowRegister(BaseReg));
99a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    bool isSub = false;
100a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    // Subtract doesn't have high register version. Load the negative value
101a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    // if either base or dest register is a high register. Also, if do not
102a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    // issue sub as part of the sequence if condition register is to be
103a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    // preserved.
104a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    if (NumBytes < 0 && !isHigh && CanChangeCC) {
105a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov      isSub = true;
106a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov      NumBytes = -NumBytes;
107a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    }
108a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    unsigned LdReg = DestReg;
109a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    if (DestReg == ARM::SP) {
110a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov      assert(BaseReg == ARM::SP && "Unexpected!");
111420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper      LdReg = MF.getRegInfo().createVirtualRegister(&ARM::tGPRRegClass);
112a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    }
113a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov
114a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    if (NumBytes <= 255 && NumBytes >= 0)
115b46aaa3874d2753632c48400c66be1a10ac18d42Evan Cheng      AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg))
1163daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov        .addImm(NumBytes).setMIFlags(MIFlags);
117a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    else if (NumBytes < 0 && NumBytes >= -255) {
118b46aaa3874d2753632c48400c66be1a10ac18d42Evan Cheng      AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg))
1193daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov        .addImm(NumBytes).setMIFlags(MIFlags);
120b46aaa3874d2753632c48400c66be1a10ac18d42Evan Cheng      AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tRSB), LdReg))
1213daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov        .addReg(LdReg, RegState::Kill).setMIFlags(MIFlags);
122a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    } else
1233daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov      MRI.emitLoadConstPool(MBB, MBBI, dl, LdReg, 0, NumBytes,
1243daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov                            ARMCC::AL, 0, MIFlags);
125a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov
126a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    // Emit add / sub.
127a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    int Opc = (isSub) ? ARM::tSUBrr : (isHigh ? ARM::tADDhirr : ARM::tADDrr);
128446c428bf394b7113b0f18cbacb5e87b4efd1e14Evan Cheng    MachineInstrBuilder MIB =
129446c428bf394b7113b0f18cbacb5e87b4efd1e14Evan Cheng      BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg);
130446c428bf394b7113b0f18cbacb5e87b4efd1e14Evan Cheng    if (Opc != ARM::tADDhirr)
131b46aaa3874d2753632c48400c66be1a10ac18d42Evan Cheng      MIB = AddDefaultT1CC(MIB);
132a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    if (DestReg == ARM::SP || isSub)
133a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov      MIB.addReg(BaseReg).addReg(LdReg, RegState::Kill);
134a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    else
135a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov      MIB.addReg(LdReg).addReg(BaseReg, RegState::Kill);
136446c428bf394b7113b0f18cbacb5e87b4efd1e14Evan Cheng    AddDefaultPred(MIB);
137a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov}
138a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov
139a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov/// calcNumMI - Returns the number of instructions required to materialize
140a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov/// the specific add / sub r, c instruction.
141a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikovstatic unsigned calcNumMI(int Opc, int ExtraOpc, unsigned Bytes,
142a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov                          unsigned NumBits, unsigned Scale) {
143a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov  unsigned NumMIs = 0;
144a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov  unsigned Chunk = ((1 << NumBits) - 1) * Scale;
145a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov
146a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov  if (Opc == ARM::tADDrSPi) {
147a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes;
148a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    Bytes -= ThisVal;
149a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    NumMIs++;
150a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    NumBits = 8;
151a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    Scale = 1;  // Followed by a number of tADDi8.
152a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    Chunk = ((1 << NumBits) - 1) * Scale;
153a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov  }
154a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov
155a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov  NumMIs += Bytes / Chunk;
156a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov  if ((Bytes % Chunk) != 0)
157a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    NumMIs++;
158a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov  if (ExtraOpc)
159a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    NumMIs++;
160a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov  return NumMIs;
161a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov}
162a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov
163a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov/// emitThumbRegPlusImmediate - Emits a series of instructions to materialize
164a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov/// a destreg = basereg + immediate in Thumb code.
165e4ad387a5a88dae20f0f7578e55170bbc8eee2a9Jim Grosbachvoid llvm::emitThumbRegPlusImmediate(MachineBasicBlock &MBB,
166e4ad387a5a88dae20f0f7578e55170bbc8eee2a9Jim Grosbach                                     MachineBasicBlock::iterator &MBBI,
16757caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov                                     DebugLoc dl,
168e4ad387a5a88dae20f0f7578e55170bbc8eee2a9Jim Grosbach                                     unsigned DestReg, unsigned BaseReg,
169e4ad387a5a88dae20f0f7578e55170bbc8eee2a9Jim Grosbach                                     int NumBytes, const TargetInstrInfo &TII,
1703daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov                                     const ARMBaseRegisterInfo& MRI,
1713daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov                                     unsigned MIFlags) {
172a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov  bool isSub = NumBytes < 0;
173a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov  unsigned Bytes = (unsigned)NumBytes;
174a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov  if (isSub) Bytes = -NumBytes;
175a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov  bool isMul4 = (Bytes & 3) == 0;
176a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov  bool isTwoAddr = false;
177a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov  bool DstNotEqBase = false;
178a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov  unsigned NumBits = 1;
179a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov  unsigned Scale = 1;
180a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov  int Opc = 0;
181a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov  int ExtraOpc = 0;
182446c428bf394b7113b0f18cbacb5e87b4efd1e14Evan Cheng  bool NeedCC = false;
183a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov
184a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov  if (DestReg == BaseReg && BaseReg == ARM::SP) {
185a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    assert(isMul4 && "Thumb sp inc / dec size must be multiple of 4!");
186a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    NumBits = 7;
187a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    Scale = 4;
188a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    Opc = isSub ? ARM::tSUBspi : ARM::tADDspi;
189a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    isTwoAddr = true;
190a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov  } else if (!isSub && BaseReg == ARM::SP) {
191a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    // r1 = add sp, 403
192a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    // =>
193a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    // r1 = add sp, 100 * 4
194a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    // r1 = add r1, 3
195a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    if (!isMul4) {
196a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov      Bytes &= ~3;
197a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov      ExtraOpc = ARM::tADDi3;
198a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    }
199a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    NumBits = 8;
200a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    Scale = 4;
201a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    Opc = ARM::tADDrSPi;
202a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov  } else {
203a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    // sp = sub sp, c
204a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    // r1 = sub sp, c
205a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    // r8 = sub sp, c
206a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    if (DestReg != BaseReg)
207a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov      DstNotEqBase = true;
208a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    NumBits = 8;
209f6fe9579505be86420beea04f2c9ecb0fd7c55fdEvan Cheng    if (DestReg == ARM::SP) {
210f6fe9579505be86420beea04f2c9ecb0fd7c55fdEvan Cheng      Opc = isSub ? ARM::tSUBspi : ARM::tADDspi;
211f6fe9579505be86420beea04f2c9ecb0fd7c55fdEvan Cheng      assert(isMul4 && "Thumb sp inc / dec size must be multiple of 4!");
212f6fe9579505be86420beea04f2c9ecb0fd7c55fdEvan Cheng      NumBits = 7;
213f6fe9579505be86420beea04f2c9ecb0fd7c55fdEvan Cheng      Scale = 4;
214f6fe9579505be86420beea04f2c9ecb0fd7c55fdEvan Cheng    } else {
215f6fe9579505be86420beea04f2c9ecb0fd7c55fdEvan Cheng      Opc = isSub ? ARM::tSUBi8 : ARM::tADDi8;
216f6fe9579505be86420beea04f2c9ecb0fd7c55fdEvan Cheng      NumBits = 8;
2175b81584f7403ffdb9cc6babaaeb0411c080e0f81Jim Grosbach      NeedCC = true;
218f6fe9579505be86420beea04f2c9ecb0fd7c55fdEvan Cheng    }
219a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    isTwoAddr = true;
220a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov  }
221a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov
222a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov  unsigned NumMIs = calcNumMI(Opc, ExtraOpc, Bytes, NumBits, Scale);
223a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov  unsigned Threshold = (DestReg == ARM::SP) ? 3 : 2;
224a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov  if (NumMIs > Threshold) {
225a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    // This will expand into too many instructions. Load the immediate from a
226a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    // constpool entry.
2273daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov    emitThumbRegPlusImmInReg(MBB, MBBI, dl,
2283daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov                             DestReg, BaseReg, NumBytes, true,
2293daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov                             TII, MRI, MIFlags);
230a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    return;
231a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov  }
232a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov
233a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov  if (DstNotEqBase) {
23455ad1f22b4554be3a9547fe7a8d84ce05b3d5c72Anton Korobeynikov    if (isARMLowRegister(DestReg) && isARMLowRegister(BaseReg)) {
235a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov      // If both are low registers, emit DestReg = add BaseReg, max(Imm, 7)
236a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov      unsigned Chunk = (1 << 3) - 1;
237a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov      unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes;
238a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov      Bytes -= ThisVal;
239e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng      const MCInstrDesc &MCID = TII.get(isSub ? ARM::tSUBi3 : ARM::tADDi3);
240446c428bf394b7113b0f18cbacb5e87b4efd1e14Evan Cheng      const MachineInstrBuilder MIB =
2414372ca6fe4119d708d43d9c9ac3feafc7607952aJim Grosbach        AddDefaultT1CC(BuildMI(MBB, MBBI, dl, MCID, DestReg)
2424372ca6fe4119d708d43d9c9ac3feafc7607952aJim Grosbach                         .setMIFlags(MIFlags));
243446c428bf394b7113b0f18cbacb5e87b4efd1e14Evan Cheng      AddDefaultPred(MIB.addReg(BaseReg, RegState::Kill).addImm(ThisVal));
244a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    } else {
24563b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach      AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), DestReg)
24663b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach        .addReg(BaseReg, RegState::Kill))
2473daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov        .setMIFlags(MIFlags);
248a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    }
249a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    BaseReg = DestReg;
250a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov  }
251a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov
252a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov  unsigned Chunk = ((1 << NumBits) - 1) * Scale;
253a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov  while (Bytes) {
254a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes;
255a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    Bytes -= ThisVal;
256a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    ThisVal /= Scale;
257a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    // Build the new tADD / tSUB.
258446c428bf394b7113b0f18cbacb5e87b4efd1e14Evan Cheng    if (isTwoAddr) {
259446c428bf394b7113b0f18cbacb5e87b4efd1e14Evan Cheng      MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg);
260446c428bf394b7113b0f18cbacb5e87b4efd1e14Evan Cheng      if (NeedCC)
261b46aaa3874d2753632c48400c66be1a10ac18d42Evan Cheng        MIB = AddDefaultT1CC(MIB);
2623daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov      MIB.addReg(DestReg).addImm(ThisVal);
2635b81584f7403ffdb9cc6babaaeb0411c080e0f81Jim Grosbach      MIB = AddDefaultPred(MIB);
2643daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov      MIB.setMIFlags(MIFlags);
2658884148b8e8f19d5484e735618cf188cfa02c626Jim Grosbach    } else {
266a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov      bool isKill = BaseReg != ARM::SP;
267446c428bf394b7113b0f18cbacb5e87b4efd1e14Evan Cheng      MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg);
268446c428bf394b7113b0f18cbacb5e87b4efd1e14Evan Cheng      if (NeedCC)
269b46aaa3874d2753632c48400c66be1a10ac18d42Evan Cheng        MIB = AddDefaultT1CC(MIB);
270446c428bf394b7113b0f18cbacb5e87b4efd1e14Evan Cheng      MIB.addReg(BaseReg, getKillRegState(isKill)).addImm(ThisVal);
2715b81584f7403ffdb9cc6babaaeb0411c080e0f81Jim Grosbach      MIB = AddDefaultPred(MIB);
2723daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov      MIB.setMIFlags(MIFlags);
273a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov
2743daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov      BaseReg = DestReg;
275a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov      if (Opc == ARM::tADDrSPi) {
276a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov        // r4 = add sp, imm
277a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov        // r4 = add r4, imm
278a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov        // ...
279a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov        NumBits = 8;
280a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov        Scale = 1;
281a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov        Chunk = ((1 << NumBits) - 1) * Scale;
282a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov        Opc = isSub ? ARM::tSUBi8 : ARM::tADDi8;
2835b81584f7403ffdb9cc6babaaeb0411c080e0f81Jim Grosbach        NeedCC = isTwoAddr = true;
284a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov      }
285a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    }
286a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov  }
287a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov
288446c428bf394b7113b0f18cbacb5e87b4efd1e14Evan Cheng  if (ExtraOpc) {
289e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng    const MCInstrDesc &MCID = TII.get(ExtraOpc);
290e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng    AddDefaultPred(AddDefaultT1CC(BuildMI(MBB, MBBI, dl, MCID, DestReg))
291446c428bf394b7113b0f18cbacb5e87b4efd1e14Evan Cheng                   .addReg(DestReg, RegState::Kill)
2923daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov                   .addImm(((unsigned)NumBytes) & 3)
2933daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov                   .setMIFlags(MIFlags));
294446c428bf394b7113b0f18cbacb5e87b4efd1e14Evan Cheng  }
295a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov}
296a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov
297a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov/// emitThumbConstant - Emit a series of instructions to materialize a
298a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov/// constant.
299a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikovstatic void emitThumbConstant(MachineBasicBlock &MBB,
300a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov                              MachineBasicBlock::iterator &MBBI,
301a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov                              unsigned DestReg, int Imm,
302a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov                              const TargetInstrInfo &TII,
303b50ea5c48f8b1ce259e034ca5c16dc14af1a582cDavid Goodwin                              const Thumb1RegisterInfo& MRI,
304a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov                              DebugLoc dl) {
305a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov  bool isSub = Imm < 0;
306a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov  if (isSub) Imm = -Imm;
307a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov
308a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov  int Chunk = (1 << 8) - 1;
309a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov  int ThisVal = (Imm > Chunk) ? Chunk : Imm;
310a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov  Imm -= ThisVal;
311b46aaa3874d2753632c48400c66be1a10ac18d42Evan Cheng  AddDefaultPred(AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8),
312b46aaa3874d2753632c48400c66be1a10ac18d42Evan Cheng                                        DestReg))
313446c428bf394b7113b0f18cbacb5e87b4efd1e14Evan Cheng                 .addImm(ThisVal));
314a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov  if (Imm > 0)
31557caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov    emitThumbRegPlusImmediate(MBB, MBBI, dl, DestReg, DestReg, Imm, TII, MRI);
316446c428bf394b7113b0f18cbacb5e87b4efd1e14Evan Cheng  if (isSub) {
317e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng    const MCInstrDesc &MCID = TII.get(ARM::tRSB);
318e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng    AddDefaultPred(AddDefaultT1CC(BuildMI(MBB, MBBI, dl, MCID, DestReg))
319446c428bf394b7113b0f18cbacb5e87b4efd1e14Evan Cheng                   .addReg(DestReg, RegState::Kill));
320446c428bf394b7113b0f18cbacb5e87b4efd1e14Evan Cheng  }
321446c428bf394b7113b0f18cbacb5e87b4efd1e14Evan Cheng}
322446c428bf394b7113b0f18cbacb5e87b4efd1e14Evan Cheng
323446c428bf394b7113b0f18cbacb5e87b4efd1e14Evan Chengstatic void removeOperands(MachineInstr &MI, unsigned i) {
324446c428bf394b7113b0f18cbacb5e87b4efd1e14Evan Cheng  unsigned Op = i;
325446c428bf394b7113b0f18cbacb5e87b4efd1e14Evan Cheng  for (unsigned e = MI.getNumOperands(); i != e; ++i)
326446c428bf394b7113b0f18cbacb5e87b4efd1e14Evan Cheng    MI.RemoveOperand(Op);
327a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov}
328a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov
3297a905a82f7425d1a10b828c8bb3365b2ebc15833Bill Wendling/// convertToNonSPOpcode - Change the opcode to the non-SP version, because
3307a905a82f7425d1a10b828c8bb3365b2ebc15833Bill Wendling/// we're replacing the frame index with a non-SP register.
3317a905a82f7425d1a10b828c8bb3365b2ebc15833Bill Wendlingstatic unsigned convertToNonSPOpcode(unsigned Opcode) {
3327a905a82f7425d1a10b828c8bb3365b2ebc15833Bill Wendling  switch (Opcode) {
3337a905a82f7425d1a10b828c8bb3365b2ebc15833Bill Wendling  case ARM::tLDRspi:
3347a905a82f7425d1a10b828c8bb3365b2ebc15833Bill Wendling    return ARM::tLDRi;
3357a905a82f7425d1a10b828c8bb3365b2ebc15833Bill Wendling
3367a905a82f7425d1a10b828c8bb3365b2ebc15833Bill Wendling  case ARM::tSTRspi:
3377a905a82f7425d1a10b828c8bb3365b2ebc15833Bill Wendling    return ARM::tSTRi;
3387a905a82f7425d1a10b828c8bb3365b2ebc15833Bill Wendling  }
3397a905a82f7425d1a10b828c8bb3365b2ebc15833Bill Wendling
3407a905a82f7425d1a10b828c8bb3365b2ebc15833Bill Wendling  return Opcode;
3417a905a82f7425d1a10b828c8bb3365b2ebc15833Bill Wendling}
3427a905a82f7425d1a10b828c8bb3365b2ebc15833Bill Wendling
34374d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbachbool Thumb1RegisterInfo::
34474d7b0af58951dce2f874c600a6a48a2454b4914Jim GrosbachrewriteFrameIndex(MachineBasicBlock::iterator II, unsigned FrameRegIdx,
34574d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach                  unsigned FrameReg, int &Offset,
34674d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach                  const ARMBaseInstrInfo &TII) const {
347a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov  MachineInstr &MI = *II;
348a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov  MachineBasicBlock &MBB = *MI.getParent();
349a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov  DebugLoc dl = MI.getDebugLoc();
35037a942cd52725b1d390989a8267a764b42fcb5d3Jakob Stoklund Olesen  MachineInstrBuilder MIB(*MBB.getParent(), &MI);
351a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov  unsigned Opcode = MI.getOpcode();
352e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  const MCInstrDesc &Desc = MI.getDesc();
353a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov  unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
354a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov
355a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov  if (Opcode == ARM::tADDrSPi) {
35674d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach    Offset += MI.getOperand(FrameRegIdx+1).getImm();
357a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov
358a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    // Can't use tADDrSPi if it's based off the frame pointer.
359a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    unsigned NumBits = 0;
360a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    unsigned Scale = 1;
361a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    if (FrameReg != ARM::SP) {
362a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov      Opcode = ARM::tADDi3;
363a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov      NumBits = 3;
364a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    } else {
365a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov      NumBits = 8;
366a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov      Scale = 4;
367a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov      assert((Offset & 3) == 0 &&
368a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov             "Thumb add/sub sp, #imm immediate must be multiple of 4!");
369a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    }
370a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov
37135f0febcb66b5a50a5a750efcbefc95f7fc25c7bJakob Stoklund Olesen    unsigned PredReg;
37235f0febcb66b5a50a5a750efcbefc95f7fc25c7bJakob Stoklund Olesen    if (Offset == 0 && getInstrPredicate(&MI, PredReg) == ARMCC::AL) {
373a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov      // Turn it into a move.
3742a7b41ba4d3eb3c6003f6768dc20b28d83eac265Jim Grosbach      MI.setDesc(TII.get(ARM::tMOVr));
37574d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach      MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
3765b81584f7403ffdb9cc6babaaeb0411c080e0f81Jim Grosbach      // Remove offset
37763b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach      MI.RemoveOperand(FrameRegIdx+1);
37874d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach      return true;
379a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    }
380a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov
381a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    // Common case: small offset, fits into instruction.
382a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    unsigned Mask = (1 << NumBits) - 1;
383a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    if (((Offset / Scale) & ~Mask) == 0) {
384a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov      // Replace the FrameIndex with sp / fp
385446c428bf394b7113b0f18cbacb5e87b4efd1e14Evan Cheng      if (Opcode == ARM::tADDi3) {
3865b81584f7403ffdb9cc6babaaeb0411c080e0f81Jim Grosbach        MI.setDesc(TII.get(Opcode));
38774d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach        removeOperands(MI, FrameRegIdx);
388b46aaa3874d2753632c48400c66be1a10ac18d42Evan Cheng        AddDefaultPred(AddDefaultT1CC(MIB).addReg(FrameReg)
389f6fe9579505be86420beea04f2c9ecb0fd7c55fdEvan Cheng                       .addImm(Offset / Scale));
390446c428bf394b7113b0f18cbacb5e87b4efd1e14Evan Cheng      } else {
39174d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach        MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
39274d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach        MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset / Scale);
393446c428bf394b7113b0f18cbacb5e87b4efd1e14Evan Cheng      }
39474d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach      return true;
395a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    }
396a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov
397a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    unsigned DestReg = MI.getOperand(0).getReg();
398a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    unsigned Bytes = (Offset > 0) ? Offset : -Offset;
399a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    unsigned NumMIs = calcNumMI(Opcode, 0, Bytes, NumBits, Scale);
400a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    // MI would expand into a large number of instructions. Don't try to
401a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    // simplify the immediate.
402a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    if (NumMIs > 2) {
40357caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      emitThumbRegPlusImmediate(MBB, II, dl, DestReg, FrameReg, Offset, TII,
40457caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov                                *this);
405a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov      MBB.erase(II);
40674d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach      return true;
407a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    }
408a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov
409a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    if (Offset > 0) {
410a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov      // Translate r0 = add sp, imm to
411a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov      // r0 = add sp, 255*4
412a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov      // r0 = add r0, (imm - 255*4)
413446c428bf394b7113b0f18cbacb5e87b4efd1e14Evan Cheng      if (Opcode == ARM::tADDi3) {
41429b9d7e4ea7521be25bccdb66ecd9c9df5ed8b4bChad Rosier        MI.setDesc(TII.get(Opcode));
41574d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach        removeOperands(MI, FrameRegIdx);
416b46aaa3874d2753632c48400c66be1a10ac18d42Evan Cheng        AddDefaultPred(AddDefaultT1CC(MIB).addReg(FrameReg).addImm(Mask));
417446c428bf394b7113b0f18cbacb5e87b4efd1e14Evan Cheng      } else {
41874d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach        MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
41974d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach        MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Mask);
420446c428bf394b7113b0f18cbacb5e87b4efd1e14Evan Cheng      }
421a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov      Offset = (Offset - Mask * Scale);
42236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      MachineBasicBlock::iterator NII = std::next(II);
42357caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      emitThumbRegPlusImmediate(MBB, NII, dl, DestReg, DestReg, Offset, TII,
42457caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov                                *this);
425a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    } else {
426a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov      // Translate r0 = add sp, -imm to
4273f4f420ab7acb10221ba971543a7eed5489fb626Robert Wilhelm      // r0 = -imm (this is then translated into a series of instructions)
428a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov      // r0 = add r0, sp
429a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov      emitThumbConstant(MBB, II, DestReg, Offset, TII, *this, dl);
430bae20a6353583089224b94280a2dd69805dca247Evan Cheng
431a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov      MI.setDesc(TII.get(ARM::tADDhirr));
43274d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach      MI.getOperand(FrameRegIdx).ChangeToRegister(DestReg, false, false, true);
43374d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach      MI.getOperand(FrameRegIdx+1).ChangeToRegister(FrameReg, false);
434a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    }
43574d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach    return true;
436a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov  } else {
4377a905a82f7425d1a10b828c8bb3365b2ebc15833Bill Wendling    if (AddrMode != ARMII::AddrModeT1_s)
438c23197a26f34f559ea9797de51e187087c039c42Torok Edwin      llvm_unreachable("Unsupported addressing mode!");
4397a905a82f7425d1a10b828c8bb3365b2ebc15833Bill Wendling
4407a905a82f7425d1a10b828c8bb3365b2ebc15833Bill Wendling    unsigned ImmIdx = FrameRegIdx + 1;
4417a905a82f7425d1a10b828c8bb3365b2ebc15833Bill Wendling    int InstrOffs = MI.getOperand(ImmIdx).getImm();
4427a905a82f7425d1a10b828c8bb3365b2ebc15833Bill Wendling    unsigned NumBits = (FrameReg == ARM::SP) ? 8 : 5;
4437a905a82f7425d1a10b828c8bb3365b2ebc15833Bill Wendling    unsigned Scale = 4;
444a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov
445a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    Offset += InstrOffs * Scale;
4467a905a82f7425d1a10b828c8bb3365b2ebc15833Bill Wendling    assert((Offset & (Scale - 1)) == 0 && "Can't encode this offset!");
447a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov
448a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    // Common case: small offset, fits into instruction.
449a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    MachineOperand &ImmOp = MI.getOperand(ImmIdx);
450a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    int ImmedOffset = Offset / Scale;
451a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    unsigned Mask = (1 << NumBits) - 1;
4527a905a82f7425d1a10b828c8bb3365b2ebc15833Bill Wendling
453a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    if ((unsigned)Offset <= Mask * Scale) {
4547a905a82f7425d1a10b828c8bb3365b2ebc15833Bill Wendling      // Replace the FrameIndex with the frame register (e.g., sp).
45574d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach      MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
456a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov      ImmOp.ChangeToImmediate(ImmedOffset);
4577a905a82f7425d1a10b828c8bb3365b2ebc15833Bill Wendling
4587a905a82f7425d1a10b828c8bb3365b2ebc15833Bill Wendling      // If we're using a register where sp was stored, convert the instruction
4597a905a82f7425d1a10b828c8bb3365b2ebc15833Bill Wendling      // to the non-SP version.
4607a905a82f7425d1a10b828c8bb3365b2ebc15833Bill Wendling      unsigned NewOpc = convertToNonSPOpcode(Opcode);
4617a905a82f7425d1a10b828c8bb3365b2ebc15833Bill Wendling      if (NewOpc != Opcode && FrameReg != ARM::SP)
4627a905a82f7425d1a10b828c8bb3365b2ebc15833Bill Wendling        MI.setDesc(TII.get(NewOpc));
4637a905a82f7425d1a10b828c8bb3365b2ebc15833Bill Wendling
46474d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach      return true;
465a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    }
466a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov
4677a905a82f7425d1a10b828c8bb3365b2ebc15833Bill Wendling    NumBits = 5;
4687a905a82f7425d1a10b828c8bb3365b2ebc15833Bill Wendling    Mask = (1 << NumBits) - 1;
4697a905a82f7425d1a10b828c8bb3365b2ebc15833Bill Wendling
470a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    // If this is a thumb spill / restore, we will be using a constpool load to
471a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    // materialize the offset.
47274472b4bf963c424da04f42dffdb94c85ef964bcJim Grosbach    if (Opcode == ARM::tLDRspi || Opcode == ARM::tSTRspi) {
473a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov      ImmOp.ChangeToImmediate(0);
4747a905a82f7425d1a10b828c8bb3365b2ebc15833Bill Wendling    } else {
475a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov      // Otherwise, it didn't fit. Pull in what we can to simplify the immed.
476a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov      ImmedOffset = ImmedOffset & Mask;
477a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov      ImmOp.ChangeToImmediate(ImmedOffset);
4787a905a82f7425d1a10b828c8bb3365b2ebc15833Bill Wendling      Offset &= ~(Mask * Scale);
479a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    }
480a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov  }
4817a905a82f7425d1a10b828c8bb3365b2ebc15833Bill Wendling
48274d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach  return Offset == 0;
48374d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach}
48474d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach
48536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid Thumb1RegisterInfo::resolveFrameIndex(MachineInstr &MI, unsigned BaseReg,
48636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                           int64_t Offset) const {
48757148c166ab232191098492633c924fad9c44ef3Bill Wendling  const ARMBaseInstrInfo &TII =
48857148c166ab232191098492633c924fad9c44ef3Bill Wendling    *static_cast<const ARMBaseInstrInfo*>(
48957148c166ab232191098492633c924fad9c44ef3Bill Wendling      MI.getParent()->getParent()->getTarget().getInstrInfo());
49074d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach  int Off = Offset; // ARM doesn't need the general 64-bit offsets
49174d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach  unsigned i = 0;
49274d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach
49374d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach  while (!MI.getOperand(i).isFI()) {
49474d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach    ++i;
49574d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach    assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
49674d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach  }
4971f6a329f79b3568d379142f921f59c4143ddaa14Duncan Sands  bool Done = rewriteFrameIndex(MI, i, BaseReg, Off, TII);
49874d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach  assert (Done && "Unable to resolve frame index!");
4991f6a329f79b3568d379142f921f59c4143ddaa14Duncan Sands  (void)Done;
50074d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach}
50174d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach
50274d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach/// saveScavengerRegister - Spill the register so it can be used by the
50374d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach/// register scavenger. Return true.
50474d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbachbool
50574d7b0af58951dce2f874c600a6a48a2454b4914Jim GrosbachThumb1RegisterInfo::saveScavengerRegister(MachineBasicBlock &MBB,
50674d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach                                          MachineBasicBlock::iterator I,
50774d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach                                          MachineBasicBlock::iterator &UseMI,
50874d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach                                          const TargetRegisterClass *RC,
50974d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach                                          unsigned Reg) const {
51074d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach  // Thumb1 can't use the emergency spill slot on the stack because
51174d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach  // ldr/str immediate offsets must be positive, and if we're referencing
51274d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach  // off the frame pointer (if, for example, there are alloca() calls in
51374d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach  // the function, the offset will be negative. Use R12 instead since that's
51474d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach  // a call clobbered register that we know won't be used in Thumb1 mode.
51557148c166ab232191098492633c924fad9c44ef3Bill Wendling  const TargetInstrInfo &TII = *MBB.getParent()->getTarget().getInstrInfo();
51674d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach  DebugLoc DL;
5172a7b41ba4d3eb3c6003f6768dc20b28d83eac265Jim Grosbach  AddDefaultPred(BuildMI(MBB, I, DL, TII.get(ARM::tMOVr))
51863b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach    .addReg(ARM::R12, RegState::Define)
51963b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach    .addReg(Reg, RegState::Kill));
52074d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach
52174d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach  // The UseMI is where we would like to restore the register. If there's
52274d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach  // interference with R12 before then, however, we'll need to restore it
52374d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach  // before that instead and adjust the UseMI.
52474d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach  bool done = false;
52574d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach  for (MachineBasicBlock::iterator II = I; !done && II != UseMI ; ++II) {
52674d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach    if (II->isDebugValue())
52774d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach      continue;
52874d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach    // If this instruction affects R12, adjust our restore point.
52974d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach    for (unsigned i = 0, e = II->getNumOperands(); i != e; ++i) {
53074d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach      const MachineOperand &MO = II->getOperand(i);
531b24b820bd7ddfe118141422f4d0cf378b2c9a6fdJakob Stoklund Olesen      if (MO.isRegMask() && MO.clobbersPhysReg(ARM::R12)) {
532b24b820bd7ddfe118141422f4d0cf378b2c9a6fdJakob Stoklund Olesen        UseMI = II;
533b24b820bd7ddfe118141422f4d0cf378b2c9a6fdJakob Stoklund Olesen        done = true;
534b24b820bd7ddfe118141422f4d0cf378b2c9a6fdJakob Stoklund Olesen        break;
535b24b820bd7ddfe118141422f4d0cf378b2c9a6fdJakob Stoklund Olesen      }
53674d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach      if (!MO.isReg() || MO.isUndef() || !MO.getReg() ||
53774d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach          TargetRegisterInfo::isVirtualRegister(MO.getReg()))
53874d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach        continue;
53974d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach      if (MO.getReg() == ARM::R12) {
54074d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach        UseMI = II;
54174d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach        done = true;
54274d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach        break;
54374d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach      }
54474d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach    }
54574d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach  }
54674d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach  // Restore the register from R12
5472a7b41ba4d3eb3c6003f6768dc20b28d83eac265Jim Grosbach  AddDefaultPred(BuildMI(MBB, UseMI, DL, TII.get(ARM::tMOVr)).
54863b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach    addReg(Reg, RegState::Define).addReg(ARM::R12, RegState::Kill));
54974d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach
55074d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach  return true;
55174d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach}
55274d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach
553fcb4a8ead3cd8d9540d5eaa448af5d14a0ee341aJim Grosbachvoid
55474d7b0af58951dce2f874c600a6a48a2454b4914Jim GrosbachThumb1RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
555108fb3202af6f500073cdbb7be32c25d7a273a2eChad Rosier                                        int SPAdj, unsigned FIOperandNum,
556108fb3202af6f500073cdbb7be32c25d7a273a2eChad Rosier                                        RegScavenger *RS) const {
55774d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach  unsigned VReg = 0;
55874d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach  MachineInstr &MI = *II;
55974d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach  MachineBasicBlock &MBB = *MI.getParent();
56074d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach  MachineFunction &MF = *MBB.getParent();
56157148c166ab232191098492633c924fad9c44ef3Bill Wendling  const ARMBaseInstrInfo &TII =
56257148c166ab232191098492633c924fad9c44ef3Bill Wendling    *static_cast<const ARMBaseInstrInfo*>(MF.getTarget().getInstrInfo());
56374d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
56474d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach  DebugLoc dl = MI.getDebugLoc();
56537a942cd52725b1d390989a8267a764b42fcb5d3Jakob Stoklund Olesen  MachineInstrBuilder MIB(*MBB.getParent(), &MI);
56674d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach
56774d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach  unsigned FrameReg = ARM::SP;
568108fb3202af6f500073cdbb7be32c25d7a273a2eChad Rosier  int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
56974d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach  int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) +
57074d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach               MF.getFrameInfo()->getStackSize() + SPAdj;
57174d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach
572e53abc20724ddde4e91467671328b531361a734fTim Northover  if (MF.getFrameInfo()->hasVarSizedObjects()) {
57316c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov    assert(SPAdj == 0 && MF.getTarget().getFrameLowering()->hasFP(MF) &&
5747920d96964d707a3af85332c98d95b2fabc3d5c9Benjamin Kramer           "Unexpected");
57574d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach    // There are alloca()'s in this function, must reference off the frame
57665482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach    // pointer or base pointer instead.
57765482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach    if (!hasBasePointer(MF)) {
57865482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach      FrameReg = getFrameRegister(MF);
57965482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach      Offset -= AFI->getFramePtrSpillOffset();
58065482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach    } else
58165482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach      FrameReg = BasePtr;
58274d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach  }
58374d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach
5840f9d07fb2526c0acdf7ad9fa6e9c1a97a746c0e9Jakob Stoklund Olesen  // PEI::scavengeFrameVirtualRegs() cannot accurately track SPAdj because the
5850f9d07fb2526c0acdf7ad9fa6e9c1a97a746c0e9Jakob Stoklund Olesen  // call frame setup/destroy instructions have already been eliminated.  That
5860f9d07fb2526c0acdf7ad9fa6e9c1a97a746c0e9Jakob Stoklund Olesen  // means the stack pointer cannot be used to access the emergency spill slot
5870f9d07fb2526c0acdf7ad9fa6e9c1a97a746c0e9Jakob Stoklund Olesen  // when !hasReservedCallFrame().
5880f9d07fb2526c0acdf7ad9fa6e9c1a97a746c0e9Jakob Stoklund Olesen#ifndef NDEBUG
589dc3beb90178fc316f63790812b22201884eaa017Hal Finkel  if (RS && FrameReg == ARM::SP && RS->isScavengingFrameIndex(FrameIndex)){
5900f9d07fb2526c0acdf7ad9fa6e9c1a97a746c0e9Jakob Stoklund Olesen    assert(MF.getTarget().getFrameLowering()->hasReservedCallFrame(MF) &&
5910f9d07fb2526c0acdf7ad9fa6e9c1a97a746c0e9Jakob Stoklund Olesen           "Cannot use SP to access the emergency spill slot in "
5920f9d07fb2526c0acdf7ad9fa6e9c1a97a746c0e9Jakob Stoklund Olesen           "functions without a reserved call frame");
5930f9d07fb2526c0acdf7ad9fa6e9c1a97a746c0e9Jakob Stoklund Olesen    assert(!MF.getFrameInfo()->hasVarSizedObjects() &&
5940f9d07fb2526c0acdf7ad9fa6e9c1a97a746c0e9Jakob Stoklund Olesen           "Cannot use SP to access the emergency spill slot in "
5950f9d07fb2526c0acdf7ad9fa6e9c1a97a746c0e9Jakob Stoklund Olesen           "functions with variable sized frame objects");
5960f9d07fb2526c0acdf7ad9fa6e9c1a97a746c0e9Jakob Stoklund Olesen  }
5970f9d07fb2526c0acdf7ad9fa6e9c1a97a746c0e9Jakob Stoklund Olesen#endif // NDEBUG
5980f9d07fb2526c0acdf7ad9fa6e9c1a97a746c0e9Jakob Stoklund Olesen
59974d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach  // Special handling of dbg_value instructions.
60074d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach  if (MI.isDebugValue()) {
601108fb3202af6f500073cdbb7be32c25d7a273a2eChad Rosier    MI.getOperand(FIOperandNum).  ChangeToRegister(FrameReg, false /*isDef*/);
602108fb3202af6f500073cdbb7be32c25d7a273a2eChad Rosier    MI.getOperand(FIOperandNum+1).ChangeToImmediate(Offset);
603fcb4a8ead3cd8d9540d5eaa448af5d14a0ee341aJim Grosbach    return;
60474d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach  }
60574d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach
60674d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach  // Modify MI as necessary to handle as much of 'Offset' as possible
60774d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach  assert(AFI->isThumbFunction() &&
60874d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach         "This eliminateFrameIndex only supports Thumb1!");
609108fb3202af6f500073cdbb7be32c25d7a273a2eChad Rosier  if (rewriteFrameIndex(MI, FIOperandNum, FrameReg, Offset, TII))
610fcb4a8ead3cd8d9540d5eaa448af5d14a0ee341aJim Grosbach    return;
611a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov
612a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov  // If we get here, the immediate doesn't fit into the instruction.  We folded
613a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov  // as much as possible above, handle the rest, providing a register that is
614a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov  // SP+LargeImm.
615a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov  assert(Offset && "This code isn't needed if offset already handled!");
616a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov
61774d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach  unsigned Opcode = MI.getOpcode();
61874d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach
619446c428bf394b7113b0f18cbacb5e87b4efd1e14Evan Cheng  // Remove predicate first.
620446c428bf394b7113b0f18cbacb5e87b4efd1e14Evan Cheng  int PIdx = MI.findFirstPredOperandIdx();
621446c428bf394b7113b0f18cbacb5e87b4efd1e14Evan Cheng  if (PIdx != -1)
622446c428bf394b7113b0f18cbacb5e87b4efd1e14Evan Cheng    removeOperands(MI, PIdx);
623446c428bf394b7113b0f18cbacb5e87b4efd1e14Evan Cheng
6245a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng  if (MI.mayLoad()) {
625a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    // Use the destination register to materialize sp + offset.
626a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    unsigned TmpReg = MI.getOperand(0).getReg();
627a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    bool UseRR = false;
62874472b4bf963c424da04f42dffdb94c85ef964bcJim Grosbach    if (Opcode == ARM::tLDRspi) {
629a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov      if (FrameReg == ARM::SP)
6303daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov        emitThumbRegPlusImmInReg(MBB, II, dl, TmpReg, FrameReg,
6313daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov                                 Offset, false, TII, *this);
632a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov      else {
633378445303b10b092a898a75131141a8259cff50bEvan Cheng        emitLoadConstPool(MBB, II, dl, TmpReg, 0, Offset);
634a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov        UseRR = true;
635a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov      }
636446c428bf394b7113b0f18cbacb5e87b4efd1e14Evan Cheng    } else {
63757caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov      emitThumbRegPlusImmediate(MBB, II, dl, TmpReg, FrameReg, Offset, TII,
63857caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov                                *this);
639446c428bf394b7113b0f18cbacb5e87b4efd1e14Evan Cheng    }
640446c428bf394b7113b0f18cbacb5e87b4efd1e14Evan Cheng
6416e90ce21cc2b0627ee9219e3fb0cf808f2b73328Eric Christopher    MI.setDesc(TII.get(UseRR ? ARM::tLDRr : ARM::tLDRi));
642108fb3202af6f500073cdbb7be32c25d7a273a2eChad Rosier    MI.getOperand(FIOperandNum).ChangeToRegister(TmpReg, false, false, true);
643a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov    if (UseRR)
6445f3e2be7c941b26ac865fa00c3f314bcd1e6cec8Jim Grosbach      // Use [reg, reg] addrmode. Replace the immediate operand w/ the frame
6455f3e2be7c941b26ac865fa00c3f314bcd1e6cec8Jim Grosbach      // register. The offset is already handled in the vreg value.
646108fb3202af6f500073cdbb7be32c25d7a273a2eChad Rosier      MI.getOperand(FIOperandNum+1).ChangeToRegister(FrameReg, false, false,
647108fb3202af6f500073cdbb7be32c25d7a273a2eChad Rosier                                                     false);
6485a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng  } else if (MI.mayStore()) {
649420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper      VReg = MF.getRegInfo().createVirtualRegister(&ARM::tGPRRegClass);
6503d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach      bool UseRR = false;
651b58f498f7502e7e1833decbbbb4df771367c7341Jim Grosbach
65274472b4bf963c424da04f42dffdb94c85ef964bcJim Grosbach      if (Opcode == ARM::tSTRspi) {
6533d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach        if (FrameReg == ARM::SP)
6543daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov          emitThumbRegPlusImmInReg(MBB, II, dl, VReg, FrameReg,
6553daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov                                   Offset, false, TII, *this);
6563d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach        else {
657b58f498f7502e7e1833decbbbb4df771367c7341Jim Grosbach          emitLoadConstPool(MBB, II, dl, VReg, 0, Offset);
6583d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach          UseRR = true;
6593d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach        }
6603d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach      } else
66157caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov        emitThumbRegPlusImmediate(MBB, II, dl, VReg, FrameReg, Offset, TII,
66257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov                                  *this);
6636e90ce21cc2b0627ee9219e3fb0cf808f2b73328Eric Christopher      MI.setDesc(TII.get(UseRR ? ARM::tSTRr : ARM::tSTRi));
664108fb3202af6f500073cdbb7be32c25d7a273a2eChad Rosier      MI.getOperand(FIOperandNum).ChangeToRegister(VReg, false, false, true);
6655f3e2be7c941b26ac865fa00c3f314bcd1e6cec8Jim Grosbach      if (UseRR)
6665f3e2be7c941b26ac865fa00c3f314bcd1e6cec8Jim Grosbach        // Use [reg, reg] addrmode. Replace the immediate operand w/ the frame
6675f3e2be7c941b26ac865fa00c3f314bcd1e6cec8Jim Grosbach        // register. The offset is already handled in the vreg value.
668108fb3202af6f500073cdbb7be32c25d7a273a2eChad Rosier        MI.getOperand(FIOperandNum+1).ChangeToRegister(FrameReg, false, false,
669108fb3202af6f500073cdbb7be32c25d7a273a2eChad Rosier                                                       false);
670f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  } else {
671bc2198133a1836598b54b943420748e75d5dea94Craig Topper    llvm_unreachable("Unexpected opcode!");
672f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  }
673446c428bf394b7113b0f18cbacb5e87b4efd1e14Evan Cheng
674446c428bf394b7113b0f18cbacb5e87b4efd1e14Evan Cheng  // Add predicate back if it's needed.
67537a942cd52725b1d390989a8267a764b42fcb5d3Jakob Stoklund Olesen  if (MI.isPredicable())
676446c428bf394b7113b0f18cbacb5e87b4efd1e14Evan Cheng    AddDefaultPred(MIB);
677a98cbc554ca2cd40426e7c3ff8d1467da32e195dAnton Korobeynikov}
678