ARMBaseRegisterInfo.cpp revision 8a8d479214745c82ef00f08d4e4f1c173b5f9ce2
12cfd52c507bd5790457a171eb9bcb39019cc6860Chris Lattner//===- ARMBaseRegisterInfo.cpp - ARM Register Information -------*- C++ -*-===//
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
14c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "ARM.h"
15db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin#include "ARMBaseInstrInfo.h"
16c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "ARMBaseRegisterInfo.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
64c140c4803dc3e10e08138670829bc0494986abe9David Goodwinconst unsigned*
65c140c4803dc3e10e08138670829bc0494986abe9David GoodwinARMBaseRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
66c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  static const unsigned CalleeSavedRegs[] = {
67c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::LR, ARM::R11, ARM::R10, ARM::R9, ARM::R8,
68c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R7, ARM::R6,  ARM::R5,  ARM::R4,
69c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
70c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::D15, ARM::D14, ARM::D13, ARM::D12,
71c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::D11, ARM::D10, ARM::D9,  ARM::D8,
72c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    0
73c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
74c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
75c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  static const unsigned DarwinCalleeSavedRegs[] = {
76c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // Darwin ABI deviates from ARM standard ABI. R9 is not a callee-saved
77c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // register.
78ab3d00e5350fd4c097e2a5b077da7584692029a7Jim Grosbach    ARM::LR,  ARM::R7,  ARM::R6, ARM::R5, ARM::R4,
79ab3d00e5350fd4c097e2a5b077da7584692029a7Jim Grosbach    ARM::R11, ARM::R10, ARM::R8,
80c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
81c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::D15, ARM::D14, ARM::D13, ARM::D12,
82c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::D11, ARM::D10, ARM::D9,  ARM::D8,
83c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    0
84c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
85c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  return STI.isTargetDarwin() ? DarwinCalleeSavedRegs : CalleeSavedRegs;
86c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
87c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
889631864688c593711f82bb8d21f8b724c628d786Jim GrosbachBitVector ARMBaseRegisterInfo::
899631864688c593711f82bb8d21f8b724c628d786Jim GrosbachgetReservedRegs(const MachineFunction &MF) const {
9016c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
91d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov
927a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner  // FIXME: avoid re-calculating this every time.
93c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  BitVector Reserved(getNumRegs());
94c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  Reserved.set(ARM::SP);
95c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  Reserved.set(ARM::PC);
96d1fb583128c6682bb8a7c74eafa810a9270cc8dfNate Begeman  Reserved.set(ARM::FPSCR);
97d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  if (TFI->hasFP(MF))
98c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    Reserved.set(FramePtr);
9965482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach  if (hasBasePointer(MF))
10065482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach    Reserved.set(BasePtr);
101c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // Some targets reserve R9.
102c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  if (STI.isR9Reserved())
103c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    Reserved.set(ARM::R9);
1043b6434e360315849a65b1ac85e16d160131a77a4Jakob Stoklund Olesen  // Reserve D16-D31 if the subtarget doesn't support them.
1053b6434e360315849a65b1ac85e16d160131a77a4Jakob Stoklund Olesen  if (!STI.hasVFP3() || STI.hasD16()) {
1063b6434e360315849a65b1ac85e16d160131a77a4Jakob Stoklund Olesen    assert(ARM::D31 == ARM::D16 + 15);
1073b6434e360315849a65b1ac85e16d160131a77a4Jakob Stoklund Olesen    for (unsigned i = 0; i != 16; ++i)
1083b6434e360315849a65b1ac85e16d160131a77a4Jakob Stoklund Olesen      Reserved.set(ARM::D16 + i);
1093b6434e360315849a65b1ac85e16d160131a77a4Jakob Stoklund Olesen  }
110c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  return Reserved;
111c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
112c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
1132cfd52c507bd5790457a171eb9bcb39019cc6860Chris Lattnerbool ARMBaseRegisterInfo::isReservedReg(const MachineFunction &MF,
1142cfd52c507bd5790457a171eb9bcb39019cc6860Chris Lattner                                        unsigned Reg) const {
11516c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
116d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov
117c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  switch (Reg) {
118c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  default: break;
119c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::SP:
120c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::PC:
121c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return true;
12265482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach  case ARM::R6:
12365482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach    if (hasBasePointer(MF))
12465482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach      return true;
12565482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach    break;
126c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::R7:
127c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::R11:
128d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov    if (FramePtr == Reg && TFI->hasFP(MF))
129c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      return true;
130c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    break;
131c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::R9:
132c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return STI.isR9Reserved();
133c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  }
134c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
135c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  return false;
136c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
137c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
1382cfd52c507bd5790457a171eb9bcb39019cc6860Chris Lattnerconst TargetRegisterClass *
1394f54c1293af174a8002db20faf7b4f82ba4e8514Evan ChengARMBaseRegisterInfo::getMatchingSuperRegClass(const TargetRegisterClass *A,
1404f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng                                              const TargetRegisterClass *B,
1414f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng                                              unsigned SubIdx) const {
1424f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng  switch (SubIdx) {
1434f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng  default: return 0;
144e00fa64c16f40230d76417be8f09166b7c84c52dJakob Stoklund Olesen  case ARM::ssub_0:
145e00fa64c16f40230d76417be8f09166b7c84c52dJakob Stoklund Olesen  case ARM::ssub_1:
146e00fa64c16f40230d76417be8f09166b7c84c52dJakob Stoklund Olesen  case ARM::ssub_2:
147e00fa64c16f40230d76417be8f09166b7c84c52dJakob Stoklund Olesen  case ARM::ssub_3: {
1484f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng    // S sub-registers.
1494f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng    if (A->getSize() == 8) {
150ba908640b3e0c1218748776e244d4b7234451155Evan Cheng      if (B == &ARM::SPR_8RegClass)
151ba908640b3e0c1218748776e244d4b7234451155Evan Cheng        return &ARM::DPR_8RegClass;
152ba908640b3e0c1218748776e244d4b7234451155Evan Cheng      assert(B == &ARM::SPRRegClass && "Expecting SPR register class!");
1534f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng      if (A == &ARM::DPR_8RegClass)
1544f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng        return A;
1554f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng      return &ARM::DPR_VFP2RegClass;
1564f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng    }
1574f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng
158b63387afc6b10e88631d1ef232c41ab6c18c8581Evan Cheng    if (A->getSize() == 16) {
159b63387afc6b10e88631d1ef232c41ab6c18c8581Evan Cheng      if (B == &ARM::SPR_8RegClass)
160b63387afc6b10e88631d1ef232c41ab6c18c8581Evan Cheng        return &ARM::QPR_8RegClass;
161b63387afc6b10e88631d1ef232c41ab6c18c8581Evan Cheng      return &ARM::QPR_VFP2RegClass;
162b63387afc6b10e88631d1ef232c41ab6c18c8581Evan Cheng    }
163b63387afc6b10e88631d1ef232c41ab6c18c8581Evan Cheng
16422c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng    if (A->getSize() == 32) {
16522c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng      if (B == &ARM::SPR_8RegClass)
16622c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng        return 0;  // Do not allow coalescing!
16722c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng      return &ARM::QQPR_VFP2RegClass;
16822c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng    }
16922c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng
17022c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng    assert(A->getSize() == 64 && "Expecting a QQQQ register class!");
17122c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng    return 0;  // Do not allow coalescing!
172b63387afc6b10e88631d1ef232c41ab6c18c8581Evan Cheng  }
173e00fa64c16f40230d76417be8f09166b7c84c52dJakob Stoklund Olesen  case ARM::dsub_0:
174e00fa64c16f40230d76417be8f09166b7c84c52dJakob Stoklund Olesen  case ARM::dsub_1:
175e00fa64c16f40230d76417be8f09166b7c84c52dJakob Stoklund Olesen  case ARM::dsub_2:
176e00fa64c16f40230d76417be8f09166b7c84c52dJakob Stoklund Olesen  case ARM::dsub_3: {
1774f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng    // D sub-registers.
178b63387afc6b10e88631d1ef232c41ab6c18c8581Evan Cheng    if (A->getSize() == 16) {
179b63387afc6b10e88631d1ef232c41ab6c18c8581Evan Cheng      if (B == &ARM::DPR_VFP2RegClass)
180b63387afc6b10e88631d1ef232c41ab6c18c8581Evan Cheng        return &ARM::QPR_VFP2RegClass;
181b63387afc6b10e88631d1ef232c41ab6c18c8581Evan Cheng      if (B == &ARM::DPR_8RegClass)
18222c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng        return 0;  // Do not allow coalescing!
183b63387afc6b10e88631d1ef232c41ab6c18c8581Evan Cheng      return A;
184b63387afc6b10e88631d1ef232c41ab6c18c8581Evan Cheng    }
185b63387afc6b10e88631d1ef232c41ab6c18c8581Evan Cheng
18622c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng    if (A->getSize() == 32) {
18722c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng      if (B == &ARM::DPR_VFP2RegClass)
18822c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng        return &ARM::QQPR_VFP2RegClass;
18922c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng      if (B == &ARM::DPR_8RegClass)
19022c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng        return 0;  // Do not allow coalescing!
19122c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng      return A;
19222c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng    }
19322c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng
19422c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng    assert(A->getSize() == 64 && "Expecting a QQQQ register class!");
19522c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng    if (B != &ARM::DPRRegClass)
19622c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng      return 0;  // Do not allow coalescing!
1974f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng    return A;
1984f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng  }
199e00fa64c16f40230d76417be8f09166b7c84c52dJakob Stoklund Olesen  case ARM::dsub_4:
200e00fa64c16f40230d76417be8f09166b7c84c52dJakob Stoklund Olesen  case ARM::dsub_5:
201e00fa64c16f40230d76417be8f09166b7c84c52dJakob Stoklund Olesen  case ARM::dsub_6:
202e00fa64c16f40230d76417be8f09166b7c84c52dJakob Stoklund Olesen  case ARM::dsub_7: {
20322c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng    // D sub-registers of QQQQ registers.
20422c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng    if (A->getSize() == 64 && B == &ARM::DPRRegClass)
20522c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng      return A;
20622c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng    return 0;  // Do not allow coalescing!
20722c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng  }
20822c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng
209e00fa64c16f40230d76417be8f09166b7c84c52dJakob Stoklund Olesen  case ARM::qsub_0:
210e00fa64c16f40230d76417be8f09166b7c84c52dJakob Stoklund Olesen  case ARM::qsub_1: {
211b63387afc6b10e88631d1ef232c41ab6c18c8581Evan Cheng    // Q sub-registers.
21222c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng    if (A->getSize() == 32) {
21322c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng      if (B == &ARM::QPR_VFP2RegClass)
21422c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng        return &ARM::QQPR_VFP2RegClass;
21522c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng      if (B == &ARM::QPR_8RegClass)
21622c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng        return 0;  // Do not allow coalescing!
21722c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng      return A;
21822c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng    }
21922c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng
22022c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng    assert(A->getSize() == 64 && "Expecting a QQQQ register class!");
22122c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng    if (B == &ARM::QPRRegClass)
22222c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng      return A;
22322c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng    return 0;  // Do not allow coalescing!
22422c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng  }
225e00fa64c16f40230d76417be8f09166b7c84c52dJakob Stoklund Olesen  case ARM::qsub_2:
226e00fa64c16f40230d76417be8f09166b7c84c52dJakob Stoklund Olesen  case ARM::qsub_3: {
22722c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng    // Q sub-registers of QQQQ registers.
22822c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng    if (A->getSize() == 64 && B == &ARM::QPRRegClass)
22922c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng      return A;
23022c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng    return 0;  // Do not allow coalescing!
231b63387afc6b10e88631d1ef232c41ab6c18c8581Evan Cheng  }
232b63387afc6b10e88631d1ef232c41ab6c18c8581Evan Cheng  }
2334f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng  return 0;
2344f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng}
2354f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng
236b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Chengbool
23791a74da036d3a9442953ae1de3e797a50da4ccf0Bob WilsonARMBaseRegisterInfo::canCombineSubRegIndices(const TargetRegisterClass *RC,
238b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng                                          SmallVectorImpl<unsigned> &SubIndices,
239b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng                                          unsigned &NewSubIdx) const {
240b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng
241b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng  unsigned Size = RC->getSize() * 8;
242b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng  if (Size < 6)
243b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng    return 0;
244b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng
245b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng  NewSubIdx = 0;  // Whole register.
246b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng  unsigned NumRegs = SubIndices.size();
247b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng  if (NumRegs == 8) {
248b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng    // 8 D registers -> 1 QQQQ register.
249b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng    return (Size == 512 &&
250558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen            SubIndices[0] == ARM::dsub_0 &&
251558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen            SubIndices[1] == ARM::dsub_1 &&
252558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen            SubIndices[2] == ARM::dsub_2 &&
253558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen            SubIndices[3] == ARM::dsub_3 &&
254558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen            SubIndices[4] == ARM::dsub_4 &&
255558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen            SubIndices[5] == ARM::dsub_5 &&
256558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen            SubIndices[6] == ARM::dsub_6 &&
257558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen            SubIndices[7] == ARM::dsub_7);
258b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng  } else if (NumRegs == 4) {
259558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen    if (SubIndices[0] == ARM::qsub_0) {
260b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng      // 4 Q registers -> 1 QQQQ register.
261b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng      return (Size == 512 &&
262558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen              SubIndices[1] == ARM::qsub_1 &&
263558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen              SubIndices[2] == ARM::qsub_2 &&
264558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen              SubIndices[3] == ARM::qsub_3);
265558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen    } else if (SubIndices[0] == ARM::dsub_0) {
266b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng      // 4 D registers -> 1 QQ register.
267b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng      if (Size >= 256 &&
268558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen          SubIndices[1] == ARM::dsub_1 &&
269558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen          SubIndices[2] == ARM::dsub_2 &&
270558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen          SubIndices[3] == ARM::dsub_3) {
271b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng        if (Size == 512)
272558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen          NewSubIdx = ARM::qqsub_0;
273b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng        return true;
274b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng      }
275558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen    } else if (SubIndices[0] == ARM::dsub_4) {
276b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng      // 4 D registers -> 1 QQ register (2nd).
277b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng      if (Size == 512 &&
278558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen          SubIndices[1] == ARM::dsub_5 &&
279558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen          SubIndices[2] == ARM::dsub_6 &&
280558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen          SubIndices[3] == ARM::dsub_7) {
281558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen        NewSubIdx = ARM::qqsub_1;
282b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng        return true;
283b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng      }
284558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen    } else if (SubIndices[0] == ARM::ssub_0) {
285b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng      // 4 S registers -> 1 Q register.
286b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng      if (Size >= 128 &&
287558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen          SubIndices[1] == ARM::ssub_1 &&
288558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen          SubIndices[2] == ARM::ssub_2 &&
289558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen          SubIndices[3] == ARM::ssub_3) {
290b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng        if (Size >= 256)
291558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen          NewSubIdx = ARM::qsub_0;
292b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng        return true;
293b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng      }
294b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng    }
295b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng  } else if (NumRegs == 2) {
296558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen    if (SubIndices[0] == ARM::qsub_0) {
297b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng      // 2 Q registers -> 1 QQ register.
298558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen      if (Size >= 256 && SubIndices[1] == ARM::qsub_1) {
299b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng        if (Size == 512)
300558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen          NewSubIdx = ARM::qqsub_0;
301b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng        return true;
302b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng      }
303558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen    } else if (SubIndices[0] == ARM::qsub_2) {
304b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng      // 2 Q registers -> 1 QQ register (2nd).
305558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen      if (Size == 512 && SubIndices[1] == ARM::qsub_3) {
306558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen        NewSubIdx = ARM::qqsub_1;
307b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng        return true;
308b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng      }
309558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen    } else if (SubIndices[0] == ARM::dsub_0) {
310b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng      // 2 D registers -> 1 Q register.
311558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen      if (Size >= 128 && SubIndices[1] == ARM::dsub_1) {
312b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng        if (Size >= 256)
313558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen          NewSubIdx = ARM::qsub_0;
314b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng        return true;
315b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng      }
316558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen    } else if (SubIndices[0] == ARM::dsub_2) {
317b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng      // 2 D registers -> 1 Q register (2nd).
318558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen      if (Size >= 256 && SubIndices[1] == ARM::dsub_3) {
319558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen        NewSubIdx = ARM::qsub_1;
320b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng        return true;
321b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng      }
322558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen    } else if (SubIndices[0] == ARM::dsub_4) {
323b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng      // 2 D registers -> 1 Q register (3rd).
324558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen      if (Size == 512 && SubIndices[1] == ARM::dsub_5) {
325558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen        NewSubIdx = ARM::qsub_2;
326b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng        return true;
327b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng      }
328558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen    } else if (SubIndices[0] == ARM::dsub_6) {
329b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng      // 2 D registers -> 1 Q register (3rd).
330558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen      if (Size == 512 && SubIndices[1] == ARM::dsub_7) {
331558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen        NewSubIdx = ARM::qsub_3;
332b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng        return true;
333b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng      }
334558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen    } else if (SubIndices[0] == ARM::ssub_0) {
335b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng      // 2 S registers -> 1 D register.
336558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen      if (SubIndices[1] == ARM::ssub_1) {
337b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng        if (Size >= 128)
338558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen          NewSubIdx = ARM::dsub_0;
339b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng        return true;
340b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng      }
341558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen    } else if (SubIndices[0] == ARM::ssub_2) {
342b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng      // 2 S registers -> 1 D register (2nd).
343558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen      if (Size >= 128 && SubIndices[1] == ARM::ssub_3) {
344558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen        NewSubIdx = ARM::dsub_1;
345b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng        return true;
346b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng      }
347b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng    }
348b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng  }
349b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng  return false;
350b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng}
351b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng
352c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesenconst TargetRegisterClass*
353c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund OlesenARMBaseRegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC)
354c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesen                                                                         const {
355c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesen  const TargetRegisterClass *Super = RC;
356c8e2bb68bbc4a71cc10084c8f89565b9f05e12efJakob Stoklund Olesen  TargetRegisterClass::sc_iterator I = RC->getSuperClasses();
357c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesen  do {
358c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesen    switch (Super->getID()) {
359c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesen    case ARM::GPRRegClassID:
360c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesen    case ARM::SPRRegClassID:
361c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesen    case ARM::DPRRegClassID:
362c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesen    case ARM::QPRRegClassID:
363c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesen    case ARM::QQPRRegClassID:
364c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesen    case ARM::QQQQPRRegClassID:
365c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesen      return Super;
366c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesen    }
367c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesen    Super = *I++;
368c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesen  } while (Super);
369c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesen  return RC;
370c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesen}
371b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng
3724f54c1293af174a8002db20faf7b4f82ba4e8514Evan Chengconst TargetRegisterClass *
3732cfd52c507bd5790457a171eb9bcb39019cc6860Chris LattnerARMBaseRegisterInfo::getPointerRegClass(unsigned Kind) const {
374e11a8f565c6a019ddc54667227be9c4d8f117473Jim Grosbach  return ARM::GPRRegisterClass;
375c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
376be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarich
377342e3161d9dd4fa485b47788aa0266f9c91c3832Evan Chengconst TargetRegisterClass *
378342e3161d9dd4fa485b47788aa0266f9c91c3832Evan ChengARMBaseRegisterInfo::getCrossCopyRegClass(const TargetRegisterClass *RC) const {
379342e3161d9dd4fa485b47788aa0266f9c91c3832Evan Cheng  if (RC == &ARM::CCRRegClass)
380342e3161d9dd4fa485b47788aa0266f9c91c3832Evan Cheng    return 0;  // Can't copy CCR registers.
381342e3161d9dd4fa485b47788aa0266f9c91c3832Evan Cheng  return RC;
382342e3161d9dd4fa485b47788aa0266f9c91c3832Evan Cheng}
383342e3161d9dd4fa485b47788aa0266f9c91c3832Evan Cheng
384be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarichunsigned
385be2119e8e2bc7006cfd638a24367acbfda625d16Cameron ZwarichARMBaseRegisterInfo::getRegPressureLimit(const TargetRegisterClass *RC,
386be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarich                                         MachineFunction &MF) const {
387be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarich  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
388be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarich
389be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarich  switch (RC->getID()) {
390be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarich  default:
391be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarich    return 0;
392be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarich  case ARM::tGPRRegClassID:
393be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarich    return TFI->hasFP(MF) ? 4 : 5;
394be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarich  case ARM::GPRRegClassID: {
395be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarich    unsigned FP = TFI->hasFP(MF) ? 1 : 0;
396be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarich    return 10 - FP - (STI.isR9Reserved() ? 1 : 0);
397be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarich  }
398be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarich  case ARM::SPRRegClassID:  // Currently not used as 'rep' register class.
399be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarich  case ARM::DPRRegClassID:
400be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarich    return 32 - 10;
401be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarich  }
402be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarich}
403c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
404dd5a8471526ceadf9bceb1a1221299b3db49c33aJakob Stoklund Olesen/// getRawAllocationOrder - Returns the register allocation order for a
405dd5a8471526ceadf9bceb1a1221299b3db49c33aJakob Stoklund Olesen/// specified register class with a target-dependent hint.
406dd5a8471526ceadf9bceb1a1221299b3db49c33aJakob Stoklund OlesenArrayRef<unsigned>
407dd5a8471526ceadf9bceb1a1221299b3db49c33aJakob Stoklund OlesenARMBaseRegisterInfo::getRawAllocationOrder(const TargetRegisterClass *RC,
408dd5a8471526ceadf9bceb1a1221299b3db49c33aJakob Stoklund Olesen                                           unsigned HintType, unsigned HintReg,
409dd5a8471526ceadf9bceb1a1221299b3db49c33aJakob Stoklund Olesen                                           const MachineFunction &MF) const {
41016c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
411c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // Alternative register allocation orders when favoring even / odd registers
412c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // of register pairs.
413c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
414c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // No FP, R9 is available.
415c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  static const unsigned GPREven1[] = {
416c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R0, ARM::R2, ARM::R4, ARM::R6, ARM::R8, ARM::R10,
417c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R1, ARM::R3, ARM::R12,ARM::LR, ARM::R5, ARM::R7,
418c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R9, ARM::R11
419c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
420c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  static const unsigned GPROdd1[] = {
421c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R1, ARM::R3, ARM::R5, ARM::R7, ARM::R9, ARM::R11,
422c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R0, ARM::R2, ARM::R12,ARM::LR, ARM::R4, ARM::R6,
423c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R8, ARM::R10
424c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
425c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
426c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // FP is R7, R9 is available.
427c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  static const unsigned GPREven2[] = {
428c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R0, ARM::R2, ARM::R4,          ARM::R8, ARM::R10,
429c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R1, ARM::R3, ARM::R12,ARM::LR, ARM::R5, ARM::R6,
430c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R9, ARM::R11
431c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
432c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  static const unsigned GPROdd2[] = {
433c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R1, ARM::R3, ARM::R5,          ARM::R9, ARM::R11,
434c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R0, ARM::R2, ARM::R12,ARM::LR, ARM::R4, ARM::R6,
435c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R8, ARM::R10
436c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
437c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
438c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // FP is R11, R9 is available.
439c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  static const unsigned GPREven3[] = {
440c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R0, ARM::R2, ARM::R4, ARM::R6, ARM::R8,
441c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R1, ARM::R3, ARM::R10,ARM::R12,ARM::LR, ARM::R5, ARM::R7,
442c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R9
443c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
444c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  static const unsigned GPROdd3[] = {
445c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R1, ARM::R3, ARM::R5, ARM::R6, ARM::R9,
446c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R0, ARM::R2, ARM::R10,ARM::R12,ARM::LR, ARM::R4, ARM::R7,
447c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R8
448c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
449c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
450c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // No FP, R9 is not available.
451c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  static const unsigned GPREven4[] = {
452c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R0, ARM::R2, ARM::R4, ARM::R6,          ARM::R10,
453c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R1, ARM::R3, ARM::R12,ARM::LR, ARM::R5, ARM::R7, ARM::R8,
454c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R11
455c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
456c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  static const unsigned GPROdd4[] = {
457c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R1, ARM::R3, ARM::R5, ARM::R7,          ARM::R11,
458c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R0, ARM::R2, ARM::R12,ARM::LR, ARM::R4, ARM::R6, ARM::R8,
459c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R10
460c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
461c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
462c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // FP is R7, R9 is not available.
463c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  static const unsigned GPREven5[] = {
464c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R0, ARM::R2, ARM::R4,                   ARM::R10,
465c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R1, ARM::R3, ARM::R12,ARM::LR, ARM::R5, ARM::R6, ARM::R8,
466c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R11
467c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
468c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  static const unsigned GPROdd5[] = {
469c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R1, ARM::R3, ARM::R5,                   ARM::R11,
470c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R0, ARM::R2, ARM::R12,ARM::LR, ARM::R4, ARM::R6, ARM::R8,
471c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R10
472c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
473c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
474c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // FP is R11, R9 is not available.
475c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  static const unsigned GPREven6[] = {
476c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R0, ARM::R2, ARM::R4, ARM::R6,
477c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R1, ARM::R3, ARM::R10,ARM::R12,ARM::LR, ARM::R5, ARM::R7, ARM::R8
478c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
479c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  static const unsigned GPROdd6[] = {
480c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R1, ARM::R3, ARM::R5, ARM::R7,
481c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R0, ARM::R2, ARM::R10,ARM::R12,ARM::LR, ARM::R4, ARM::R6, ARM::R8
482c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
483c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
484eb5067e0d9ca182f21db24949b63616ce4bb1eafJakob Stoklund Olesen  // We only support even/odd hints for GPR and rGPR.
485eb5067e0d9ca182f21db24949b63616ce4bb1eafJakob Stoklund Olesen  if (RC != ARM::GPRRegisterClass && RC != ARM::rGPRRegisterClass)
486dd5a8471526ceadf9bceb1a1221299b3db49c33aJakob Stoklund Olesen    return RC->getRawAllocationOrder(MF);
487c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
488c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  if (HintType == ARMRI::RegPairEven) {
489c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    if (isPhysicalRegister(HintReg) && getRegisterPairEven(HintReg, MF) == 0)
490c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      // It's no longer possible to fulfill this hint. Return the default
491c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      // allocation order.
492dd5a8471526ceadf9bceb1a1221299b3db49c33aJakob Stoklund Olesen      return RC->getRawAllocationOrder(MF);
493c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
494d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov    if (!TFI->hasFP(MF)) {
495c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      if (!STI.isR9Reserved())
49639b5abf507b43da6b92f68b86406e0015ead18e9Frits van Bommel        return makeArrayRef(GPREven1);
497c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      else
49839b5abf507b43da6b92f68b86406e0015ead18e9Frits van Bommel        return makeArrayRef(GPREven4);
499c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    } else if (FramePtr == ARM::R7) {
500c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      if (!STI.isR9Reserved())
50139b5abf507b43da6b92f68b86406e0015ead18e9Frits van Bommel        return makeArrayRef(GPREven2);
502c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      else
50339b5abf507b43da6b92f68b86406e0015ead18e9Frits van Bommel        return makeArrayRef(GPREven5);
504c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    } else { // FramePtr == ARM::R11
505c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      if (!STI.isR9Reserved())
50639b5abf507b43da6b92f68b86406e0015ead18e9Frits van Bommel        return makeArrayRef(GPREven3);
507c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      else
50839b5abf507b43da6b92f68b86406e0015ead18e9Frits van Bommel        return makeArrayRef(GPREven6);
509c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    }
510c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  } else if (HintType == ARMRI::RegPairOdd) {
511c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    if (isPhysicalRegister(HintReg) && getRegisterPairOdd(HintReg, MF) == 0)
512c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      // It's no longer possible to fulfill this hint. Return the default
513c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      // allocation order.
514dd5a8471526ceadf9bceb1a1221299b3db49c33aJakob Stoklund Olesen      return RC->getRawAllocationOrder(MF);
515c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
516d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov    if (!TFI->hasFP(MF)) {
517c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      if (!STI.isR9Reserved())
51839b5abf507b43da6b92f68b86406e0015ead18e9Frits van Bommel        return makeArrayRef(GPROdd1);
519c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      else
52039b5abf507b43da6b92f68b86406e0015ead18e9Frits van Bommel        return makeArrayRef(GPROdd4);
521c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    } else if (FramePtr == ARM::R7) {
522c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      if (!STI.isR9Reserved())
52339b5abf507b43da6b92f68b86406e0015ead18e9Frits van Bommel        return makeArrayRef(GPROdd2);
524c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      else
52539b5abf507b43da6b92f68b86406e0015ead18e9Frits van Bommel        return makeArrayRef(GPROdd5);
526c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    } else { // FramePtr == ARM::R11
527c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      if (!STI.isR9Reserved())
52839b5abf507b43da6b92f68b86406e0015ead18e9Frits van Bommel        return makeArrayRef(GPROdd3);
529c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      else
53039b5abf507b43da6b92f68b86406e0015ead18e9Frits van Bommel        return makeArrayRef(GPROdd6);
531c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    }
532c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  }
533dd5a8471526ceadf9bceb1a1221299b3db49c33aJakob Stoklund Olesen  return RC->getRawAllocationOrder(MF);
534c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
535c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
536c140c4803dc3e10e08138670829bc0494986abe9David Goodwin/// ResolveRegAllocHint - Resolves the specified register allocation hint
537c140c4803dc3e10e08138670829bc0494986abe9David Goodwin/// to a physical register. Returns the physical register if it is successful.
538c140c4803dc3e10e08138670829bc0494986abe9David Goodwinunsigned
539c140c4803dc3e10e08138670829bc0494986abe9David GoodwinARMBaseRegisterInfo::ResolveRegAllocHint(unsigned Type, unsigned Reg,
540c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                                         const MachineFunction &MF) const {
541c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  if (Reg == 0 || !isPhysicalRegister(Reg))
542c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return 0;
543c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  if (Type == 0)
544c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return Reg;
545c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  else if (Type == (unsigned)ARMRI::RegPairOdd)
546c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // Odd register.
547c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return getRegisterPairOdd(Reg, MF);
548c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  else if (Type == (unsigned)ARMRI::RegPairEven)
549c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // Even register.
550c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return getRegisterPairEven(Reg, MF);
551c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  return 0;
552c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
553c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
554c140c4803dc3e10e08138670829bc0494986abe9David Goodwinvoid
555c140c4803dc3e10e08138670829bc0494986abe9David GoodwinARMBaseRegisterInfo::UpdateRegAllocHint(unsigned Reg, unsigned NewReg,
556c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                                        MachineFunction &MF) const {
557c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  MachineRegisterInfo *MRI = &MF.getRegInfo();
558c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  std::pair<unsigned, unsigned> Hint = MRI->getRegAllocationHint(Reg);
559c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  if ((Hint.first == (unsigned)ARMRI::RegPairOdd ||
560c140c4803dc3e10e08138670829bc0494986abe9David Goodwin       Hint.first == (unsigned)ARMRI::RegPairEven) &&
561c9df025e33ac435adb3b3318d237c36ca7cec659Jakob Stoklund Olesen      TargetRegisterInfo::isVirtualRegister(Hint.second)) {
562c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // If 'Reg' is one of the even / odd register pair and it's now changed
563c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // (e.g. coalesced) into a different register. The other register of the
564c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // pair allocation hint must be updated to reflect the relationship
565c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // change.
566c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    unsigned OtherReg = Hint.second;
567c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    Hint = MRI->getRegAllocationHint(OtherReg);
568c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    if (Hint.second == Reg)
569c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      // Make sure the pair has not already divorced.
570c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      MRI->setRegAllocationHint(OtherReg, Hint.first, NewReg);
571c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  }
572c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
573f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson
574f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilsonbool
575f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob WilsonARMBaseRegisterInfo::avoidWriteAfterWrite(const TargetRegisterClass *RC) const {
576f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson  // CortexA9 has a Write-after-write hazard for NEON registers.
577f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson  if (!STI.isCortexA9())
578f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson    return false;
579f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson
580f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson  switch (RC->getID()) {
581f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson  case ARM::DPRRegClassID:
582f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson  case ARM::DPR_8RegClassID:
583f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson  case ARM::DPR_VFP2RegClassID:
584f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson  case ARM::QPRRegClassID:
585f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson  case ARM::QPR_8RegClassID:
586f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson  case ARM::QPR_VFP2RegClassID:
587f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson  case ARM::SPRRegClassID:
588f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson  case ARM::SPR_8RegClassID:
589f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson    // Avoid reusing S, D, and Q registers.
590f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson    // Don't increase register pressure for QQ and QQQQ.
591f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson    return true;
592f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson  default:
593f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson    return false;
594f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson  }
595f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson}
596c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
59765482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbachbool ARMBaseRegisterInfo::hasBasePointer(const MachineFunction &MF) const {
5986a8700301ca6f8f2f5f787c8d1f5206a7dfceed6Daniel Dunbar  const MachineFrameInfo *MFI = MF.getFrameInfo();
5991755b3964f931bdd6fa9b4c0138f666ccfa12acaJim Grosbach  const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
60065482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach
60165482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach  if (!EnableBasePointer)
60265482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach    return false;
60365482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach
60465482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach  if (needsStackRealignment(MF) && MFI->hasVarSizedObjects())
60565482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach    return true;
60665482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach
60765482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach  // Thumb has trouble with negative offsets from the FP. Thumb2 has a limited
60865482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach  // negative range for ldr/str (255), and thumb1 is positive offsets only.
60965482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach  // It's going to be better to use the SP or Base Pointer instead. When there
61065482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach  // are variable sized objects, we can't reference off of the SP, so we
61165482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach  // reserve a Base Pointer.
61265482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach  if (AFI->isThumbFunction() && MFI->hasVarSizedObjects()) {
61365482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach    // Conservatively estimate whether the negative offset from the frame
61465482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach    // pointer will be sufficient to reach. If a function has a smallish
61565482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach    // frame, it's less likely to have lots of spills and callee saved
61665482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach    // space, so it's all more likely to be within range of the frame pointer.
61765482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach    // If it's wrong, the scavenger will still enable access to work, it just
61865482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach    // won't be optimal.
61965482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach    if (AFI->isThumb2Function() && MFI->getLocalFrameSize() < 128)
62065482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach      return false;
62165482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach    return true;
62265482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach  }
62365482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach
62465482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach  return false;
62565482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach}
62665482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach
62765482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbachbool ARMBaseRegisterInfo::canRealignStack(const MachineFunction &MF) const {
62830c93e1cd3e43e174994834900325fcff3322288Jim Grosbach  const MachineFrameInfo *MFI = MF.getFrameInfo();
6296690bca623d1f6405b95db5b1760f7ba8436e3fbChad Rosier  const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
63030c93e1cd3e43e174994834900325fcff3322288Jim Grosbach  // We can't realign the stack if:
63130c93e1cd3e43e174994834900325fcff3322288Jim Grosbach  // 1. Dynamic stack realignment is explicitly disabled,
6326690bca623d1f6405b95db5b1760f7ba8436e3fbChad Rosier  // 2. This is a Thumb1 function (it's not useful, so we don't bother), or
6336690bca623d1f6405b95db5b1760f7ba8436e3fbChad Rosier  // 3. There are VLAs in the function and the base pointer is disabled.
6348a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky  return (MF.getTarget().Options.RealignStack && !AFI->isThumb1OnlyFunction() &&
6356690bca623d1f6405b95db5b1760f7ba8436e3fbChad Rosier          (!MFI->hasVarSizedObjects() || EnableBasePointer));
636e45ab8a0a90e4f3a59d8c38038ae3e495ee1fef3Jim Grosbach}
637e45ab8a0a90e4f3a59d8c38038ae3e495ee1fef3Jim Grosbach
6383dab2778571b5bb00b35a0adcb7011dc85158bebJim Grosbachbool ARMBaseRegisterInfo::
6393dab2778571b5bb00b35a0adcb7011dc85158bebJim GrosbachneedsStackRealignment(const MachineFunction &MF) const {
6403dab2778571b5bb00b35a0adcb7011dc85158bebJim Grosbach  const MachineFrameInfo *MFI = MF.getFrameInfo();
641d4c36cec1db81b4ee48cd4ab462262615d78f22cEric Christopher  const Function *F = MF.getFunction();
64216c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  unsigned StackAlign = MF.getTarget().getFrameLowering()->getStackAlignment();
643fc633002339439339e94f83eca9a012c6fc51e50Jim Grosbach  bool requiresRealignment = ((MFI->getLocalFrameMaxAlign() > StackAlign) ||
644697cba8ec2b3f5160175fd5b4a641dbd48606e17Eric Christopher                               F->hasFnAttr(Attribute::StackAlignment));
6455c33f5bf67f61e3a1addda6de735d28d550dd0ebJim Grosbach
646d4c36cec1db81b4ee48cd4ab462262615d78f22cEric Christopher  return requiresRealignment && canRealignStack(MF);
6473dab2778571b5bb00b35a0adcb7011dc85158bebJim Grosbach}
6483dab2778571b5bb00b35a0adcb7011dc85158bebJim Grosbach
6499631864688c593711f82bb8d21f8b724c628d786Jim Grosbachbool ARMBaseRegisterInfo::
6509631864688c593711f82bb8d21f8b724c628d786Jim GrosbachcannotEliminateFrame(const MachineFunction &MF) const {
65198a0104014e9bb6ed89c2572f615351fd526674aEvan Cheng  const MachineFrameInfo *MFI = MF.getFrameInfo();
6528a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky  if (MF.getTarget().Options.DisableFramePointerElim(MF) && MFI->adjustsStack())
65398a0104014e9bb6ed89c2572f615351fd526674aEvan Cheng    return true;
65431bc849123011b8eae6bb3c79876d9a3c26a6a1dJim Grosbach  return MFI->hasVarSizedObjects() || MFI->isFrameAddressTaken()
65531bc849123011b8eae6bb3c79876d9a3c26a6a1dJim Grosbach    || needsStackRealignment(MF);
65698a0104014e9bb6ed89c2572f615351fd526674aEvan Cheng}
65798a0104014e9bb6ed89c2572f615351fd526674aEvan Cheng
6585c33f5bf67f61e3a1addda6de735d28d550dd0ebJim Grosbachunsigned
6593f2bf85d14759cc4b28a86805f566ac805a54d00David GreeneARMBaseRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
66016c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
661d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov
662d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  if (TFI->hasFP(MF))
663c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return FramePtr;
664c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  return ARM::SP;
665c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
666c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
667c140c4803dc3e10e08138670829bc0494986abe9David Goodwinunsigned ARMBaseRegisterInfo::getEHExceptionRegister() const {
668c23197a26f34f559ea9797de51e187087c039c42Torok Edwin  llvm_unreachable("What is the exception register");
669c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  return 0;
670c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
671c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
672c140c4803dc3e10e08138670829bc0494986abe9David Goodwinunsigned ARMBaseRegisterInfo::getEHHandlerRegister() const {
673c23197a26f34f559ea9797de51e187087c039c42Torok Edwin  llvm_unreachable("What is the exception handler register");
674c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  return 0;
675c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
676c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
677c140c4803dc3e10e08138670829bc0494986abe9David Goodwinunsigned ARMBaseRegisterInfo::getRegisterPairEven(unsigned Reg,
6789631864688c593711f82bb8d21f8b724c628d786Jim Grosbach                                              const MachineFunction &MF) const {
679c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  switch (Reg) {
680c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  default: break;
681c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // Return 0 if either register of the pair is a special register.
682c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // So no R12, etc.
6838f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::R1: return ARM::R0;
6848f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::R3: return ARM::R2;
6858f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::R5: return ARM::R4;
686c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::R7:
68765482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach    return (isReservedReg(MF, ARM::R7) || isReservedReg(MF, ARM::R6))
68865482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach      ? 0 : ARM::R6;
6898f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::R9: return isReservedReg(MF, ARM::R9)  ? 0 :ARM::R8;
6908f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::R11: return isReservedReg(MF, ARM::R11) ? 0 : ARM::R10;
6918f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach
6928f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S1: return ARM::S0;
6938f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S3: return ARM::S2;
6948f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S5: return ARM::S4;
6958f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S7: return ARM::S6;
6968f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S9: return ARM::S8;
6978f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S11: return ARM::S10;
6988f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S13: return ARM::S12;
6998f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S15: return ARM::S14;
7008f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S17: return ARM::S16;
7018f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S19: return ARM::S18;
7028f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S21: return ARM::S20;
7038f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S23: return ARM::S22;
7048f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S25: return ARM::S24;
7058f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S27: return ARM::S26;
7068f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S29: return ARM::S28;
7078f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S31: return ARM::S30;
7088f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach
7098f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D1: return ARM::D0;
7108f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D3: return ARM::D2;
7118f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D5: return ARM::D4;
7128f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D7: return ARM::D6;
7138f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D9: return ARM::D8;
7148f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D11: return ARM::D10;
7158f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D13: return ARM::D12;
7168f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D15: return ARM::D14;
7178f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D17: return ARM::D16;
7188f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D19: return ARM::D18;
7198f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D21: return ARM::D20;
7208f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D23: return ARM::D22;
7218f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D25: return ARM::D24;
7228f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D27: return ARM::D26;
7238f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D29: return ARM::D28;
7248f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D31: return ARM::D30;
725c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  }
726c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
727c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  return 0;
728c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
729c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
730c140c4803dc3e10e08138670829bc0494986abe9David Goodwinunsigned ARMBaseRegisterInfo::getRegisterPairOdd(unsigned Reg,
731c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                                             const MachineFunction &MF) const {
732c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  switch (Reg) {
733c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  default: break;
734c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // Return 0 if either register of the pair is a special register.
735c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // So no R12, etc.
7368f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::R0: return ARM::R1;
7378f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::R2: return ARM::R3;
7388f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::R4: return ARM::R5;
739c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::R6:
74065482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach    return (isReservedReg(MF, ARM::R7) || isReservedReg(MF, ARM::R6))
74165482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach      ? 0 : ARM::R7;
7428f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::R8: return isReservedReg(MF, ARM::R9)  ? 0 :ARM::R9;
7438f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::R10: return isReservedReg(MF, ARM::R11) ? 0 : ARM::R11;
7448f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach
7458f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S0: return ARM::S1;
7468f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S2: return ARM::S3;
7478f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S4: return ARM::S5;
7488f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S6: return ARM::S7;
7498f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S8: return ARM::S9;
7508f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S10: return ARM::S11;
7518f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S12: return ARM::S13;
7528f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S14: return ARM::S15;
7538f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S16: return ARM::S17;
7548f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S18: return ARM::S19;
7558f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S20: return ARM::S21;
7568f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S22: return ARM::S23;
7578f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S24: return ARM::S25;
7588f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S26: return ARM::S27;
7598f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S28: return ARM::S29;
7608f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::S30: return ARM::S31;
7618f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach
7628f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D0: return ARM::D1;
7638f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D2: return ARM::D3;
7648f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D4: return ARM::D5;
7658f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D6: return ARM::D7;
7668f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D8: return ARM::D9;
7678f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D10: return ARM::D11;
7688f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D12: return ARM::D13;
7698f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D14: return ARM::D15;
7708f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D16: return ARM::D17;
7718f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D18: return ARM::D19;
7728f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D20: return ARM::D21;
7738f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D22: return ARM::D23;
7748f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D24: return ARM::D25;
7758f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D26: return ARM::D27;
7768f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D28: return ARM::D29;
7778f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach  case ARM::D30: return ARM::D31;
778c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  }
779c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
780c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  return 0;
781c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
782c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
783db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin/// emitLoadConstPool - Emits a load from constpool to materialize the
784db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin/// specified immediate.
785db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwinvoid ARMBaseRegisterInfo::
786db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid GoodwinemitLoadConstPool(MachineBasicBlock &MBB,
787db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin                  MachineBasicBlock::iterator &MBBI,
78877521f5232e679aa3de10aaaed2464aa91d7ff55David Goodwin                  DebugLoc dl,
789378445303b10b092a898a75131141a8259cff50bEvan Cheng                  unsigned DestReg, unsigned SubIdx, int Val,
790db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin                  ARMCC::CondCodes Pred,
7913daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov                  unsigned PredReg, unsigned MIFlags) const {
792db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  MachineFunction &MF = *MBB.getParent();
793db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  MachineConstantPool *ConstantPool = MF.getConstantPool();
79446510a73e977273ec67747eb34cbdb43f815e451Dan Gohman  const Constant *C =
7951d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson        ConstantInt::get(Type::getInt32Ty(MF.getFunction()->getContext()), Val);
796db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4);
797db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
798378445303b10b092a898a75131141a8259cff50bEvan Cheng  BuildMI(MBB, MBBI, dl, TII.get(ARM::LDRcp))
799378445303b10b092a898a75131141a8259cff50bEvan Cheng    .addReg(DestReg, getDefRegState(true), SubIdx)
800db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    .addConstantPoolIndex(Idx)
8013daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov    .addImm(0).addImm(Pred).addReg(PredReg)
8023daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov    .setMIFlags(MIFlags);
803db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin}
804db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
805db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwinbool ARMBaseRegisterInfo::
806db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid GoodwinrequiresRegisterScavenging(const MachineFunction &MF) const {
807db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  return true;
808db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin}
80941fff8c19ab6d8e28f5362481c184ad628f8c704Jim Grosbach
8107e831db1d4f5dc51ca6526739cf41e59895c5c20Jim Grosbachbool ARMBaseRegisterInfo::
8117e831db1d4f5dc51ca6526739cf41e59895c5c20Jim GrosbachrequiresFrameIndexScavenging(const MachineFunction &MF) const {
812ca5dfb71ba4aa4a8392a021ec056cf0b70f74f1eJim Grosbach  return true;
8137e831db1d4f5dc51ca6526739cf41e59895c5c20Jim Grosbach}
814db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
815a273442891ae20fd8192526132e3819ea9e5eda9Jim Grosbachbool ARMBaseRegisterInfo::
816a273442891ae20fd8192526132e3819ea9e5eda9Jim GrosbachrequiresVirtualBaseRegisters(const MachineFunction &MF) const {
817a273442891ae20fd8192526132e3819ea9e5eda9Jim Grosbach  return EnableLocalStackAlloc;
818a273442891ae20fd8192526132e3819ea9e5eda9Jim Grosbach}
819a273442891ae20fd8192526132e3819ea9e5eda9Jim Grosbach
820db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwinstatic void
8216495f63945e8dbde81f03a1dc2ab421993b9a495Evan ChengemitSPUpdate(bool isARM,
8226495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng             MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
8236495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng             DebugLoc dl, const ARMBaseInstrInfo &TII,
824db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin             int NumBytes,
825db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin             ARMCC::CondCodes Pred = ARMCC::AL, unsigned PredReg = 0) {
8266495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng  if (isARM)
8276495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    emitARMRegPlusImmediate(MBB, MBBI, dl, ARM::SP, ARM::SP, NumBytes,
8286495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng                            Pred, PredReg, TII);
8296495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng  else
8306495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    emitT2RegPlusImmediate(MBB, MBBI, dl, ARM::SP, ARM::SP, NumBytes,
8316495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng                           Pred, PredReg, TII);
832db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin}
833db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
8346495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng
835db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwinvoid ARMBaseRegisterInfo::
836db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid GoodwineliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
837db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin                              MachineBasicBlock::iterator I) const {
83816c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
839d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  if (!TFI->hasReservedCallFrame(MF)) {
840db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    // If we have alloca, convert as follows:
841db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    // ADJCALLSTACKDOWN -> sub, sp, sp, amount
842db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    // ADJCALLSTACKUP   -> add, sp, sp, amount
843db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    MachineInstr *Old = I;
844db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    DebugLoc dl = Old->getDebugLoc();
845db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    unsigned Amount = Old->getOperand(0).getImm();
846db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    if (Amount != 0) {
847db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      // We need to keep the stack aligned properly.  To do this, we round the
848db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      // amount of space needed for the outgoing arguments up to the next
849db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      // alignment boundary.
85016c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov      unsigned Align = TFI->getStackAlignment();
851db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      Amount = (Amount+Align-1)/Align*Align;
852db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
8536495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng      ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
8546495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng      assert(!AFI->isThumb1OnlyFunction() &&
855cf453ee70a1ae03cc641686fd5db0f8a7d8ce250Jim Grosbach             "This eliminateCallFramePseudoInstr does not support Thumb1!");
8566495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng      bool isARM = !AFI->isThumbFunction();
8576495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng
858db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      // Replace the pseudo instruction with a new instruction...
859db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      unsigned Opc = Old->getOpcode();
8604c7628e43d8468f215ea345545479b6d728cee92Jim Grosbach      int PIdx = Old->findFirstPredOperandIdx();
8614c7628e43d8468f215ea345545479b6d728cee92Jim Grosbach      ARMCC::CondCodes Pred = (PIdx == -1)
8624c7628e43d8468f215ea345545479b6d728cee92Jim Grosbach        ? ARMCC::AL : (ARMCC::CondCodes)Old->getOperand(PIdx).getImm();
863db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      if (Opc == ARM::ADJCALLSTACKDOWN || Opc == ARM::tADJCALLSTACKDOWN) {
864db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        // Note: PredReg is operand 2 for ADJCALLSTACKDOWN.
865db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        unsigned PredReg = Old->getOperand(2).getReg();
8666495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng        emitSPUpdate(isARM, MBB, I, dl, TII, -Amount, Pred, PredReg);
867db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      } else {
868db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        // Note: PredReg is operand 3 for ADJCALLSTACKUP.
869db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        unsigned PredReg = Old->getOperand(3).getReg();
870db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        assert(Opc == ARM::ADJCALLSTACKUP || Opc == ARM::tADJCALLSTACKUP);
8716495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng        emitSPUpdate(isARM, MBB, I, dl, TII, Amount, Pred, PredReg);
872db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      }
873db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    }
874db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  }
875db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  MBB.erase(I);
876db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin}
877db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
878e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbachint64_t ARMBaseRegisterInfo::
8791ab3f16f06698596716593a30545799688acccd7Jim GrosbachgetFrameIndexInstrOffset(const MachineInstr *MI, int Idx) const {
880e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  const MCInstrDesc &Desc = MI->getDesc();
881e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach  unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
882e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach  int64_t InstrOffs = 0;;
883e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach  int Scale = 1;
884e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach  unsigned ImmIdx = 0;
8851ab3f16f06698596716593a30545799688acccd7Jim Grosbach  switch (AddrMode) {
886e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach  case ARMII::AddrModeT2_i8:
887e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach  case ARMII::AddrModeT2_i12:
8883e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach  case ARMII::AddrMode_i12:
889e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach    InstrOffs = MI->getOperand(Idx+1).getImm();
890e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach    Scale = 1;
891e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach    break;
892e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach  case ARMII::AddrMode5: {
893e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach    // VFP address mode.
894e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach    const MachineOperand &OffOp = MI->getOperand(Idx+1);
895f78ee6316bc755779920ac207edc27a89c0bd2f9Jim Grosbach    InstrOffs = ARM_AM::getAM5Offset(OffOp.getImm());
896e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach    if (ARM_AM::getAM5Op(OffOp.getImm()) == ARM_AM::sub)
897e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach      InstrOffs = -InstrOffs;
898e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach    Scale = 4;
899e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach    break;
900e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach  }
901e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach  case ARMII::AddrMode2: {
902e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach    ImmIdx = Idx+2;
903e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach    InstrOffs = ARM_AM::getAM2Offset(MI->getOperand(ImmIdx).getImm());
904e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach    if (ARM_AM::getAM2Op(MI->getOperand(ImmIdx).getImm()) == ARM_AM::sub)
905e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach      InstrOffs = -InstrOffs;
906e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach    break;
907e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach  }
908e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach  case ARMII::AddrMode3: {
909e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach    ImmIdx = Idx+2;
910e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach    InstrOffs = ARM_AM::getAM3Offset(MI->getOperand(ImmIdx).getImm());
911e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach    if (ARM_AM::getAM3Op(MI->getOperand(ImmIdx).getImm()) == ARM_AM::sub)
912e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach      InstrOffs = -InstrOffs;
913e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach    break;
914e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach  }
915e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach  case ARMII::AddrModeT1_s: {
916e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach    ImmIdx = Idx+1;
917e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach    InstrOffs = MI->getOperand(ImmIdx).getImm();
918e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach    Scale = 4;
919e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach    break;
920e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach  }
921e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach  default:
922e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach    llvm_unreachable("Unsupported addressing mode!");
923e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach    break;
924e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach  }
925e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach
926e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach  return InstrOffs * Scale;
927e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach}
928e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach
9298708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach/// needsFrameBaseReg - Returns true if the instruction's frame index
9308708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach/// reference would be better served by a base register other than FP
9318708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach/// or SP. Used by LocalStackFrameAllocation to determine which frame index
9328708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach/// references it should create new base registers for.
9338708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbachbool ARMBaseRegisterInfo::
9343197380143cdc18837722129ac888528b9fbfc2bJim GrosbachneedsFrameBaseReg(MachineInstr *MI, int64_t Offset) const {
9353197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  for (unsigned i = 0; !MI->getOperand(i).isFI(); ++i) {
9363197380143cdc18837722129ac888528b9fbfc2bJim Grosbach    assert(i < MI->getNumOperands() &&"Instr doesn't have FrameIndex operand!");
9373197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  }
9388708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach
9398708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach  // It's the load/store FI references that cause issues, as it can be difficult
9408708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach  // to materialize the offset if it won't fit in the literal field. Estimate
9418708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach  // based on the size of the local frame and some conservative assumptions
9428708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach  // about the rest of the stack frame (note, this is pre-regalloc, so
9438708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach  // we don't know everything for certain yet) whether this offset is likely
9448708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach  // to be out of range of the immediate. Return true if so.
9458708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach
946cd59dc5e81eb080cd9b61f5a7e7d9f3eec206d8cJim Grosbach  // We only generate virtual base registers for loads and stores, so
947cd59dc5e81eb080cd9b61f5a7e7d9f3eec206d8cJim Grosbach  // return false for everything else.
9488708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach  unsigned Opc = MI->getOpcode();
9498708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach  switch (Opc) {
950c1d30212e911d1e55ff6b25bffefb503708883c3Jim Grosbach  case ARM::LDRi12: case ARM::LDRH: case ARM::LDRBi12:
9517e3383c007f53b3a00675af225e428cb66ddf404Jim Grosbach  case ARM::STRi12: case ARM::STRH: case ARM::STRBi12:
9528708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach  case ARM::t2LDRi12: case ARM::t2LDRi8:
9538708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach  case ARM::t2STRi12: case ARM::t2STRi8:
9548708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach  case ARM::VLDRS: case ARM::VLDRD:
9558708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach  case ARM::VSTRS: case ARM::VSTRD:
95674d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach  case ARM::tSTRspi: case ARM::tLDRspi:
957cd59dc5e81eb080cd9b61f5a7e7d9f3eec206d8cJim Grosbach    if (ForceAllBaseRegAlloc)
958cd59dc5e81eb080cd9b61f5a7e7d9f3eec206d8cJim Grosbach      return true;
959cd59dc5e81eb080cd9b61f5a7e7d9f3eec206d8cJim Grosbach    break;
9608708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach  default:
9618708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach    return false;
9628708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach  }
963cd59dc5e81eb080cd9b61f5a7e7d9f3eec206d8cJim Grosbach
964cd59dc5e81eb080cd9b61f5a7e7d9f3eec206d8cJim Grosbach  // Without a virtual base register, if the function has variable sized
965cd59dc5e81eb080cd9b61f5a7e7d9f3eec206d8cJim Grosbach  // objects, all fixed-size local references will be via the frame pointer,
9663197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  // Approximate the offset and see if it's legal for the instruction.
9673197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  // Note that the incoming offset is based on the SP value at function entry,
9683197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  // so it'll be negative.
9693197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  MachineFunction &MF = *MI->getParent()->getParent();
97016c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
9713197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  MachineFrameInfo *MFI = MF.getFrameInfo();
9723197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
9733197380143cdc18837722129ac888528b9fbfc2bJim Grosbach
9743197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  // Estimate an offset from the frame pointer.
9753197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  // Conservatively assume all callee-saved registers get pushed. R4-R6
9763197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  // will be earlier than the FP, so we ignore those.
9773197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  // R7, LR
9783197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  int64_t FPOffset = Offset - 8;
9793197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  // ARM and Thumb2 functions also need to consider R8-R11 and D8-D15
9803197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  if (!AFI->isThumbFunction() || !AFI->isThumb1OnlyFunction())
9813197380143cdc18837722129ac888528b9fbfc2bJim Grosbach    FPOffset -= 80;
9823197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  // Estimate an offset from the stack pointer.
983c1dc78de762e8a65fe1edd0cced13d94ab5a971fJim Grosbach  // The incoming offset is relating to the SP at the start of the function,
984c1dc78de762e8a65fe1edd0cced13d94ab5a971fJim Grosbach  // but when we access the local it'll be relative to the SP after local
985c1dc78de762e8a65fe1edd0cced13d94ab5a971fJim Grosbach  // allocation, so adjust our SP-relative offset by that allocation size.
9863197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  Offset = -Offset;
987c1dc78de762e8a65fe1edd0cced13d94ab5a971fJim Grosbach  Offset += MFI->getLocalFrameSize();
9883197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  // Assume that we'll have at least some spill slots allocated.
9893197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  // FIXME: This is a total SWAG number. We should run some statistics
9903197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  //        and pick a real one.
9913197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  Offset += 128; // 128 bytes of spill slots
9923197380143cdc18837722129ac888528b9fbfc2bJim Grosbach
9933197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  // If there is a frame pointer, try using it.
9943197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  // The FP is only available if there is no dynamic realignment. We
9953197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  // don't know for sure yet whether we'll need that, so we guess based
9963197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  // on whether there are any local variables that would trigger it.
99716c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  unsigned StackAlign = TFI->getStackAlignment();
998d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  if (TFI->hasFP(MF) &&
9993197380143cdc18837722129ac888528b9fbfc2bJim Grosbach      !((MFI->getLocalFrameMaxAlign() > StackAlign) && canRealignStack(MF))) {
10003197380143cdc18837722129ac888528b9fbfc2bJim Grosbach    if (isFrameOffsetLegal(MI, FPOffset))
10013197380143cdc18837722129ac888528b9fbfc2bJim Grosbach      return false;
10023197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  }
10033197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  // If we can reference via the stack pointer, try that.
10043197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  // FIXME: This (and the code that resolves the references) can be improved
10053197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  //        to only disallow SP relative references in the live range of
10063197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  //        the VLA(s). In practice, it's unclear how much difference that
10073197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  //        would make, but it may be worth doing.
10083197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  if (!MFI->hasVarSizedObjects() && isFrameOffsetLegal(MI, Offset))
10093197380143cdc18837722129ac888528b9fbfc2bJim Grosbach    return false;
1010cd59dc5e81eb080cd9b61f5a7e7d9f3eec206d8cJim Grosbach
10113197380143cdc18837722129ac888528b9fbfc2bJim Grosbach  // The offset likely isn't legal, we want to allocate a virtual base register.
1012cd59dc5e81eb080cd9b61f5a7e7d9f3eec206d8cJim Grosbach  return true;
10138708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach}
10148708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach
1015976ef86689ed065361a748f81c44ca3510af2202Bill Wendling/// materializeFrameBaseRegister - Insert defining instruction(s) for BaseReg to
1016976ef86689ed065361a748f81c44ca3510af2202Bill Wendling/// be a pointer to FrameIdx at the beginning of the basic block.
1017dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbachvoid ARMBaseRegisterInfo::
1018976ef86689ed065361a748f81c44ca3510af2202Bill WendlingmaterializeFrameBaseRegister(MachineBasicBlock *MBB,
1019976ef86689ed065361a748f81c44ca3510af2202Bill Wendling                             unsigned BaseReg, int FrameIdx,
1020976ef86689ed065361a748f81c44ca3510af2202Bill Wendling                             int64_t Offset) const {
1021976ef86689ed065361a748f81c44ca3510af2202Bill Wendling  ARMFunctionInfo *AFI = MBB->getParent()->getInfo<ARMFunctionInfo>();
102274d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach  unsigned ADDriOpc = !AFI->isThumbFunction() ? ARM::ADDri :
102374d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach    (AFI->isThumb1OnlyFunction() ? ARM::tADDrSPi : ARM::t2ADDri);
1024dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach
1025976ef86689ed065361a748f81c44ca3510af2202Bill Wendling  MachineBasicBlock::iterator Ins = MBB->begin();
1026976ef86689ed065361a748f81c44ca3510af2202Bill Wendling  DebugLoc DL;                  // Defaults to "unknown"
1027976ef86689ed065361a748f81c44ca3510af2202Bill Wendling  if (Ins != MBB->end())
1028976ef86689ed065361a748f81c44ca3510af2202Bill Wendling    DL = Ins->getDebugLoc();
1029976ef86689ed065361a748f81c44ca3510af2202Bill Wendling
1030e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  const MCInstrDesc &MCID = TII.get(ADDriOpc);
103121803721d538255e4d223c29b6c8d3c9e93d4d86Cameron Zwarich  MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo();
1032e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  MRI.constrainRegClass(BaseReg, TII.getRegClass(MCID, 0, this));
103321803721d538255e4d223c29b6c8d3c9e93d4d86Cameron Zwarich
10345b81584f7403ffdb9cc6babaaeb0411c080e0f81Jim Grosbach  MachineInstrBuilder MIB = AddDefaultPred(BuildMI(*MBB, Ins, DL, MCID, BaseReg)
10355b81584f7403ffdb9cc6babaaeb0411c080e0f81Jim Grosbach    .addFrameIndex(FrameIdx).addImm(Offset));
1036976ef86689ed065361a748f81c44ca3510af2202Bill Wendling
103774d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach  if (!AFI->isThumb1OnlyFunction())
10385b81584f7403ffdb9cc6babaaeb0411c080e0f81Jim Grosbach    AddDefaultCC(MIB);
1039dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach}
1040dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach
1041dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbachvoid
1042dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim GrosbachARMBaseRegisterInfo::resolveFrameIndex(MachineBasicBlock::iterator I,
1043dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach                                       unsigned BaseReg, int64_t Offset) const {
1044dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach  MachineInstr &MI = *I;
1045dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach  MachineBasicBlock &MBB = *MI.getParent();
1046dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach  MachineFunction &MF = *MBB.getParent();
1047dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
1048dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach  int Off = Offset; // ARM doesn't need the general 64-bit offsets
1049dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach  unsigned i = 0;
1050dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach
1051dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach  assert(!AFI->isThumb1OnlyFunction() &&
1052dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach         "This resolveFrameIndex does not support Thumb1!");
1053dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach
1054dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach  while (!MI.getOperand(i).isFI()) {
1055dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach    ++i;
1056dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach    assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
1057dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach  }
1058dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach  bool Done = false;
1059dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach  if (!AFI->isThumbFunction())
1060dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach    Done = rewriteARMFrameIndex(MI, i, BaseReg, Off, TII);
1061dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach  else {
1062dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach    assert(AFI->isThumb2Function());
1063dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach    Done = rewriteT2FrameIndex(MI, i, BaseReg, Off, TII);
1064dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach  }
1065dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach  assert (Done && "Unable to resolve frame index!");
10661f6a329f79b3568d379142f921f59c4143ddaa14Duncan Sands  (void)Done;
1067dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach}
10688708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach
1069e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbachbool ARMBaseRegisterInfo::isFrameOffsetLegal(const MachineInstr *MI,
1070e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach                                             int64_t Offset) const {
1071e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  const MCInstrDesc &Desc = MI->getDesc();
10722b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach  unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
10732b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach  unsigned i = 0;
10742b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach
10752b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach  while (!MI->getOperand(i).isFI()) {
10762b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach    ++i;
10772b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach    assert(i < MI->getNumOperands() &&"Instr doesn't have FrameIndex operand!");
10782b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach  }
10792b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach
10802b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach  // AddrMode4 and AddrMode6 cannot handle any offset.
10812b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach  if (AddrMode == ARMII::AddrMode4 || AddrMode == ARMII::AddrMode6)
10822b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach    return Offset == 0;
10832b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach
10842b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach  unsigned NumBits = 0;
10852b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach  unsigned Scale = 1;
1086e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach  bool isSigned = true;
10871ab3f16f06698596716593a30545799688acccd7Jim Grosbach  switch (AddrMode) {
10882b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach  case ARMII::AddrModeT2_i8:
10892b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach  case ARMII::AddrModeT2_i12:
10902b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach    // i8 supports only negative, and i12 supports only positive, so
10912b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach    // based on Offset sign, consider the appropriate instruction
109274d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach    Scale = 1;
10932b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach    if (Offset < 0) {
10942b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach      NumBits = 8;
10952b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach      Offset = -Offset;
10962b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach    } else {
10972b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach      NumBits = 12;
10982b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach    }
10992b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach    break;
11001ab3f16f06698596716593a30545799688acccd7Jim Grosbach  case ARMII::AddrMode5:
11012b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach    // VFP address mode.
11022b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach    NumBits = 8;
11032b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach    Scale = 4;
11042b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach    break;
11053e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach  case ARMII::AddrMode_i12:
11061ab3f16f06698596716593a30545799688acccd7Jim Grosbach  case ARMII::AddrMode2:
11072b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach    NumBits = 12;
11082b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach    break;
11091ab3f16f06698596716593a30545799688acccd7Jim Grosbach  case ARMII::AddrMode3:
11102b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach    NumBits = 8;
11112b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach    break;
1112e575499d830008784b11499dae290ad0480c8f9dBill Wendling  case ARMII::AddrModeT1_s:
1113e575499d830008784b11499dae290ad0480c8f9dBill Wendling    NumBits = 5;
111474d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach    Scale = 4;
1115e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach    isSigned = false;
111674d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach    break;
11172b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach  default:
11182b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach    llvm_unreachable("Unsupported addressing mode!");
11192b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach    break;
11202b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach  }
11212b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach
11221ab3f16f06698596716593a30545799688acccd7Jim Grosbach  Offset += getFrameIndexInstrOffset(MI, i);
1123d4511e947ee1e89a4f199bfac0d401976930ccfeJim Grosbach  // Make sure the offset is encodable for instructions that scale the
1124d4511e947ee1e89a4f199bfac0d401976930ccfeJim Grosbach  // immediate.
1125d4511e947ee1e89a4f199bfac0d401976930ccfeJim Grosbach  if ((Offset & (Scale-1)) != 0)
1126d4511e947ee1e89a4f199bfac0d401976930ccfeJim Grosbach    return false;
1127d4511e947ee1e89a4f199bfac0d401976930ccfeJim Grosbach
1128e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach  if (isSigned && Offset < 0)
11292b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach    Offset = -Offset;
11302b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach
11312b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach  unsigned Mask = (1 << NumBits) - 1;
11322b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach  if ((unsigned)Offset <= Mask * Scale)
11332b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach    return true;
113474d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach
113574d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach  return false;
113674d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach}
113774d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach
1138fcb4a8ead3cd8d9540d5eaa448af5d14a0ee341aJim Grosbachvoid
11396495f63945e8dbde81f03a1dc2ab421993b9a495Evan ChengARMBaseRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
1140fcb4a8ead3cd8d9540d5eaa448af5d14a0ee341aJim Grosbach                                         int SPAdj, RegScavenger *RS) const {
11415ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin  unsigned i = 0;
11425ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin  MachineInstr &MI = *II;
11435ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin  MachineBasicBlock &MBB = *MI.getParent();
11445ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin  MachineFunction &MF = *MBB.getParent();
114516c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov  const ARMFrameLowering *TFI =
114616c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov    static_cast<const ARMFrameLowering*>(MF.getTarget().getFrameLowering());
11475ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
11486495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng  assert(!AFI->isThumb1OnlyFunction() &&
1149a15de00f8246f19180b26ee5fe7ff8f436e0de08Bob Wilson         "This eliminateFrameIndex does not support Thumb1!");
11505ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin
11515ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin  while (!MI.getOperand(i).isFI()) {
11525ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin    ++i;
11535ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin    assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
11545ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin  }
11555ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin
11565ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin  int FrameIndex = MI.getOperand(i).getIndex();
1157a37aa546224ec03ba1f1a1598e0781af4b692673Jim Grosbach  unsigned FrameReg;
11585ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin
115982f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov  int Offset = TFI->ResolveFrameIndexReference(MF, FrameIndex, FrameReg, SPAdj);
11605ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin
116162b50656ceb854eb0be265d63b2a1d46e7400d8aEvan Cheng  // Special handling of dbg_value instructions.
116262b50656ceb854eb0be265d63b2a1d46e7400d8aEvan Cheng  if (MI.isDebugValue()) {
116362b50656ceb854eb0be265d63b2a1d46e7400d8aEvan Cheng    MI.getOperand(i).  ChangeToRegister(FrameReg, false /*isDef*/);
116462b50656ceb854eb0be265d63b2a1d46e7400d8aEvan Cheng    MI.getOperand(i+1).ChangeToImmediate(Offset);
1165fcb4a8ead3cd8d9540d5eaa448af5d14a0ee341aJim Grosbach    return;
116662b50656ceb854eb0be265d63b2a1d46e7400d8aEvan Cheng  }
116762b50656ceb854eb0be265d63b2a1d46e7400d8aEvan Cheng
116848d8afab73d72418cf9505a020f621014920463cEvan Cheng  // Modify MI as necessary to handle as much of 'Offset' as possible
1169cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng  bool Done = false;
11706495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng  if (!AFI->isThumbFunction())
1171cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng    Done = rewriteARMFrameIndex(MI, i, FrameReg, Offset, TII);
11726495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng  else {
11736495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    assert(AFI->isThumb2Function());
1174cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng    Done = rewriteT2FrameIndex(MI, i, FrameReg, Offset, TII);
11756495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng  }
1176cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng  if (Done)
1177fcb4a8ead3cd8d9540d5eaa448af5d14a0ee341aJim Grosbach    return;
11785ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin
1179db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  // If we get here, the immediate doesn't fit into the instruction.  We folded
1180db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  // as much as possible above, handle the rest, providing a register that is
1181db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  // SP+LargeImm.
118219bb87d0f80f3e6eed38a9fa267bf2b0474aeaabDaniel Dunbar  assert((Offset ||
1183a44321776ecd96fa0344335d3027758be3386e45Jim Grosbach          (MI.getDesc().TSFlags & ARMII::AddrModeMask) == ARMII::AddrMode4 ||
1184a44321776ecd96fa0344335d3027758be3386e45Jim Grosbach          (MI.getDesc().TSFlags & ARMII::AddrModeMask) == ARMII::AddrMode6) &&
1185cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng         "This code isn't needed if offset already handled!");
1186db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
11877e831db1d4f5dc51ca6526739cf41e59895c5c20Jim Grosbach  unsigned ScratchReg = 0;
1188db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  int PIdx = MI.findFirstPredOperandIdx();
1189db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  ARMCC::CondCodes Pred = (PIdx == -1)
1190db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    ? ARMCC::AL : (ARMCC::CondCodes)MI.getOperand(PIdx).getImm();
1191db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  unsigned PredReg = (PIdx == -1) ? 0 : MI.getOperand(PIdx+1).getReg();
1192cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng  if (Offset == 0)
1193a44321776ecd96fa0344335d3027758be3386e45Jim Grosbach    // Must be addrmode4/6.
1194cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng    MI.getOperand(i).ChangeToRegister(FrameReg, false, false, false);
11956495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng  else {
1196ca5dfb71ba4aa4a8392a021ec056cf0b70f74f1eJim Grosbach    ScratchReg = MF.getRegInfo().createVirtualRegister(ARM::GPRRegisterClass);
1197cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng    if (!AFI->isThumbFunction())
1198cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng      emitARMRegPlusImmediate(MBB, II, MI.getDebugLoc(), ScratchReg, FrameReg,
1199cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng                              Offset, Pred, PredReg, TII);
1200cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng    else {
1201cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng      assert(AFI->isThumb2Function());
1202cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng      emitT2RegPlusImmediate(MBB, II, MI.getDebugLoc(), ScratchReg, FrameReg,
1203cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng                             Offset, Pred, PredReg, TII);
1204cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng    }
1205cde31293d45f14ddff482d385429d256bd4e0820Jim Grosbach    // Update the original instruction to use the scratch register.
1206cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng    MI.getOperand(i).ChangeToRegister(ScratchReg, false, false, true);
12076495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng  }
1208db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin}
1209