blob: d41fdb9d2ac73b482f6ee8955f3da195cd153f57 [file] [log] [blame]
Chris Lattner2cfd52c2009-07-29 20:31:52 +00001//===- ARMBaseRegisterInfo.cpp - ARM Register Information -------*- C++ -*-===//
David Goodwinc140c482009-07-08 17:28:55 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file contains the base ARM implementation of TargetRegisterInfo class.
11//
12//===----------------------------------------------------------------------===//
13
14#include "ARM.h"
15#include "ARMAddressingModes.h"
David Goodwindb5a71a2009-07-08 18:31:39 +000016#include "ARMBaseInstrInfo.h"
David Goodwinc140c482009-07-08 17:28:55 +000017#include "ARMBaseRegisterInfo.h"
Anton Korobeynikov16c29b52011-01-10 12:39:04 +000018#include "ARMFrameLowering.h"
David Goodwinc140c482009-07-08 17:28:55 +000019#include "ARMInstrInfo.h"
20#include "ARMMachineFunctionInfo.h"
21#include "ARMSubtarget.h"
22#include "llvm/Constants.h"
23#include "llvm/DerivedTypes.h"
Owen Anderson9adc0ab2009-07-14 23:09:55 +000024#include "llvm/Function.h"
25#include "llvm/LLVMContext.h"
David Goodwinc140c482009-07-08 17:28:55 +000026#include "llvm/CodeGen/MachineConstantPool.h"
27#include "llvm/CodeGen/MachineFrameInfo.h"
28#include "llvm/CodeGen/MachineFunction.h"
29#include "llvm/CodeGen/MachineInstrBuilder.h"
30#include "llvm/CodeGen/MachineLocation.h"
31#include "llvm/CodeGen/MachineRegisterInfo.h"
32#include "llvm/CodeGen/RegisterScavenging.h"
Jim Grosbach3dab2772009-10-27 22:45:39 +000033#include "llvm/Support/Debug.h"
Torok Edwinab7c09b2009-07-08 18:01:40 +000034#include "llvm/Support/ErrorHandling.h"
Torok Edwindac237e2009-07-08 20:53:28 +000035#include "llvm/Support/raw_ostream.h"
Anton Korobeynikov16c29b52011-01-10 12:39:04 +000036#include "llvm/Target/TargetFrameLowering.h"
David Goodwinc140c482009-07-08 17:28:55 +000037#include "llvm/Target/TargetMachine.h"
38#include "llvm/Target/TargetOptions.h"
39#include "llvm/ADT/BitVector.h"
40#include "llvm/ADT/SmallVector.h"
Jim Grosbach18ed9c92009-10-20 20:19:50 +000041#include "llvm/Support/CommandLine.h"
Evan Cheng73f50d92011-06-27 18:32:37 +000042
Evan Cheng73f50d92011-06-27 18:32:37 +000043#define GET_REGINFO_TARGET_DESC
Evan Chenga347f852011-06-24 01:44:41 +000044#include "ARMGenRegisterInfo.inc"
David Goodwinc140c482009-07-08 17:28:55 +000045
Evan Cheng1b4886d2010-11-18 01:28:51 +000046using namespace llvm;
47
Jim Grosbacha2734422010-08-24 19:05:43 +000048static cl::opt<bool>
Jim Grosbach31973802010-08-24 21:19:33 +000049ForceAllBaseRegAlloc("arm-force-base-reg-alloc", cl::Hidden, cl::init(false),
Jim Grosbachcd59dc52010-08-24 18:04:52 +000050 cl::desc("Force use of virtual base registers for stack load/store"));
Jim Grosbacha2734422010-08-24 19:05:43 +000051static cl::opt<bool>
Jim Grosbachae47c6d2010-08-26 00:58:06 +000052EnableLocalStackAlloc("enable-local-stack-alloc", cl::init(true), cl::Hidden,
Jim Grosbacha2734422010-08-24 19:05:43 +000053 cl::desc("Enable pre-regalloc stack frame index allocation"));
Jim Grosbach65482b12010-09-03 18:37:12 +000054static cl::opt<bool>
Jim Grosbachd0bd76b2010-09-08 20:12:02 +000055EnableBasePointer("arm-use-base-pointer", cl::Hidden, cl::init(true),
Jim Grosbach65482b12010-09-03 18:37:12 +000056 cl::desc("Enable use of a base pointer for complex stack frames"));
57
David Goodwindb5a71a2009-07-08 18:31:39 +000058ARMBaseRegisterInfo::ARMBaseRegisterInfo(const ARMBaseInstrInfo &tii,
David Goodwinc140c482009-07-08 17:28:55 +000059 const ARMSubtarget &sti)
Evan Cheng0e6a0522011-07-18 20:57:22 +000060 : ARMGenRegisterInfo(ARM::LR), TII(tii), STI(sti),
Jim Grosbach65482b12010-09-03 18:37:12 +000061 FramePtr((STI.isTargetDarwin() || STI.isThumb()) ? ARM::R7 : ARM::R11),
62 BasePtr(ARM::R6) {
David Goodwinc140c482009-07-08 17:28:55 +000063}
64
65const unsigned*
66ARMBaseRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
67 static const unsigned CalleeSavedRegs[] = {
68 ARM::LR, ARM::R11, ARM::R10, ARM::R9, ARM::R8,
69 ARM::R7, ARM::R6, ARM::R5, ARM::R4,
70
71 ARM::D15, ARM::D14, ARM::D13, ARM::D12,
72 ARM::D11, ARM::D10, ARM::D9, ARM::D8,
73 0
74 };
75
76 static const unsigned DarwinCalleeSavedRegs[] = {
77 // Darwin ABI deviates from ARM standard ABI. R9 is not a callee-saved
78 // register.
Jim Grosbachab3d00e2010-11-02 17:35:25 +000079 ARM::LR, ARM::R7, ARM::R6, ARM::R5, ARM::R4,
80 ARM::R11, ARM::R10, ARM::R8,
David Goodwinc140c482009-07-08 17:28:55 +000081
82 ARM::D15, ARM::D14, ARM::D13, ARM::D12,
83 ARM::D11, ARM::D10, ARM::D9, ARM::D8,
84 0
85 };
86 return STI.isTargetDarwin() ? DarwinCalleeSavedRegs : CalleeSavedRegs;
87}
88
Jim Grosbach96318642010-01-06 23:54:42 +000089BitVector ARMBaseRegisterInfo::
90getReservedRegs(const MachineFunction &MF) const {
Anton Korobeynikov16c29b52011-01-10 12:39:04 +000091 const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
Anton Korobeynikovd0c38172010-11-18 21:19:35 +000092
Chris Lattner7a2bdde2011-04-15 05:18:47 +000093 // FIXME: avoid re-calculating this every time.
David Goodwinc140c482009-07-08 17:28:55 +000094 BitVector Reserved(getNumRegs());
95 Reserved.set(ARM::SP);
96 Reserved.set(ARM::PC);
Nate Begemand1fb5832010-08-03 21:31:55 +000097 Reserved.set(ARM::FPSCR);
Anton Korobeynikovd0c38172010-11-18 21:19:35 +000098 if (TFI->hasFP(MF))
David Goodwinc140c482009-07-08 17:28:55 +000099 Reserved.set(FramePtr);
Jim Grosbach65482b12010-09-03 18:37:12 +0000100 if (hasBasePointer(MF))
101 Reserved.set(BasePtr);
David Goodwinc140c482009-07-08 17:28:55 +0000102 // Some targets reserve R9.
103 if (STI.isR9Reserved())
104 Reserved.set(ARM::R9);
Jakob Stoklund Olesen3b6434e2011-06-18 00:53:27 +0000105 // Reserve D16-D31 if the subtarget doesn't support them.
106 if (!STI.hasVFP3() || STI.hasD16()) {
107 assert(ARM::D31 == ARM::D16 + 15);
108 for (unsigned i = 0; i != 16; ++i)
109 Reserved.set(ARM::D16 + i);
110 }
David Goodwinc140c482009-07-08 17:28:55 +0000111 return Reserved;
112}
113
Chris Lattner2cfd52c2009-07-29 20:31:52 +0000114bool ARMBaseRegisterInfo::isReservedReg(const MachineFunction &MF,
115 unsigned Reg) const {
Anton Korobeynikov16c29b52011-01-10 12:39:04 +0000116 const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
Anton Korobeynikovd0c38172010-11-18 21:19:35 +0000117
David Goodwinc140c482009-07-08 17:28:55 +0000118 switch (Reg) {
119 default: break;
120 case ARM::SP:
121 case ARM::PC:
122 return true;
Jim Grosbach65482b12010-09-03 18:37:12 +0000123 case ARM::R6:
124 if (hasBasePointer(MF))
125 return true;
126 break;
David Goodwinc140c482009-07-08 17:28:55 +0000127 case ARM::R7:
128 case ARM::R11:
Anton Korobeynikovd0c38172010-11-18 21:19:35 +0000129 if (FramePtr == Reg && TFI->hasFP(MF))
David Goodwinc140c482009-07-08 17:28:55 +0000130 return true;
131 break;
132 case ARM::R9:
133 return STI.isR9Reserved();
134 }
135
136 return false;
137}
138
Chris Lattner2cfd52c2009-07-29 20:31:52 +0000139const TargetRegisterClass *
Evan Cheng4f54c122009-10-25 07:53:28 +0000140ARMBaseRegisterInfo::getMatchingSuperRegClass(const TargetRegisterClass *A,
141 const TargetRegisterClass *B,
142 unsigned SubIdx) const {
143 switch (SubIdx) {
144 default: return 0;
Jakob Stoklund Olesene00fa642010-05-25 00:15:15 +0000145 case ARM::ssub_0:
146 case ARM::ssub_1:
147 case ARM::ssub_2:
148 case ARM::ssub_3: {
Evan Cheng4f54c122009-10-25 07:53:28 +0000149 // S sub-registers.
150 if (A->getSize() == 8) {
Evan Chengba908642009-11-03 05:52:54 +0000151 if (B == &ARM::SPR_8RegClass)
152 return &ARM::DPR_8RegClass;
153 assert(B == &ARM::SPRRegClass && "Expecting SPR register class!");
Evan Cheng4f54c122009-10-25 07:53:28 +0000154 if (A == &ARM::DPR_8RegClass)
155 return A;
156 return &ARM::DPR_VFP2RegClass;
157 }
158
Evan Chengb63387a2010-05-06 06:36:08 +0000159 if (A->getSize() == 16) {
160 if (B == &ARM::SPR_8RegClass)
161 return &ARM::QPR_8RegClass;
162 return &ARM::QPR_VFP2RegClass;
163 }
164
Evan Cheng22c687b2010-05-14 02:13:41 +0000165 if (A->getSize() == 32) {
166 if (B == &ARM::SPR_8RegClass)
167 return 0; // Do not allow coalescing!
168 return &ARM::QQPR_VFP2RegClass;
169 }
170
171 assert(A->getSize() == 64 && "Expecting a QQQQ register class!");
172 return 0; // Do not allow coalescing!
Evan Chengb63387a2010-05-06 06:36:08 +0000173 }
Jakob Stoklund Olesene00fa642010-05-25 00:15:15 +0000174 case ARM::dsub_0:
175 case ARM::dsub_1:
176 case ARM::dsub_2:
177 case ARM::dsub_3: {
Evan Cheng4f54c122009-10-25 07:53:28 +0000178 // D sub-registers.
Evan Chengb63387a2010-05-06 06:36:08 +0000179 if (A->getSize() == 16) {
180 if (B == &ARM::DPR_VFP2RegClass)
181 return &ARM::QPR_VFP2RegClass;
182 if (B == &ARM::DPR_8RegClass)
Evan Cheng22c687b2010-05-14 02:13:41 +0000183 return 0; // Do not allow coalescing!
Evan Chengb63387a2010-05-06 06:36:08 +0000184 return A;
185 }
186
Evan Cheng22c687b2010-05-14 02:13:41 +0000187 if (A->getSize() == 32) {
188 if (B == &ARM::DPR_VFP2RegClass)
189 return &ARM::QQPR_VFP2RegClass;
190 if (B == &ARM::DPR_8RegClass)
191 return 0; // Do not allow coalescing!
192 return A;
193 }
194
195 assert(A->getSize() == 64 && "Expecting a QQQQ register class!");
196 if (B != &ARM::DPRRegClass)
197 return 0; // Do not allow coalescing!
Evan Cheng4f54c122009-10-25 07:53:28 +0000198 return A;
199 }
Jakob Stoklund Olesene00fa642010-05-25 00:15:15 +0000200 case ARM::dsub_4:
201 case ARM::dsub_5:
202 case ARM::dsub_6:
203 case ARM::dsub_7: {
Evan Cheng22c687b2010-05-14 02:13:41 +0000204 // D sub-registers of QQQQ registers.
205 if (A->getSize() == 64 && B == &ARM::DPRRegClass)
206 return A;
207 return 0; // Do not allow coalescing!
208 }
209
Jakob Stoklund Olesene00fa642010-05-25 00:15:15 +0000210 case ARM::qsub_0:
211 case ARM::qsub_1: {
Evan Chengb63387a2010-05-06 06:36:08 +0000212 // Q sub-registers.
Evan Cheng22c687b2010-05-14 02:13:41 +0000213 if (A->getSize() == 32) {
214 if (B == &ARM::QPR_VFP2RegClass)
215 return &ARM::QQPR_VFP2RegClass;
216 if (B == &ARM::QPR_8RegClass)
217 return 0; // Do not allow coalescing!
218 return A;
219 }
220
221 assert(A->getSize() == 64 && "Expecting a QQQQ register class!");
222 if (B == &ARM::QPRRegClass)
223 return A;
224 return 0; // Do not allow coalescing!
225 }
Jakob Stoklund Olesene00fa642010-05-25 00:15:15 +0000226 case ARM::qsub_2:
227 case ARM::qsub_3: {
Evan Cheng22c687b2010-05-14 02:13:41 +0000228 // Q sub-registers of QQQQ registers.
229 if (A->getSize() == 64 && B == &ARM::QPRRegClass)
230 return A;
231 return 0; // Do not allow coalescing!
Evan Chengb63387a2010-05-06 06:36:08 +0000232 }
233 }
Evan Cheng4f54c122009-10-25 07:53:28 +0000234 return 0;
235}
236
Evan Chengb990a2f2010-05-14 23:21:14 +0000237bool
Bob Wilson91a74da2010-06-02 18:54:47 +0000238ARMBaseRegisterInfo::canCombineSubRegIndices(const TargetRegisterClass *RC,
Evan Chengb990a2f2010-05-14 23:21:14 +0000239 SmallVectorImpl<unsigned> &SubIndices,
240 unsigned &NewSubIdx) const {
241
242 unsigned Size = RC->getSize() * 8;
243 if (Size < 6)
244 return 0;
245
246 NewSubIdx = 0; // Whole register.
247 unsigned NumRegs = SubIndices.size();
248 if (NumRegs == 8) {
249 // 8 D registers -> 1 QQQQ register.
250 return (Size == 512 &&
Jakob Stoklund Olesen558661d2010-05-24 16:54:32 +0000251 SubIndices[0] == ARM::dsub_0 &&
252 SubIndices[1] == ARM::dsub_1 &&
253 SubIndices[2] == ARM::dsub_2 &&
254 SubIndices[3] == ARM::dsub_3 &&
255 SubIndices[4] == ARM::dsub_4 &&
256 SubIndices[5] == ARM::dsub_5 &&
257 SubIndices[6] == ARM::dsub_6 &&
258 SubIndices[7] == ARM::dsub_7);
Evan Chengb990a2f2010-05-14 23:21:14 +0000259 } else if (NumRegs == 4) {
Jakob Stoklund Olesen558661d2010-05-24 16:54:32 +0000260 if (SubIndices[0] == ARM::qsub_0) {
Evan Chengb990a2f2010-05-14 23:21:14 +0000261 // 4 Q registers -> 1 QQQQ register.
262 return (Size == 512 &&
Jakob Stoklund Olesen558661d2010-05-24 16:54:32 +0000263 SubIndices[1] == ARM::qsub_1 &&
264 SubIndices[2] == ARM::qsub_2 &&
265 SubIndices[3] == ARM::qsub_3);
266 } else if (SubIndices[0] == ARM::dsub_0) {
Evan Chengb990a2f2010-05-14 23:21:14 +0000267 // 4 D registers -> 1 QQ register.
268 if (Size >= 256 &&
Jakob Stoklund Olesen558661d2010-05-24 16:54:32 +0000269 SubIndices[1] == ARM::dsub_1 &&
270 SubIndices[2] == ARM::dsub_2 &&
271 SubIndices[3] == ARM::dsub_3) {
Evan Chengb990a2f2010-05-14 23:21:14 +0000272 if (Size == 512)
Jakob Stoklund Olesen558661d2010-05-24 16:54:32 +0000273 NewSubIdx = ARM::qqsub_0;
Evan Chengb990a2f2010-05-14 23:21:14 +0000274 return true;
275 }
Jakob Stoklund Olesen558661d2010-05-24 16:54:32 +0000276 } else if (SubIndices[0] == ARM::dsub_4) {
Evan Chengb990a2f2010-05-14 23:21:14 +0000277 // 4 D registers -> 1 QQ register (2nd).
278 if (Size == 512 &&
Jakob Stoklund Olesen558661d2010-05-24 16:54:32 +0000279 SubIndices[1] == ARM::dsub_5 &&
280 SubIndices[2] == ARM::dsub_6 &&
281 SubIndices[3] == ARM::dsub_7) {
282 NewSubIdx = ARM::qqsub_1;
Evan Chengb990a2f2010-05-14 23:21:14 +0000283 return true;
284 }
Jakob Stoklund Olesen558661d2010-05-24 16:54:32 +0000285 } else if (SubIndices[0] == ARM::ssub_0) {
Evan Chengb990a2f2010-05-14 23:21:14 +0000286 // 4 S registers -> 1 Q register.
287 if (Size >= 128 &&
Jakob Stoklund Olesen558661d2010-05-24 16:54:32 +0000288 SubIndices[1] == ARM::ssub_1 &&
289 SubIndices[2] == ARM::ssub_2 &&
290 SubIndices[3] == ARM::ssub_3) {
Evan Chengb990a2f2010-05-14 23:21:14 +0000291 if (Size >= 256)
Jakob Stoklund Olesen558661d2010-05-24 16:54:32 +0000292 NewSubIdx = ARM::qsub_0;
Evan Chengb990a2f2010-05-14 23:21:14 +0000293 return true;
294 }
295 }
296 } else if (NumRegs == 2) {
Jakob Stoklund Olesen558661d2010-05-24 16:54:32 +0000297 if (SubIndices[0] == ARM::qsub_0) {
Evan Chengb990a2f2010-05-14 23:21:14 +0000298 // 2 Q registers -> 1 QQ register.
Jakob Stoklund Olesen558661d2010-05-24 16:54:32 +0000299 if (Size >= 256 && SubIndices[1] == ARM::qsub_1) {
Evan Chengb990a2f2010-05-14 23:21:14 +0000300 if (Size == 512)
Jakob Stoklund Olesen558661d2010-05-24 16:54:32 +0000301 NewSubIdx = ARM::qqsub_0;
Evan Chengb990a2f2010-05-14 23:21:14 +0000302 return true;
303 }
Jakob Stoklund Olesen558661d2010-05-24 16:54:32 +0000304 } else if (SubIndices[0] == ARM::qsub_2) {
Evan Chengb990a2f2010-05-14 23:21:14 +0000305 // 2 Q registers -> 1 QQ register (2nd).
Jakob Stoklund Olesen558661d2010-05-24 16:54:32 +0000306 if (Size == 512 && SubIndices[1] == ARM::qsub_3) {
307 NewSubIdx = ARM::qqsub_1;
Evan Chengb990a2f2010-05-14 23:21:14 +0000308 return true;
309 }
Jakob Stoklund Olesen558661d2010-05-24 16:54:32 +0000310 } else if (SubIndices[0] == ARM::dsub_0) {
Evan Chengb990a2f2010-05-14 23:21:14 +0000311 // 2 D registers -> 1 Q register.
Jakob Stoklund Olesen558661d2010-05-24 16:54:32 +0000312 if (Size >= 128 && SubIndices[1] == ARM::dsub_1) {
Evan Chengb990a2f2010-05-14 23:21:14 +0000313 if (Size >= 256)
Jakob Stoklund Olesen558661d2010-05-24 16:54:32 +0000314 NewSubIdx = ARM::qsub_0;
Evan Chengb990a2f2010-05-14 23:21:14 +0000315 return true;
316 }
Jakob Stoklund Olesen558661d2010-05-24 16:54:32 +0000317 } else if (SubIndices[0] == ARM::dsub_2) {
Evan Chengb990a2f2010-05-14 23:21:14 +0000318 // 2 D registers -> 1 Q register (2nd).
Jakob Stoklund Olesen558661d2010-05-24 16:54:32 +0000319 if (Size >= 256 && SubIndices[1] == ARM::dsub_3) {
320 NewSubIdx = ARM::qsub_1;
Evan Chengb990a2f2010-05-14 23:21:14 +0000321 return true;
322 }
Jakob Stoklund Olesen558661d2010-05-24 16:54:32 +0000323 } else if (SubIndices[0] == ARM::dsub_4) {
Evan Chengb990a2f2010-05-14 23:21:14 +0000324 // 2 D registers -> 1 Q register (3rd).
Jakob Stoklund Olesen558661d2010-05-24 16:54:32 +0000325 if (Size == 512 && SubIndices[1] == ARM::dsub_5) {
326 NewSubIdx = ARM::qsub_2;
Evan Chengb990a2f2010-05-14 23:21:14 +0000327 return true;
328 }
Jakob Stoklund Olesen558661d2010-05-24 16:54:32 +0000329 } else if (SubIndices[0] == ARM::dsub_6) {
Evan Chengb990a2f2010-05-14 23:21:14 +0000330 // 2 D registers -> 1 Q register (3rd).
Jakob Stoklund Olesen558661d2010-05-24 16:54:32 +0000331 if (Size == 512 && SubIndices[1] == ARM::dsub_7) {
332 NewSubIdx = ARM::qsub_3;
Evan Chengb990a2f2010-05-14 23:21:14 +0000333 return true;
334 }
Jakob Stoklund Olesen558661d2010-05-24 16:54:32 +0000335 } else if (SubIndices[0] == ARM::ssub_0) {
Evan Chengb990a2f2010-05-14 23:21:14 +0000336 // 2 S registers -> 1 D register.
Jakob Stoklund Olesen558661d2010-05-24 16:54:32 +0000337 if (SubIndices[1] == ARM::ssub_1) {
Evan Chengb990a2f2010-05-14 23:21:14 +0000338 if (Size >= 128)
Jakob Stoklund Olesen558661d2010-05-24 16:54:32 +0000339 NewSubIdx = ARM::dsub_0;
Evan Chengb990a2f2010-05-14 23:21:14 +0000340 return true;
341 }
Jakob Stoklund Olesen558661d2010-05-24 16:54:32 +0000342 } else if (SubIndices[0] == ARM::ssub_2) {
Evan Chengb990a2f2010-05-14 23:21:14 +0000343 // 2 S registers -> 1 D register (2nd).
Jakob Stoklund Olesen558661d2010-05-24 16:54:32 +0000344 if (Size >= 128 && SubIndices[1] == ARM::ssub_3) {
345 NewSubIdx = ARM::dsub_1;
Evan Chengb990a2f2010-05-14 23:21:14 +0000346 return true;
347 }
348 }
349 }
350 return false;
351}
352
Jakob Stoklund Olesenc9e50152011-04-26 18:52:33 +0000353const TargetRegisterClass*
354ARMBaseRegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC)
355 const {
356 const TargetRegisterClass *Super = RC;
357 TargetRegisterClass::sc_iterator I = RC->superclasses_begin();
358 do {
359 switch (Super->getID()) {
360 case ARM::GPRRegClassID:
361 case ARM::SPRRegClassID:
362 case ARM::DPRRegClassID:
363 case ARM::QPRRegClassID:
364 case ARM::QQPRRegClassID:
365 case ARM::QQQQPRRegClassID:
366 return Super;
367 }
368 Super = *I++;
369 } while (Super);
370 return RC;
371}
Evan Chengb990a2f2010-05-14 23:21:14 +0000372
Evan Cheng4f54c122009-10-25 07:53:28 +0000373const TargetRegisterClass *
Chris Lattner2cfd52c2009-07-29 20:31:52 +0000374ARMBaseRegisterInfo::getPointerRegClass(unsigned Kind) const {
Jim Grosbache11a8f52009-09-11 19:49:06 +0000375 return ARM::GPRRegisterClass;
David Goodwinc140c482009-07-08 17:28:55 +0000376}
377
Cameron Zwarichbe2119e2011-03-07 21:56:36 +0000378unsigned
379ARMBaseRegisterInfo::getRegPressureLimit(const TargetRegisterClass *RC,
380 MachineFunction &MF) const {
381 const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
382
383 switch (RC->getID()) {
384 default:
385 return 0;
386 case ARM::tGPRRegClassID:
387 return TFI->hasFP(MF) ? 4 : 5;
388 case ARM::GPRRegClassID: {
389 unsigned FP = TFI->hasFP(MF) ? 1 : 0;
390 return 10 - FP - (STI.isR9Reserved() ? 1 : 0);
391 }
392 case ARM::SPRRegClassID: // Currently not used as 'rep' register class.
393 case ARM::DPRRegClassID:
394 return 32 - 10;
395 }
396}
397
Jakob Stoklund Olesendd5a8472011-06-16 23:31:16 +0000398/// getRawAllocationOrder - Returns the register allocation order for a
399/// specified register class with a target-dependent hint.
400ArrayRef<unsigned>
401ARMBaseRegisterInfo::getRawAllocationOrder(const TargetRegisterClass *RC,
402 unsigned HintType, unsigned HintReg,
403 const MachineFunction &MF) const {
Anton Korobeynikov16c29b52011-01-10 12:39:04 +0000404 const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
David Goodwinc140c482009-07-08 17:28:55 +0000405 // Alternative register allocation orders when favoring even / odd registers
406 // of register pairs.
407
408 // No FP, R9 is available.
409 static const unsigned GPREven1[] = {
410 ARM::R0, ARM::R2, ARM::R4, ARM::R6, ARM::R8, ARM::R10,
411 ARM::R1, ARM::R3, ARM::R12,ARM::LR, ARM::R5, ARM::R7,
412 ARM::R9, ARM::R11
413 };
414 static const unsigned GPROdd1[] = {
415 ARM::R1, ARM::R3, ARM::R5, ARM::R7, ARM::R9, ARM::R11,
416 ARM::R0, ARM::R2, ARM::R12,ARM::LR, ARM::R4, ARM::R6,
417 ARM::R8, ARM::R10
418 };
419
420 // FP is R7, R9 is available.
421 static const unsigned GPREven2[] = {
422 ARM::R0, ARM::R2, ARM::R4, ARM::R8, ARM::R10,
423 ARM::R1, ARM::R3, ARM::R12,ARM::LR, ARM::R5, ARM::R6,
424 ARM::R9, ARM::R11
425 };
426 static const unsigned GPROdd2[] = {
427 ARM::R1, ARM::R3, ARM::R5, ARM::R9, ARM::R11,
428 ARM::R0, ARM::R2, ARM::R12,ARM::LR, ARM::R4, ARM::R6,
429 ARM::R8, ARM::R10
430 };
431
432 // FP is R11, R9 is available.
433 static const unsigned GPREven3[] = {
434 ARM::R0, ARM::R2, ARM::R4, ARM::R6, ARM::R8,
435 ARM::R1, ARM::R3, ARM::R10,ARM::R12,ARM::LR, ARM::R5, ARM::R7,
436 ARM::R9
437 };
438 static const unsigned GPROdd3[] = {
439 ARM::R1, ARM::R3, ARM::R5, ARM::R6, ARM::R9,
440 ARM::R0, ARM::R2, ARM::R10,ARM::R12,ARM::LR, ARM::R4, ARM::R7,
441 ARM::R8
442 };
443
444 // No FP, R9 is not available.
445 static const unsigned GPREven4[] = {
446 ARM::R0, ARM::R2, ARM::R4, ARM::R6, ARM::R10,
447 ARM::R1, ARM::R3, ARM::R12,ARM::LR, ARM::R5, ARM::R7, ARM::R8,
448 ARM::R11
449 };
450 static const unsigned GPROdd4[] = {
451 ARM::R1, ARM::R3, ARM::R5, ARM::R7, ARM::R11,
452 ARM::R0, ARM::R2, ARM::R12,ARM::LR, ARM::R4, ARM::R6, ARM::R8,
453 ARM::R10
454 };
455
456 // FP is R7, R9 is not available.
457 static const unsigned GPREven5[] = {
458 ARM::R0, ARM::R2, ARM::R4, ARM::R10,
459 ARM::R1, ARM::R3, ARM::R12,ARM::LR, ARM::R5, ARM::R6, ARM::R8,
460 ARM::R11
461 };
462 static const unsigned GPROdd5[] = {
463 ARM::R1, ARM::R3, ARM::R5, ARM::R11,
464 ARM::R0, ARM::R2, ARM::R12,ARM::LR, ARM::R4, ARM::R6, ARM::R8,
465 ARM::R10
466 };
467
468 // FP is R11, R9 is not available.
469 static const unsigned GPREven6[] = {
470 ARM::R0, ARM::R2, ARM::R4, ARM::R6,
471 ARM::R1, ARM::R3, ARM::R10,ARM::R12,ARM::LR, ARM::R5, ARM::R7, ARM::R8
472 };
473 static const unsigned GPROdd6[] = {
474 ARM::R1, ARM::R3, ARM::R5, ARM::R7,
475 ARM::R0, ARM::R2, ARM::R10,ARM::R12,ARM::LR, ARM::R4, ARM::R6, ARM::R8
476 };
477
Jakob Stoklund Oleseneb5067e2011-03-25 01:48:18 +0000478 // We only support even/odd hints for GPR and rGPR.
479 if (RC != ARM::GPRRegisterClass && RC != ARM::rGPRRegisterClass)
Jakob Stoklund Olesendd5a8472011-06-16 23:31:16 +0000480 return RC->getRawAllocationOrder(MF);
David Goodwinc140c482009-07-08 17:28:55 +0000481
482 if (HintType == ARMRI::RegPairEven) {
483 if (isPhysicalRegister(HintReg) && getRegisterPairEven(HintReg, MF) == 0)
484 // It's no longer possible to fulfill this hint. Return the default
485 // allocation order.
Jakob Stoklund Olesendd5a8472011-06-16 23:31:16 +0000486 return RC->getRawAllocationOrder(MF);
David Goodwinc140c482009-07-08 17:28:55 +0000487
Anton Korobeynikovd0c38172010-11-18 21:19:35 +0000488 if (!TFI->hasFP(MF)) {
David Goodwinc140c482009-07-08 17:28:55 +0000489 if (!STI.isR9Reserved())
Frits van Bommel39b5abf2011-07-18 12:00:32 +0000490 return makeArrayRef(GPREven1);
David Goodwinc140c482009-07-08 17:28:55 +0000491 else
Frits van Bommel39b5abf2011-07-18 12:00:32 +0000492 return makeArrayRef(GPREven4);
David Goodwinc140c482009-07-08 17:28:55 +0000493 } else if (FramePtr == ARM::R7) {
494 if (!STI.isR9Reserved())
Frits van Bommel39b5abf2011-07-18 12:00:32 +0000495 return makeArrayRef(GPREven2);
David Goodwinc140c482009-07-08 17:28:55 +0000496 else
Frits van Bommel39b5abf2011-07-18 12:00:32 +0000497 return makeArrayRef(GPREven5);
David Goodwinc140c482009-07-08 17:28:55 +0000498 } else { // FramePtr == ARM::R11
499 if (!STI.isR9Reserved())
Frits van Bommel39b5abf2011-07-18 12:00:32 +0000500 return makeArrayRef(GPREven3);
David Goodwinc140c482009-07-08 17:28:55 +0000501 else
Frits van Bommel39b5abf2011-07-18 12:00:32 +0000502 return makeArrayRef(GPREven6);
David Goodwinc140c482009-07-08 17:28:55 +0000503 }
504 } else if (HintType == ARMRI::RegPairOdd) {
505 if (isPhysicalRegister(HintReg) && getRegisterPairOdd(HintReg, MF) == 0)
506 // It's no longer possible to fulfill this hint. Return the default
507 // allocation order.
Jakob Stoklund Olesendd5a8472011-06-16 23:31:16 +0000508 return RC->getRawAllocationOrder(MF);
David Goodwinc140c482009-07-08 17:28:55 +0000509
Anton Korobeynikovd0c38172010-11-18 21:19:35 +0000510 if (!TFI->hasFP(MF)) {
David Goodwinc140c482009-07-08 17:28:55 +0000511 if (!STI.isR9Reserved())
Frits van Bommel39b5abf2011-07-18 12:00:32 +0000512 return makeArrayRef(GPROdd1);
David Goodwinc140c482009-07-08 17:28:55 +0000513 else
Frits van Bommel39b5abf2011-07-18 12:00:32 +0000514 return makeArrayRef(GPROdd4);
David Goodwinc140c482009-07-08 17:28:55 +0000515 } else if (FramePtr == ARM::R7) {
516 if (!STI.isR9Reserved())
Frits van Bommel39b5abf2011-07-18 12:00:32 +0000517 return makeArrayRef(GPROdd2);
David Goodwinc140c482009-07-08 17:28:55 +0000518 else
Frits van Bommel39b5abf2011-07-18 12:00:32 +0000519 return makeArrayRef(GPROdd5);
David Goodwinc140c482009-07-08 17:28:55 +0000520 } else { // FramePtr == ARM::R11
521 if (!STI.isR9Reserved())
Frits van Bommel39b5abf2011-07-18 12:00:32 +0000522 return makeArrayRef(GPROdd3);
David Goodwinc140c482009-07-08 17:28:55 +0000523 else
Frits van Bommel39b5abf2011-07-18 12:00:32 +0000524 return makeArrayRef(GPROdd6);
David Goodwinc140c482009-07-08 17:28:55 +0000525 }
526 }
Jakob Stoklund Olesendd5a8472011-06-16 23:31:16 +0000527 return RC->getRawAllocationOrder(MF);
David Goodwinc140c482009-07-08 17:28:55 +0000528}
529
530/// ResolveRegAllocHint - Resolves the specified register allocation hint
531/// to a physical register. Returns the physical register if it is successful.
532unsigned
533ARMBaseRegisterInfo::ResolveRegAllocHint(unsigned Type, unsigned Reg,
534 const MachineFunction &MF) const {
535 if (Reg == 0 || !isPhysicalRegister(Reg))
536 return 0;
537 if (Type == 0)
538 return Reg;
539 else if (Type == (unsigned)ARMRI::RegPairOdd)
540 // Odd register.
541 return getRegisterPairOdd(Reg, MF);
542 else if (Type == (unsigned)ARMRI::RegPairEven)
543 // Even register.
544 return getRegisterPairEven(Reg, MF);
545 return 0;
546}
547
548void
549ARMBaseRegisterInfo::UpdateRegAllocHint(unsigned Reg, unsigned NewReg,
550 MachineFunction &MF) const {
551 MachineRegisterInfo *MRI = &MF.getRegInfo();
552 std::pair<unsigned, unsigned> Hint = MRI->getRegAllocationHint(Reg);
553 if ((Hint.first == (unsigned)ARMRI::RegPairOdd ||
554 Hint.first == (unsigned)ARMRI::RegPairEven) &&
Jakob Stoklund Olesenc9df0252011-01-10 02:58:51 +0000555 TargetRegisterInfo::isVirtualRegister(Hint.second)) {
David Goodwinc140c482009-07-08 17:28:55 +0000556 // If 'Reg' is one of the even / odd register pair and it's now changed
557 // (e.g. coalesced) into a different register. The other register of the
558 // pair allocation hint must be updated to reflect the relationship
559 // change.
560 unsigned OtherReg = Hint.second;
561 Hint = MRI->getRegAllocationHint(OtherReg);
562 if (Hint.second == Reg)
563 // Make sure the pair has not already divorced.
564 MRI->setRegAllocationHint(OtherReg, Hint.first, NewReg);
565 }
566}
567
Bob Wilsonf6a4d3c2011-04-19 18:11:45 +0000568bool
569ARMBaseRegisterInfo::avoidWriteAfterWrite(const TargetRegisterClass *RC) const {
570 // CortexA9 has a Write-after-write hazard for NEON registers.
571 if (!STI.isCortexA9())
572 return false;
573
574 switch (RC->getID()) {
575 case ARM::DPRRegClassID:
576 case ARM::DPR_8RegClassID:
577 case ARM::DPR_VFP2RegClassID:
578 case ARM::QPRRegClassID:
579 case ARM::QPR_8RegClassID:
580 case ARM::QPR_VFP2RegClassID:
581 case ARM::SPRRegClassID:
582 case ARM::SPR_8RegClassID:
583 // Avoid reusing S, D, and Q registers.
584 // Don't increase register pressure for QQ and QQQQ.
585 return true;
586 default:
587 return false;
588 }
589}
590
Jim Grosbach65482b12010-09-03 18:37:12 +0000591bool ARMBaseRegisterInfo::hasBasePointer(const MachineFunction &MF) const {
Jim Grosbache45ab8a2010-01-19 18:31:11 +0000592 const MachineFrameInfo *MFI = MF.getFrameInfo();
593 const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
Jim Grosbach65482b12010-09-03 18:37:12 +0000594
595 if (!EnableBasePointer)
596 return false;
597
598 if (needsStackRealignment(MF) && MFI->hasVarSizedObjects())
599 return true;
600
601 // Thumb has trouble with negative offsets from the FP. Thumb2 has a limited
602 // negative range for ldr/str (255), and thumb1 is positive offsets only.
603 // It's going to be better to use the SP or Base Pointer instead. When there
604 // are variable sized objects, we can't reference off of the SP, so we
605 // reserve a Base Pointer.
606 if (AFI->isThumbFunction() && MFI->hasVarSizedObjects()) {
607 // Conservatively estimate whether the negative offset from the frame
608 // pointer will be sufficient to reach. If a function has a smallish
609 // frame, it's less likely to have lots of spills and callee saved
610 // space, so it's all more likely to be within range of the frame pointer.
611 // If it's wrong, the scavenger will still enable access to work, it just
612 // won't be optimal.
613 if (AFI->isThumb2Function() && MFI->getLocalFrameSize() < 128)
614 return false;
615 return true;
616 }
617
618 return false;
619}
620
621bool ARMBaseRegisterInfo::canRealignStack(const MachineFunction &MF) const {
Jim Grosbach30c93e12010-09-08 17:22:12 +0000622 const MachineFrameInfo *MFI = MF.getFrameInfo();
Jim Grosbach65482b12010-09-03 18:37:12 +0000623 const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
Jim Grosbach30c93e12010-09-08 17:22:12 +0000624 // We can't realign the stack if:
625 // 1. Dynamic stack realignment is explicitly disabled,
626 // 2. This is a Thumb1 function (it's not useful, so we don't bother), or
627 // 3. There are VLAs in the function and the base pointer is disabled.
628 return (RealignStack && !AFI->isThumb1OnlyFunction() &&
629 (!MFI->hasVarSizedObjects() || EnableBasePointer));
Jim Grosbache45ab8a2010-01-19 18:31:11 +0000630}
631
Jim Grosbach3dab2772009-10-27 22:45:39 +0000632bool ARMBaseRegisterInfo::
633needsStackRealignment(const MachineFunction &MF) const {
Jim Grosbach3dab2772009-10-27 22:45:39 +0000634 const MachineFrameInfo *MFI = MF.getFrameInfo();
Eric Christopherd4c36ce2010-07-17 00:27:24 +0000635 const Function *F = MF.getFunction();
Anton Korobeynikov16c29b52011-01-10 12:39:04 +0000636 unsigned StackAlign = MF.getTarget().getFrameLowering()->getStackAlignment();
Jim Grosbachfc633002010-09-03 18:28:19 +0000637 bool requiresRealignment = ((MFI->getLocalFrameMaxAlign() > StackAlign) ||
Eric Christopher697cba82010-07-17 00:33:04 +0000638 F->hasFnAttr(Attribute::StackAlignment));
Jim Grosbach5c33f5b2010-09-02 19:52:39 +0000639
Eric Christopherd4c36ce2010-07-17 00:27:24 +0000640 return requiresRealignment && canRealignStack(MF);
Jim Grosbach3dab2772009-10-27 22:45:39 +0000641}
642
Jim Grosbach96318642010-01-06 23:54:42 +0000643bool ARMBaseRegisterInfo::
644cannotEliminateFrame(const MachineFunction &MF) const {
Evan Cheng98a01042009-08-14 20:48:13 +0000645 const MachineFrameInfo *MFI = MF.getFrameInfo();
Bill Wendlingb92187a2010-05-14 21:14:32 +0000646 if (DisableFramePointerElim(MF) && MFI->adjustsStack())
Evan Cheng98a01042009-08-14 20:48:13 +0000647 return true;
Jim Grosbach31bc8492009-11-08 00:27:19 +0000648 return MFI->hasVarSizedObjects() || MFI->isFrameAddressTaken()
649 || needsStackRealignment(MF);
Evan Cheng98a01042009-08-14 20:48:13 +0000650}
651
Jim Grosbach5c33f5b2010-09-02 19:52:39 +0000652unsigned
David Greene3f2bf852009-11-12 20:49:22 +0000653ARMBaseRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
Anton Korobeynikov16c29b52011-01-10 12:39:04 +0000654 const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
Anton Korobeynikovd0c38172010-11-18 21:19:35 +0000655
656 if (TFI->hasFP(MF))
David Goodwinc140c482009-07-08 17:28:55 +0000657 return FramePtr;
658 return ARM::SP;
659}
660
661unsigned ARMBaseRegisterInfo::getEHExceptionRegister() const {
Torok Edwinc23197a2009-07-14 16:55:14 +0000662 llvm_unreachable("What is the exception register");
David Goodwinc140c482009-07-08 17:28:55 +0000663 return 0;
664}
665
666unsigned ARMBaseRegisterInfo::getEHHandlerRegister() const {
Torok Edwinc23197a2009-07-14 16:55:14 +0000667 llvm_unreachable("What is the exception handler register");
David Goodwinc140c482009-07-08 17:28:55 +0000668 return 0;
669}
670
David Goodwinc140c482009-07-08 17:28:55 +0000671unsigned ARMBaseRegisterInfo::getRegisterPairEven(unsigned Reg,
Jim Grosbach96318642010-01-06 23:54:42 +0000672 const MachineFunction &MF) const {
David Goodwinc140c482009-07-08 17:28:55 +0000673 switch (Reg) {
674 default: break;
675 // Return 0 if either register of the pair is a special register.
676 // So no R12, etc.
677 case ARM::R1:
678 return ARM::R0;
679 case ARM::R3:
Jim Grosbach60097512009-10-19 22:57:03 +0000680 return ARM::R2;
David Goodwinc140c482009-07-08 17:28:55 +0000681 case ARM::R5:
682 return ARM::R4;
683 case ARM::R7:
Jim Grosbach65482b12010-09-03 18:37:12 +0000684 return (isReservedReg(MF, ARM::R7) || isReservedReg(MF, ARM::R6))
685 ? 0 : ARM::R6;
David Goodwinc140c482009-07-08 17:28:55 +0000686 case ARM::R9:
687 return isReservedReg(MF, ARM::R9) ? 0 :ARM::R8;
688 case ARM::R11:
689 return isReservedReg(MF, ARM::R11) ? 0 : ARM::R10;
690
691 case ARM::S1:
692 return ARM::S0;
693 case ARM::S3:
694 return ARM::S2;
695 case ARM::S5:
696 return ARM::S4;
697 case ARM::S7:
698 return ARM::S6;
699 case ARM::S9:
700 return ARM::S8;
701 case ARM::S11:
702 return ARM::S10;
703 case ARM::S13:
704 return ARM::S12;
705 case ARM::S15:
706 return ARM::S14;
707 case ARM::S17:
708 return ARM::S16;
709 case ARM::S19:
710 return ARM::S18;
711 case ARM::S21:
712 return ARM::S20;
713 case ARM::S23:
714 return ARM::S22;
715 case ARM::S25:
716 return ARM::S24;
717 case ARM::S27:
718 return ARM::S26;
719 case ARM::S29:
720 return ARM::S28;
721 case ARM::S31:
722 return ARM::S30;
723
724 case ARM::D1:
725 return ARM::D0;
726 case ARM::D3:
727 return ARM::D2;
728 case ARM::D5:
729 return ARM::D4;
730 case ARM::D7:
731 return ARM::D6;
732 case ARM::D9:
733 return ARM::D8;
734 case ARM::D11:
735 return ARM::D10;
736 case ARM::D13:
737 return ARM::D12;
738 case ARM::D15:
739 return ARM::D14;
Evan Cheng8295d992009-07-22 05:55:18 +0000740 case ARM::D17:
741 return ARM::D16;
742 case ARM::D19:
743 return ARM::D18;
744 case ARM::D21:
745 return ARM::D20;
746 case ARM::D23:
747 return ARM::D22;
748 case ARM::D25:
749 return ARM::D24;
750 case ARM::D27:
751 return ARM::D26;
752 case ARM::D29:
753 return ARM::D28;
754 case ARM::D31:
755 return ARM::D30;
David Goodwinc140c482009-07-08 17:28:55 +0000756 }
757
758 return 0;
759}
760
761unsigned ARMBaseRegisterInfo::getRegisterPairOdd(unsigned Reg,
762 const MachineFunction &MF) const {
763 switch (Reg) {
764 default: break;
765 // Return 0 if either register of the pair is a special register.
766 // So no R12, etc.
767 case ARM::R0:
768 return ARM::R1;
769 case ARM::R2:
Jim Grosbach60097512009-10-19 22:57:03 +0000770 return ARM::R3;
David Goodwinc140c482009-07-08 17:28:55 +0000771 case ARM::R4:
772 return ARM::R5;
773 case ARM::R6:
Jim Grosbach65482b12010-09-03 18:37:12 +0000774 return (isReservedReg(MF, ARM::R7) || isReservedReg(MF, ARM::R6))
775 ? 0 : ARM::R7;
David Goodwinc140c482009-07-08 17:28:55 +0000776 case ARM::R8:
777 return isReservedReg(MF, ARM::R9) ? 0 :ARM::R9;
778 case ARM::R10:
779 return isReservedReg(MF, ARM::R11) ? 0 : ARM::R11;
780
781 case ARM::S0:
782 return ARM::S1;
783 case ARM::S2:
784 return ARM::S3;
785 case ARM::S4:
786 return ARM::S5;
787 case ARM::S6:
788 return ARM::S7;
789 case ARM::S8:
790 return ARM::S9;
791 case ARM::S10:
792 return ARM::S11;
793 case ARM::S12:
794 return ARM::S13;
795 case ARM::S14:
796 return ARM::S15;
797 case ARM::S16:
798 return ARM::S17;
799 case ARM::S18:
800 return ARM::S19;
801 case ARM::S20:
802 return ARM::S21;
803 case ARM::S22:
804 return ARM::S23;
805 case ARM::S24:
806 return ARM::S25;
807 case ARM::S26:
808 return ARM::S27;
809 case ARM::S28:
810 return ARM::S29;
811 case ARM::S30:
812 return ARM::S31;
813
814 case ARM::D0:
815 return ARM::D1;
816 case ARM::D2:
817 return ARM::D3;
818 case ARM::D4:
819 return ARM::D5;
820 case ARM::D6:
821 return ARM::D7;
822 case ARM::D8:
823 return ARM::D9;
824 case ARM::D10:
825 return ARM::D11;
826 case ARM::D12:
827 return ARM::D13;
828 case ARM::D14:
829 return ARM::D15;
Evan Cheng8295d992009-07-22 05:55:18 +0000830 case ARM::D16:
831 return ARM::D17;
832 case ARM::D18:
833 return ARM::D19;
834 case ARM::D20:
835 return ARM::D21;
836 case ARM::D22:
837 return ARM::D23;
838 case ARM::D24:
839 return ARM::D25;
840 case ARM::D26:
841 return ARM::D27;
842 case ARM::D28:
843 return ARM::D29;
844 case ARM::D30:
845 return ARM::D31;
David Goodwinc140c482009-07-08 17:28:55 +0000846 }
847
848 return 0;
849}
850
David Goodwindb5a71a2009-07-08 18:31:39 +0000851/// emitLoadConstPool - Emits a load from constpool to materialize the
852/// specified immediate.
853void ARMBaseRegisterInfo::
854emitLoadConstPool(MachineBasicBlock &MBB,
855 MachineBasicBlock::iterator &MBBI,
David Goodwin77521f52009-07-08 20:28:28 +0000856 DebugLoc dl,
Evan Cheng37844532009-07-16 09:20:10 +0000857 unsigned DestReg, unsigned SubIdx, int Val,
David Goodwindb5a71a2009-07-08 18:31:39 +0000858 ARMCC::CondCodes Pred,
Anton Korobeynikov3daccd82011-03-05 18:43:50 +0000859 unsigned PredReg, unsigned MIFlags) const {
David Goodwindb5a71a2009-07-08 18:31:39 +0000860 MachineFunction &MF = *MBB.getParent();
861 MachineConstantPool *ConstantPool = MF.getConstantPool();
Dan Gohman46510a72010-04-15 01:51:59 +0000862 const Constant *C =
Owen Anderson1d0be152009-08-13 21:58:54 +0000863 ConstantInt::get(Type::getInt32Ty(MF.getFunction()->getContext()), Val);
David Goodwindb5a71a2009-07-08 18:31:39 +0000864 unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4);
865
Evan Cheng37844532009-07-16 09:20:10 +0000866 BuildMI(MBB, MBBI, dl, TII.get(ARM::LDRcp))
867 .addReg(DestReg, getDefRegState(true), SubIdx)
David Goodwindb5a71a2009-07-08 18:31:39 +0000868 .addConstantPoolIndex(Idx)
Anton Korobeynikov3daccd82011-03-05 18:43:50 +0000869 .addImm(0).addImm(Pred).addReg(PredReg)
870 .setMIFlags(MIFlags);
David Goodwindb5a71a2009-07-08 18:31:39 +0000871}
872
873bool ARMBaseRegisterInfo::
874requiresRegisterScavenging(const MachineFunction &MF) const {
875 return true;
876}
Jim Grosbach41fff8c2009-10-21 23:40:56 +0000877
Jim Grosbach7e831db2009-10-20 01:26:58 +0000878bool ARMBaseRegisterInfo::
879requiresFrameIndexScavenging(const MachineFunction &MF) const {
Jim Grosbachca5dfb72009-10-28 17:33:28 +0000880 return true;
Jim Grosbach7e831db2009-10-20 01:26:58 +0000881}
David Goodwindb5a71a2009-07-08 18:31:39 +0000882
Jim Grosbacha2734422010-08-24 19:05:43 +0000883bool ARMBaseRegisterInfo::
884requiresVirtualBaseRegisters(const MachineFunction &MF) const {
885 return EnableLocalStackAlloc;
886}
887
David Goodwindb5a71a2009-07-08 18:31:39 +0000888static void
Evan Cheng6495f632009-07-28 05:48:47 +0000889emitSPUpdate(bool isARM,
890 MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
891 DebugLoc dl, const ARMBaseInstrInfo &TII,
David Goodwindb5a71a2009-07-08 18:31:39 +0000892 int NumBytes,
893 ARMCC::CondCodes Pred = ARMCC::AL, unsigned PredReg = 0) {
Evan Cheng6495f632009-07-28 05:48:47 +0000894 if (isARM)
895 emitARMRegPlusImmediate(MBB, MBBI, dl, ARM::SP, ARM::SP, NumBytes,
896 Pred, PredReg, TII);
897 else
898 emitT2RegPlusImmediate(MBB, MBBI, dl, ARM::SP, ARM::SP, NumBytes,
899 Pred, PredReg, TII);
David Goodwindb5a71a2009-07-08 18:31:39 +0000900}
901
Evan Cheng6495f632009-07-28 05:48:47 +0000902
David Goodwindb5a71a2009-07-08 18:31:39 +0000903void ARMBaseRegisterInfo::
904eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
905 MachineBasicBlock::iterator I) const {
Anton Korobeynikov16c29b52011-01-10 12:39:04 +0000906 const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
Anton Korobeynikovd0c38172010-11-18 21:19:35 +0000907 if (!TFI->hasReservedCallFrame(MF)) {
David Goodwindb5a71a2009-07-08 18:31:39 +0000908 // If we have alloca, convert as follows:
909 // ADJCALLSTACKDOWN -> sub, sp, sp, amount
910 // ADJCALLSTACKUP -> add, sp, sp, amount
911 MachineInstr *Old = I;
912 DebugLoc dl = Old->getDebugLoc();
913 unsigned Amount = Old->getOperand(0).getImm();
914 if (Amount != 0) {
915 // We need to keep the stack aligned properly. To do this, we round the
916 // amount of space needed for the outgoing arguments up to the next
917 // alignment boundary.
Anton Korobeynikov16c29b52011-01-10 12:39:04 +0000918 unsigned Align = TFI->getStackAlignment();
David Goodwindb5a71a2009-07-08 18:31:39 +0000919 Amount = (Amount+Align-1)/Align*Align;
920
Evan Cheng6495f632009-07-28 05:48:47 +0000921 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
922 assert(!AFI->isThumb1OnlyFunction() &&
Jim Grosbachcf453ee2010-02-23 17:16:27 +0000923 "This eliminateCallFramePseudoInstr does not support Thumb1!");
Evan Cheng6495f632009-07-28 05:48:47 +0000924 bool isARM = !AFI->isThumbFunction();
925
David Goodwindb5a71a2009-07-08 18:31:39 +0000926 // Replace the pseudo instruction with a new instruction...
927 unsigned Opc = Old->getOpcode();
Jim Grosbach4c7628e2010-02-22 22:47:46 +0000928 int PIdx = Old->findFirstPredOperandIdx();
929 ARMCC::CondCodes Pred = (PIdx == -1)
930 ? ARMCC::AL : (ARMCC::CondCodes)Old->getOperand(PIdx).getImm();
David Goodwindb5a71a2009-07-08 18:31:39 +0000931 if (Opc == ARM::ADJCALLSTACKDOWN || Opc == ARM::tADJCALLSTACKDOWN) {
932 // Note: PredReg is operand 2 for ADJCALLSTACKDOWN.
933 unsigned PredReg = Old->getOperand(2).getReg();
Evan Cheng6495f632009-07-28 05:48:47 +0000934 emitSPUpdate(isARM, MBB, I, dl, TII, -Amount, Pred, PredReg);
David Goodwindb5a71a2009-07-08 18:31:39 +0000935 } else {
936 // Note: PredReg is operand 3 for ADJCALLSTACKUP.
937 unsigned PredReg = Old->getOperand(3).getReg();
938 assert(Opc == ARM::ADJCALLSTACKUP || Opc == ARM::tADJCALLSTACKUP);
Evan Cheng6495f632009-07-28 05:48:47 +0000939 emitSPUpdate(isARM, MBB, I, dl, TII, Amount, Pred, PredReg);
David Goodwindb5a71a2009-07-08 18:31:39 +0000940 }
941 }
942 }
943 MBB.erase(I);
944}
945
Jim Grosbache2f55692010-08-19 23:52:25 +0000946int64_t ARMBaseRegisterInfo::
Jim Grosbach1ab3f162010-08-26 21:56:30 +0000947getFrameIndexInstrOffset(const MachineInstr *MI, int Idx) const {
Evan Chenge837dea2011-06-28 19:10:37 +0000948 const MCInstrDesc &Desc = MI->getDesc();
Jim Grosbache2f55692010-08-19 23:52:25 +0000949 unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
950 int64_t InstrOffs = 0;;
951 int Scale = 1;
952 unsigned ImmIdx = 0;
Jim Grosbach1ab3f162010-08-26 21:56:30 +0000953 switch (AddrMode) {
Jim Grosbache2f55692010-08-19 23:52:25 +0000954 case ARMII::AddrModeT2_i8:
955 case ARMII::AddrModeT2_i12:
Jim Grosbach3e556122010-10-26 22:37:02 +0000956 case ARMII::AddrMode_i12:
Jim Grosbache2f55692010-08-19 23:52:25 +0000957 InstrOffs = MI->getOperand(Idx+1).getImm();
958 Scale = 1;
959 break;
960 case ARMII::AddrMode5: {
961 // VFP address mode.
962 const MachineOperand &OffOp = MI->getOperand(Idx+1);
Jim Grosbachf78ee632010-08-25 19:11:34 +0000963 InstrOffs = ARM_AM::getAM5Offset(OffOp.getImm());
Jim Grosbache2f55692010-08-19 23:52:25 +0000964 if (ARM_AM::getAM5Op(OffOp.getImm()) == ARM_AM::sub)
965 InstrOffs = -InstrOffs;
966 Scale = 4;
967 break;
968 }
969 case ARMII::AddrMode2: {
970 ImmIdx = Idx+2;
971 InstrOffs = ARM_AM::getAM2Offset(MI->getOperand(ImmIdx).getImm());
972 if (ARM_AM::getAM2Op(MI->getOperand(ImmIdx).getImm()) == ARM_AM::sub)
973 InstrOffs = -InstrOffs;
974 break;
975 }
976 case ARMII::AddrMode3: {
977 ImmIdx = Idx+2;
978 InstrOffs = ARM_AM::getAM3Offset(MI->getOperand(ImmIdx).getImm());
979 if (ARM_AM::getAM3Op(MI->getOperand(ImmIdx).getImm()) == ARM_AM::sub)
980 InstrOffs = -InstrOffs;
981 break;
982 }
983 case ARMII::AddrModeT1_s: {
984 ImmIdx = Idx+1;
985 InstrOffs = MI->getOperand(ImmIdx).getImm();
986 Scale = 4;
987 break;
988 }
989 default:
990 llvm_unreachable("Unsupported addressing mode!");
991 break;
992 }
993
994 return InstrOffs * Scale;
995}
996
Jim Grosbach8708ead2010-08-17 18:13:53 +0000997/// needsFrameBaseReg - Returns true if the instruction's frame index
998/// reference would be better served by a base register other than FP
999/// or SP. Used by LocalStackFrameAllocation to determine which frame index
1000/// references it should create new base registers for.
1001bool ARMBaseRegisterInfo::
Jim Grosbach31973802010-08-24 21:19:33 +00001002needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const {
1003 for (unsigned i = 0; !MI->getOperand(i).isFI(); ++i) {
1004 assert(i < MI->getNumOperands() &&"Instr doesn't have FrameIndex operand!");
1005 }
Jim Grosbach8708ead2010-08-17 18:13:53 +00001006
1007 // It's the load/store FI references that cause issues, as it can be difficult
1008 // to materialize the offset if it won't fit in the literal field. Estimate
1009 // based on the size of the local frame and some conservative assumptions
1010 // about the rest of the stack frame (note, this is pre-regalloc, so
1011 // we don't know everything for certain yet) whether this offset is likely
1012 // to be out of range of the immediate. Return true if so.
1013
Jim Grosbachcd59dc52010-08-24 18:04:52 +00001014 // We only generate virtual base registers for loads and stores, so
1015 // return false for everything else.
Jim Grosbach8708ead2010-08-17 18:13:53 +00001016 unsigned Opc = MI->getOpcode();
Jim Grosbach8708ead2010-08-17 18:13:53 +00001017 switch (Opc) {
Jim Grosbachc1d30212010-10-27 00:19:44 +00001018 case ARM::LDRi12: case ARM::LDRH: case ARM::LDRBi12:
Jim Grosbach7e3383c2010-10-27 23:12:14 +00001019 case ARM::STRi12: case ARM::STRH: case ARM::STRBi12:
Jim Grosbach8708ead2010-08-17 18:13:53 +00001020 case ARM::t2LDRi12: case ARM::t2LDRi8:
1021 case ARM::t2STRi12: case ARM::t2STRi8:
1022 case ARM::VLDRS: case ARM::VLDRD:
1023 case ARM::VSTRS: case ARM::VSTRD:
Jim Grosbach74d7b0a2010-08-19 17:52:13 +00001024 case ARM::tSTRspi: case ARM::tLDRspi:
Jim Grosbachcd59dc52010-08-24 18:04:52 +00001025 if (ForceAllBaseRegAlloc)
1026 return true;
1027 break;
Jim Grosbach8708ead2010-08-17 18:13:53 +00001028 default:
1029 return false;
1030 }
Jim Grosbachcd59dc52010-08-24 18:04:52 +00001031
Jim Grosbachcd59dc52010-08-24 18:04:52 +00001032 // Without a virtual base register, if the function has variable sized
1033 // objects, all fixed-size local references will be via the frame pointer,
Jim Grosbach31973802010-08-24 21:19:33 +00001034 // Approximate the offset and see if it's legal for the instruction.
1035 // Note that the incoming offset is based on the SP value at function entry,
1036 // so it'll be negative.
1037 MachineFunction &MF = *MI->getParent()->getParent();
Anton Korobeynikov16c29b52011-01-10 12:39:04 +00001038 const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
Jim Grosbach31973802010-08-24 21:19:33 +00001039 MachineFrameInfo *MFI = MF.getFrameInfo();
1040 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
Jim Grosbachcd59dc52010-08-24 18:04:52 +00001041
Jim Grosbach31973802010-08-24 21:19:33 +00001042 // Estimate an offset from the frame pointer.
1043 // Conservatively assume all callee-saved registers get pushed. R4-R6
1044 // will be earlier than the FP, so we ignore those.
1045 // R7, LR
1046 int64_t FPOffset = Offset - 8;
1047 // ARM and Thumb2 functions also need to consider R8-R11 and D8-D15
1048 if (!AFI->isThumbFunction() || !AFI->isThumb1OnlyFunction())
1049 FPOffset -= 80;
1050 // Estimate an offset from the stack pointer.
Jim Grosbachc1dc78d2010-08-31 18:52:31 +00001051 // The incoming offset is relating to the SP at the start of the function,
1052 // but when we access the local it'll be relative to the SP after local
1053 // allocation, so adjust our SP-relative offset by that allocation size.
Jim Grosbach31973802010-08-24 21:19:33 +00001054 Offset = -Offset;
Jim Grosbachc1dc78d2010-08-31 18:52:31 +00001055 Offset += MFI->getLocalFrameSize();
Jim Grosbach31973802010-08-24 21:19:33 +00001056 // Assume that we'll have at least some spill slots allocated.
1057 // FIXME: This is a total SWAG number. We should run some statistics
1058 // and pick a real one.
1059 Offset += 128; // 128 bytes of spill slots
1060
1061 // If there is a frame pointer, try using it.
1062 // The FP is only available if there is no dynamic realignment. We
1063 // don't know for sure yet whether we'll need that, so we guess based
1064 // on whether there are any local variables that would trigger it.
Anton Korobeynikov16c29b52011-01-10 12:39:04 +00001065 unsigned StackAlign = TFI->getStackAlignment();
Anton Korobeynikovd0c38172010-11-18 21:19:35 +00001066 if (TFI->hasFP(MF) &&
Jim Grosbach31973802010-08-24 21:19:33 +00001067 !((MFI->getLocalFrameMaxAlign() > StackAlign) && canRealignStack(MF))) {
1068 if (isFrameOffsetLegal(MI, FPOffset))
1069 return false;
1070 }
1071 // If we can reference via the stack pointer, try that.
1072 // FIXME: This (and the code that resolves the references) can be improved
1073 // to only disallow SP relative references in the live range of
1074 // the VLA(s). In practice, it's unclear how much difference that
1075 // would make, but it may be worth doing.
1076 if (!MFI->hasVarSizedObjects() && isFrameOffsetLegal(MI, Offset))
1077 return false;
1078
1079 // The offset likely isn't legal, we want to allocate a virtual base register.
Jim Grosbachcd59dc52010-08-24 18:04:52 +00001080 return true;
Jim Grosbach8708ead2010-08-17 18:13:53 +00001081}
1082
Bill Wendling976ef862010-12-17 23:09:14 +00001083/// materializeFrameBaseRegister - Insert defining instruction(s) for BaseReg to
1084/// be a pointer to FrameIdx at the beginning of the basic block.
Jim Grosbachdc140c62010-08-17 22:41:55 +00001085void ARMBaseRegisterInfo::
Bill Wendling976ef862010-12-17 23:09:14 +00001086materializeFrameBaseRegister(MachineBasicBlock *MBB,
1087 unsigned BaseReg, int FrameIdx,
1088 int64_t Offset) const {
1089 ARMFunctionInfo *AFI = MBB->getParent()->getInfo<ARMFunctionInfo>();
Jim Grosbach74d7b0a2010-08-19 17:52:13 +00001090 unsigned ADDriOpc = !AFI->isThumbFunction() ? ARM::ADDri :
1091 (AFI->isThumb1OnlyFunction() ? ARM::tADDrSPi : ARM::t2ADDri);
Jim Grosbachdc140c62010-08-17 22:41:55 +00001092
Bill Wendling976ef862010-12-17 23:09:14 +00001093 MachineBasicBlock::iterator Ins = MBB->begin();
1094 DebugLoc DL; // Defaults to "unknown"
1095 if (Ins != MBB->end())
1096 DL = Ins->getDebugLoc();
1097
Evan Chenge837dea2011-06-28 19:10:37 +00001098 const MCInstrDesc &MCID = TII.get(ADDriOpc);
Cameron Zwarich21803722011-05-19 02:18:27 +00001099 MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo();
Evan Chenge837dea2011-06-28 19:10:37 +00001100 MRI.constrainRegClass(BaseReg, TII.getRegClass(MCID, 0, this));
Cameron Zwarich21803722011-05-19 02:18:27 +00001101
Evan Chenge837dea2011-06-28 19:10:37 +00001102 MachineInstrBuilder MIB = BuildMI(*MBB, Ins, DL, MCID, BaseReg)
Jim Grosbache2f55692010-08-19 23:52:25 +00001103 .addFrameIndex(FrameIdx).addImm(Offset);
Bill Wendling976ef862010-12-17 23:09:14 +00001104
Jim Grosbach74d7b0a2010-08-19 17:52:13 +00001105 if (!AFI->isThumb1OnlyFunction())
1106 AddDefaultCC(AddDefaultPred(MIB));
Jim Grosbachdc140c62010-08-17 22:41:55 +00001107}
1108
1109void
1110ARMBaseRegisterInfo::resolveFrameIndex(MachineBasicBlock::iterator I,
1111 unsigned BaseReg, int64_t Offset) const {
1112 MachineInstr &MI = *I;
1113 MachineBasicBlock &MBB = *MI.getParent();
1114 MachineFunction &MF = *MBB.getParent();
1115 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
1116 int Off = Offset; // ARM doesn't need the general 64-bit offsets
1117 unsigned i = 0;
1118
1119 assert(!AFI->isThumb1OnlyFunction() &&
1120 "This resolveFrameIndex does not support Thumb1!");
1121
1122 while (!MI.getOperand(i).isFI()) {
1123 ++i;
1124 assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
1125 }
1126 bool Done = false;
1127 if (!AFI->isThumbFunction())
1128 Done = rewriteARMFrameIndex(MI, i, BaseReg, Off, TII);
1129 else {
1130 assert(AFI->isThumb2Function());
1131 Done = rewriteT2FrameIndex(MI, i, BaseReg, Off, TII);
1132 }
1133 assert (Done && "Unable to resolve frame index!");
1134}
Jim Grosbach8708ead2010-08-17 18:13:53 +00001135
Jim Grosbache2f55692010-08-19 23:52:25 +00001136bool ARMBaseRegisterInfo::isFrameOffsetLegal(const MachineInstr *MI,
1137 int64_t Offset) const {
Evan Chenge837dea2011-06-28 19:10:37 +00001138 const MCInstrDesc &Desc = MI->getDesc();
Jim Grosbach2b1e2022010-08-18 22:44:49 +00001139 unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
1140 unsigned i = 0;
1141
1142 while (!MI->getOperand(i).isFI()) {
1143 ++i;
1144 assert(i < MI->getNumOperands() &&"Instr doesn't have FrameIndex operand!");
1145 }
1146
1147 // AddrMode4 and AddrMode6 cannot handle any offset.
1148 if (AddrMode == ARMII::AddrMode4 || AddrMode == ARMII::AddrMode6)
1149 return Offset == 0;
1150
1151 unsigned NumBits = 0;
1152 unsigned Scale = 1;
Jim Grosbache2f55692010-08-19 23:52:25 +00001153 bool isSigned = true;
Jim Grosbach1ab3f162010-08-26 21:56:30 +00001154 switch (AddrMode) {
Jim Grosbach2b1e2022010-08-18 22:44:49 +00001155 case ARMII::AddrModeT2_i8:
1156 case ARMII::AddrModeT2_i12:
1157 // i8 supports only negative, and i12 supports only positive, so
1158 // based on Offset sign, consider the appropriate instruction
Jim Grosbach74d7b0a2010-08-19 17:52:13 +00001159 Scale = 1;
Jim Grosbach2b1e2022010-08-18 22:44:49 +00001160 if (Offset < 0) {
1161 NumBits = 8;
1162 Offset = -Offset;
1163 } else {
1164 NumBits = 12;
1165 }
1166 break;
Jim Grosbach1ab3f162010-08-26 21:56:30 +00001167 case ARMII::AddrMode5:
Jim Grosbach2b1e2022010-08-18 22:44:49 +00001168 // VFP address mode.
Jim Grosbach2b1e2022010-08-18 22:44:49 +00001169 NumBits = 8;
1170 Scale = 4;
1171 break;
Jim Grosbach3e556122010-10-26 22:37:02 +00001172 case ARMII::AddrMode_i12:
Jim Grosbach1ab3f162010-08-26 21:56:30 +00001173 case ARMII::AddrMode2:
Jim Grosbach2b1e2022010-08-18 22:44:49 +00001174 NumBits = 12;
1175 break;
Jim Grosbach1ab3f162010-08-26 21:56:30 +00001176 case ARMII::AddrMode3:
Jim Grosbach2b1e2022010-08-18 22:44:49 +00001177 NumBits = 8;
1178 break;
Jim Grosbach1ab3f162010-08-26 21:56:30 +00001179 case ARMII::AddrModeT1_s:
Jim Grosbach74d7b0a2010-08-19 17:52:13 +00001180 NumBits = 5;
1181 Scale = 4;
Jim Grosbache2f55692010-08-19 23:52:25 +00001182 isSigned = false;
Jim Grosbach74d7b0a2010-08-19 17:52:13 +00001183 break;
Jim Grosbach2b1e2022010-08-18 22:44:49 +00001184 default:
1185 llvm_unreachable("Unsupported addressing mode!");
1186 break;
1187 }
1188
Jim Grosbach1ab3f162010-08-26 21:56:30 +00001189 Offset += getFrameIndexInstrOffset(MI, i);
Jim Grosbachd4511e92010-08-31 18:49:31 +00001190 // Make sure the offset is encodable for instructions that scale the
1191 // immediate.
1192 if ((Offset & (Scale-1)) != 0)
1193 return false;
1194
Jim Grosbache2f55692010-08-19 23:52:25 +00001195 if (isSigned && Offset < 0)
Jim Grosbach2b1e2022010-08-18 22:44:49 +00001196 Offset = -Offset;
1197
1198 unsigned Mask = (1 << NumBits) - 1;
1199 if ((unsigned)Offset <= Mask * Scale)
1200 return true;
Jim Grosbach74d803a2010-08-18 17:57:37 +00001201
1202 return false;
1203}
1204
Jim Grosbachfcb4a8e2010-08-26 23:32:16 +00001205void
Evan Cheng6495f632009-07-28 05:48:47 +00001206ARMBaseRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
Jim Grosbachfcb4a8e2010-08-26 23:32:16 +00001207 int SPAdj, RegScavenger *RS) const {
David Goodwindb5a71a2009-07-08 18:31:39 +00001208 unsigned i = 0;
1209 MachineInstr &MI = *II;
1210 MachineBasicBlock &MBB = *MI.getParent();
1211 MachineFunction &MF = *MBB.getParent();
Anton Korobeynikov16c29b52011-01-10 12:39:04 +00001212 const ARMFrameLowering *TFI =
1213 static_cast<const ARMFrameLowering*>(MF.getTarget().getFrameLowering());
David Goodwindb5a71a2009-07-08 18:31:39 +00001214 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
Evan Cheng6495f632009-07-28 05:48:47 +00001215 assert(!AFI->isThumb1OnlyFunction() &&
Bob Wilsona15de002009-09-18 21:42:44 +00001216 "This eliminateFrameIndex does not support Thumb1!");
David Goodwindb5a71a2009-07-08 18:31:39 +00001217
1218 while (!MI.getOperand(i).isFI()) {
1219 ++i;
1220 assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
1221 }
1222
David Goodwindb5a71a2009-07-08 18:31:39 +00001223 int FrameIndex = MI.getOperand(i).getIndex();
Jim Grosbacha37aa542009-11-22 20:05:32 +00001224 unsigned FrameReg;
David Goodwindb5a71a2009-07-08 18:31:39 +00001225
Anton Korobeynikov82f58742010-11-20 15:59:32 +00001226 int Offset = TFI->ResolveFrameIndexReference(MF, FrameIndex, FrameReg, SPAdj);
David Goodwindb5a71a2009-07-08 18:31:39 +00001227
Evan Cheng62b50652010-04-26 07:39:25 +00001228 // Special handling of dbg_value instructions.
1229 if (MI.isDebugValue()) {
1230 MI.getOperand(i). ChangeToRegister(FrameReg, false /*isDef*/);
1231 MI.getOperand(i+1).ChangeToImmediate(Offset);
Jim Grosbachfcb4a8e2010-08-26 23:32:16 +00001232 return;
Evan Cheng62b50652010-04-26 07:39:25 +00001233 }
1234
Evan Cheng48d8afa2009-11-01 21:12:51 +00001235 // Modify MI as necessary to handle as much of 'Offset' as possible
Evan Chengcdbb3f52009-08-27 01:23:50 +00001236 bool Done = false;
Evan Cheng6495f632009-07-28 05:48:47 +00001237 if (!AFI->isThumbFunction())
Evan Chengcdbb3f52009-08-27 01:23:50 +00001238 Done = rewriteARMFrameIndex(MI, i, FrameReg, Offset, TII);
Evan Cheng6495f632009-07-28 05:48:47 +00001239 else {
1240 assert(AFI->isThumb2Function());
Evan Chengcdbb3f52009-08-27 01:23:50 +00001241 Done = rewriteT2FrameIndex(MI, i, FrameReg, Offset, TII);
Evan Cheng6495f632009-07-28 05:48:47 +00001242 }
Evan Chengcdbb3f52009-08-27 01:23:50 +00001243 if (Done)
Jim Grosbachfcb4a8e2010-08-26 23:32:16 +00001244 return;
David Goodwindb5a71a2009-07-08 18:31:39 +00001245
1246 // If we get here, the immediate doesn't fit into the instruction. We folded
1247 // as much as possible above, handle the rest, providing a register that is
1248 // SP+LargeImm.
Daniel Dunbar19bb87d2009-08-28 08:08:22 +00001249 assert((Offset ||
Jim Grosbacha4432172009-11-15 21:45:34 +00001250 (MI.getDesc().TSFlags & ARMII::AddrModeMask) == ARMII::AddrMode4 ||
1251 (MI.getDesc().TSFlags & ARMII::AddrModeMask) == ARMII::AddrMode6) &&
Evan Chengcdbb3f52009-08-27 01:23:50 +00001252 "This code isn't needed if offset already handled!");
David Goodwindb5a71a2009-07-08 18:31:39 +00001253
Jim Grosbach7e831db2009-10-20 01:26:58 +00001254 unsigned ScratchReg = 0;
David Goodwindb5a71a2009-07-08 18:31:39 +00001255 int PIdx = MI.findFirstPredOperandIdx();
1256 ARMCC::CondCodes Pred = (PIdx == -1)
1257 ? ARMCC::AL : (ARMCC::CondCodes)MI.getOperand(PIdx).getImm();
1258 unsigned PredReg = (PIdx == -1) ? 0 : MI.getOperand(PIdx+1).getReg();
Evan Chengcdbb3f52009-08-27 01:23:50 +00001259 if (Offset == 0)
Jim Grosbacha4432172009-11-15 21:45:34 +00001260 // Must be addrmode4/6.
Evan Chengcdbb3f52009-08-27 01:23:50 +00001261 MI.getOperand(i).ChangeToRegister(FrameReg, false, false, false);
Evan Cheng6495f632009-07-28 05:48:47 +00001262 else {
Jim Grosbachca5dfb72009-10-28 17:33:28 +00001263 ScratchReg = MF.getRegInfo().createVirtualRegister(ARM::GPRRegisterClass);
Evan Chengcdbb3f52009-08-27 01:23:50 +00001264 if (!AFI->isThumbFunction())
1265 emitARMRegPlusImmediate(MBB, II, MI.getDebugLoc(), ScratchReg, FrameReg,
1266 Offset, Pred, PredReg, TII);
1267 else {
1268 assert(AFI->isThumb2Function());
1269 emitT2RegPlusImmediate(MBB, II, MI.getDebugLoc(), ScratchReg, FrameReg,
1270 Offset, Pred, PredReg, TII);
1271 }
Jim Grosbachcde31292010-12-09 01:22:13 +00001272 // Update the original instruction to use the scratch register.
Evan Chengcdbb3f52009-08-27 01:23:50 +00001273 MI.getOperand(i).ChangeToRegister(ScratchReg, false, false, true);
Evan Cheng6495f632009-07-28 05:48:47 +00001274 }
David Goodwindb5a71a2009-07-08 18:31:39 +00001275}