blob: 14b9a7017caa8bd247300491a481f015fcd9ee12 [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 Chengd5b03f22011-06-28 21:14:33 +000060 : ARMGenRegisterInfo(), 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
David Goodwinc140c482009-07-08 17:28:55 +0000652unsigned ARMBaseRegisterInfo::getRARegister() const {
653 return ARM::LR;
654}
655
Jim Grosbach5c33f5b2010-09-02 19:52:39 +0000656unsigned
David Greene3f2bf852009-11-12 20:49:22 +0000657ARMBaseRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
Anton Korobeynikov16c29b52011-01-10 12:39:04 +0000658 const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
Anton Korobeynikovd0c38172010-11-18 21:19:35 +0000659
660 if (TFI->hasFP(MF))
David Goodwinc140c482009-07-08 17:28:55 +0000661 return FramePtr;
662 return ARM::SP;
663}
664
665unsigned ARMBaseRegisterInfo::getEHExceptionRegister() const {
Torok Edwinc23197a2009-07-14 16:55:14 +0000666 llvm_unreachable("What is the exception register");
David Goodwinc140c482009-07-08 17:28:55 +0000667 return 0;
668}
669
670unsigned ARMBaseRegisterInfo::getEHHandlerRegister() const {
Torok Edwinc23197a2009-07-14 16:55:14 +0000671 llvm_unreachable("What is the exception handler register");
David Goodwinc140c482009-07-08 17:28:55 +0000672 return 0;
673}
674
675int ARMBaseRegisterInfo::getDwarfRegNum(unsigned RegNum, bool isEH) const {
676 return ARMGenRegisterInfo::getDwarfRegNumFull(RegNum, 0);
677}
678
Rafael Espindola6e032942011-05-30 20:20:15 +0000679int ARMBaseRegisterInfo::getLLVMRegNum(unsigned DwarfRegNo, bool isEH) const {
680 return ARMGenRegisterInfo::getLLVMRegNumFull(DwarfRegNo,0);
681}
682
David Goodwinc140c482009-07-08 17:28:55 +0000683unsigned ARMBaseRegisterInfo::getRegisterPairEven(unsigned Reg,
Jim Grosbach96318642010-01-06 23:54:42 +0000684 const MachineFunction &MF) const {
David Goodwinc140c482009-07-08 17:28:55 +0000685 switch (Reg) {
686 default: break;
687 // Return 0 if either register of the pair is a special register.
688 // So no R12, etc.
689 case ARM::R1:
690 return ARM::R0;
691 case ARM::R3:
Jim Grosbach60097512009-10-19 22:57:03 +0000692 return ARM::R2;
David Goodwinc140c482009-07-08 17:28:55 +0000693 case ARM::R5:
694 return ARM::R4;
695 case ARM::R7:
Jim Grosbach65482b12010-09-03 18:37:12 +0000696 return (isReservedReg(MF, ARM::R7) || isReservedReg(MF, ARM::R6))
697 ? 0 : ARM::R6;
David Goodwinc140c482009-07-08 17:28:55 +0000698 case ARM::R9:
699 return isReservedReg(MF, ARM::R9) ? 0 :ARM::R8;
700 case ARM::R11:
701 return isReservedReg(MF, ARM::R11) ? 0 : ARM::R10;
702
703 case ARM::S1:
704 return ARM::S0;
705 case ARM::S3:
706 return ARM::S2;
707 case ARM::S5:
708 return ARM::S4;
709 case ARM::S7:
710 return ARM::S6;
711 case ARM::S9:
712 return ARM::S8;
713 case ARM::S11:
714 return ARM::S10;
715 case ARM::S13:
716 return ARM::S12;
717 case ARM::S15:
718 return ARM::S14;
719 case ARM::S17:
720 return ARM::S16;
721 case ARM::S19:
722 return ARM::S18;
723 case ARM::S21:
724 return ARM::S20;
725 case ARM::S23:
726 return ARM::S22;
727 case ARM::S25:
728 return ARM::S24;
729 case ARM::S27:
730 return ARM::S26;
731 case ARM::S29:
732 return ARM::S28;
733 case ARM::S31:
734 return ARM::S30;
735
736 case ARM::D1:
737 return ARM::D0;
738 case ARM::D3:
739 return ARM::D2;
740 case ARM::D5:
741 return ARM::D4;
742 case ARM::D7:
743 return ARM::D6;
744 case ARM::D9:
745 return ARM::D8;
746 case ARM::D11:
747 return ARM::D10;
748 case ARM::D13:
749 return ARM::D12;
750 case ARM::D15:
751 return ARM::D14;
Evan Cheng8295d992009-07-22 05:55:18 +0000752 case ARM::D17:
753 return ARM::D16;
754 case ARM::D19:
755 return ARM::D18;
756 case ARM::D21:
757 return ARM::D20;
758 case ARM::D23:
759 return ARM::D22;
760 case ARM::D25:
761 return ARM::D24;
762 case ARM::D27:
763 return ARM::D26;
764 case ARM::D29:
765 return ARM::D28;
766 case ARM::D31:
767 return ARM::D30;
David Goodwinc140c482009-07-08 17:28:55 +0000768 }
769
770 return 0;
771}
772
773unsigned ARMBaseRegisterInfo::getRegisterPairOdd(unsigned Reg,
774 const MachineFunction &MF) const {
775 switch (Reg) {
776 default: break;
777 // Return 0 if either register of the pair is a special register.
778 // So no R12, etc.
779 case ARM::R0:
780 return ARM::R1;
781 case ARM::R2:
Jim Grosbach60097512009-10-19 22:57:03 +0000782 return ARM::R3;
David Goodwinc140c482009-07-08 17:28:55 +0000783 case ARM::R4:
784 return ARM::R5;
785 case ARM::R6:
Jim Grosbach65482b12010-09-03 18:37:12 +0000786 return (isReservedReg(MF, ARM::R7) || isReservedReg(MF, ARM::R6))
787 ? 0 : ARM::R7;
David Goodwinc140c482009-07-08 17:28:55 +0000788 case ARM::R8:
789 return isReservedReg(MF, ARM::R9) ? 0 :ARM::R9;
790 case ARM::R10:
791 return isReservedReg(MF, ARM::R11) ? 0 : ARM::R11;
792
793 case ARM::S0:
794 return ARM::S1;
795 case ARM::S2:
796 return ARM::S3;
797 case ARM::S4:
798 return ARM::S5;
799 case ARM::S6:
800 return ARM::S7;
801 case ARM::S8:
802 return ARM::S9;
803 case ARM::S10:
804 return ARM::S11;
805 case ARM::S12:
806 return ARM::S13;
807 case ARM::S14:
808 return ARM::S15;
809 case ARM::S16:
810 return ARM::S17;
811 case ARM::S18:
812 return ARM::S19;
813 case ARM::S20:
814 return ARM::S21;
815 case ARM::S22:
816 return ARM::S23;
817 case ARM::S24:
818 return ARM::S25;
819 case ARM::S26:
820 return ARM::S27;
821 case ARM::S28:
822 return ARM::S29;
823 case ARM::S30:
824 return ARM::S31;
825
826 case ARM::D0:
827 return ARM::D1;
828 case ARM::D2:
829 return ARM::D3;
830 case ARM::D4:
831 return ARM::D5;
832 case ARM::D6:
833 return ARM::D7;
834 case ARM::D8:
835 return ARM::D9;
836 case ARM::D10:
837 return ARM::D11;
838 case ARM::D12:
839 return ARM::D13;
840 case ARM::D14:
841 return ARM::D15;
Evan Cheng8295d992009-07-22 05:55:18 +0000842 case ARM::D16:
843 return ARM::D17;
844 case ARM::D18:
845 return ARM::D19;
846 case ARM::D20:
847 return ARM::D21;
848 case ARM::D22:
849 return ARM::D23;
850 case ARM::D24:
851 return ARM::D25;
852 case ARM::D26:
853 return ARM::D27;
854 case ARM::D28:
855 return ARM::D29;
856 case ARM::D30:
857 return ARM::D31;
David Goodwinc140c482009-07-08 17:28:55 +0000858 }
859
860 return 0;
861}
862
David Goodwindb5a71a2009-07-08 18:31:39 +0000863/// emitLoadConstPool - Emits a load from constpool to materialize the
864/// specified immediate.
865void ARMBaseRegisterInfo::
866emitLoadConstPool(MachineBasicBlock &MBB,
867 MachineBasicBlock::iterator &MBBI,
David Goodwin77521f52009-07-08 20:28:28 +0000868 DebugLoc dl,
Evan Cheng37844532009-07-16 09:20:10 +0000869 unsigned DestReg, unsigned SubIdx, int Val,
David Goodwindb5a71a2009-07-08 18:31:39 +0000870 ARMCC::CondCodes Pred,
Anton Korobeynikov3daccd82011-03-05 18:43:50 +0000871 unsigned PredReg, unsigned MIFlags) const {
David Goodwindb5a71a2009-07-08 18:31:39 +0000872 MachineFunction &MF = *MBB.getParent();
873 MachineConstantPool *ConstantPool = MF.getConstantPool();
Dan Gohman46510a72010-04-15 01:51:59 +0000874 const Constant *C =
Owen Anderson1d0be152009-08-13 21:58:54 +0000875 ConstantInt::get(Type::getInt32Ty(MF.getFunction()->getContext()), Val);
David Goodwindb5a71a2009-07-08 18:31:39 +0000876 unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4);
877
Evan Cheng37844532009-07-16 09:20:10 +0000878 BuildMI(MBB, MBBI, dl, TII.get(ARM::LDRcp))
879 .addReg(DestReg, getDefRegState(true), SubIdx)
David Goodwindb5a71a2009-07-08 18:31:39 +0000880 .addConstantPoolIndex(Idx)
Anton Korobeynikov3daccd82011-03-05 18:43:50 +0000881 .addImm(0).addImm(Pred).addReg(PredReg)
882 .setMIFlags(MIFlags);
David Goodwindb5a71a2009-07-08 18:31:39 +0000883}
884
885bool ARMBaseRegisterInfo::
886requiresRegisterScavenging(const MachineFunction &MF) const {
887 return true;
888}
Jim Grosbach41fff8c2009-10-21 23:40:56 +0000889
Jim Grosbach7e831db2009-10-20 01:26:58 +0000890bool ARMBaseRegisterInfo::
891requiresFrameIndexScavenging(const MachineFunction &MF) const {
Jim Grosbachca5dfb72009-10-28 17:33:28 +0000892 return true;
Jim Grosbach7e831db2009-10-20 01:26:58 +0000893}
David Goodwindb5a71a2009-07-08 18:31:39 +0000894
Jim Grosbacha2734422010-08-24 19:05:43 +0000895bool ARMBaseRegisterInfo::
896requiresVirtualBaseRegisters(const MachineFunction &MF) const {
897 return EnableLocalStackAlloc;
898}
899
David Goodwindb5a71a2009-07-08 18:31:39 +0000900static void
Evan Cheng6495f632009-07-28 05:48:47 +0000901emitSPUpdate(bool isARM,
902 MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
903 DebugLoc dl, const ARMBaseInstrInfo &TII,
David Goodwindb5a71a2009-07-08 18:31:39 +0000904 int NumBytes,
905 ARMCC::CondCodes Pred = ARMCC::AL, unsigned PredReg = 0) {
Evan Cheng6495f632009-07-28 05:48:47 +0000906 if (isARM)
907 emitARMRegPlusImmediate(MBB, MBBI, dl, ARM::SP, ARM::SP, NumBytes,
908 Pred, PredReg, TII);
909 else
910 emitT2RegPlusImmediate(MBB, MBBI, dl, ARM::SP, ARM::SP, NumBytes,
911 Pred, PredReg, TII);
David Goodwindb5a71a2009-07-08 18:31:39 +0000912}
913
Evan Cheng6495f632009-07-28 05:48:47 +0000914
David Goodwindb5a71a2009-07-08 18:31:39 +0000915void ARMBaseRegisterInfo::
916eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
917 MachineBasicBlock::iterator I) const {
Anton Korobeynikov16c29b52011-01-10 12:39:04 +0000918 const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
Anton Korobeynikovd0c38172010-11-18 21:19:35 +0000919 if (!TFI->hasReservedCallFrame(MF)) {
David Goodwindb5a71a2009-07-08 18:31:39 +0000920 // If we have alloca, convert as follows:
921 // ADJCALLSTACKDOWN -> sub, sp, sp, amount
922 // ADJCALLSTACKUP -> add, sp, sp, amount
923 MachineInstr *Old = I;
924 DebugLoc dl = Old->getDebugLoc();
925 unsigned Amount = Old->getOperand(0).getImm();
926 if (Amount != 0) {
927 // We need to keep the stack aligned properly. To do this, we round the
928 // amount of space needed for the outgoing arguments up to the next
929 // alignment boundary.
Anton Korobeynikov16c29b52011-01-10 12:39:04 +0000930 unsigned Align = TFI->getStackAlignment();
David Goodwindb5a71a2009-07-08 18:31:39 +0000931 Amount = (Amount+Align-1)/Align*Align;
932
Evan Cheng6495f632009-07-28 05:48:47 +0000933 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
934 assert(!AFI->isThumb1OnlyFunction() &&
Jim Grosbachcf453ee2010-02-23 17:16:27 +0000935 "This eliminateCallFramePseudoInstr does not support Thumb1!");
Evan Cheng6495f632009-07-28 05:48:47 +0000936 bool isARM = !AFI->isThumbFunction();
937
David Goodwindb5a71a2009-07-08 18:31:39 +0000938 // Replace the pseudo instruction with a new instruction...
939 unsigned Opc = Old->getOpcode();
Jim Grosbach4c7628e2010-02-22 22:47:46 +0000940 int PIdx = Old->findFirstPredOperandIdx();
941 ARMCC::CondCodes Pred = (PIdx == -1)
942 ? ARMCC::AL : (ARMCC::CondCodes)Old->getOperand(PIdx).getImm();
David Goodwindb5a71a2009-07-08 18:31:39 +0000943 if (Opc == ARM::ADJCALLSTACKDOWN || Opc == ARM::tADJCALLSTACKDOWN) {
944 // Note: PredReg is operand 2 for ADJCALLSTACKDOWN.
945 unsigned PredReg = Old->getOperand(2).getReg();
Evan Cheng6495f632009-07-28 05:48:47 +0000946 emitSPUpdate(isARM, MBB, I, dl, TII, -Amount, Pred, PredReg);
David Goodwindb5a71a2009-07-08 18:31:39 +0000947 } else {
948 // Note: PredReg is operand 3 for ADJCALLSTACKUP.
949 unsigned PredReg = Old->getOperand(3).getReg();
950 assert(Opc == ARM::ADJCALLSTACKUP || Opc == ARM::tADJCALLSTACKUP);
Evan Cheng6495f632009-07-28 05:48:47 +0000951 emitSPUpdate(isARM, MBB, I, dl, TII, Amount, Pred, PredReg);
David Goodwindb5a71a2009-07-08 18:31:39 +0000952 }
953 }
954 }
955 MBB.erase(I);
956}
957
Jim Grosbache2f55692010-08-19 23:52:25 +0000958int64_t ARMBaseRegisterInfo::
Jim Grosbach1ab3f162010-08-26 21:56:30 +0000959getFrameIndexInstrOffset(const MachineInstr *MI, int Idx) const {
Evan Chenge837dea2011-06-28 19:10:37 +0000960 const MCInstrDesc &Desc = MI->getDesc();
Jim Grosbache2f55692010-08-19 23:52:25 +0000961 unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
962 int64_t InstrOffs = 0;;
963 int Scale = 1;
964 unsigned ImmIdx = 0;
Jim Grosbach1ab3f162010-08-26 21:56:30 +0000965 switch (AddrMode) {
Jim Grosbache2f55692010-08-19 23:52:25 +0000966 case ARMII::AddrModeT2_i8:
967 case ARMII::AddrModeT2_i12:
Jim Grosbach3e556122010-10-26 22:37:02 +0000968 case ARMII::AddrMode_i12:
Jim Grosbache2f55692010-08-19 23:52:25 +0000969 InstrOffs = MI->getOperand(Idx+1).getImm();
970 Scale = 1;
971 break;
972 case ARMII::AddrMode5: {
973 // VFP address mode.
974 const MachineOperand &OffOp = MI->getOperand(Idx+1);
Jim Grosbachf78ee632010-08-25 19:11:34 +0000975 InstrOffs = ARM_AM::getAM5Offset(OffOp.getImm());
Jim Grosbache2f55692010-08-19 23:52:25 +0000976 if (ARM_AM::getAM5Op(OffOp.getImm()) == ARM_AM::sub)
977 InstrOffs = -InstrOffs;
978 Scale = 4;
979 break;
980 }
981 case ARMII::AddrMode2: {
982 ImmIdx = Idx+2;
983 InstrOffs = ARM_AM::getAM2Offset(MI->getOperand(ImmIdx).getImm());
984 if (ARM_AM::getAM2Op(MI->getOperand(ImmIdx).getImm()) == ARM_AM::sub)
985 InstrOffs = -InstrOffs;
986 break;
987 }
988 case ARMII::AddrMode3: {
989 ImmIdx = Idx+2;
990 InstrOffs = ARM_AM::getAM3Offset(MI->getOperand(ImmIdx).getImm());
991 if (ARM_AM::getAM3Op(MI->getOperand(ImmIdx).getImm()) == ARM_AM::sub)
992 InstrOffs = -InstrOffs;
993 break;
994 }
995 case ARMII::AddrModeT1_s: {
996 ImmIdx = Idx+1;
997 InstrOffs = MI->getOperand(ImmIdx).getImm();
998 Scale = 4;
999 break;
1000 }
1001 default:
1002 llvm_unreachable("Unsupported addressing mode!");
1003 break;
1004 }
1005
1006 return InstrOffs * Scale;
1007}
1008
Jim Grosbach8708ead2010-08-17 18:13:53 +00001009/// needsFrameBaseReg - Returns true if the instruction's frame index
1010/// reference would be better served by a base register other than FP
1011/// or SP. Used by LocalStackFrameAllocation to determine which frame index
1012/// references it should create new base registers for.
1013bool ARMBaseRegisterInfo::
Jim Grosbach31973802010-08-24 21:19:33 +00001014needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const {
1015 for (unsigned i = 0; !MI->getOperand(i).isFI(); ++i) {
1016 assert(i < MI->getNumOperands() &&"Instr doesn't have FrameIndex operand!");
1017 }
Jim Grosbach8708ead2010-08-17 18:13:53 +00001018
1019 // It's the load/store FI references that cause issues, as it can be difficult
1020 // to materialize the offset if it won't fit in the literal field. Estimate
1021 // based on the size of the local frame and some conservative assumptions
1022 // about the rest of the stack frame (note, this is pre-regalloc, so
1023 // we don't know everything for certain yet) whether this offset is likely
1024 // to be out of range of the immediate. Return true if so.
1025
Jim Grosbachcd59dc52010-08-24 18:04:52 +00001026 // We only generate virtual base registers for loads and stores, so
1027 // return false for everything else.
Jim Grosbach8708ead2010-08-17 18:13:53 +00001028 unsigned Opc = MI->getOpcode();
Jim Grosbach8708ead2010-08-17 18:13:53 +00001029 switch (Opc) {
Jim Grosbachc1d30212010-10-27 00:19:44 +00001030 case ARM::LDRi12: case ARM::LDRH: case ARM::LDRBi12:
Jim Grosbach7e3383c2010-10-27 23:12:14 +00001031 case ARM::STRi12: case ARM::STRH: case ARM::STRBi12:
Jim Grosbach8708ead2010-08-17 18:13:53 +00001032 case ARM::t2LDRi12: case ARM::t2LDRi8:
1033 case ARM::t2STRi12: case ARM::t2STRi8:
1034 case ARM::VLDRS: case ARM::VLDRD:
1035 case ARM::VSTRS: case ARM::VSTRD:
Jim Grosbach74d7b0a2010-08-19 17:52:13 +00001036 case ARM::tSTRspi: case ARM::tLDRspi:
Jim Grosbachcd59dc52010-08-24 18:04:52 +00001037 if (ForceAllBaseRegAlloc)
1038 return true;
1039 break;
Jim Grosbach8708ead2010-08-17 18:13:53 +00001040 default:
1041 return false;
1042 }
Jim Grosbachcd59dc52010-08-24 18:04:52 +00001043
Jim Grosbachcd59dc52010-08-24 18:04:52 +00001044 // Without a virtual base register, if the function has variable sized
1045 // objects, all fixed-size local references will be via the frame pointer,
Jim Grosbach31973802010-08-24 21:19:33 +00001046 // Approximate the offset and see if it's legal for the instruction.
1047 // Note that the incoming offset is based on the SP value at function entry,
1048 // so it'll be negative.
1049 MachineFunction &MF = *MI->getParent()->getParent();
Anton Korobeynikov16c29b52011-01-10 12:39:04 +00001050 const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
Jim Grosbach31973802010-08-24 21:19:33 +00001051 MachineFrameInfo *MFI = MF.getFrameInfo();
1052 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
Jim Grosbachcd59dc52010-08-24 18:04:52 +00001053
Jim Grosbach31973802010-08-24 21:19:33 +00001054 // Estimate an offset from the frame pointer.
1055 // Conservatively assume all callee-saved registers get pushed. R4-R6
1056 // will be earlier than the FP, so we ignore those.
1057 // R7, LR
1058 int64_t FPOffset = Offset - 8;
1059 // ARM and Thumb2 functions also need to consider R8-R11 and D8-D15
1060 if (!AFI->isThumbFunction() || !AFI->isThumb1OnlyFunction())
1061 FPOffset -= 80;
1062 // Estimate an offset from the stack pointer.
Jim Grosbachc1dc78d2010-08-31 18:52:31 +00001063 // The incoming offset is relating to the SP at the start of the function,
1064 // but when we access the local it'll be relative to the SP after local
1065 // allocation, so adjust our SP-relative offset by that allocation size.
Jim Grosbach31973802010-08-24 21:19:33 +00001066 Offset = -Offset;
Jim Grosbachc1dc78d2010-08-31 18:52:31 +00001067 Offset += MFI->getLocalFrameSize();
Jim Grosbach31973802010-08-24 21:19:33 +00001068 // Assume that we'll have at least some spill slots allocated.
1069 // FIXME: This is a total SWAG number. We should run some statistics
1070 // and pick a real one.
1071 Offset += 128; // 128 bytes of spill slots
1072
1073 // If there is a frame pointer, try using it.
1074 // The FP is only available if there is no dynamic realignment. We
1075 // don't know for sure yet whether we'll need that, so we guess based
1076 // on whether there are any local variables that would trigger it.
Anton Korobeynikov16c29b52011-01-10 12:39:04 +00001077 unsigned StackAlign = TFI->getStackAlignment();
Anton Korobeynikovd0c38172010-11-18 21:19:35 +00001078 if (TFI->hasFP(MF) &&
Jim Grosbach31973802010-08-24 21:19:33 +00001079 !((MFI->getLocalFrameMaxAlign() > StackAlign) && canRealignStack(MF))) {
1080 if (isFrameOffsetLegal(MI, FPOffset))
1081 return false;
1082 }
1083 // If we can reference via the stack pointer, try that.
1084 // FIXME: This (and the code that resolves the references) can be improved
1085 // to only disallow SP relative references in the live range of
1086 // the VLA(s). In practice, it's unclear how much difference that
1087 // would make, but it may be worth doing.
1088 if (!MFI->hasVarSizedObjects() && isFrameOffsetLegal(MI, Offset))
1089 return false;
1090
1091 // The offset likely isn't legal, we want to allocate a virtual base register.
Jim Grosbachcd59dc52010-08-24 18:04:52 +00001092 return true;
Jim Grosbach8708ead2010-08-17 18:13:53 +00001093}
1094
Bill Wendling976ef862010-12-17 23:09:14 +00001095/// materializeFrameBaseRegister - Insert defining instruction(s) for BaseReg to
1096/// be a pointer to FrameIdx at the beginning of the basic block.
Jim Grosbachdc140c62010-08-17 22:41:55 +00001097void ARMBaseRegisterInfo::
Bill Wendling976ef862010-12-17 23:09:14 +00001098materializeFrameBaseRegister(MachineBasicBlock *MBB,
1099 unsigned BaseReg, int FrameIdx,
1100 int64_t Offset) const {
1101 ARMFunctionInfo *AFI = MBB->getParent()->getInfo<ARMFunctionInfo>();
Jim Grosbach74d7b0a2010-08-19 17:52:13 +00001102 unsigned ADDriOpc = !AFI->isThumbFunction() ? ARM::ADDri :
1103 (AFI->isThumb1OnlyFunction() ? ARM::tADDrSPi : ARM::t2ADDri);
Jim Grosbachdc140c62010-08-17 22:41:55 +00001104
Bill Wendling976ef862010-12-17 23:09:14 +00001105 MachineBasicBlock::iterator Ins = MBB->begin();
1106 DebugLoc DL; // Defaults to "unknown"
1107 if (Ins != MBB->end())
1108 DL = Ins->getDebugLoc();
1109
Evan Chenge837dea2011-06-28 19:10:37 +00001110 const MCInstrDesc &MCID = TII.get(ADDriOpc);
Cameron Zwarich21803722011-05-19 02:18:27 +00001111 MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo();
Evan Chenge837dea2011-06-28 19:10:37 +00001112 MRI.constrainRegClass(BaseReg, TII.getRegClass(MCID, 0, this));
Cameron Zwarich21803722011-05-19 02:18:27 +00001113
Evan Chenge837dea2011-06-28 19:10:37 +00001114 MachineInstrBuilder MIB = BuildMI(*MBB, Ins, DL, MCID, BaseReg)
Jim Grosbache2f55692010-08-19 23:52:25 +00001115 .addFrameIndex(FrameIdx).addImm(Offset);
Bill Wendling976ef862010-12-17 23:09:14 +00001116
Jim Grosbach74d7b0a2010-08-19 17:52:13 +00001117 if (!AFI->isThumb1OnlyFunction())
1118 AddDefaultCC(AddDefaultPred(MIB));
Jim Grosbachdc140c62010-08-17 22:41:55 +00001119}
1120
1121void
1122ARMBaseRegisterInfo::resolveFrameIndex(MachineBasicBlock::iterator I,
1123 unsigned BaseReg, int64_t Offset) const {
1124 MachineInstr &MI = *I;
1125 MachineBasicBlock &MBB = *MI.getParent();
1126 MachineFunction &MF = *MBB.getParent();
1127 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
1128 int Off = Offset; // ARM doesn't need the general 64-bit offsets
1129 unsigned i = 0;
1130
1131 assert(!AFI->isThumb1OnlyFunction() &&
1132 "This resolveFrameIndex does not support Thumb1!");
1133
1134 while (!MI.getOperand(i).isFI()) {
1135 ++i;
1136 assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
1137 }
1138 bool Done = false;
1139 if (!AFI->isThumbFunction())
1140 Done = rewriteARMFrameIndex(MI, i, BaseReg, Off, TII);
1141 else {
1142 assert(AFI->isThumb2Function());
1143 Done = rewriteT2FrameIndex(MI, i, BaseReg, Off, TII);
1144 }
1145 assert (Done && "Unable to resolve frame index!");
1146}
Jim Grosbach8708ead2010-08-17 18:13:53 +00001147
Jim Grosbache2f55692010-08-19 23:52:25 +00001148bool ARMBaseRegisterInfo::isFrameOffsetLegal(const MachineInstr *MI,
1149 int64_t Offset) const {
Evan Chenge837dea2011-06-28 19:10:37 +00001150 const MCInstrDesc &Desc = MI->getDesc();
Jim Grosbach2b1e2022010-08-18 22:44:49 +00001151 unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
1152 unsigned i = 0;
1153
1154 while (!MI->getOperand(i).isFI()) {
1155 ++i;
1156 assert(i < MI->getNumOperands() &&"Instr doesn't have FrameIndex operand!");
1157 }
1158
1159 // AddrMode4 and AddrMode6 cannot handle any offset.
1160 if (AddrMode == ARMII::AddrMode4 || AddrMode == ARMII::AddrMode6)
1161 return Offset == 0;
1162
1163 unsigned NumBits = 0;
1164 unsigned Scale = 1;
Jim Grosbache2f55692010-08-19 23:52:25 +00001165 bool isSigned = true;
Jim Grosbach1ab3f162010-08-26 21:56:30 +00001166 switch (AddrMode) {
Jim Grosbach2b1e2022010-08-18 22:44:49 +00001167 case ARMII::AddrModeT2_i8:
1168 case ARMII::AddrModeT2_i12:
1169 // i8 supports only negative, and i12 supports only positive, so
1170 // based on Offset sign, consider the appropriate instruction
Jim Grosbach74d7b0a2010-08-19 17:52:13 +00001171 Scale = 1;
Jim Grosbach2b1e2022010-08-18 22:44:49 +00001172 if (Offset < 0) {
1173 NumBits = 8;
1174 Offset = -Offset;
1175 } else {
1176 NumBits = 12;
1177 }
1178 break;
Jim Grosbach1ab3f162010-08-26 21:56:30 +00001179 case ARMII::AddrMode5:
Jim Grosbach2b1e2022010-08-18 22:44:49 +00001180 // VFP address mode.
Jim Grosbach2b1e2022010-08-18 22:44:49 +00001181 NumBits = 8;
1182 Scale = 4;
1183 break;
Jim Grosbach3e556122010-10-26 22:37:02 +00001184 case ARMII::AddrMode_i12:
Jim Grosbach1ab3f162010-08-26 21:56:30 +00001185 case ARMII::AddrMode2:
Jim Grosbach2b1e2022010-08-18 22:44:49 +00001186 NumBits = 12;
1187 break;
Jim Grosbach1ab3f162010-08-26 21:56:30 +00001188 case ARMII::AddrMode3:
Jim Grosbach2b1e2022010-08-18 22:44:49 +00001189 NumBits = 8;
1190 break;
Jim Grosbach1ab3f162010-08-26 21:56:30 +00001191 case ARMII::AddrModeT1_s:
Jim Grosbach74d7b0a2010-08-19 17:52:13 +00001192 NumBits = 5;
1193 Scale = 4;
Jim Grosbache2f55692010-08-19 23:52:25 +00001194 isSigned = false;
Jim Grosbach74d7b0a2010-08-19 17:52:13 +00001195 break;
Jim Grosbach2b1e2022010-08-18 22:44:49 +00001196 default:
1197 llvm_unreachable("Unsupported addressing mode!");
1198 break;
1199 }
1200
Jim Grosbach1ab3f162010-08-26 21:56:30 +00001201 Offset += getFrameIndexInstrOffset(MI, i);
Jim Grosbachd4511e92010-08-31 18:49:31 +00001202 // Make sure the offset is encodable for instructions that scale the
1203 // immediate.
1204 if ((Offset & (Scale-1)) != 0)
1205 return false;
1206
Jim Grosbache2f55692010-08-19 23:52:25 +00001207 if (isSigned && Offset < 0)
Jim Grosbach2b1e2022010-08-18 22:44:49 +00001208 Offset = -Offset;
1209
1210 unsigned Mask = (1 << NumBits) - 1;
1211 if ((unsigned)Offset <= Mask * Scale)
1212 return true;
Jim Grosbach74d803a2010-08-18 17:57:37 +00001213
1214 return false;
1215}
1216
Jim Grosbachfcb4a8e2010-08-26 23:32:16 +00001217void
Evan Cheng6495f632009-07-28 05:48:47 +00001218ARMBaseRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
Jim Grosbachfcb4a8e2010-08-26 23:32:16 +00001219 int SPAdj, RegScavenger *RS) const {
David Goodwindb5a71a2009-07-08 18:31:39 +00001220 unsigned i = 0;
1221 MachineInstr &MI = *II;
1222 MachineBasicBlock &MBB = *MI.getParent();
1223 MachineFunction &MF = *MBB.getParent();
Anton Korobeynikov16c29b52011-01-10 12:39:04 +00001224 const ARMFrameLowering *TFI =
1225 static_cast<const ARMFrameLowering*>(MF.getTarget().getFrameLowering());
David Goodwindb5a71a2009-07-08 18:31:39 +00001226 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
Evan Cheng6495f632009-07-28 05:48:47 +00001227 assert(!AFI->isThumb1OnlyFunction() &&
Bob Wilsona15de002009-09-18 21:42:44 +00001228 "This eliminateFrameIndex does not support Thumb1!");
David Goodwindb5a71a2009-07-08 18:31:39 +00001229
1230 while (!MI.getOperand(i).isFI()) {
1231 ++i;
1232 assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
1233 }
1234
David Goodwindb5a71a2009-07-08 18:31:39 +00001235 int FrameIndex = MI.getOperand(i).getIndex();
Jim Grosbacha37aa542009-11-22 20:05:32 +00001236 unsigned FrameReg;
David Goodwindb5a71a2009-07-08 18:31:39 +00001237
Anton Korobeynikov82f58742010-11-20 15:59:32 +00001238 int Offset = TFI->ResolveFrameIndexReference(MF, FrameIndex, FrameReg, SPAdj);
David Goodwindb5a71a2009-07-08 18:31:39 +00001239
Evan Cheng62b50652010-04-26 07:39:25 +00001240 // Special handling of dbg_value instructions.
1241 if (MI.isDebugValue()) {
1242 MI.getOperand(i). ChangeToRegister(FrameReg, false /*isDef*/);
1243 MI.getOperand(i+1).ChangeToImmediate(Offset);
Jim Grosbachfcb4a8e2010-08-26 23:32:16 +00001244 return;
Evan Cheng62b50652010-04-26 07:39:25 +00001245 }
1246
Evan Cheng48d8afa2009-11-01 21:12:51 +00001247 // Modify MI as necessary to handle as much of 'Offset' as possible
Evan Chengcdbb3f52009-08-27 01:23:50 +00001248 bool Done = false;
Evan Cheng6495f632009-07-28 05:48:47 +00001249 if (!AFI->isThumbFunction())
Evan Chengcdbb3f52009-08-27 01:23:50 +00001250 Done = rewriteARMFrameIndex(MI, i, FrameReg, Offset, TII);
Evan Cheng6495f632009-07-28 05:48:47 +00001251 else {
1252 assert(AFI->isThumb2Function());
Evan Chengcdbb3f52009-08-27 01:23:50 +00001253 Done = rewriteT2FrameIndex(MI, i, FrameReg, Offset, TII);
Evan Cheng6495f632009-07-28 05:48:47 +00001254 }
Evan Chengcdbb3f52009-08-27 01:23:50 +00001255 if (Done)
Jim Grosbachfcb4a8e2010-08-26 23:32:16 +00001256 return;
David Goodwindb5a71a2009-07-08 18:31:39 +00001257
1258 // If we get here, the immediate doesn't fit into the instruction. We folded
1259 // as much as possible above, handle the rest, providing a register that is
1260 // SP+LargeImm.
Daniel Dunbar19bb87d2009-08-28 08:08:22 +00001261 assert((Offset ||
Jim Grosbacha4432172009-11-15 21:45:34 +00001262 (MI.getDesc().TSFlags & ARMII::AddrModeMask) == ARMII::AddrMode4 ||
1263 (MI.getDesc().TSFlags & ARMII::AddrModeMask) == ARMII::AddrMode6) &&
Evan Chengcdbb3f52009-08-27 01:23:50 +00001264 "This code isn't needed if offset already handled!");
David Goodwindb5a71a2009-07-08 18:31:39 +00001265
Jim Grosbach7e831db2009-10-20 01:26:58 +00001266 unsigned ScratchReg = 0;
David Goodwindb5a71a2009-07-08 18:31:39 +00001267 int PIdx = MI.findFirstPredOperandIdx();
1268 ARMCC::CondCodes Pred = (PIdx == -1)
1269 ? ARMCC::AL : (ARMCC::CondCodes)MI.getOperand(PIdx).getImm();
1270 unsigned PredReg = (PIdx == -1) ? 0 : MI.getOperand(PIdx+1).getReg();
Evan Chengcdbb3f52009-08-27 01:23:50 +00001271 if (Offset == 0)
Jim Grosbacha4432172009-11-15 21:45:34 +00001272 // Must be addrmode4/6.
Evan Chengcdbb3f52009-08-27 01:23:50 +00001273 MI.getOperand(i).ChangeToRegister(FrameReg, false, false, false);
Evan Cheng6495f632009-07-28 05:48:47 +00001274 else {
Jim Grosbachca5dfb72009-10-28 17:33:28 +00001275 ScratchReg = MF.getRegInfo().createVirtualRegister(ARM::GPRRegisterClass);
Evan Chengcdbb3f52009-08-27 01:23:50 +00001276 if (!AFI->isThumbFunction())
1277 emitARMRegPlusImmediate(MBB, II, MI.getDebugLoc(), ScratchReg, FrameReg,
1278 Offset, Pred, PredReg, TII);
1279 else {
1280 assert(AFI->isThumb2Function());
1281 emitT2RegPlusImmediate(MBB, II, MI.getDebugLoc(), ScratchReg, FrameReg,
1282 Offset, Pred, PredReg, TII);
1283 }
Jim Grosbachcde31292010-12-09 01:22:13 +00001284 // Update the original instruction to use the scratch register.
Evan Chengcdbb3f52009-08-27 01:23:50 +00001285 MI.getOperand(i).ChangeToRegister(ScratchReg, false, false, true);
Evan Cheng6495f632009-07-28 05:48:47 +00001286 }
David Goodwindb5a71a2009-07-08 18:31:39 +00001287}