ARMBaseRegisterInfo.cpp revision 055a8127c9ffee287807fe7cc1b115d0f40162b0
131d157ae1ac2cd9c787dc3c1d28e64c682803844Jia Liu//===-- ARMBaseRegisterInfo.cpp - ARM Register Information ----------------===//
2c140c4803dc3e10e08138670829bc0494986abe9David Goodwin//
3c140c4803dc3e10e08138670829bc0494986abe9David Goodwin//                     The LLVM Compiler Infrastructure
4c140c4803dc3e10e08138670829bc0494986abe9David Goodwin//
5c140c4803dc3e10e08138670829bc0494986abe9David Goodwin// This file is distributed under the University of Illinois Open Source
6c140c4803dc3e10e08138670829bc0494986abe9David Goodwin// License. See LICENSE.TXT for details.
7c140c4803dc3e10e08138670829bc0494986abe9David Goodwin//
8c140c4803dc3e10e08138670829bc0494986abe9David Goodwin//===----------------------------------------------------------------------===//
9c140c4803dc3e10e08138670829bc0494986abe9David Goodwin//
10c140c4803dc3e10e08138670829bc0494986abe9David Goodwin// This file contains the base ARM implementation of TargetRegisterInfo class.
11c140c4803dc3e10e08138670829bc0494986abe9David Goodwin//
12c140c4803dc3e10e08138670829bc0494986abe9David Goodwin//===----------------------------------------------------------------------===//
13c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
14c1f6f42049696e7357fb4837e1b25dabbaed3fe6Craig Topper#include "ARMBaseRegisterInfo.h"
15c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "ARM.h"
16db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin#include "ARMBaseInstrInfo.h"
1716c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov#include "ARMFrameLowering.h"
18c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "ARMInstrInfo.h"
19c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "ARMMachineFunctionInfo.h"
20c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "ARMSubtarget.h"
21ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMAddressingModes.h"
22c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "llvm/Constants.h"
23c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "llvm/DerivedTypes.h"
249adc0abad3c3ed40a268ccbcee0c74cb9e1359feOwen Anderson#include "llvm/Function.h"
259adc0abad3c3ed40a268ccbcee0c74cb9e1359feOwen Anderson#include "llvm/LLVMContext.h"
26c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "llvm/CodeGen/MachineConstantPool.h"
27c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "llvm/CodeGen/MachineFrameInfo.h"
28c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "llvm/CodeGen/MachineFunction.h"
29c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "llvm/CodeGen/MachineInstrBuilder.h"
30c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "llvm/CodeGen/MachineRegisterInfo.h"
31c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "llvm/CodeGen/RegisterScavenging.h"
323dab2778571b5bb00b35a0adcb7011dc85158bebJim Grosbach#include "llvm/Support/Debug.h"
33ab7c09b6b6f4516a631fd6788918c237c83939afTorok Edwin#include "llvm/Support/ErrorHandling.h"
34dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#include "llvm/Support/raw_ostream.h"
3516c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov#include "llvm/Target/TargetFrameLowering.h"
36c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "llvm/Target/TargetMachine.h"
37c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "llvm/Target/TargetOptions.h"
38c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "llvm/ADT/BitVector.h"
39c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "llvm/ADT/SmallVector.h"
4018ed9c9a2bd7f1f56129495b499264c58b5cc4f4Jim Grosbach#include "llvm/Support/CommandLine.h"
4173f50d9bc3bd46cc0abeba9bb0d46977ba1aea42Evan Cheng
4273f50d9bc3bd46cc0abeba9bb0d46977ba1aea42Evan Cheng#define GET_REGINFO_TARGET_DESC
43a347f85dbeee37a7f2bb68df1a7d4cdfbb7b576dEvan Cheng#include "ARMGenRegisterInfo.inc"
44c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
451b4886dd00578038c0ca70b3bab97382b89def26Evan Chengusing namespace llvm;
461b4886dd00578038c0ca70b3bab97382b89def26Evan Cheng
47a273442891ae20fd8192526132e3819ea9e5eda9Jim Grosbachstatic cl::opt<bool>
483197380143cdc18837722129ac888528b9fbfc2bJim GrosbachForceAllBaseRegAlloc("arm-force-base-reg-alloc", cl::Hidden, cl::init(false),
49cd59dc5e81eb080cd9b61f5a7e7d9f3eec206d8cJim Grosbach          cl::desc("Force use of virtual base registers for stack load/store"));
50a273442891ae20fd8192526132e3819ea9e5eda9Jim Grosbachstatic cl::opt<bool>
51ae47c6d69e2e34bc558a302586cbc3f27a6d7334Jim GrosbachEnableLocalStackAlloc("enable-local-stack-alloc", cl::init(true), cl::Hidden,
52a273442891ae20fd8192526132e3819ea9e5eda9Jim Grosbach          cl::desc("Enable pre-regalloc stack frame index allocation"));
5365482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbachstatic cl::opt<bool>
54d0bd76b0fb27830f18e15e3d73f2e383ff1c59f1Jim GrosbachEnableBasePointer("arm-use-base-pointer", cl::Hidden, cl::init(true),
5565482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach          cl::desc("Enable use of a base pointer for complex stack frames"));
5665482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach
57db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid GoodwinARMBaseRegisterInfo::ARMBaseRegisterInfo(const ARMBaseInstrInfo &tii,
58c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                                         const ARMSubtarget &sti)
590e6a052331f674dd70e28af41f654a7874405eabEvan Cheng  : ARMGenRegisterInfo(ARM::LR), TII(tii), STI(sti),
6065482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach    FramePtr((STI.isTargetDarwin() || STI.isThumb()) ? ARM::R7 : ARM::R11),
6165482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach    BasePtr(ARM::R6) {
62c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
63c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
64015f228861ef9b337366f92f637d4e8d624bb006Craig Topperconst uint16_t*
65c140c4803dc3e10e08138670829bc0494986abe9David GoodwinARMBaseRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
663ee7d15284f188672e9e429e9e5cf7b870698677Jakob Stoklund Olesen  return (STI.isTargetIOS()) ? CSR_iOS_SaveList : CSR_AAPCS_SaveList;
673ee7d15284f188672e9e429e9e5cf7b870698677Jakob Stoklund Olesen}
68c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
693ee7d15284f188672e9e429e9e5cf7b870698677Jakob Stoklund Olesenconst uint32_t*
703ee7d15284f188672e9e429e9e5cf7b870698677Jakob Stoklund OlesenARMBaseRegisterInfo::getCallPreservedMask(CallingConv::ID) const {
713ee7d15284f188672e9e429e9e5cf7b870698677Jakob Stoklund Olesen  return (STI.isTargetIOS()) ? CSR_iOS_RegMask : CSR_AAPCS_RegMask;
72c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
73c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
749631864688c593711f82bb8d21f8b724c628d786Jim GrosbachBitVector ARMBaseRegisterInfo::
759631864688c593711f82bb8d21f8b724c628d786Jim GrosbachgetReservedRegs(const MachineFunction &MF) const {
7616c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
77d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov
787a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner  // FIXME: avoid re-calculating this every time.
79c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  BitVector Reserved(getNumRegs());
80c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  Reserved.set(ARM::SP);
81c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  Reserved.set(ARM::PC);
824f92b5e6163b16d63eb63269c2aec670b55ea19aLang Hames  Reserved.set(ARM::FPSCR);
83d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  if (TFI->hasFP(MF))
84c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    Reserved.set(FramePtr);
8565482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach  if (hasBasePointer(MF))
8665482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach    Reserved.set(BasePtr);
87c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // Some targets reserve R9.
88c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  if (STI.isR9Reserved())
89c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    Reserved.set(ARM::R9);
903b6434e360315849a65b1ac85e16d160131a77a4Jakob Stoklund Olesen  // Reserve D16-D31 if the subtarget doesn't support them.
913b6434e360315849a65b1ac85e16d160131a77a4Jakob Stoklund Olesen  if (!STI.hasVFP3() || STI.hasD16()) {
923b6434e360315849a65b1ac85e16d160131a77a4Jakob Stoklund Olesen    assert(ARM::D31 == ARM::D16 + 15);
933b6434e360315849a65b1ac85e16d160131a77a4Jakob Stoklund Olesen    for (unsigned i = 0; i != 16; ++i)
943b6434e360315849a65b1ac85e16d160131a77a4Jakob Stoklund Olesen      Reserved.set(ARM::D16 + i);
953b6434e360315849a65b1ac85e16d160131a77a4Jakob Stoklund Olesen  }
96c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  return Reserved;
97c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
98c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
992cfd52c507bd5790457a171eb9bcb39019cc6860Chris Lattnerbool ARMBaseRegisterInfo::isReservedReg(const MachineFunction &MF,
1002cfd52c507bd5790457a171eb9bcb39019cc6860Chris Lattner                                        unsigned Reg) const {
10116c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
102d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov
103c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  switch (Reg) {
104c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  default: break;
105c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::SP:
106c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::PC:
107c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return true;
10865482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach  case ARM::R6:
10965482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach    if (hasBasePointer(MF))
11065482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach      return true;
11165482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach    break;
112c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::R7:
113c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::R11:
114d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov    if (FramePtr == Reg && TFI->hasFP(MF))
115c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      return true;
116c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    break;
117c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::R9:
118c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return STI.isR9Reserved();
119c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  }
120c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
121c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  return false;
122c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
123c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
124b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Chengbool
12591a74da036d3a9442953ae1de3e797a50da4ccf0Bob WilsonARMBaseRegisterInfo::canCombineSubRegIndices(const TargetRegisterClass *RC,
126b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng                                          SmallVectorImpl<unsigned> &SubIndices,
127b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng                                          unsigned &NewSubIdx) const {
128b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng
129b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng  unsigned Size = RC->getSize() * 8;
130b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng  if (Size < 6)
131b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng    return 0;
132b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng
133b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng  NewSubIdx = 0;  // Whole register.
134b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng  unsigned NumRegs = SubIndices.size();
135b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng  if (NumRegs == 8) {
136b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng    // 8 D registers -> 1 QQQQ register.
137b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng    return (Size == 512 &&
138558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen            SubIndices[0] == ARM::dsub_0 &&
139558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen            SubIndices[1] == ARM::dsub_1 &&
140558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen            SubIndices[2] == ARM::dsub_2 &&
141558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen            SubIndices[3] == ARM::dsub_3 &&
142558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen            SubIndices[4] == ARM::dsub_4 &&
143558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen            SubIndices[5] == ARM::dsub_5 &&
144558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen            SubIndices[6] == ARM::dsub_6 &&
145558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen            SubIndices[7] == ARM::dsub_7);
146b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng  } else if (NumRegs == 4) {
147558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen    if (SubIndices[0] == ARM::qsub_0) {
148b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng      // 4 Q registers -> 1 QQQQ register.
149b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng      return (Size == 512 &&
150558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen              SubIndices[1] == ARM::qsub_1 &&
151558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen              SubIndices[2] == ARM::qsub_2 &&
152558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen              SubIndices[3] == ARM::qsub_3);
153558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen    } else if (SubIndices[0] == ARM::dsub_0) {
154b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng      // 4 D registers -> 1 QQ register.
155b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng      if (Size >= 256 &&
156558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen          SubIndices[1] == ARM::dsub_1 &&
157558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen          SubIndices[2] == ARM::dsub_2 &&
158558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen          SubIndices[3] == ARM::dsub_3) {
159b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng        if (Size == 512)
160558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen          NewSubIdx = ARM::qqsub_0;
161b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng        return true;
162b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng      }
163558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen    } else if (SubIndices[0] == ARM::dsub_4) {
164b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng      // 4 D registers -> 1 QQ register (2nd).
165b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng      if (Size == 512 &&
166558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen          SubIndices[1] == ARM::dsub_5 &&
167558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen          SubIndices[2] == ARM::dsub_6 &&
168558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen          SubIndices[3] == ARM::dsub_7) {
169558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen        NewSubIdx = ARM::qqsub_1;
170b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng        return true;
171b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng      }
172558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen    } else if (SubIndices[0] == ARM::ssub_0) {
173b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng      // 4 S registers -> 1 Q register.
174b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng      if (Size >= 128 &&
175558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen          SubIndices[1] == ARM::ssub_1 &&
176558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen          SubIndices[2] == ARM::ssub_2 &&
177558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen          SubIndices[3] == ARM::ssub_3) {
178b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng        if (Size >= 256)
179558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen          NewSubIdx = ARM::qsub_0;
180b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng        return true;
181b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng      }
182b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng    }
183b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng  } else if (NumRegs == 2) {
184558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen    if (SubIndices[0] == ARM::qsub_0) {
185b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng      // 2 Q registers -> 1 QQ register.
186558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen      if (Size >= 256 && SubIndices[1] == ARM::qsub_1) {
187b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng        if (Size == 512)
188558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen          NewSubIdx = ARM::qqsub_0;
189b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng        return true;
190b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng      }
191558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen    } else if (SubIndices[0] == ARM::qsub_2) {
192b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng      // 2 Q registers -> 1 QQ register (2nd).
193558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen      if (Size == 512 && SubIndices[1] == ARM::qsub_3) {
194558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen        NewSubIdx = ARM::qqsub_1;
195b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng        return true;
196b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng      }
197558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen    } else if (SubIndices[0] == ARM::dsub_0) {
198b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng      // 2 D registers -> 1 Q register.
199558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen      if (Size >= 128 && SubIndices[1] == ARM::dsub_1) {
200b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng        if (Size >= 256)
201558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen          NewSubIdx = ARM::qsub_0;
202b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng        return true;
203b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng      }
204558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen    } else if (SubIndices[0] == ARM::dsub_2) {
205b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng      // 2 D registers -> 1 Q register (2nd).
206558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen      if (Size >= 256 && SubIndices[1] == ARM::dsub_3) {
207558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen        NewSubIdx = ARM::qsub_1;
208b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng        return true;
209b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng      }
210558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen    } else if (SubIndices[0] == ARM::dsub_4) {
211b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng      // 2 D registers -> 1 Q register (3rd).
212558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen      if (Size == 512 && SubIndices[1] == ARM::dsub_5) {
213558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen        NewSubIdx = ARM::qsub_2;
214b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng        return true;
215b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng      }
216558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen    } else if (SubIndices[0] == ARM::dsub_6) {
217b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng      // 2 D registers -> 1 Q register (3rd).
218558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen      if (Size == 512 && SubIndices[1] == ARM::dsub_7) {
219558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen        NewSubIdx = ARM::qsub_3;
220b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng        return true;
221b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng      }
222558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen    } else if (SubIndices[0] == ARM::ssub_0) {
223b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng      // 2 S registers -> 1 D register.
224558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen      if (SubIndices[1] == ARM::ssub_1) {
225b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng        if (Size >= 128)
226558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen          NewSubIdx = ARM::dsub_0;
227b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng        return true;
228b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng      }
229558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen    } else if (SubIndices[0] == ARM::ssub_2) {
230b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng      // 2 S registers -> 1 D register (2nd).
231558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen      if (Size >= 128 && SubIndices[1] == ARM::ssub_3) {
232558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen        NewSubIdx = ARM::dsub_1;
233b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng        return true;
234b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng      }
235b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng    }
236b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng  }
237b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng  return false;
238b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng}
239b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng
240c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesenconst TargetRegisterClass*
241c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund OlesenARMBaseRegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC)
242c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesen                                                                         const {
243c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesen  const TargetRegisterClass *Super = RC;
244c8e2bb68bbc4a71cc10084c8f89565b9f05e12efJakob Stoklund Olesen  TargetRegisterClass::sc_iterator I = RC->getSuperClasses();
245c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesen  do {
246c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesen    switch (Super->getID()) {
247c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesen    case ARM::GPRRegClassID:
248c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesen    case ARM::SPRRegClassID:
249c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesen    case ARM::DPRRegClassID:
250c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesen    case ARM::QPRRegClassID:
251c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesen    case ARM::QQPRRegClassID:
252c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesen    case ARM::QQQQPRRegClassID:
253c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesen      return Super;
254c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesen    }
255c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesen    Super = *I++;
256c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesen  } while (Super);
257c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesen  return RC;
258c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesen}
259b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng
2604f54c1293af174a8002db20faf7b4f82ba4e8514Evan Chengconst TargetRegisterClass *
2612cfd52c507bd5790457a171eb9bcb39019cc6860Chris LattnerARMBaseRegisterInfo::getPointerRegClass(unsigned Kind) const {
262e11a8f565c6a019ddc54667227be9c4d8f117473Jim Grosbach  return ARM::GPRRegisterClass;
263c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
264be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarich
265342e3161d9dd4fa485b47788aa0266f9c91c3832Evan Chengconst TargetRegisterClass *
266342e3161d9dd4fa485b47788aa0266f9c91c3832Evan ChengARMBaseRegisterInfo::getCrossCopyRegClass(const TargetRegisterClass *RC) const {
267342e3161d9dd4fa485b47788aa0266f9c91c3832Evan Cheng  if (RC == &ARM::CCRRegClass)
268342e3161d9dd4fa485b47788aa0266f9c91c3832Evan Cheng    return 0;  // Can't copy CCR registers.
269342e3161d9dd4fa485b47788aa0266f9c91c3832Evan Cheng  return RC;
270342e3161d9dd4fa485b47788aa0266f9c91c3832Evan Cheng}
271342e3161d9dd4fa485b47788aa0266f9c91c3832Evan Cheng
272be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarichunsigned
273be2119e8e2bc7006cfd638a24367acbfda625d16Cameron ZwarichARMBaseRegisterInfo::getRegPressureLimit(const TargetRegisterClass *RC,
274be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarich                                         MachineFunction &MF) const {
275be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarich  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
276be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarich
277be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarich  switch (RC->getID()) {
278be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarich  default:
279be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarich    return 0;
280be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarich  case ARM::tGPRRegClassID:
281be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarich    return TFI->hasFP(MF) ? 4 : 5;
282be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarich  case ARM::GPRRegClassID: {
283be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarich    unsigned FP = TFI->hasFP(MF) ? 1 : 0;
284be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarich    return 10 - FP - (STI.isR9Reserved() ? 1 : 0);
285be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarich  }
286be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarich  case ARM::SPRRegClassID:  // Currently not used as 'rep' register class.
287be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarich  case ARM::DPRRegClassID:
288be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarich    return 32 - 10;
289be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarich  }
290be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarich}
291c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
292dd5a8471526ceadf9bceb1a1221299b3db49c33aJakob Stoklund Olesen/// getRawAllocationOrder - Returns the register allocation order for a
293dd5a8471526ceadf9bceb1a1221299b3db49c33aJakob Stoklund Olesen/// specified register class with a target-dependent hint.
294b6632ba380cf624e60fe16b03d6e21b05dd07724Craig TopperArrayRef<uint16_t>
295dd5a8471526ceadf9bceb1a1221299b3db49c33aJakob Stoklund OlesenARMBaseRegisterInfo::getRawAllocationOrder(const TargetRegisterClass *RC,
296dd5a8471526ceadf9bceb1a1221299b3db49c33aJakob Stoklund Olesen                                           unsigned HintType, unsigned HintReg,
297dd5a8471526ceadf9bceb1a1221299b3db49c33aJakob Stoklund Olesen                                           const MachineFunction &MF) const {
29816c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
299c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // Alternative register allocation orders when favoring even / odd registers
300c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // of register pairs.
301c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
302c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // No FP, R9 is available.
303b6632ba380cf624e60fe16b03d6e21b05dd07724Craig Topper  static const uint16_t GPREven1[] = {
304c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R0, ARM::R2, ARM::R4, ARM::R6, ARM::R8, ARM::R10,
305c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R1, ARM::R3, ARM::R12,ARM::LR, ARM::R5, ARM::R7,
306c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R9, ARM::R11
307c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
308b6632ba380cf624e60fe16b03d6e21b05dd07724Craig Topper  static const uint16_t GPROdd1[] = {
309c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R1, ARM::R3, ARM::R5, ARM::R7, ARM::R9, ARM::R11,
310c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R0, ARM::R2, ARM::R12,ARM::LR, ARM::R4, ARM::R6,
311c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R8, ARM::R10
312c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
313c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
314c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // FP is R7, R9 is available.
315b6632ba380cf624e60fe16b03d6e21b05dd07724Craig Topper  static const uint16_t GPREven2[] = {
316c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R0, ARM::R2, ARM::R4,          ARM::R8, ARM::R10,
317c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R1, ARM::R3, ARM::R12,ARM::LR, ARM::R5, ARM::R6,
318c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R9, ARM::R11
319c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
320b6632ba380cf624e60fe16b03d6e21b05dd07724Craig Topper  static const uint16_t GPROdd2[] = {
321c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R1, ARM::R3, ARM::R5,          ARM::R9, ARM::R11,
322c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R0, ARM::R2, ARM::R12,ARM::LR, ARM::R4, ARM::R6,
323c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R8, ARM::R10
324c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
325c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
326c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // FP is R11, R9 is available.
327b6632ba380cf624e60fe16b03d6e21b05dd07724Craig Topper  static const uint16_t GPREven3[] = {
328c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R0, ARM::R2, ARM::R4, ARM::R6, ARM::R8,
329c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R1, ARM::R3, ARM::R10,ARM::R12,ARM::LR, ARM::R5, ARM::R7,
330c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R9
331c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
332b6632ba380cf624e60fe16b03d6e21b05dd07724Craig Topper  static const uint16_t GPROdd3[] = {
333c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R1, ARM::R3, ARM::R5, ARM::R6, ARM::R9,
334c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R0, ARM::R2, ARM::R10,ARM::R12,ARM::LR, ARM::R4, ARM::R7,
335c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R8
336c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
337c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
338c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // No FP, R9 is not available.
339b6632ba380cf624e60fe16b03d6e21b05dd07724Craig Topper  static const uint16_t GPREven4[] = {
340c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R0, ARM::R2, ARM::R4, ARM::R6,          ARM::R10,
341c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R1, ARM::R3, ARM::R12,ARM::LR, ARM::R5, ARM::R7, ARM::R8,
342c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R11
343c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
344b6632ba380cf624e60fe16b03d6e21b05dd07724Craig Topper  static const uint16_t GPROdd4[] = {
345c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R1, ARM::R3, ARM::R5, ARM::R7,          ARM::R11,
346c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R0, ARM::R2, ARM::R12,ARM::LR, ARM::R4, ARM::R6, ARM::R8,
347c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R10
348c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
349c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
350c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // FP is R7, R9 is not available.
351b6632ba380cf624e60fe16b03d6e21b05dd07724Craig Topper  static const uint16_t GPREven5[] = {
352c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R0, ARM::R2, ARM::R4,                   ARM::R10,
353c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R1, ARM::R3, ARM::R12,ARM::LR, ARM::R5, ARM::R6, ARM::R8,
354c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R11
355c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
356b6632ba380cf624e60fe16b03d6e21b05dd07724Craig Topper  static const uint16_t GPROdd5[] = {
357c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R1, ARM::R3, ARM::R5,                   ARM::R11,
358c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R0, ARM::R2, ARM::R12,ARM::LR, ARM::R4, ARM::R6, ARM::R8,
359c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R10
360c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
361c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
362c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // FP is R11, R9 is not available.
363b6632ba380cf624e60fe16b03d6e21b05dd07724Craig Topper  static const uint16_t GPREven6[] = {
364c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R0, ARM::R2, ARM::R4, ARM::R6,
365c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R1, ARM::R3, ARM::R10,ARM::R12,ARM::LR, ARM::R5, ARM::R7, ARM::R8
366c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
367b6632ba380cf624e60fe16b03d6e21b05dd07724Craig Topper  static const uint16_t GPROdd6[] = {
368c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R1, ARM::R3, ARM::R5, ARM::R7,
369c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R0, ARM::R2, ARM::R10,ARM::R12,ARM::LR, ARM::R4, ARM::R6, ARM::R8
370c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
371c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
372eb5067e0d9ca182f21db24949b63616ce4bb1eafJakob Stoklund Olesen  // We only support even/odd hints for GPR and rGPR.
373eb5067e0d9ca182f21db24949b63616ce4bb1eafJakob Stoklund Olesen  if (RC != ARM::GPRRegisterClass && RC != ARM::rGPRRegisterClass)
374dd5a8471526ceadf9bceb1a1221299b3db49c33aJakob Stoklund Olesen    return RC->getRawAllocationOrder(MF);
375c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
376c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  if (HintType == ARMRI::RegPairEven) {
377c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    if (isPhysicalRegister(HintReg) && getRegisterPairEven(HintReg, MF) == 0)
378c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      // It's no longer possible to fulfill this hint. Return the default
379c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      // allocation order.
380dd5a8471526ceadf9bceb1a1221299b3db49c33aJakob Stoklund Olesen      return RC->getRawAllocationOrder(MF);
381c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
382d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov    if (!TFI->hasFP(MF)) {
383c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      if (!STI.isR9Reserved())
38439b5abf507b43da6b92f68b86406e0015ead18e9Frits van Bommel        return makeArrayRef(GPREven1);
385c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      else
38639b5abf507b43da6b92f68b86406e0015ead18e9Frits van Bommel        return makeArrayRef(GPREven4);
387c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    } else if (FramePtr == ARM::R7) {
388c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      if (!STI.isR9Reserved())
38939b5abf507b43da6b92f68b86406e0015ead18e9Frits van Bommel        return makeArrayRef(GPREven2);
390c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      else
39139b5abf507b43da6b92f68b86406e0015ead18e9Frits van Bommel        return makeArrayRef(GPREven5);
392c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    } else { // FramePtr == ARM::R11
393c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      if (!STI.isR9Reserved())
39439b5abf507b43da6b92f68b86406e0015ead18e9Frits van Bommel        return makeArrayRef(GPREven3);
395c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      else
39639b5abf507b43da6b92f68b86406e0015ead18e9Frits van Bommel        return makeArrayRef(GPREven6);
397c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    }
398c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  } else if (HintType == ARMRI::RegPairOdd) {
399c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    if (isPhysicalRegister(HintReg) && getRegisterPairOdd(HintReg, MF) == 0)
400c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      // It's no longer possible to fulfill this hint. Return the default
401c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      // allocation order.
402dd5a8471526ceadf9bceb1a1221299b3db49c33aJakob Stoklund Olesen      return RC->getRawAllocationOrder(MF);
403c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
404d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov    if (!TFI->hasFP(MF)) {
405c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      if (!STI.isR9Reserved())
40639b5abf507b43da6b92f68b86406e0015ead18e9Frits van Bommel        return makeArrayRef(GPROdd1);
407c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      else
40839b5abf507b43da6b92f68b86406e0015ead18e9Frits van Bommel        return makeArrayRef(GPROdd4);
409c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    } else if (FramePtr == ARM::R7) {
410c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      if (!STI.isR9Reserved())
41139b5abf507b43da6b92f68b86406e0015ead18e9Frits van Bommel        return makeArrayRef(GPROdd2);
412c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      else
41339b5abf507b43da6b92f68b86406e0015ead18e9Frits van Bommel        return makeArrayRef(GPROdd5);
414c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    } else { // FramePtr == ARM::R11
415c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      if (!STI.isR9Reserved())
41639b5abf507b43da6b92f68b86406e0015ead18e9Frits van Bommel        return makeArrayRef(GPROdd3);
417c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      else
41839b5abf507b43da6b92f68b86406e0015ead18e9Frits van Bommel        return makeArrayRef(GPROdd6);
419c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    }
420c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  }
421dd5a8471526ceadf9bceb1a1221299b3db49c33aJakob Stoklund Olesen  return RC->getRawAllocationOrder(MF);
422c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
423c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
424c140c4803dc3e10e08138670829bc0494986abe9David Goodwin/// ResolveRegAllocHint - Resolves the specified register allocation hint
425c140c4803dc3e10e08138670829bc0494986abe9David Goodwin/// to a physical register. Returns the physical register if it is successful.
426c140c4803dc3e10e08138670829bc0494986abe9David Goodwinunsigned
427c140c4803dc3e10e08138670829bc0494986abe9David GoodwinARMBaseRegisterInfo::ResolveRegAllocHint(unsigned Type, unsigned Reg,
428c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                                         const MachineFunction &MF) const {
429c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  if (Reg == 0 || !isPhysicalRegister(Reg))
430c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return 0;
431c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  if (Type == 0)
432c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return Reg;
433c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  else if (Type == (unsigned)ARMRI::RegPairOdd)
434c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // Odd register.
435c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return getRegisterPairOdd(Reg, MF);
436c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  else if (Type == (unsigned)ARMRI::RegPairEven)
437c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // Even register.
438c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return getRegisterPairEven(Reg, MF);
439c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  return 0;
440c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
441c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
442c140c4803dc3e10e08138670829bc0494986abe9David Goodwinvoid
443c140c4803dc3e10e08138670829bc0494986abe9David GoodwinARMBaseRegisterInfo::UpdateRegAllocHint(unsigned Reg, unsigned NewReg,
444c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                                        MachineFunction &MF) const {
445c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  MachineRegisterInfo *MRI = &MF.getRegInfo();
446c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  std::pair<unsigned, unsigned> Hint = MRI->getRegAllocationHint(Reg);
447c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  if ((Hint.first == (unsigned)ARMRI::RegPairOdd ||
448c140c4803dc3e10e08138670829bc0494986abe9David Goodwin       Hint.first == (unsigned)ARMRI::RegPairEven) &&
449c9df025e33ac435adb3b3318d237c36ca7cec659Jakob Stoklund Olesen      TargetRegisterInfo::isVirtualRegister(Hint.second)) {
450c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // If 'Reg' is one of the even / odd register pair and it's now changed
451c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // (e.g. coalesced) into a different register. The other register of the
452c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // pair allocation hint must be updated to reflect the relationship
453c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // change.
454c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    unsigned OtherReg = Hint.second;
455c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    Hint = MRI->getRegAllocationHint(OtherReg);
456c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    if (Hint.second == Reg)
457c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      // Make sure the pair has not already divorced.
458c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      MRI->setRegAllocationHint(OtherReg, Hint.first, NewReg);
459c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  }
460c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
461f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson
462f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilsonbool
463f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob WilsonARMBaseRegisterInfo::avoidWriteAfterWrite(const TargetRegisterClass *RC) const {
464f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson  // CortexA9 has a Write-after-write hazard for NEON registers.
465f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson  if (!STI.isCortexA9())
466f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson    return false;
467f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson
468f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson  switch (RC->getID()) {
469f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson  case ARM::DPRRegClassID:
470f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson  case ARM::DPR_8RegClassID:
471f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson  case ARM::DPR_VFP2RegClassID:
472f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson  case ARM::QPRRegClassID:
473f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson  case ARM::QPR_8RegClassID:
474f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson  case ARM::QPR_VFP2RegClassID:
475f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson  case ARM::SPRRegClassID:
476f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson  case ARM::SPR_8RegClassID:
477f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson    // Avoid reusing S, D, and Q registers.
478f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson    // Don't increase register pressure for QQ and QQQQ.
479f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson    return true;
480f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson  default:
481f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson    return false;
482f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson  }
483f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson}
484c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
48565482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbachbool ARMBaseRegisterInfo::hasBasePointer(const MachineFunction &MF) const {
4866a8700301ca6f8f2f5f787c8d1f5206a7dfceed6Daniel Dunbar  const MachineFrameInfo *MFI = MF.getFrameInfo();
4871755b3964f931bdd6fa9b4c0138f666ccfa12acaJim Grosbach  const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
4880f9d07fb2526c0acdf7ad9fa6e9c1a97a746c0e9Jakob Stoklund Olesen  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
48965482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach
49065482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach  if (!EnableBasePointer)
49165482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach    return false;
49265482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach
4930f9d07fb2526c0acdf7ad9fa6e9c1a97a746c0e9Jakob Stoklund Olesen  // When outgoing call frames are so large that we adjust the stack pointer
4940f9d07fb2526c0acdf7ad9fa6e9c1a97a746c0e9Jakob Stoklund Olesen  // around the call, we can no longer use the stack pointer to reach the
4950f9d07fb2526c0acdf7ad9fa6e9c1a97a746c0e9Jakob Stoklund Olesen  // emergency spill slot.
496055a8127c9ffee287807fe7cc1b115d0f40162b0Bob Wilson  if (needsStackRealignment(MF) && !TFI->hasReservedCallFrame(MF))
49765482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach    return true;
49865482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach
49965482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach  // Thumb has trouble with negative offsets from the FP. Thumb2 has a limited
50065482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach  // negative range for ldr/str (255), and thumb1 is positive offsets only.
50165482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach  // It's going to be better to use the SP or Base Pointer instead. When there
50265482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach  // are variable sized objects, we can't reference off of the SP, so we
50365482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach  // reserve a Base Pointer.
50465482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach  if (AFI->isThumbFunction() && MFI->hasVarSizedObjects()) {
50565482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach    // Conservatively estimate whether the negative offset from the frame
50665482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach    // pointer will be sufficient to reach. If a function has a smallish
50765482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach    // frame, it's less likely to have lots of spills and callee saved
50865482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach    // space, so it's all more likely to be within range of the frame pointer.
50965482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach    // If it's wrong, the scavenger will still enable access to work, it just
51065482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach    // won't be optimal.
51165482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach    if (AFI->isThumb2Function() && MFI->getLocalFrameSize() < 128)
51265482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach      return false;
51365482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach    return true;
51465482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach  }
51565482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach
51665482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach  return false;
51765482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach}
51865482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach
51965482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbachbool ARMBaseRegisterInfo::canRealignStack(const MachineFunction &MF) const {
52030c93e1cd3e43e174994834900325fcff3322288Jim Grosbach  const MachineFrameInfo *MFI = MF.getFrameInfo();
52154f3b7a9109d1916cf25ffdb2ed5045f03121b5aJakob Stoklund Olesen  const MachineRegisterInfo *MRI = &MF.getRegInfo();
5226690bca623d1f6405b95db5b1760f7ba8436e3fbChad Rosier  const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
52330c93e1cd3e43e174994834900325fcff3322288Jim Grosbach  // We can't realign the stack if:
52430c93e1cd3e43e174994834900325fcff3322288Jim Grosbach  // 1. Dynamic stack realignment is explicitly disabled,
5256690bca623d1f6405b95db5b1760f7ba8436e3fbChad Rosier  // 2. This is a Thumb1 function (it's not useful, so we don't bother), or
5266690bca623d1f6405b95db5b1760f7ba8436e3fbChad Rosier  // 3. There are VLAs in the function and the base pointer is disabled.
52754f3b7a9109d1916cf25ffdb2ed5045f03121b5aJakob Stoklund Olesen  if (!MF.getTarget().Options.RealignStack)
52854f3b7a9109d1916cf25ffdb2ed5045f03121b5aJakob Stoklund Olesen    return false;
52954f3b7a9109d1916cf25ffdb2ed5045f03121b5aJakob Stoklund Olesen  if (AFI->isThumb1OnlyFunction())
53054f3b7a9109d1916cf25ffdb2ed5045f03121b5aJakob Stoklund Olesen    return false;
53154f3b7a9109d1916cf25ffdb2ed5045f03121b5aJakob Stoklund Olesen  // Stack realignment requires a frame pointer.  If we already started
53254f3b7a9109d1916cf25ffdb2ed5045f03121b5aJakob Stoklund Olesen  // register allocation with frame pointer elimination, it is too late now.
53354f3b7a9109d1916cf25ffdb2ed5045f03121b5aJakob Stoklund Olesen  if (!MRI->canReserveReg(FramePtr))
53454f3b7a9109d1916cf25ffdb2ed5045f03121b5aJakob Stoklund Olesen    return false;
53554f3b7a9109d1916cf25ffdb2ed5045f03121b5aJakob Stoklund Olesen  // We may also need a base pointer if there are dynamic allocas.
53654f3b7a9109d1916cf25ffdb2ed5045f03121b5aJakob Stoklund Olesen  if (!MFI->hasVarSizedObjects())
53754f3b7a9109d1916cf25ffdb2ed5045f03121b5aJakob Stoklund Olesen    return true;
53854f3b7a9109d1916cf25ffdb2ed5045f03121b5aJakob Stoklund Olesen  if (!EnableBasePointer)
53954f3b7a9109d1916cf25ffdb2ed5045f03121b5aJakob Stoklund Olesen    return false;
54054f3b7a9109d1916cf25ffdb2ed5045f03121b5aJakob Stoklund Olesen  // A base pointer is required and allowed.  Check that it isn't too late to
54154f3b7a9109d1916cf25ffdb2ed5045f03121b5aJakob Stoklund Olesen  // reserve it.
54254f3b7a9109d1916cf25ffdb2ed5045f03121b5aJakob Stoklund Olesen  return MRI->canReserveReg(BasePtr);
543e45ab8a0a90e4f3a59d8c38038ae3e495ee1fef3Jim Grosbach}
544e45ab8a0a90e4f3a59d8c38038ae3e495ee1fef3Jim Grosbach
5453dab2778571b5bb00b35a0adcb7011dc85158bebJim Grosbachbool ARMBaseRegisterInfo::
5463dab2778571b5bb00b35a0adcb7011dc85158bebJim GrosbachneedsStackRealignment(const MachineFunction &MF) const {
5473dab2778571b5bb00b35a0adcb7011dc85158bebJim Grosbach  const MachineFrameInfo *MFI = MF.getFrameInfo();
548d4c36cec1db81b4ee48cd4ab462262615d78f22cEric Christopher  const Function *F = MF.getFunction();
54916c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  unsigned StackAlign = MF.getTarget().getFrameLowering()->getStackAlignment();
5507255a4e1332ccb69918ebe041dff05f9e4e5815dJakob Stoklund Olesen  bool requiresRealignment = ((MFI->getMaxAlignment() > StackAlign) ||
551697cba8ec2b3f5160175fd5b4a641dbd48606e17Eric Christopher                               F->hasFnAttr(Attribute::StackAlignment));
5525c33f5bf67f61e3a1addda6de735d28d550dd0ebJim Grosbach
553d4c36cec1db81b4ee48cd4ab462262615d78f22cEric Christopher  return requiresRealignment && canRealignStack(MF);
5543dab2778571b5bb00b35a0adcb7011dc85158bebJim Grosbach}
5553dab2778571b5bb00b35a0adcb7011dc85158bebJim Grosbach
5569631864688c593711f82bb8d21f8b724c628d786Jim Grosbachbool ARMBaseRegisterInfo::
5579631864688c593711f82bb8d21f8b724c628d786Jim GrosbachcannotEliminateFrame(const MachineFunction &MF) const {
55898a0104014e9bb6ed89c2572f615351fd526674aEvan Cheng  const MachineFrameInfo *MFI = MF.getFrameInfo();
5598a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky  if (MF.getTarget().Options.DisableFramePointerElim(MF) && MFI->adjustsStack())
56098a0104014e9bb6ed89c2572f615351fd526674aEvan Cheng    return true;
56131bc849123011b8eae6bb3c79876d9a3c26a6a1dJim Grosbach  return MFI->hasVarSizedObjects() || MFI->isFrameAddressTaken()
56231bc849123011b8eae6bb3c79876d9a3c26a6a1dJim Grosbach    || needsStackRealignment(MF);
56398a0104014e9bb6ed89c2572f615351fd526674aEvan Cheng}
56498a0104014e9bb6ed89c2572f615351fd526674aEvan Cheng
5655c33f5bf67f61e3a1addda6de735d28d550dd0ebJim Grosbachunsigned
5663f2bf85d14759cc4b28a86805f566ac805a54d00David GreeneARMBaseRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
56716c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
568d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov
569d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  if (TFI->hasFP(MF))
570c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return FramePtr;
571c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  return ARM::SP;
572c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
573c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
574c140c4803dc3e10e08138670829bc0494986abe9David Goodwinunsigned ARMBaseRegisterInfo::getEHExceptionRegister() const {
575c23197a26f34f559ea9797de51e187087c039c42Torok Edwin  llvm_unreachable("What is the exception register");
576c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
577c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
578c140c4803dc3e10e08138670829bc0494986abe9David Goodwinunsigned ARMBaseRegisterInfo::getEHHandlerRegister() const {
579c23197a26f34f559ea9797de51e187087c039c42Torok Edwin  llvm_unreachable("What is the exception handler register");
580c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
581c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
582c140c4803dc3e10e08138670829bc0494986abe9David Goodwinunsigned ARMBaseRegisterInfo::getRegisterPairEven(unsigned Reg,
5839631864688c593711f82bb8d21f8b724c628d786Jim Grosbach                                              const MachineFunction &MF) const {
584c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  switch (Reg) {
585c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  default: break;
586c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // Return 0 if either register of the pair is a special register.
587c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // So no R12, etc.
5888f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::R1: return ARM::R0;
5898f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::R3: return ARM::R2;
5908f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::R5: return ARM::R4;
591c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::R7:
59265482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach    return (isReservedReg(MF, ARM::R7) || isReservedReg(MF, ARM::R6))
59365482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach      ? 0 : ARM::R6;
5948f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::R9: return isReservedReg(MF, ARM::R9)  ? 0 :ARM::R8;
5958f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::R11: return isReservedReg(MF, ARM::R11) ? 0 : ARM::R10;
5968f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach
5978f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S1: return ARM::S0;
5988f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S3: return ARM::S2;
5998f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S5: return ARM::S4;
6008f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S7: return ARM::S6;
6018f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S9: return ARM::S8;
6028f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S11: return ARM::S10;
6038f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S13: return ARM::S12;
6048f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S15: return ARM::S14;
6058f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S17: return ARM::S16;
6068f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S19: return ARM::S18;
6078f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S21: return ARM::S20;
6088f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S23: return ARM::S22;
6098f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S25: return ARM::S24;
6108f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S27: return ARM::S26;
6118f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S29: return ARM::S28;
6128f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S31: return ARM::S30;
6138f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach
6148f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D1: return ARM::D0;
6158f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D3: return ARM::D2;
6168f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D5: return ARM::D4;
6178f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D7: return ARM::D6;
6188f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D9: return ARM::D8;
6198f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D11: return ARM::D10;
6208f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D13: return ARM::D12;
6218f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D15: return ARM::D14;
6228f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D17: return ARM::D16;
6238f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D19: return ARM::D18;
6248f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D21: return ARM::D20;
6258f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D23: return ARM::D22;
6268f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D25: return ARM::D24;
6278f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D27: return ARM::D26;
6288f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D29: return ARM::D28;
6298f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D31: return ARM::D30;
630c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  }
631c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
632c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  return 0;
633c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
634c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
635c140c4803dc3e10e08138670829bc0494986abe9David Goodwinunsigned ARMBaseRegisterInfo::getRegisterPairOdd(unsigned Reg,
636c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                                             const MachineFunction &MF) const {
637c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  switch (Reg) {
638c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  default: break;
639c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // Return 0 if either register of the pair is a special register.
640c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // So no R12, etc.
6418f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::R0: return ARM::R1;
6428f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::R2: return ARM::R3;
6438f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::R4: return ARM::R5;
644c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::R6:
64565482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach    return (isReservedReg(MF, ARM::R7) || isReservedReg(MF, ARM::R6))
64665482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach      ? 0 : ARM::R7;
6478f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::R8: return isReservedReg(MF, ARM::R9)  ? 0 :ARM::R9;
6488f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::R10: return isReservedReg(MF, ARM::R11) ? 0 : ARM::R11;
6498f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach
6508f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S0: return ARM::S1;
6518f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S2: return ARM::S3;
6528f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S4: return ARM::S5;
6538f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S6: return ARM::S7;
6548f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S8: return ARM::S9;
6558f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S10: return ARM::S11;
6568f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S12: return ARM::S13;
6578f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S14: return ARM::S15;
6588f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S16: return ARM::S17;
6598f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S18: return ARM::S19;
6608f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S20: return ARM::S21;
6618f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S22: return ARM::S23;
6628f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S24: return ARM::S25;
6638f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S26: return ARM::S27;
6648f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S28: return ARM::S29;
6658f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S30: return ARM::S31;
6668f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach
6678f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D0: return ARM::D1;
6688f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D2: return ARM::D3;
6698f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D4: return ARM::D5;
6708f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D6: return ARM::D7;
6718f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D8: return ARM::D9;
6728f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D10: return ARM::D11;
6738f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D12: return ARM::D13;
6748f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D14: return ARM::D15;
6758f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D16: return ARM::D17;
6768f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D18: return ARM::D19;
6778f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D20: return ARM::D21;
6788f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D22: return ARM::D23;
6798f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D24: return ARM::D25;
6808f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D26: return ARM::D27;
6818f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D28: return ARM::D29;
6828f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D30: return ARM::D31;
683c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  }
684c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
685c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  return 0;
686c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
687c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
688db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin/// emitLoadConstPool - Emits a load from constpool to materialize the
689db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin/// specified immediate.
690db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwinvoid ARMBaseRegisterInfo::
691db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid GoodwinemitLoadConstPool(MachineBasicBlock &MBB,
692db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin                  MachineBasicBlock::iterator &MBBI,
69377521f5232e679aa3de10aaaed2464aa91d7ff55David Goodwin                  DebugLoc dl,
694378445303b10b092a898a75131141a8259cff50bEvan Cheng                  unsigned DestReg, unsigned SubIdx, int Val,
695db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin                  ARMCC::CondCodes Pred,
6963daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov                  unsigned PredReg, unsigned MIFlags) const {
697db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  MachineFunction &MF = *MBB.getParent();
698db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  MachineConstantPool *ConstantPool = MF.getConstantPool();
69946510a73e977273ec67747eb34cbdb43f815e451Dan Gohman  const Constant *C =
7001d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson        ConstantInt::get(Type::getInt32Ty(MF.getFunction()->getContext()), Val);
701db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4);
702db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
703378445303b10b092a898a75131141a8259cff50bEvan Cheng  BuildMI(MBB, MBBI, dl, TII.get(ARM::LDRcp))
704378445303b10b092a898a75131141a8259cff50bEvan Cheng    .addReg(DestReg, getDefRegState(true), SubIdx)
705db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    .addConstantPoolIndex(Idx)
7063daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov    .addImm(0).addImm(Pred).addReg(PredReg)
7073daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov    .setMIFlags(MIFlags);
708db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin}
709db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
710db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwinbool ARMBaseRegisterInfo::
711db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid GoodwinrequiresRegisterScavenging(const MachineFunction &MF) const {
712db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  return true;
713db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin}
71441fff8c19ab6d8e28f5362481c184ad628f8c704Jim Grosbach
7157e831db1d4f5dc51ca6526739cf41e59895c5c20Jim Grosbachbool ARMBaseRegisterInfo::
7167e831db1d4f5dc51ca6526739cf41e59895c5c20Jim GrosbachrequiresFrameIndexScavenging(const MachineFunction &MF) const {
717ca5dfb71ba4aa4a8392a021ec056cf0b70f74f1eJim Grosbach  return true;
7187e831db1d4f5dc51ca6526739cf41e59895c5c20Jim Grosbach}
719db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
720a273442891ae20fd8192526132e3819ea9e5eda9Jim Grosbachbool ARMBaseRegisterInfo::
721a273442891ae20fd8192526132e3819ea9e5eda9Jim GrosbachrequiresVirtualBaseRegisters(const MachineFunction &MF) const {
722a273442891ae20fd8192526132e3819ea9e5eda9Jim Grosbach  return EnableLocalStackAlloc;
723a273442891ae20fd8192526132e3819ea9e5eda9Jim Grosbach}
724a273442891ae20fd8192526132e3819ea9e5eda9Jim Grosbach
725db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwinstatic void
7266495f63945e8dbde81f03a1dc2ab421993b9a495Evan ChengemitSPUpdate(bool isARM,
7276495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng             MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
7286495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng             DebugLoc dl, const ARMBaseInstrInfo &TII,
729db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin             int NumBytes,
730db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin             ARMCC::CondCodes Pred = ARMCC::AL, unsigned PredReg = 0) {
7316495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng  if (isARM)
7326495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    emitARMRegPlusImmediate(MBB, MBBI, dl, ARM::SP, ARM::SP, NumBytes,
7336495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng                            Pred, PredReg, TII);
7346495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng  else
7356495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    emitT2RegPlusImmediate(MBB, MBBI, dl, ARM::SP, ARM::SP, NumBytes,
7366495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng                           Pred, PredReg, TII);
737db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin}
738db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
7396495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng
740db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwinvoid ARMBaseRegisterInfo::
741db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid GoodwineliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
742db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin                              MachineBasicBlock::iterator I) const {
74316c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
744d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  if (!TFI->hasReservedCallFrame(MF)) {
745db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    // If we have alloca, convert as follows:
746db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    // ADJCALLSTACKDOWN -> sub, sp, sp, amount
747db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    // ADJCALLSTACKUP   -> add, sp, sp, amount
748db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    MachineInstr *Old = I;
749db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    DebugLoc dl = Old->getDebugLoc();
750db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    unsigned Amount = Old->getOperand(0).getImm();
751db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    if (Amount != 0) {
752db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      // We need to keep the stack aligned properly.  To do this, we round the
753db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      // amount of space needed for the outgoing arguments up to the next
754db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      // alignment boundary.
75516c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov      unsigned Align = TFI->getStackAlignment();
756db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      Amount = (Amount+Align-1)/Align*Align;
757db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
7586495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng      ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
7596495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng      assert(!AFI->isThumb1OnlyFunction() &&
760cf453ee70a1ae03cc641686fd5db0f8a7d8ce250Jim Grosbach             "This eliminateCallFramePseudoInstr does not support Thumb1!");
7616495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng      bool isARM = !AFI->isThumbFunction();
7626495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng
763db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      // Replace the pseudo instruction with a new instruction...
764db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      unsigned Opc = Old->getOpcode();
7654c7628e43d8468f215ea345545479b6d728cee92Jim Grosbach      int PIdx = Old->findFirstPredOperandIdx();
7664c7628e43d8468f215ea345545479b6d728cee92Jim Grosbach      ARMCC::CondCodes Pred = (PIdx == -1)
7674c7628e43d8468f215ea345545479b6d728cee92Jim Grosbach        ? ARMCC::AL : (ARMCC::CondCodes)Old->getOperand(PIdx).getImm();
768db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      if (Opc == ARM::ADJCALLSTACKDOWN || Opc == ARM::tADJCALLSTACKDOWN) {
769db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        // Note: PredReg is operand 2 for ADJCALLSTACKDOWN.
770db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        unsigned PredReg = Old->getOperand(2).getReg();
7716495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng        emitSPUpdate(isARM, MBB, I, dl, TII, -Amount, Pred, PredReg);
772db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      } else {
773db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        // Note: PredReg is operand 3 for ADJCALLSTACKUP.
774db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        unsigned PredReg = Old->getOperand(3).getReg();
775db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        assert(Opc == ARM::ADJCALLSTACKUP || Opc == ARM::tADJCALLSTACKUP);
7766495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng        emitSPUpdate(isARM, MBB, I, dl, TII, Amount, Pred, PredReg);
777db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      }
778db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    }
779db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  }
780db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  MBB.erase(I);
781db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin}
782db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
783e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbachint64_t ARMBaseRegisterInfo::
7841ab3f16f06698596716593a30545799688acccd7Jim GrosbachgetFrameIndexInstrOffset(const MachineInstr *MI, int Idx) const {
785e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  const MCInstrDesc &Desc = MI->getDesc();
786e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach  unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
78790f20044ade3712c8b0c3f4ebe47d57ad15ae6ceChad Rosier  int64_t InstrOffs = 0;
788e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach  int Scale = 1;
789e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach  unsigned ImmIdx = 0;
7901ab3f16f06698596716593a30545799688acccd7Jim Grosbach  switch (AddrMode) {
791e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach  case ARMII::AddrModeT2_i8:
792e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach  case ARMII::AddrModeT2_i12:
7933e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach  case ARMII::AddrMode_i12:
794e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach    InstrOffs = MI->getOperand(Idx+1).getImm();
795e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach    Scale = 1;
796e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach    break;
797e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach  case ARMII::AddrMode5: {
798e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach    // VFP address mode.
799e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach    const MachineOperand &OffOp = MI->getOperand(Idx+1);
800f78ee6316bc755779920ac207edc27a89c0bd2f9Jim Grosbach    InstrOffs = ARM_AM::getAM5Offset(OffOp.getImm());
801e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach    if (ARM_AM::getAM5Op(OffOp.getImm()) == ARM_AM::sub)
802e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach      InstrOffs = -InstrOffs;
803e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach    Scale = 4;
804e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach    break;
805e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach  }
806e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach  case ARMII::AddrMode2: {
807e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach    ImmIdx = Idx+2;
808e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach    InstrOffs = ARM_AM::getAM2Offset(MI->getOperand(ImmIdx).getImm());
809e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach    if (ARM_AM::getAM2Op(MI->getOperand(ImmIdx).getImm()) == ARM_AM::sub)
810e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach      InstrOffs = -InstrOffs;
811e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach    break;
812e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach  }
813e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach  case ARMII::AddrMode3: {
814e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach    ImmIdx = Idx+2;
815e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach    InstrOffs = ARM_AM::getAM3Offset(MI->getOperand(ImmIdx).getImm());
816e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach    if (ARM_AM::getAM3Op(MI->getOperand(ImmIdx).getImm()) == ARM_AM::sub)
817e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach      InstrOffs = -InstrOffs;
818e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach    break;
819e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach  }
820e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach  case ARMII::AddrModeT1_s: {
821e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach    ImmIdx = Idx+1;
822e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach    InstrOffs = MI->getOperand(ImmIdx).getImm();
823e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach    Scale = 4;
824e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach    break;
825e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach  }
826e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach  default:
827e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach    llvm_unreachable("Unsupported addressing mode!");
828e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach  }
829e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach
830e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach  return InstrOffs * Scale;
831e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach}
832e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach
8338708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach/// needsFrameBaseReg - Returns true if the instruction's frame index
8348708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach/// reference would be better served by a base register other than FP
8358708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach/// or SP. Used by LocalStackFrameAllocation to determine which frame index
8368708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach/// references it should create new base registers for.
8378708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbachbool ARMBaseRegisterInfo::
8383197380143cdc18837722129ac888528b9fbfc2bJim GrosbachneedsFrameBaseReg(MachineInstr *MI, int64_t Offset) const {
8393197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  for (unsigned i = 0; !MI->getOperand(i).isFI(); ++i) {
8403197380143cdc18837722129ac888528b9fbfc2bJim Grosbach    assert(i < MI->getNumOperands() &&"Instr doesn't have FrameIndex operand!");
8413197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  }
8428708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach
8438708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach  // It's the load/store FI references that cause issues, as it can be difficult
8448708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach  // to materialize the offset if it won't fit in the literal field. Estimate
8458708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach  // based on the size of the local frame and some conservative assumptions
8468708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach  // about the rest of the stack frame (note, this is pre-regalloc, so
8478708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach  // we don't know everything for certain yet) whether this offset is likely
8488708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach  // to be out of range of the immediate. Return true if so.
8498708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach
850cd59dc5e81eb080cd9b61f5a7e7d9f3eec206d8cJim Grosbach  // We only generate virtual base registers for loads and stores, so
851cd59dc5e81eb080cd9b61f5a7e7d9f3eec206d8cJim Grosbach  // return false for everything else.
8528708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach  unsigned Opc = MI->getOpcode();
8538708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach  switch (Opc) {
854c1d30212e911d1e55ff6b25bffefb503708883c3Jim Grosbach  case ARM::LDRi12: case ARM::LDRH: case ARM::LDRBi12:
8557e3383c007f53b3a00675af225e428cb66ddf404Jim Grosbach  case ARM::STRi12: case ARM::STRH: case ARM::STRBi12:
8568708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach  case ARM::t2LDRi12: case ARM::t2LDRi8:
8578708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach  case ARM::t2STRi12: case ARM::t2STRi8:
8588708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach  case ARM::VLDRS: case ARM::VLDRD:
8598708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach  case ARM::VSTRS: case ARM::VSTRD:
86074d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach  case ARM::tSTRspi: case ARM::tLDRspi:
861cd59dc5e81eb080cd9b61f5a7e7d9f3eec206d8cJim Grosbach    if (ForceAllBaseRegAlloc)
862cd59dc5e81eb080cd9b61f5a7e7d9f3eec206d8cJim Grosbach      return true;
863cd59dc5e81eb080cd9b61f5a7e7d9f3eec206d8cJim Grosbach    break;
8648708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach  default:
8658708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach    return false;
8668708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach  }
867cd59dc5e81eb080cd9b61f5a7e7d9f3eec206d8cJim Grosbach
868cd59dc5e81eb080cd9b61f5a7e7d9f3eec206d8cJim Grosbach  // Without a virtual base register, if the function has variable sized
869cd59dc5e81eb080cd9b61f5a7e7d9f3eec206d8cJim Grosbach  // objects, all fixed-size local references will be via the frame pointer,
8703197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  // Approximate the offset and see if it's legal for the instruction.
8713197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  // Note that the incoming offset is based on the SP value at function entry,
8723197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  // so it'll be negative.
8733197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  MachineFunction &MF = *MI->getParent()->getParent();
87416c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
8753197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  MachineFrameInfo *MFI = MF.getFrameInfo();
8763197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
8773197380143cdc18837722129ac888528b9fbfc2bJim Grosbach
8783197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  // Estimate an offset from the frame pointer.
8793197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  // Conservatively assume all callee-saved registers get pushed. R4-R6
8803197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  // will be earlier than the FP, so we ignore those.
8813197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  // R7, LR
8823197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  int64_t FPOffset = Offset - 8;
8833197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  // ARM and Thumb2 functions also need to consider R8-R11 and D8-D15
8843197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  if (!AFI->isThumbFunction() || !AFI->isThumb1OnlyFunction())
8853197380143cdc18837722129ac888528b9fbfc2bJim Grosbach    FPOffset -= 80;
8863197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  // Estimate an offset from the stack pointer.
887c1dc78de762e8a65fe1edd0cced13d94ab5a971fJim Grosbach  // The incoming offset is relating to the SP at the start of the function,
888c1dc78de762e8a65fe1edd0cced13d94ab5a971fJim Grosbach  // but when we access the local it'll be relative to the SP after local
889c1dc78de762e8a65fe1edd0cced13d94ab5a971fJim Grosbach  // allocation, so adjust our SP-relative offset by that allocation size.
8903197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  Offset = -Offset;
891c1dc78de762e8a65fe1edd0cced13d94ab5a971fJim Grosbach  Offset += MFI->getLocalFrameSize();
8923197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  // Assume that we'll have at least some spill slots allocated.
8933197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  // FIXME: This is a total SWAG number. We should run some statistics
8943197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  //        and pick a real one.
8953197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  Offset += 128; // 128 bytes of spill slots
8963197380143cdc18837722129ac888528b9fbfc2bJim Grosbach
8973197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  // If there is a frame pointer, try using it.
8983197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  // The FP is only available if there is no dynamic realignment. We
8993197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  // don't know for sure yet whether we'll need that, so we guess based
9003197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  // on whether there are any local variables that would trigger it.
90116c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  unsigned StackAlign = TFI->getStackAlignment();
902d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  if (TFI->hasFP(MF) &&
9033197380143cdc18837722129ac888528b9fbfc2bJim Grosbach      !((MFI->getLocalFrameMaxAlign() > StackAlign) && canRealignStack(MF))) {
9043197380143cdc18837722129ac888528b9fbfc2bJim Grosbach    if (isFrameOffsetLegal(MI, FPOffset))
9053197380143cdc18837722129ac888528b9fbfc2bJim Grosbach      return false;
9063197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  }
9073197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  // If we can reference via the stack pointer, try that.
9083197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  // FIXME: This (and the code that resolves the references) can be improved
9093197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  //        to only disallow SP relative references in the live range of
9103197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  //        the VLA(s). In practice, it's unclear how much difference that
9113197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  //        would make, but it may be worth doing.
9123197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  if (!MFI->hasVarSizedObjects() && isFrameOffsetLegal(MI, Offset))
9133197380143cdc18837722129ac888528b9fbfc2bJim Grosbach    return false;
914cd59dc5e81eb080cd9b61f5a7e7d9f3eec206d8cJim Grosbach
9153197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  // The offset likely isn't legal, we want to allocate a virtual base register.
916cd59dc5e81eb080cd9b61f5a7e7d9f3eec206d8cJim Grosbach  return true;
9178708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach}
9188708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach
919976ef86689ed065361a748f81c44ca3510af2202Bill Wendling/// materializeFrameBaseRegister - Insert defining instruction(s) for BaseReg to
920976ef86689ed065361a748f81c44ca3510af2202Bill Wendling/// be a pointer to FrameIdx at the beginning of the basic block.
921dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbachvoid ARMBaseRegisterInfo::
922976ef86689ed065361a748f81c44ca3510af2202Bill WendlingmaterializeFrameBaseRegister(MachineBasicBlock *MBB,
923976ef86689ed065361a748f81c44ca3510af2202Bill Wendling                             unsigned BaseReg, int FrameIdx,
924976ef86689ed065361a748f81c44ca3510af2202Bill Wendling                             int64_t Offset) const {
925976ef86689ed065361a748f81c44ca3510af2202Bill Wendling  ARMFunctionInfo *AFI = MBB->getParent()->getInfo<ARMFunctionInfo>();
92674d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach  unsigned ADDriOpc = !AFI->isThumbFunction() ? ARM::ADDri :
92774d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach    (AFI->isThumb1OnlyFunction() ? ARM::tADDrSPi : ARM::t2ADDri);
928dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach
929976ef86689ed065361a748f81c44ca3510af2202Bill Wendling  MachineBasicBlock::iterator Ins = MBB->begin();
930976ef86689ed065361a748f81c44ca3510af2202Bill Wendling  DebugLoc DL;                  // Defaults to "unknown"
931976ef86689ed065361a748f81c44ca3510af2202Bill Wendling  if (Ins != MBB->end())
932976ef86689ed065361a748f81c44ca3510af2202Bill Wendling    DL = Ins->getDebugLoc();
933976ef86689ed065361a748f81c44ca3510af2202Bill Wendling
934e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  const MCInstrDesc &MCID = TII.get(ADDriOpc);
93521803721d538255e4d223c29b6c8d3c9e93d4d86Cameron Zwarich  MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo();
936e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  MRI.constrainRegClass(BaseReg, TII.getRegClass(MCID, 0, this));
93721803721d538255e4d223c29b6c8d3c9e93d4d86Cameron Zwarich
9385b81584f7403ffdb9cc6babaaeb0411c080e0f81Jim Grosbach  MachineInstrBuilder MIB = AddDefaultPred(BuildMI(*MBB, Ins, DL, MCID, BaseReg)
9395b81584f7403ffdb9cc6babaaeb0411c080e0f81Jim Grosbach    .addFrameIndex(FrameIdx).addImm(Offset));
940976ef86689ed065361a748f81c44ca3510af2202Bill Wendling
94174d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach  if (!AFI->isThumb1OnlyFunction())
9425b81584f7403ffdb9cc6babaaeb0411c080e0f81Jim Grosbach    AddDefaultCC(MIB);
943dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach}
944dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach
945dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbachvoid
946dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim GrosbachARMBaseRegisterInfo::resolveFrameIndex(MachineBasicBlock::iterator I,
947dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach                                       unsigned BaseReg, int64_t Offset) const {
948dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach  MachineInstr &MI = *I;
949dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach  MachineBasicBlock &MBB = *MI.getParent();
950dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach  MachineFunction &MF = *MBB.getParent();
951dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
952dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach  int Off = Offset; // ARM doesn't need the general 64-bit offsets
953dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach  unsigned i = 0;
954dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach
955dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach  assert(!AFI->isThumb1OnlyFunction() &&
956dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach         "This resolveFrameIndex does not support Thumb1!");
957dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach
958dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach  while (!MI.getOperand(i).isFI()) {
959dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach    ++i;
960dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach    assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
961dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach  }
962dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach  bool Done = false;
963dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach  if (!AFI->isThumbFunction())
964dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach    Done = rewriteARMFrameIndex(MI, i, BaseReg, Off, TII);
965dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach  else {
966dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach    assert(AFI->isThumb2Function());
967dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach    Done = rewriteT2FrameIndex(MI, i, BaseReg, Off, TII);
968dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach  }
969dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach  assert (Done && "Unable to resolve frame index!");
9701f6a329f79b3568d379142f921f59c4143ddaa14Duncan Sands  (void)Done;
971dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach}
9728708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach
973e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbachbool ARMBaseRegisterInfo::isFrameOffsetLegal(const MachineInstr *MI,
974e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach                                             int64_t Offset) const {
975e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  const MCInstrDesc &Desc = MI->getDesc();
9762b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach  unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
9772b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach  unsigned i = 0;
9782b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach
9792b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach  while (!MI->getOperand(i).isFI()) {
9802b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach    ++i;
9812b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach    assert(i < MI->getNumOperands() &&"Instr doesn't have FrameIndex operand!");
9822b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach  }
9832b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach
9842b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach  // AddrMode4 and AddrMode6 cannot handle any offset.
9852b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach  if (AddrMode == ARMII::AddrMode4 || AddrMode == ARMII::AddrMode6)
9862b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach    return Offset == 0;
9872b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach
9882b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach  unsigned NumBits = 0;
9892b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach  unsigned Scale = 1;
990e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach  bool isSigned = true;
9911ab3f16f06698596716593a30545799688acccd7Jim Grosbach  switch (AddrMode) {
9922b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach  case ARMII::AddrModeT2_i8:
9932b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach  case ARMII::AddrModeT2_i12:
9942b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach    // i8 supports only negative, and i12 supports only positive, so
9952b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach    // based on Offset sign, consider the appropriate instruction
99674d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach    Scale = 1;
9972b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach    if (Offset < 0) {
9982b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach      NumBits = 8;
9992b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach      Offset = -Offset;
10002b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach    } else {
10012b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach      NumBits = 12;
10022b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach    }
10032b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach    break;
10041ab3f16f06698596716593a30545799688acccd7Jim Grosbach  case ARMII::AddrMode5:
10052b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach    // VFP address mode.
10062b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach    NumBits = 8;
10072b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach    Scale = 4;
10082b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach    break;
10093e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach  case ARMII::AddrMode_i12:
10101ab3f16f06698596716593a30545799688acccd7Jim Grosbach  case ARMII::AddrMode2:
10112b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach    NumBits = 12;
10122b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach    break;
10131ab3f16f06698596716593a30545799688acccd7Jim Grosbach  case ARMII::AddrMode3:
10142b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach    NumBits = 8;
10152b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach    break;
1016e575499d830008784b11499dae290ad0480c8f9dBill Wendling  case ARMII::AddrModeT1_s:
1017e575499d830008784b11499dae290ad0480c8f9dBill Wendling    NumBits = 5;
101874d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach    Scale = 4;
1019e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach    isSigned = false;
102074d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach    break;
10212b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach  default:
10222b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach    llvm_unreachable("Unsupported addressing mode!");
10232b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach  }
10242b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach
10251ab3f16f06698596716593a30545799688acccd7Jim Grosbach  Offset += getFrameIndexInstrOffset(MI, i);
1026d4511e947ee1e89a4f199bfac0d401976930ccfeJim Grosbach  // Make sure the offset is encodable for instructions that scale the
1027d4511e947ee1e89a4f199bfac0d401976930ccfeJim Grosbach  // immediate.
1028d4511e947ee1e89a4f199bfac0d401976930ccfeJim Grosbach  if ((Offset & (Scale-1)) != 0)
1029d4511e947ee1e89a4f199bfac0d401976930ccfeJim Grosbach    return false;
1030d4511e947ee1e89a4f199bfac0d401976930ccfeJim Grosbach
1031e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach  if (isSigned && Offset < 0)
10322b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach    Offset = -Offset;
10332b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach
10342b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach  unsigned Mask = (1 << NumBits) - 1;
10352b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach  if ((unsigned)Offset <= Mask * Scale)
10362b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach    return true;
103774d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach
103874d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach  return false;
103974d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach}
104074d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach
1041fcb4a8ead3cd8d9540d5eaa448af5d14a0ee341aJim Grosbachvoid
10426495f63945e8dbde81f03a1dc2ab421993b9a495Evan ChengARMBaseRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
1043fcb4a8ead3cd8d9540d5eaa448af5d14a0ee341aJim Grosbach                                         int SPAdj, RegScavenger *RS) const {
10445ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin  unsigned i = 0;
10455ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin  MachineInstr &MI = *II;
10465ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin  MachineBasicBlock &MBB = *MI.getParent();
10475ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin  MachineFunction &MF = *MBB.getParent();
104816c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  const ARMFrameLowering *TFI =
104916c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov    static_cast<const ARMFrameLowering*>(MF.getTarget().getFrameLowering());
10505ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
10516495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng  assert(!AFI->isThumb1OnlyFunction() &&
1052a15de00f8246f19180b26ee5fe7ff8f436e0de08Bob Wilson         "This eliminateFrameIndex does not support Thumb1!");
10535ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin
10545ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin  while (!MI.getOperand(i).isFI()) {
10555ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin    ++i;
10565ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin    assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
10575ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin  }
10585ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin
10595ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin  int FrameIndex = MI.getOperand(i).getIndex();
1060a37aa546224ec03ba1f1a1598e0781af4b692673Jim Grosbach  unsigned FrameReg;
10615ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin
106282f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov  int Offset = TFI->ResolveFrameIndexReference(MF, FrameIndex, FrameReg, SPAdj);
10635ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin
10640f9d07fb2526c0acdf7ad9fa6e9c1a97a746c0e9Jakob Stoklund Olesen  // PEI::scavengeFrameVirtualRegs() cannot accurately track SPAdj because the
10650f9d07fb2526c0acdf7ad9fa6e9c1a97a746c0e9Jakob Stoklund Olesen  // call frame setup/destroy instructions have already been eliminated.  That
10660f9d07fb2526c0acdf7ad9fa6e9c1a97a746c0e9Jakob Stoklund Olesen  // means the stack pointer cannot be used to access the emergency spill slot
10670f9d07fb2526c0acdf7ad9fa6e9c1a97a746c0e9Jakob Stoklund Olesen  // when !hasReservedCallFrame().
10680f9d07fb2526c0acdf7ad9fa6e9c1a97a746c0e9Jakob Stoklund Olesen#ifndef NDEBUG
10690f9d07fb2526c0acdf7ad9fa6e9c1a97a746c0e9Jakob Stoklund Olesen  if (RS && FrameReg == ARM::SP && FrameIndex == RS->getScavengingFrameIndex()){
10700f9d07fb2526c0acdf7ad9fa6e9c1a97a746c0e9Jakob Stoklund Olesen    assert(TFI->hasReservedCallFrame(MF) &&
10710f9d07fb2526c0acdf7ad9fa6e9c1a97a746c0e9Jakob Stoklund Olesen           "Cannot use SP to access the emergency spill slot in "
10720f9d07fb2526c0acdf7ad9fa6e9c1a97a746c0e9Jakob Stoklund Olesen           "functions without a reserved call frame");
10730f9d07fb2526c0acdf7ad9fa6e9c1a97a746c0e9Jakob Stoklund Olesen    assert(!MF.getFrameInfo()->hasVarSizedObjects() &&
10740f9d07fb2526c0acdf7ad9fa6e9c1a97a746c0e9Jakob Stoklund Olesen           "Cannot use SP to access the emergency spill slot in "
10750f9d07fb2526c0acdf7ad9fa6e9c1a97a746c0e9Jakob Stoklund Olesen           "functions with variable sized frame objects");
10760f9d07fb2526c0acdf7ad9fa6e9c1a97a746c0e9Jakob Stoklund Olesen  }
10770f9d07fb2526c0acdf7ad9fa6e9c1a97a746c0e9Jakob Stoklund Olesen#endif // NDEBUG
10780f9d07fb2526c0acdf7ad9fa6e9c1a97a746c0e9Jakob Stoklund Olesen
107962b50656ceb854eb0be265d63b2a1d46e7400d8aEvan Cheng  // Special handling of dbg_value instructions.
108062b50656ceb854eb0be265d63b2a1d46e7400d8aEvan Cheng  if (MI.isDebugValue()) {
108162b50656ceb854eb0be265d63b2a1d46e7400d8aEvan Cheng    MI.getOperand(i).  ChangeToRegister(FrameReg, false /*isDef*/);
108262b50656ceb854eb0be265d63b2a1d46e7400d8aEvan Cheng    MI.getOperand(i+1).ChangeToImmediate(Offset);
1083fcb4a8ead3cd8d9540d5eaa448af5d14a0ee341aJim Grosbach    return;
108462b50656ceb854eb0be265d63b2a1d46e7400d8aEvan Cheng  }
108562b50656ceb854eb0be265d63b2a1d46e7400d8aEvan Cheng
108648d8afab73d72418cf9505a020f621014920463cEvan Cheng  // Modify MI as necessary to handle as much of 'Offset' as possible
1087cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng  bool Done = false;
10886495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng  if (!AFI->isThumbFunction())
1089cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng    Done = rewriteARMFrameIndex(MI, i, FrameReg, Offset, TII);
10906495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng  else {
10916495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    assert(AFI->isThumb2Function());
1092cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng    Done = rewriteT2FrameIndex(MI, i, FrameReg, Offset, TII);
10936495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng  }
1094cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng  if (Done)
1095fcb4a8ead3cd8d9540d5eaa448af5d14a0ee341aJim Grosbach    return;
10965ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin
1097db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  // If we get here, the immediate doesn't fit into the instruction.  We folded
1098db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  // as much as possible above, handle the rest, providing a register that is
1099db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  // SP+LargeImm.
110019bb87d0f80f3e6eed38a9fa267bf2b0474aeaabDaniel Dunbar  assert((Offset ||
1101a44321776ecd96fa0344335d3027758be3386e45Jim Grosbach          (MI.getDesc().TSFlags & ARMII::AddrModeMask) == ARMII::AddrMode4 ||
1102a44321776ecd96fa0344335d3027758be3386e45Jim Grosbach          (MI.getDesc().TSFlags & ARMII::AddrModeMask) == ARMII::AddrMode6) &&
1103cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng         "This code isn't needed if offset already handled!");
1104db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
11057e831db1d4f5dc51ca6526739cf41e59895c5c20Jim Grosbach  unsigned ScratchReg = 0;
1106db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  int PIdx = MI.findFirstPredOperandIdx();
1107db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  ARMCC::CondCodes Pred = (PIdx == -1)
1108db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    ? ARMCC::AL : (ARMCC::CondCodes)MI.getOperand(PIdx).getImm();
1109db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  unsigned PredReg = (PIdx == -1) ? 0 : MI.getOperand(PIdx+1).getReg();
1110cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng  if (Offset == 0)
1111a44321776ecd96fa0344335d3027758be3386e45Jim Grosbach    // Must be addrmode4/6.
1112cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng    MI.getOperand(i).ChangeToRegister(FrameReg, false, false, false);
11136495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng  else {
1114ca5dfb71ba4aa4a8392a021ec056cf0b70f74f1eJim Grosbach    ScratchReg = MF.getRegInfo().createVirtualRegister(ARM::GPRRegisterClass);
1115cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng    if (!AFI->isThumbFunction())
1116cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng      emitARMRegPlusImmediate(MBB, II, MI.getDebugLoc(), ScratchReg, FrameReg,
1117cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng                              Offset, Pred, PredReg, TII);
1118cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng    else {
1119cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng      assert(AFI->isThumb2Function());
1120cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng      emitT2RegPlusImmediate(MBB, II, MI.getDebugLoc(), ScratchReg, FrameReg,
1121cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng                             Offset, Pred, PredReg, TII);
1122cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng    }
1123cde31293d45f14ddff482d385429d256bd4e0820Jim Grosbach    // Update the original instruction to use the scratch register.
1124cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng    MI.getOperand(i).ChangeToRegister(ScratchReg, false, false, true);
11256495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng  }
1126db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin}
1127