blob: 6dbf0fc98ba5e45f28107d7bc5798be7fbfb221e [file] [log] [blame]
Eric Christopherab695882010-07-21 22:26:11 +00001//===-- ARMFastISel.cpp - ARM FastISel implementation ---------------------===//
2//
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 defines the ARM-specific support for the FastISel class. Some
11// of the target-specific code is generated by tablegen in the file
12// ARMGenFastISel.inc, which is #included here.
13//
14//===----------------------------------------------------------------------===//
15
16#include "ARM.h"
Eric Christopher456144e2010-08-19 00:37:05 +000017#include "ARMBaseInstrInfo.h"
Eric Christopherab695882010-07-21 22:26:11 +000018#include "ARMRegisterInfo.h"
19#include "ARMTargetMachine.h"
20#include "ARMSubtarget.h"
21#include "llvm/CallingConv.h"
22#include "llvm/DerivedTypes.h"
23#include "llvm/GlobalVariable.h"
24#include "llvm/Instructions.h"
25#include "llvm/IntrinsicInst.h"
26#include "llvm/CodeGen/Analysis.h"
27#include "llvm/CodeGen/FastISel.h"
28#include "llvm/CodeGen/FunctionLoweringInfo.h"
Eric Christopher0fe7d542010-08-17 01:25:29 +000029#include "llvm/CodeGen/MachineInstrBuilder.h"
30#include "llvm/CodeGen/MachineModuleInfo.h"
Eric Christopherab695882010-07-21 22:26:11 +000031#include "llvm/CodeGen/MachineConstantPool.h"
32#include "llvm/CodeGen/MachineFrameInfo.h"
33#include "llvm/CodeGen/MachineRegisterInfo.h"
34#include "llvm/Support/CallSite.h"
Eric Christopher038fea52010-08-17 00:46:57 +000035#include "llvm/Support/CommandLine.h"
Eric Christopherab695882010-07-21 22:26:11 +000036#include "llvm/Support/ErrorHandling.h"
37#include "llvm/Support/GetElementPtrTypeIterator.h"
Eric Christopher0fe7d542010-08-17 01:25:29 +000038#include "llvm/Target/TargetData.h"
39#include "llvm/Target/TargetInstrInfo.h"
40#include "llvm/Target/TargetLowering.h"
41#include "llvm/Target/TargetMachine.h"
Eric Christopherab695882010-07-21 22:26:11 +000042#include "llvm/Target/TargetOptions.h"
43using namespace llvm;
44
Eric Christopher038fea52010-08-17 00:46:57 +000045static cl::opt<bool>
46EnableARMFastISel("arm-fast-isel",
47 cl::desc("Turn on experimental ARM fast-isel support"),
48 cl::init(false), cl::Hidden);
49
Eric Christopherab695882010-07-21 22:26:11 +000050namespace {
51
52class ARMFastISel : public FastISel {
53
54 /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can
55 /// make the right decision when generating code for different targets.
56 const ARMSubtarget *Subtarget;
Eric Christopher0fe7d542010-08-17 01:25:29 +000057 const TargetMachine &TM;
58 const TargetInstrInfo &TII;
59 const TargetLowering &TLI;
Eric Christopherab695882010-07-21 22:26:11 +000060
61 public:
Eric Christopher0fe7d542010-08-17 01:25:29 +000062 explicit ARMFastISel(FunctionLoweringInfo &funcInfo)
63 : FastISel(funcInfo),
64 TM(funcInfo.MF->getTarget()),
65 TII(*TM.getInstrInfo()),
66 TLI(*TM.getTargetLowering()) {
Eric Christopherab695882010-07-21 22:26:11 +000067 Subtarget = &TM.getSubtarget<ARMSubtarget>();
68 }
69
Eric Christopher0fe7d542010-08-17 01:25:29 +000070 virtual unsigned FastEmitInst_(unsigned MachineInstOpcode,
71 const TargetRegisterClass *RC);
72 virtual unsigned FastEmitInst_r(unsigned MachineInstOpcode,
73 const TargetRegisterClass *RC,
74 unsigned Op0, bool Op0IsKill);
75 virtual unsigned FastEmitInst_rr(unsigned MachineInstOpcode,
76 const TargetRegisterClass *RC,
77 unsigned Op0, bool Op0IsKill,
78 unsigned Op1, bool Op1IsKill);
79 virtual unsigned FastEmitInst_ri(unsigned MachineInstOpcode,
80 const TargetRegisterClass *RC,
81 unsigned Op0, bool Op0IsKill,
82 uint64_t Imm);
83 virtual unsigned FastEmitInst_rf(unsigned MachineInstOpcode,
84 const TargetRegisterClass *RC,
85 unsigned Op0, bool Op0IsKill,
86 const ConstantFP *FPImm);
87 virtual unsigned FastEmitInst_i(unsigned MachineInstOpcode,
88 const TargetRegisterClass *RC,
89 uint64_t Imm);
90 virtual unsigned FastEmitInst_rri(unsigned MachineInstOpcode,
91 const TargetRegisterClass *RC,
92 unsigned Op0, bool Op0IsKill,
93 unsigned Op1, bool Op1IsKill,
94 uint64_t Imm);
95 virtual unsigned FastEmitInst_extractsubreg(MVT RetVT,
96 unsigned Op0, bool Op0IsKill,
97 uint32_t Idx);
Eric Christopherab695882010-07-21 22:26:11 +000098 virtual bool TargetSelectInstruction(const Instruction *I);
99
100 #include "ARMGenFastISel.inc"
101
Eric Christopher456144e2010-08-19 00:37:05 +0000102 private:
103 bool DefinesOptionalPredicate(MachineInstr *MI, bool *CPSR);
104 const MachineInstrBuilder &AddOptionalDefs(const MachineInstrBuilder &MIB);
105};
Eric Christopherab695882010-07-21 22:26:11 +0000106
107} // end anonymous namespace
108
109// #include "ARMGenCallingConv.inc"
110
Eric Christopher456144e2010-08-19 00:37:05 +0000111// DefinesOptionalPredicate - This is different from DefinesPredicate in that
112// we don't care about implicit defs here, just places we'll need to add a
113// default CCReg argument. Sets CPSR if we're setting CPSR instead of CCR.
114bool ARMFastISel::DefinesOptionalPredicate(MachineInstr *MI, bool *CPSR) {
115 const TargetInstrDesc &TID = MI->getDesc();
116 if (!TID.hasOptionalDef())
117 return false;
118
119 // Look to see if our OptionalDef is defining CPSR or CCR.
120 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
121 const MachineOperand &MO = MI->getOperand(i);
122 if (MO.isDef() && MO.isReg() && MO.getReg() == ARM::CPSR)
123 *CPSR = true;
124 }
125 return true;
126}
127
128// If the machine is predicable go ahead and add the predicate operands, if
129// it needs default CC operands add those.
130const MachineInstrBuilder &
131ARMFastISel::AddOptionalDefs(const MachineInstrBuilder &MIB) {
132 MachineInstr *MI = &*MIB;
133
134 // Do we use a predicate?
135 if (TII.isPredicable(MI))
136 AddDefaultPred(MIB);
137
138 // Do we optionally set a predicate? Preds is size > 0 iff the predicate
139 // defines CPSR. All other OptionalDefines in ARM are the CCR register.
Eric Christopher979e0a12010-08-19 15:35:27 +0000140 bool CPSR = false;
Eric Christopher456144e2010-08-19 00:37:05 +0000141 if (DefinesOptionalPredicate(MI, &CPSR)) {
142 if (CPSR)
143 AddDefaultT1CC(MIB);
144 else
145 AddDefaultCC(MIB);
146 }
147 return MIB;
148}
149
Eric Christopher0fe7d542010-08-17 01:25:29 +0000150unsigned ARMFastISel::FastEmitInst_(unsigned MachineInstOpcode,
151 const TargetRegisterClass* RC) {
152 unsigned ResultReg = createResultReg(RC);
153 const TargetInstrDesc &II = TII.get(MachineInstOpcode);
154
Eric Christopher456144e2010-08-19 00:37:05 +0000155 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg));
Eric Christopher0fe7d542010-08-17 01:25:29 +0000156 return ResultReg;
157}
158
159unsigned ARMFastISel::FastEmitInst_r(unsigned MachineInstOpcode,
160 const TargetRegisterClass *RC,
161 unsigned Op0, bool Op0IsKill) {
162 unsigned ResultReg = createResultReg(RC);
163 const TargetInstrDesc &II = TII.get(MachineInstOpcode);
164
165 if (II.getNumDefs() >= 1)
Eric Christopher456144e2010-08-19 00:37:05 +0000166 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
Eric Christopher0fe7d542010-08-17 01:25:29 +0000167 .addReg(Op0, Op0IsKill * RegState::Kill));
168 else {
Eric Christopher456144e2010-08-19 00:37:05 +0000169 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
Eric Christopher0fe7d542010-08-17 01:25:29 +0000170 .addReg(Op0, Op0IsKill * RegState::Kill));
Eric Christopher456144e2010-08-19 00:37:05 +0000171 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
Eric Christopher0fe7d542010-08-17 01:25:29 +0000172 TII.get(TargetOpcode::COPY), ResultReg)
173 .addReg(II.ImplicitDefs[0]));
174 }
175 return ResultReg;
176}
177
178unsigned ARMFastISel::FastEmitInst_rr(unsigned MachineInstOpcode,
179 const TargetRegisterClass *RC,
180 unsigned Op0, bool Op0IsKill,
181 unsigned Op1, bool Op1IsKill) {
182 unsigned ResultReg = createResultReg(RC);
183 const TargetInstrDesc &II = TII.get(MachineInstOpcode);
184
185 if (II.getNumDefs() >= 1)
Eric Christopher456144e2010-08-19 00:37:05 +0000186 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
Eric Christopher0fe7d542010-08-17 01:25:29 +0000187 .addReg(Op0, Op0IsKill * RegState::Kill)
188 .addReg(Op1, Op1IsKill * RegState::Kill));
189 else {
Eric Christopher456144e2010-08-19 00:37:05 +0000190 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
Eric Christopher0fe7d542010-08-17 01:25:29 +0000191 .addReg(Op0, Op0IsKill * RegState::Kill)
192 .addReg(Op1, Op1IsKill * RegState::Kill));
Eric Christopher456144e2010-08-19 00:37:05 +0000193 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
Eric Christopher0fe7d542010-08-17 01:25:29 +0000194 TII.get(TargetOpcode::COPY), ResultReg)
195 .addReg(II.ImplicitDefs[0]));
196 }
197 return ResultReg;
198}
199
200unsigned ARMFastISel::FastEmitInst_ri(unsigned MachineInstOpcode,
201 const TargetRegisterClass *RC,
202 unsigned Op0, bool Op0IsKill,
203 uint64_t Imm) {
204 unsigned ResultReg = createResultReg(RC);
205 const TargetInstrDesc &II = TII.get(MachineInstOpcode);
206
207 if (II.getNumDefs() >= 1)
Eric Christopher456144e2010-08-19 00:37:05 +0000208 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
Eric Christopher0fe7d542010-08-17 01:25:29 +0000209 .addReg(Op0, Op0IsKill * RegState::Kill)
210 .addImm(Imm));
211 else {
Eric Christopher456144e2010-08-19 00:37:05 +0000212 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
Eric Christopher0fe7d542010-08-17 01:25:29 +0000213 .addReg(Op0, Op0IsKill * RegState::Kill)
214 .addImm(Imm));
Eric Christopher456144e2010-08-19 00:37:05 +0000215 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
Eric Christopher0fe7d542010-08-17 01:25:29 +0000216 TII.get(TargetOpcode::COPY), ResultReg)
217 .addReg(II.ImplicitDefs[0]));
218 }
219 return ResultReg;
220}
221
222unsigned ARMFastISel::FastEmitInst_rf(unsigned MachineInstOpcode,
223 const TargetRegisterClass *RC,
224 unsigned Op0, bool Op0IsKill,
225 const ConstantFP *FPImm) {
226 unsigned ResultReg = createResultReg(RC);
227 const TargetInstrDesc &II = TII.get(MachineInstOpcode);
228
229 if (II.getNumDefs() >= 1)
Eric Christopher456144e2010-08-19 00:37:05 +0000230 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
Eric Christopher0fe7d542010-08-17 01:25:29 +0000231 .addReg(Op0, Op0IsKill * RegState::Kill)
232 .addFPImm(FPImm));
233 else {
Eric Christopher456144e2010-08-19 00:37:05 +0000234 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
Eric Christopher0fe7d542010-08-17 01:25:29 +0000235 .addReg(Op0, Op0IsKill * RegState::Kill)
236 .addFPImm(FPImm));
Eric Christopher456144e2010-08-19 00:37:05 +0000237 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
Eric Christopher0fe7d542010-08-17 01:25:29 +0000238 TII.get(TargetOpcode::COPY), ResultReg)
239 .addReg(II.ImplicitDefs[0]));
240 }
241 return ResultReg;
242}
243
244unsigned ARMFastISel::FastEmitInst_rri(unsigned MachineInstOpcode,
245 const TargetRegisterClass *RC,
246 unsigned Op0, bool Op0IsKill,
247 unsigned Op1, bool Op1IsKill,
248 uint64_t Imm) {
249 unsigned ResultReg = createResultReg(RC);
250 const TargetInstrDesc &II = TII.get(MachineInstOpcode);
251
252 if (II.getNumDefs() >= 1)
Eric Christopher456144e2010-08-19 00:37:05 +0000253 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
Eric Christopher0fe7d542010-08-17 01:25:29 +0000254 .addReg(Op0, Op0IsKill * RegState::Kill)
255 .addReg(Op1, Op1IsKill * RegState::Kill)
256 .addImm(Imm));
257 else {
Eric Christopher456144e2010-08-19 00:37:05 +0000258 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
Eric Christopher0fe7d542010-08-17 01:25:29 +0000259 .addReg(Op0, Op0IsKill * RegState::Kill)
260 .addReg(Op1, Op1IsKill * RegState::Kill)
261 .addImm(Imm));
Eric Christopher456144e2010-08-19 00:37:05 +0000262 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
Eric Christopher0fe7d542010-08-17 01:25:29 +0000263 TII.get(TargetOpcode::COPY), ResultReg)
264 .addReg(II.ImplicitDefs[0]));
265 }
266 return ResultReg;
267}
268
269unsigned ARMFastISel::FastEmitInst_i(unsigned MachineInstOpcode,
270 const TargetRegisterClass *RC,
271 uint64_t Imm) {
272 unsigned ResultReg = createResultReg(RC);
273 const TargetInstrDesc &II = TII.get(MachineInstOpcode);
274
275 if (II.getNumDefs() >= 1)
Eric Christopher456144e2010-08-19 00:37:05 +0000276 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
Eric Christopher0fe7d542010-08-17 01:25:29 +0000277 .addImm(Imm));
278 else {
Eric Christopher456144e2010-08-19 00:37:05 +0000279 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
Eric Christopher0fe7d542010-08-17 01:25:29 +0000280 .addImm(Imm));
Eric Christopher456144e2010-08-19 00:37:05 +0000281 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
Eric Christopher0fe7d542010-08-17 01:25:29 +0000282 TII.get(TargetOpcode::COPY), ResultReg)
283 .addReg(II.ImplicitDefs[0]));
284 }
285 return ResultReg;
286}
287
288unsigned ARMFastISel::FastEmitInst_extractsubreg(MVT RetVT,
289 unsigned Op0, bool Op0IsKill,
290 uint32_t Idx) {
291 unsigned ResultReg = createResultReg(TLI.getRegClassFor(RetVT));
292 assert(TargetRegisterInfo::isVirtualRegister(Op0) &&
293 "Cannot yet extract from physregs");
Eric Christopher456144e2010-08-19 00:37:05 +0000294 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt,
Eric Christopher0fe7d542010-08-17 01:25:29 +0000295 DL, TII.get(TargetOpcode::COPY), ResultReg)
296 .addReg(Op0, getKillRegState(Op0IsKill), Idx));
297 return ResultReg;
298}
299
Eric Christopherab695882010-07-21 22:26:11 +0000300bool ARMFastISel::TargetSelectInstruction(const Instruction *I) {
301 switch (I->getOpcode()) {
302 default: break;
303 }
304 return false;
305}
306
307namespace llvm {
308 llvm::FastISel *ARM::createFastISel(FunctionLoweringInfo &funcInfo) {
Eric Christopher038fea52010-08-17 00:46:57 +0000309 if (EnableARMFastISel) return new ARMFastISel(funcInfo);
Evan Cheng09447952010-07-26 18:32:55 +0000310 return 0;
Eric Christopherab695882010-07-21 22:26:11 +0000311 }
312}