blob: 9c35d0a2b4cfdb085a246bc057e01f4d64a56527 [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 Christopherd10cd7b2010-09-10 23:18:12 +000018#include "ARMCallingConv.h"
Eric Christopherab695882010-07-21 22:26:11 +000019#include "ARMRegisterInfo.h"
20#include "ARMTargetMachine.h"
21#include "ARMSubtarget.h"
22#include "llvm/CallingConv.h"
23#include "llvm/DerivedTypes.h"
24#include "llvm/GlobalVariable.h"
25#include "llvm/Instructions.h"
26#include "llvm/IntrinsicInst.h"
Eric Christopherbb3e5da2010-09-14 23:03:37 +000027#include "llvm/Module.h"
Eric Christopherab695882010-07-21 22:26:11 +000028#include "llvm/CodeGen/Analysis.h"
29#include "llvm/CodeGen/FastISel.h"
30#include "llvm/CodeGen/FunctionLoweringInfo.h"
Eric Christopher0fe7d542010-08-17 01:25:29 +000031#include "llvm/CodeGen/MachineInstrBuilder.h"
32#include "llvm/CodeGen/MachineModuleInfo.h"
Eric Christopherab695882010-07-21 22:26:11 +000033#include "llvm/CodeGen/MachineConstantPool.h"
34#include "llvm/CodeGen/MachineFrameInfo.h"
35#include "llvm/CodeGen/MachineRegisterInfo.h"
36#include "llvm/Support/CallSite.h"
Eric Christopher038fea52010-08-17 00:46:57 +000037#include "llvm/Support/CommandLine.h"
Eric Christopherab695882010-07-21 22:26:11 +000038#include "llvm/Support/ErrorHandling.h"
39#include "llvm/Support/GetElementPtrTypeIterator.h"
Eric Christopher0fe7d542010-08-17 01:25:29 +000040#include "llvm/Target/TargetData.h"
41#include "llvm/Target/TargetInstrInfo.h"
42#include "llvm/Target/TargetLowering.h"
43#include "llvm/Target/TargetMachine.h"
Eric Christopherab695882010-07-21 22:26:11 +000044#include "llvm/Target/TargetOptions.h"
45using namespace llvm;
46
Eric Christopher038fea52010-08-17 00:46:57 +000047static cl::opt<bool>
48EnableARMFastISel("arm-fast-isel",
49 cl::desc("Turn on experimental ARM fast-isel support"),
50 cl::init(false), cl::Hidden);
51
Eric Christopherab695882010-07-21 22:26:11 +000052namespace {
53
54class ARMFastISel : public FastISel {
55
56 /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can
57 /// make the right decision when generating code for different targets.
58 const ARMSubtarget *Subtarget;
Eric Christopher0fe7d542010-08-17 01:25:29 +000059 const TargetMachine &TM;
60 const TargetInstrInfo &TII;
61 const TargetLowering &TLI;
Eric Christopher7fe55b72010-08-23 22:32:45 +000062 const ARMFunctionInfo *AFI;
Eric Christopherab695882010-07-21 22:26:11 +000063
Eric Christopher8cf6c602010-09-29 22:24:45 +000064 // Convenience variables to avoid some queries.
Eric Christophereaa204b2010-09-02 01:39:14 +000065 bool isThumb;
Eric Christopher8cf6c602010-09-29 22:24:45 +000066 LLVMContext *Context;
Eric Christophereaa204b2010-09-02 01:39:14 +000067
Eric Christopherab695882010-07-21 22:26:11 +000068 public:
Eric Christopherac1a19e2010-09-09 01:06:51 +000069 explicit ARMFastISel(FunctionLoweringInfo &funcInfo)
Eric Christopher0fe7d542010-08-17 01:25:29 +000070 : FastISel(funcInfo),
71 TM(funcInfo.MF->getTarget()),
72 TII(*TM.getInstrInfo()),
73 TLI(*TM.getTargetLowering()) {
Eric Christopherab695882010-07-21 22:26:11 +000074 Subtarget = &TM.getSubtarget<ARMSubtarget>();
Eric Christopher7fe55b72010-08-23 22:32:45 +000075 AFI = funcInfo.MF->getInfo<ARMFunctionInfo>();
Eric Christophereaa204b2010-09-02 01:39:14 +000076 isThumb = AFI->isThumbFunction();
Eric Christopher8cf6c602010-09-29 22:24:45 +000077 Context = &funcInfo.Fn->getContext();
Eric Christopherab695882010-07-21 22:26:11 +000078 }
79
Eric Christophercb592292010-08-20 00:20:31 +000080 // Code from FastISel.cpp.
Eric Christopher0fe7d542010-08-17 01:25:29 +000081 virtual unsigned FastEmitInst_(unsigned MachineInstOpcode,
82 const TargetRegisterClass *RC);
83 virtual unsigned FastEmitInst_r(unsigned MachineInstOpcode,
84 const TargetRegisterClass *RC,
85 unsigned Op0, bool Op0IsKill);
86 virtual unsigned FastEmitInst_rr(unsigned MachineInstOpcode,
87 const TargetRegisterClass *RC,
88 unsigned Op0, bool Op0IsKill,
89 unsigned Op1, bool Op1IsKill);
90 virtual unsigned FastEmitInst_ri(unsigned MachineInstOpcode,
91 const TargetRegisterClass *RC,
92 unsigned Op0, bool Op0IsKill,
93 uint64_t Imm);
94 virtual unsigned FastEmitInst_rf(unsigned MachineInstOpcode,
95 const TargetRegisterClass *RC,
96 unsigned Op0, bool Op0IsKill,
97 const ConstantFP *FPImm);
98 virtual unsigned FastEmitInst_i(unsigned MachineInstOpcode,
99 const TargetRegisterClass *RC,
100 uint64_t Imm);
101 virtual unsigned FastEmitInst_rri(unsigned MachineInstOpcode,
102 const TargetRegisterClass *RC,
103 unsigned Op0, bool Op0IsKill,
104 unsigned Op1, bool Op1IsKill,
105 uint64_t Imm);
106 virtual unsigned FastEmitInst_extractsubreg(MVT RetVT,
107 unsigned Op0, bool Op0IsKill,
108 uint32_t Idx);
Eric Christopherac1a19e2010-09-09 01:06:51 +0000109
Eric Christophercb592292010-08-20 00:20:31 +0000110 // Backend specific FastISel code.
Eric Christopherab695882010-07-21 22:26:11 +0000111 virtual bool TargetSelectInstruction(const Instruction *I);
Eric Christopher1b61ef42010-09-02 01:48:11 +0000112 virtual unsigned TargetMaterializeConstant(const Constant *C);
Eric Christopherf9764fa2010-09-30 20:49:44 +0000113 virtual unsigned TargetMaterializeAlloca(const AllocaInst *AI);
Eric Christopherab695882010-07-21 22:26:11 +0000114
115 #include "ARMGenFastISel.inc"
Eric Christopherac1a19e2010-09-09 01:06:51 +0000116
Eric Christopher83007122010-08-23 21:44:12 +0000117 // Instruction selection routines.
Eric Christopher44bff902010-09-10 23:10:30 +0000118 private:
Eric Christopher43b62be2010-09-27 06:02:23 +0000119 virtual bool SelectLoad(const Instruction *I);
120 virtual bool SelectStore(const Instruction *I);
121 virtual bool SelectBranch(const Instruction *I);
122 virtual bool SelectCmp(const Instruction *I);
123 virtual bool SelectFPExt(const Instruction *I);
124 virtual bool SelectFPTrunc(const Instruction *I);
125 virtual bool SelectBinaryOp(const Instruction *I, unsigned ISDOpcode);
126 virtual bool SelectSIToFP(const Instruction *I);
127 virtual bool SelectFPToSI(const Instruction *I);
128 virtual bool SelectSDiv(const Instruction *I);
Eric Christopherf9764fa2010-09-30 20:49:44 +0000129 virtual bool SelectCall(const Instruction *I);
Eric Christopherab695882010-07-21 22:26:11 +0000130
Eric Christopher83007122010-08-23 21:44:12 +0000131 // Utility routines.
Eric Christopher456144e2010-08-19 00:37:05 +0000132 private:
Eric Christopherb1cc8482010-08-25 07:23:49 +0000133 bool isTypeLegal(const Type *Ty, EVT &VT);
Eric Christopher4e68c7c2010-09-01 18:01:32 +0000134 bool isLoadTypeLegal(const Type *Ty, EVT &VT);
Eric Christopherb1cc8482010-08-25 07:23:49 +0000135 bool ARMEmitLoad(EVT VT, unsigned &ResultReg, unsigned Reg, int Offset);
Eric Christopher318b6ee2010-09-02 00:53:56 +0000136 bool ARMEmitStore(EVT VT, unsigned SrcReg, unsigned Reg, int Offset);
Eric Christopher30b66332010-09-08 21:49:50 +0000137 bool ARMLoadAlloca(const Instruction *I, EVT VT);
138 bool ARMStoreAlloca(const Instruction *I, unsigned SrcReg, EVT VT);
Eric Christophercb0b04b2010-08-24 00:07:24 +0000139 bool ARMComputeRegOffset(const Value *Obj, unsigned &Reg, int &Offset);
Eric Christopher9ed58df2010-09-09 00:19:41 +0000140 unsigned ARMMaterializeFP(const ConstantFP *CFP, EVT VT);
Eric Christopher744c7c82010-09-28 22:47:54 +0000141 unsigned ARMMaterializeInt(const Constant *C, EVT VT);
Eric Christopheraa3ace12010-09-09 20:49:25 +0000142 unsigned ARMMoveToFPReg(EVT VT, unsigned SrcReg);
Eric Christopher9ee4ce22010-09-09 21:44:45 +0000143 unsigned ARMMoveToIntReg(EVT VT, unsigned SrcReg);
Eric Christopherac1a19e2010-09-09 01:06:51 +0000144
Eric Christopherd10cd7b2010-09-10 23:18:12 +0000145 // Call handling routines.
146 private:
147 CCAssignFn *CCAssignFnForCall(CallingConv::ID CC, bool Return);
Eric Christophera9a7a1a2010-09-29 23:11:09 +0000148 bool ProcessCallArgs(SmallVectorImpl<Value*> &Args,
149 SmallVectorImpl<unsigned> &ArgRegs,
150 SmallVectorImpl<EVT> &ArgVTs,
151 SmallVectorImpl<ISD::ArgFlagsTy> &ArgFlags,
152 SmallVectorImpl<unsigned> &RegArgs,
153 CallingConv::ID CC,
154 unsigned &NumBytes);
155 bool FinishCall(EVT RetVT, SmallVectorImpl<unsigned> &UsedRegs,
156 const Instruction *I, CallingConv::ID CC,
157 unsigned &NumBytes);
Eric Christopher7ed8ec92010-09-28 01:21:42 +0000158 bool ARMEmitLibcall(const Instruction *I, RTLIB::Libcall Call);
Eric Christopherd10cd7b2010-09-10 23:18:12 +0000159
160 // OptionalDef handling routines.
161 private:
Eric Christopher456144e2010-08-19 00:37:05 +0000162 bool DefinesOptionalPredicate(MachineInstr *MI, bool *CPSR);
163 const MachineInstrBuilder &AddOptionalDefs(const MachineInstrBuilder &MIB);
164};
Eric Christopherab695882010-07-21 22:26:11 +0000165
166} // end anonymous namespace
167
Eric Christopherd10cd7b2010-09-10 23:18:12 +0000168#include "ARMGenCallingConv.inc"
Eric Christopherab695882010-07-21 22:26:11 +0000169
Eric Christopher456144e2010-08-19 00:37:05 +0000170// DefinesOptionalPredicate - This is different from DefinesPredicate in that
171// we don't care about implicit defs here, just places we'll need to add a
172// default CCReg argument. Sets CPSR if we're setting CPSR instead of CCR.
173bool ARMFastISel::DefinesOptionalPredicate(MachineInstr *MI, bool *CPSR) {
174 const TargetInstrDesc &TID = MI->getDesc();
175 if (!TID.hasOptionalDef())
176 return false;
177
178 // Look to see if our OptionalDef is defining CPSR or CCR.
179 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
180 const MachineOperand &MO = MI->getOperand(i);
Eric Christopherf762fbe2010-08-20 00:36:24 +0000181 if (!MO.isReg() || !MO.isDef()) continue;
182 if (MO.getReg() == ARM::CPSR)
Eric Christopher456144e2010-08-19 00:37:05 +0000183 *CPSR = true;
184 }
185 return true;
186}
187
188// If the machine is predicable go ahead and add the predicate operands, if
189// it needs default CC operands add those.
190const MachineInstrBuilder &
191ARMFastISel::AddOptionalDefs(const MachineInstrBuilder &MIB) {
192 MachineInstr *MI = &*MIB;
193
194 // Do we use a predicate?
195 if (TII.isPredicable(MI))
196 AddDefaultPred(MIB);
Eric Christopherac1a19e2010-09-09 01:06:51 +0000197
Eric Christopher456144e2010-08-19 00:37:05 +0000198 // Do we optionally set a predicate? Preds is size > 0 iff the predicate
199 // defines CPSR. All other OptionalDefines in ARM are the CCR register.
Eric Christopher979e0a12010-08-19 15:35:27 +0000200 bool CPSR = false;
Eric Christopher456144e2010-08-19 00:37:05 +0000201 if (DefinesOptionalPredicate(MI, &CPSR)) {
202 if (CPSR)
203 AddDefaultT1CC(MIB);
204 else
205 AddDefaultCC(MIB);
206 }
207 return MIB;
208}
209
Eric Christopher0fe7d542010-08-17 01:25:29 +0000210unsigned ARMFastISel::FastEmitInst_(unsigned MachineInstOpcode,
211 const TargetRegisterClass* RC) {
212 unsigned ResultReg = createResultReg(RC);
213 const TargetInstrDesc &II = TII.get(MachineInstOpcode);
214
Eric Christopher456144e2010-08-19 00:37:05 +0000215 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg));
Eric Christopher0fe7d542010-08-17 01:25:29 +0000216 return ResultReg;
217}
218
219unsigned ARMFastISel::FastEmitInst_r(unsigned MachineInstOpcode,
220 const TargetRegisterClass *RC,
221 unsigned Op0, bool Op0IsKill) {
222 unsigned ResultReg = createResultReg(RC);
223 const TargetInstrDesc &II = TII.get(MachineInstOpcode);
224
225 if (II.getNumDefs() >= 1)
Eric Christopher456144e2010-08-19 00:37:05 +0000226 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
Eric Christopher0fe7d542010-08-17 01:25:29 +0000227 .addReg(Op0, Op0IsKill * RegState::Kill));
228 else {
Eric Christopher456144e2010-08-19 00:37:05 +0000229 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
Eric Christopher0fe7d542010-08-17 01:25:29 +0000230 .addReg(Op0, Op0IsKill * RegState::Kill));
Eric Christopher456144e2010-08-19 00:37:05 +0000231 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
Eric Christopher0fe7d542010-08-17 01:25:29 +0000232 TII.get(TargetOpcode::COPY), ResultReg)
233 .addReg(II.ImplicitDefs[0]));
234 }
235 return ResultReg;
236}
237
238unsigned ARMFastISel::FastEmitInst_rr(unsigned MachineInstOpcode,
239 const TargetRegisterClass *RC,
240 unsigned Op0, bool Op0IsKill,
241 unsigned Op1, bool Op1IsKill) {
242 unsigned ResultReg = createResultReg(RC);
243 const TargetInstrDesc &II = TII.get(MachineInstOpcode);
244
245 if (II.getNumDefs() >= 1)
Eric Christopher456144e2010-08-19 00:37:05 +0000246 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
Eric Christopher0fe7d542010-08-17 01:25:29 +0000247 .addReg(Op0, Op0IsKill * RegState::Kill)
248 .addReg(Op1, Op1IsKill * RegState::Kill));
249 else {
Eric Christopher456144e2010-08-19 00:37:05 +0000250 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
Eric Christopher0fe7d542010-08-17 01:25:29 +0000251 .addReg(Op0, Op0IsKill * RegState::Kill)
252 .addReg(Op1, Op1IsKill * RegState::Kill));
Eric Christopher456144e2010-08-19 00:37:05 +0000253 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
Eric Christopher0fe7d542010-08-17 01:25:29 +0000254 TII.get(TargetOpcode::COPY), ResultReg)
255 .addReg(II.ImplicitDefs[0]));
256 }
257 return ResultReg;
258}
259
260unsigned ARMFastISel::FastEmitInst_ri(unsigned MachineInstOpcode,
261 const TargetRegisterClass *RC,
262 unsigned Op0, bool Op0IsKill,
263 uint64_t Imm) {
264 unsigned ResultReg = createResultReg(RC);
265 const TargetInstrDesc &II = TII.get(MachineInstOpcode);
266
267 if (II.getNumDefs() >= 1)
Eric Christopher456144e2010-08-19 00:37:05 +0000268 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
Eric Christopher0fe7d542010-08-17 01:25:29 +0000269 .addReg(Op0, Op0IsKill * RegState::Kill)
270 .addImm(Imm));
271 else {
Eric Christopher456144e2010-08-19 00:37:05 +0000272 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
Eric Christopher0fe7d542010-08-17 01:25:29 +0000273 .addReg(Op0, Op0IsKill * RegState::Kill)
274 .addImm(Imm));
Eric Christopher456144e2010-08-19 00:37:05 +0000275 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
Eric Christopher0fe7d542010-08-17 01:25:29 +0000276 TII.get(TargetOpcode::COPY), ResultReg)
277 .addReg(II.ImplicitDefs[0]));
278 }
279 return ResultReg;
280}
281
282unsigned ARMFastISel::FastEmitInst_rf(unsigned MachineInstOpcode,
283 const TargetRegisterClass *RC,
284 unsigned Op0, bool Op0IsKill,
285 const ConstantFP *FPImm) {
286 unsigned ResultReg = createResultReg(RC);
287 const TargetInstrDesc &II = TII.get(MachineInstOpcode);
288
289 if (II.getNumDefs() >= 1)
Eric Christopher456144e2010-08-19 00:37:05 +0000290 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
Eric Christopher0fe7d542010-08-17 01:25:29 +0000291 .addReg(Op0, Op0IsKill * RegState::Kill)
292 .addFPImm(FPImm));
293 else {
Eric Christopher456144e2010-08-19 00:37:05 +0000294 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
Eric Christopher0fe7d542010-08-17 01:25:29 +0000295 .addReg(Op0, Op0IsKill * RegState::Kill)
296 .addFPImm(FPImm));
Eric Christopher456144e2010-08-19 00:37:05 +0000297 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
Eric Christopher0fe7d542010-08-17 01:25:29 +0000298 TII.get(TargetOpcode::COPY), ResultReg)
299 .addReg(II.ImplicitDefs[0]));
300 }
301 return ResultReg;
302}
303
304unsigned ARMFastISel::FastEmitInst_rri(unsigned MachineInstOpcode,
305 const TargetRegisterClass *RC,
306 unsigned Op0, bool Op0IsKill,
307 unsigned Op1, bool Op1IsKill,
308 uint64_t Imm) {
309 unsigned ResultReg = createResultReg(RC);
310 const TargetInstrDesc &II = TII.get(MachineInstOpcode);
311
312 if (II.getNumDefs() >= 1)
Eric Christopher456144e2010-08-19 00:37:05 +0000313 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
Eric Christopher0fe7d542010-08-17 01:25:29 +0000314 .addReg(Op0, Op0IsKill * RegState::Kill)
315 .addReg(Op1, Op1IsKill * RegState::Kill)
316 .addImm(Imm));
317 else {
Eric Christopher456144e2010-08-19 00:37:05 +0000318 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
Eric Christopher0fe7d542010-08-17 01:25:29 +0000319 .addReg(Op0, Op0IsKill * RegState::Kill)
320 .addReg(Op1, Op1IsKill * RegState::Kill)
321 .addImm(Imm));
Eric Christopher456144e2010-08-19 00:37:05 +0000322 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
Eric Christopher0fe7d542010-08-17 01:25:29 +0000323 TII.get(TargetOpcode::COPY), ResultReg)
324 .addReg(II.ImplicitDefs[0]));
325 }
326 return ResultReg;
327}
328
329unsigned ARMFastISel::FastEmitInst_i(unsigned MachineInstOpcode,
330 const TargetRegisterClass *RC,
331 uint64_t Imm) {
332 unsigned ResultReg = createResultReg(RC);
333 const TargetInstrDesc &II = TII.get(MachineInstOpcode);
Eric Christopherac1a19e2010-09-09 01:06:51 +0000334
Eric Christopher0fe7d542010-08-17 01:25:29 +0000335 if (II.getNumDefs() >= 1)
Eric Christopher456144e2010-08-19 00:37:05 +0000336 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
Eric Christopher0fe7d542010-08-17 01:25:29 +0000337 .addImm(Imm));
338 else {
Eric Christopher456144e2010-08-19 00:37:05 +0000339 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
Eric Christopher0fe7d542010-08-17 01:25:29 +0000340 .addImm(Imm));
Eric Christopher456144e2010-08-19 00:37:05 +0000341 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
Eric Christopher0fe7d542010-08-17 01:25:29 +0000342 TII.get(TargetOpcode::COPY), ResultReg)
343 .addReg(II.ImplicitDefs[0]));
344 }
345 return ResultReg;
346}
347
348unsigned ARMFastISel::FastEmitInst_extractsubreg(MVT RetVT,
349 unsigned Op0, bool Op0IsKill,
350 uint32_t Idx) {
351 unsigned ResultReg = createResultReg(TLI.getRegClassFor(RetVT));
352 assert(TargetRegisterInfo::isVirtualRegister(Op0) &&
353 "Cannot yet extract from physregs");
Eric Christopher456144e2010-08-19 00:37:05 +0000354 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt,
Eric Christopher0fe7d542010-08-17 01:25:29 +0000355 DL, TII.get(TargetOpcode::COPY), ResultReg)
356 .addReg(Op0, getKillRegState(Op0IsKill), Idx));
357 return ResultReg;
358}
359
Eric Christopherdb12b2b2010-09-10 00:34:35 +0000360// TODO: Don't worry about 64-bit now, but when this is fixed remove the
361// checks from the various callers.
Eric Christopheraa3ace12010-09-09 20:49:25 +0000362unsigned ARMFastISel::ARMMoveToFPReg(EVT VT, unsigned SrcReg) {
Eric Christopher9ee4ce22010-09-09 21:44:45 +0000363 if (VT.getSimpleVT().SimpleTy == MVT::f64) return 0;
364
365 unsigned MoveReg = createResultReg(TLI.getRegClassFor(VT));
366 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
367 TII.get(ARM::VMOVRS), MoveReg)
368 .addReg(SrcReg));
369 return MoveReg;
370}
371
372unsigned ARMFastISel::ARMMoveToIntReg(EVT VT, unsigned SrcReg) {
Eric Christopher9ee4ce22010-09-09 21:44:45 +0000373 if (VT.getSimpleVT().SimpleTy == MVT::i64) return 0;
374
Eric Christopheraa3ace12010-09-09 20:49:25 +0000375 unsigned MoveReg = createResultReg(TLI.getRegClassFor(VT));
376 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
Eric Christopher9ee4ce22010-09-09 21:44:45 +0000377 TII.get(ARM::VMOVSR), MoveReg)
Eric Christopheraa3ace12010-09-09 20:49:25 +0000378 .addReg(SrcReg));
379 return MoveReg;
380}
381
Eric Christopher9ed58df2010-09-09 00:19:41 +0000382// For double width floating point we need to materialize two constants
383// (the high and the low) into integer registers then use a move to get
384// the combined constant into an FP reg.
385unsigned ARMFastISel::ARMMaterializeFP(const ConstantFP *CFP, EVT VT) {
386 const APFloat Val = CFP->getValueAPF();
387 bool is64bit = VT.getSimpleVT().SimpleTy == MVT::f64;
Eric Christopherac1a19e2010-09-09 01:06:51 +0000388
Eric Christopher9ed58df2010-09-09 00:19:41 +0000389 // This checks to see if we can use VFP3 instructions to materialize
390 // a constant, otherwise we have to go through the constant pool.
391 if (TLI.isFPImmLegal(Val, VT)) {
392 unsigned Opc = is64bit ? ARM::FCONSTD : ARM::FCONSTS;
393 unsigned DestReg = createResultReg(TLI.getRegClassFor(VT));
394 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc),
395 DestReg)
396 .addFPImm(CFP));
397 return DestReg;
398 }
Eric Christopher238bb162010-09-09 23:50:00 +0000399
Eric Christopherdb12b2b2010-09-10 00:34:35 +0000400 // Require VFP2 for loading fp constants.
Eric Christopher238bb162010-09-09 23:50:00 +0000401 if (!Subtarget->hasVFP2()) return false;
402
403 // MachineConstantPool wants an explicit alignment.
404 unsigned Align = TD.getPrefTypeAlignment(CFP->getType());
405 if (Align == 0) {
406 // TODO: Figure out if this is correct.
407 Align = TD.getTypeAllocSize(CFP->getType());
408 }
409 unsigned Idx = MCP.getConstantPoolIndex(cast<Constant>(CFP), Align);
410 unsigned DestReg = createResultReg(TLI.getRegClassFor(VT));
411 unsigned Opc = is64bit ? ARM::VLDRD : ARM::VLDRS;
412
Eric Christopherdb12b2b2010-09-10 00:34:35 +0000413 // The extra reg is for addrmode5.
Eric Christopherf5732c42010-09-28 00:35:09 +0000414 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc),
415 DestReg)
416 .addConstantPoolIndex(Idx)
Eric Christopher238bb162010-09-09 23:50:00 +0000417 .addReg(0));
418 return DestReg;
Eric Christopher9ed58df2010-09-09 00:19:41 +0000419}
420
Eric Christopher744c7c82010-09-28 22:47:54 +0000421unsigned ARMFastISel::ARMMaterializeInt(const Constant *C, EVT VT) {
422
423 // For now 32-bit only.
424 if (VT.getSimpleVT().SimpleTy != MVT::i32) return false;
425
Eric Christopher56d2b722010-09-02 23:43:26 +0000426 // MachineConstantPool wants an explicit alignment.
427 unsigned Align = TD.getPrefTypeAlignment(C->getType());
428 if (Align == 0) {
429 // TODO: Figure out if this is correct.
430 Align = TD.getTypeAllocSize(C->getType());
431 }
432 unsigned Idx = MCP.getConstantPoolIndex(C, Align);
Eric Christopher744c7c82010-09-28 22:47:54 +0000433 unsigned DestReg = createResultReg(TLI.getRegClassFor(VT));
Eric Christopherdb12b2b2010-09-10 00:34:35 +0000434
Eric Christopher56d2b722010-09-02 23:43:26 +0000435 if (isThumb)
436 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
Eric Christopherfd609802010-09-28 21:55:34 +0000437 TII.get(ARM::t2LDRpci), DestReg)
438 .addConstantPoolIndex(Idx));
Eric Christopher56d2b722010-09-02 23:43:26 +0000439 else
Eric Christopherdb12b2b2010-09-10 00:34:35 +0000440 // The extra reg and immediate are for addrmode2.
Eric Christopher56d2b722010-09-02 23:43:26 +0000441 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
Eric Christopherfd609802010-09-28 21:55:34 +0000442 TII.get(ARM::LDRcp), DestReg)
443 .addConstantPoolIndex(Idx)
Eric Christopher56d2b722010-09-02 23:43:26 +0000444 .addReg(0).addImm(0));
Eric Christopherac1a19e2010-09-09 01:06:51 +0000445
Eric Christopher56d2b722010-09-02 23:43:26 +0000446 return DestReg;
Eric Christopher1b61ef42010-09-02 01:48:11 +0000447}
448
Eric Christopher9ed58df2010-09-09 00:19:41 +0000449unsigned ARMFastISel::TargetMaterializeConstant(const Constant *C) {
450 EVT VT = TLI.getValueType(C->getType(), true);
451
452 // Only handle simple types.
453 if (!VT.isSimple()) return 0;
454
455 if (const ConstantFP *CFP = dyn_cast<ConstantFP>(C))
456 return ARMMaterializeFP(CFP, VT);
Eric Christopher744c7c82010-09-28 22:47:54 +0000457 return ARMMaterializeInt(C, VT);
Eric Christopher9ed58df2010-09-09 00:19:41 +0000458}
459
Eric Christopherf9764fa2010-09-30 20:49:44 +0000460unsigned ARMFastISel::TargetMaterializeAlloca(const AllocaInst *AI) {
461 // Don't handle dynamic allocas.
462 if (!FuncInfo.StaticAllocaMap.count(AI)) return 0;
463
464 EVT VT;
465 if (!isTypeLegal(AI->getType(), VT)) return false;
466
467 DenseMap<const AllocaInst*, int>::iterator SI =
468 FuncInfo.StaticAllocaMap.find(AI);
469
470 // This will get lowered later into the correct offsets and registers
471 // via rewriteXFrameIndex.
472 if (SI != FuncInfo.StaticAllocaMap.end()) {
473 TargetRegisterClass* RC = TLI.getRegClassFor(VT);
474 unsigned ResultReg = createResultReg(RC);
475 unsigned Opc = isThumb ? ARM::t2ADDri : ARM::ADDri;
476 AddOptionalDefs(BuildMI(*FuncInfo.MBB, *FuncInfo.InsertPt, DL,
477 TII.get(Opc), ResultReg)
478 .addFrameIndex(SI->second)
479 .addImm(0));
480 return ResultReg;
481 }
482
483 return 0;
484}
485
Eric Christopherb1cc8482010-08-25 07:23:49 +0000486bool ARMFastISel::isTypeLegal(const Type *Ty, EVT &VT) {
487 VT = TLI.getValueType(Ty, true);
Eric Christopherac1a19e2010-09-09 01:06:51 +0000488
Eric Christopherb1cc8482010-08-25 07:23:49 +0000489 // Only handle simple types.
490 if (VT == MVT::Other || !VT.isSimple()) return false;
Eric Christopherac1a19e2010-09-09 01:06:51 +0000491
Eric Christopherdc908042010-08-31 01:28:42 +0000492 // Handle all legal types, i.e. a register that will directly hold this
493 // value.
494 return TLI.isTypeLegal(VT);
Eric Christopherb1cc8482010-08-25 07:23:49 +0000495}
496
Eric Christopher4e68c7c2010-09-01 18:01:32 +0000497bool ARMFastISel::isLoadTypeLegal(const Type *Ty, EVT &VT) {
498 if (isTypeLegal(Ty, VT)) return true;
Eric Christopherac1a19e2010-09-09 01:06:51 +0000499
Eric Christopher4e68c7c2010-09-01 18:01:32 +0000500 // If this is a type than can be sign or zero-extended to a basic operation
501 // go ahead and accept it now.
502 if (VT == MVT::i8 || VT == MVT::i16)
503 return true;
Eric Christopherac1a19e2010-09-09 01:06:51 +0000504
Eric Christopher4e68c7c2010-09-01 18:01:32 +0000505 return false;
506}
507
Eric Christophercb0b04b2010-08-24 00:07:24 +0000508// Computes the Reg+Offset to get to an object.
509bool ARMFastISel::ARMComputeRegOffset(const Value *Obj, unsigned &Reg,
Eric Christopher83007122010-08-23 21:44:12 +0000510 int &Offset) {
511 // Some boilerplate from the X86 FastISel.
512 const User *U = NULL;
Eric Christopher83007122010-08-23 21:44:12 +0000513 unsigned Opcode = Instruction::UserOp1;
Eric Christophercb0b04b2010-08-24 00:07:24 +0000514 if (const Instruction *I = dyn_cast<Instruction>(Obj)) {
Eric Christopher83007122010-08-23 21:44:12 +0000515 // Don't walk into other basic blocks; it's possible we haven't
516 // visited them yet, so the instructions may not yet be assigned
517 // virtual registers.
518 if (FuncInfo.MBBMap[I->getParent()] != FuncInfo.MBB)
519 return false;
Eric Christopher83007122010-08-23 21:44:12 +0000520 Opcode = I->getOpcode();
521 U = I;
Eric Christophercb0b04b2010-08-24 00:07:24 +0000522 } else if (const ConstantExpr *C = dyn_cast<ConstantExpr>(Obj)) {
Eric Christopher83007122010-08-23 21:44:12 +0000523 Opcode = C->getOpcode();
524 U = C;
525 }
526
Eric Christophercb0b04b2010-08-24 00:07:24 +0000527 if (const PointerType *Ty = dyn_cast<PointerType>(Obj->getType()))
Eric Christopher83007122010-08-23 21:44:12 +0000528 if (Ty->getAddressSpace() > 255)
529 // Fast instruction selection doesn't support the special
530 // address spaces.
531 return false;
Eric Christopherac1a19e2010-09-09 01:06:51 +0000532
Eric Christopher83007122010-08-23 21:44:12 +0000533 switch (Opcode) {
Eric Christopherac1a19e2010-09-09 01:06:51 +0000534 default:
Eric Christopher83007122010-08-23 21:44:12 +0000535 break;
536 case Instruction::Alloca: {
Eric Christopherf06f3092010-08-24 00:50:47 +0000537 assert(false && "Alloca should have been handled earlier!");
538 return false;
Eric Christopher83007122010-08-23 21:44:12 +0000539 }
540 }
Eric Christopherac1a19e2010-09-09 01:06:51 +0000541
Eric Christopherdb12b2b2010-09-10 00:34:35 +0000542 // FIXME: Handle global variables.
Eric Christophercb0b04b2010-08-24 00:07:24 +0000543 if (const GlobalValue *GV = dyn_cast<GlobalValue>(Obj)) {
Eric Christopherf06f3092010-08-24 00:50:47 +0000544 (void)GV;
Eric Christophercb0b04b2010-08-24 00:07:24 +0000545 return false;
546 }
Eric Christopherac1a19e2010-09-09 01:06:51 +0000547
Eric Christophercb0b04b2010-08-24 00:07:24 +0000548 // Try to get this in a register if nothing else has worked.
549 Reg = getRegForValue(Obj);
Eric Christopher318b6ee2010-09-02 00:53:56 +0000550 if (Reg == 0) return false;
551
552 // Since the offset may be too large for the load instruction
553 // get the reg+offset into a register.
554 // TODO: Verify the additions work, otherwise we'll need to add the
555 // offset instead of 0 to the instructions and do all sorts of operand
556 // munging.
557 // TODO: Optimize this somewhat.
558 if (Offset != 0) {
559 ARMCC::CondCodes Pred = ARMCC::AL;
560 unsigned PredReg = 0;
561
Eric Christophereaa204b2010-09-02 01:39:14 +0000562 if (!isThumb)
Eric Christopher318b6ee2010-09-02 00:53:56 +0000563 emitARMRegPlusImmediate(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
564 Reg, Reg, Offset, Pred, PredReg,
565 static_cast<const ARMBaseInstrInfo&>(TII));
566 else {
567 assert(AFI->isThumb2Function());
568 emitT2RegPlusImmediate(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
569 Reg, Reg, Offset, Pred, PredReg,
570 static_cast<const ARMBaseInstrInfo&>(TII));
571 }
572 }
Eric Christopher318b6ee2010-09-02 00:53:56 +0000573 return true;
Eric Christopher83007122010-08-23 21:44:12 +0000574}
575
Eric Christopher30b66332010-09-08 21:49:50 +0000576bool ARMFastISel::ARMLoadAlloca(const Instruction *I, EVT VT) {
Eric Christopherf06f3092010-08-24 00:50:47 +0000577 Value *Op0 = I->getOperand(0);
578
579 // Verify it's an alloca.
Eric Christophere24d66f2010-08-24 22:07:27 +0000580 if (const AllocaInst *AI = dyn_cast<AllocaInst>(Op0)) {
581 DenseMap<const AllocaInst*, int>::iterator SI =
582 FuncInfo.StaticAllocaMap.find(AI);
Eric Christopherf06f3092010-08-24 00:50:47 +0000583
Eric Christophere24d66f2010-08-24 22:07:27 +0000584 if (SI != FuncInfo.StaticAllocaMap.end()) {
Eric Christopher30b66332010-09-08 21:49:50 +0000585 TargetRegisterClass* RC = TLI.getRegClassFor(VT);
Eric Christopherb1cc8482010-08-25 07:23:49 +0000586 unsigned ResultReg = createResultReg(RC);
Eric Christophere24d66f2010-08-24 22:07:27 +0000587 TII.loadRegFromStackSlot(*FuncInfo.MBB, *FuncInfo.InsertPt,
Eric Christopherb1cc8482010-08-25 07:23:49 +0000588 ResultReg, SI->second, RC,
Eric Christophere24d66f2010-08-24 22:07:27 +0000589 TM.getRegisterInfo());
590 UpdateValueMap(I, ResultReg);
591 return true;
592 }
Eric Christopherf06f3092010-08-24 00:50:47 +0000593 }
Eric Christopherf06f3092010-08-24 00:50:47 +0000594 return false;
595}
596
Eric Christopherb1cc8482010-08-25 07:23:49 +0000597bool ARMFastISel::ARMEmitLoad(EVT VT, unsigned &ResultReg,
598 unsigned Reg, int Offset) {
Eric Christopherac1a19e2010-09-09 01:06:51 +0000599
Eric Christopherb1cc8482010-08-25 07:23:49 +0000600 assert(VT.isSimple() && "Non-simple types are invalid here!");
Eric Christopherdc908042010-08-31 01:28:42 +0000601 unsigned Opc;
Eric Christopher6dab1372010-09-18 01:59:37 +0000602 bool isFloat = false;
Eric Christopherb1cc8482010-08-25 07:23:49 +0000603 switch (VT.getSimpleVT().SimpleTy) {
Eric Christopherac1a19e2010-09-09 01:06:51 +0000604 default:
Eric Christopher98de5b42010-09-29 00:49:09 +0000605 // This is mostly going to be Neon/vector support.
Eric Christopher548d1bb2010-08-30 23:48:26 +0000606 return false;
Eric Christopher4e68c7c2010-09-01 18:01:32 +0000607 case MVT::i16:
608 Opc = isThumb ? ARM::tLDRH : ARM::LDRH;
609 VT = MVT::i32;
610 break;
611 case MVT::i8:
612 Opc = isThumb ? ARM::tLDRB : ARM::LDRB;
613 VT = MVT::i32;
614 break;
Eric Christopherdc908042010-08-31 01:28:42 +0000615 case MVT::i32:
616 Opc = isThumb ? ARM::tLDR : ARM::LDR;
617 break;
Eric Christopher6dab1372010-09-18 01:59:37 +0000618 case MVT::f32:
619 Opc = ARM::VLDRS;
620 isFloat = true;
621 break;
622 case MVT::f64:
623 Opc = ARM::VLDRD;
624 isFloat = true;
625 break;
Eric Christopherb1cc8482010-08-25 07:23:49 +0000626 }
Eric Christopherac1a19e2010-09-09 01:06:51 +0000627
Eric Christopherdc908042010-08-31 01:28:42 +0000628 ResultReg = createResultReg(TLI.getRegClassFor(VT));
Eric Christopherac1a19e2010-09-09 01:06:51 +0000629
Eric Christopherdc908042010-08-31 01:28:42 +0000630 // TODO: Fix the Addressing modes so that these can share some code.
631 // Since this is a Thumb1 load this will work in Thumb1 or 2 mode.
Eric Christopher6dab1372010-09-18 01:59:37 +0000632 // The thumb addressing mode has operands swapped from the arm addressing
633 // mode, the floating point one only has two operands.
634 if (isFloat)
635 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
636 TII.get(Opc), ResultReg)
637 .addReg(Reg).addImm(Offset));
638 else if (isThumb)
Eric Christopherdc908042010-08-31 01:28:42 +0000639 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
640 TII.get(Opc), ResultReg)
641 .addReg(Reg).addImm(Offset).addReg(0));
642 else
643 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
644 TII.get(Opc), ResultReg)
645 .addReg(Reg).addReg(0).addImm(Offset));
Eric Christopherdc908042010-08-31 01:28:42 +0000646 return true;
Eric Christopherb1cc8482010-08-25 07:23:49 +0000647}
648
Eric Christopher43b62be2010-09-27 06:02:23 +0000649bool ARMFastISel::SelectLoad(const Instruction *I) {
Eric Christopherdb12b2b2010-09-10 00:34:35 +0000650 // Verify we have a legal type before going any further.
651 EVT VT;
652 if (!isLoadTypeLegal(I->getType(), VT))
653 return false;
654
655 // If we're an alloca we know we have a frame index and can emit the load
656 // directly in short order.
657 if (ARMLoadAlloca(I, VT))
658 return true;
659
660 // Our register and offset with innocuous defaults.
661 unsigned Reg = 0;
662 int Offset = 0;
663
664 // See if we can handle this as Reg + Offset
665 if (!ARMComputeRegOffset(I->getOperand(0), Reg, Offset))
666 return false;
667
668 unsigned ResultReg;
669 if (!ARMEmitLoad(VT, ResultReg, Reg, Offset /* 0 */)) return false;
670
671 UpdateValueMap(I, ResultReg);
672 return true;
673}
674
Eric Christopher30b66332010-09-08 21:49:50 +0000675bool ARMFastISel::ARMStoreAlloca(const Instruction *I, unsigned SrcReg, EVT VT){
Eric Christopher543cf052010-09-01 22:16:27 +0000676 Value *Op1 = I->getOperand(1);
677
678 // Verify it's an alloca.
679 if (const AllocaInst *AI = dyn_cast<AllocaInst>(Op1)) {
680 DenseMap<const AllocaInst*, int>::iterator SI =
681 FuncInfo.StaticAllocaMap.find(AI);
682
683 if (SI != FuncInfo.StaticAllocaMap.end()) {
Eric Christopher30b66332010-09-08 21:49:50 +0000684 TargetRegisterClass* RC = TLI.getRegClassFor(VT);
Eric Christopher318b6ee2010-09-02 00:53:56 +0000685 assert(SrcReg != 0 && "Nothing to store!");
Eric Christopher543cf052010-09-01 22:16:27 +0000686 TII.storeRegToStackSlot(*FuncInfo.MBB, *FuncInfo.InsertPt,
Eric Christopher318b6ee2010-09-02 00:53:56 +0000687 SrcReg, true /*isKill*/, SI->second, RC,
Eric Christopher543cf052010-09-01 22:16:27 +0000688 TM.getRegisterInfo());
689 return true;
690 }
691 }
692 return false;
693}
694
Eric Christopher318b6ee2010-09-02 00:53:56 +0000695bool ARMFastISel::ARMEmitStore(EVT VT, unsigned SrcReg,
696 unsigned DstReg, int Offset) {
Eric Christopher318b6ee2010-09-02 00:53:56 +0000697 unsigned StrOpc;
Eric Christopherb74558a2010-09-18 01:23:38 +0000698 bool isFloat = false;
Eric Christopher318b6ee2010-09-02 00:53:56 +0000699 switch (VT.getSimpleVT().SimpleTy) {
700 default: return false;
701 case MVT::i1:
702 case MVT::i8: StrOpc = isThumb ? ARM::tSTRB : ARM::STRB; break;
703 case MVT::i16: StrOpc = isThumb ? ARM::tSTRH : ARM::STRH; break;
704 case MVT::i32: StrOpc = isThumb ? ARM::tSTR : ARM::STR; break;
Eric Christopher56d2b722010-09-02 23:43:26 +0000705 case MVT::f32:
706 if (!Subtarget->hasVFP2()) return false;
707 StrOpc = ARM::VSTRS;
Eric Christopherb74558a2010-09-18 01:23:38 +0000708 isFloat = true;
Eric Christopher56d2b722010-09-02 23:43:26 +0000709 break;
710 case MVT::f64:
711 if (!Subtarget->hasVFP2()) return false;
712 StrOpc = ARM::VSTRD;
Eric Christopherb74558a2010-09-18 01:23:38 +0000713 isFloat = true;
Eric Christopher56d2b722010-09-02 23:43:26 +0000714 break;
Eric Christopher318b6ee2010-09-02 00:53:56 +0000715 }
Eric Christopherac1a19e2010-09-09 01:06:51 +0000716
Eric Christopherb74558a2010-09-18 01:23:38 +0000717 // The thumb addressing mode has operands swapped from the arm addressing
718 // mode, the floating point one only has two operands.
Eric Christopher6dab1372010-09-18 01:59:37 +0000719 if (isFloat)
Eric Christopherb74558a2010-09-18 01:23:38 +0000720 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
Eric Christopher45547b82010-10-01 20:46:04 +0000721 TII.get(StrOpc))
722 .addReg(SrcReg).addReg(DstReg).addImm(Offset));
Eric Christopher6dab1372010-09-18 01:59:37 +0000723 else if (isThumb)
724 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
Eric Christopher45547b82010-10-01 20:46:04 +0000725 TII.get(StrOpc))
726 .addReg(SrcReg).addReg(DstReg).addImm(Offset).addReg(0));
Eric Christopher6dab1372010-09-18 01:59:37 +0000727
Eric Christopher318b6ee2010-09-02 00:53:56 +0000728 else
729 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
Eric Christopher45547b82010-10-01 20:46:04 +0000730 TII.get(StrOpc))
731 .addReg(SrcReg).addReg(DstReg).addReg(0).addImm(Offset));
Eric Christopherac1a19e2010-09-09 01:06:51 +0000732
Eric Christopher318b6ee2010-09-02 00:53:56 +0000733 return true;
734}
735
Eric Christopher43b62be2010-09-27 06:02:23 +0000736bool ARMFastISel::SelectStore(const Instruction *I) {
Eric Christopher318b6ee2010-09-02 00:53:56 +0000737 Value *Op0 = I->getOperand(0);
738 unsigned SrcReg = 0;
739
Eric Christopher543cf052010-09-01 22:16:27 +0000740 // Yay type legalization
741 EVT VT;
Eric Christopher318b6ee2010-09-02 00:53:56 +0000742 if (!isLoadTypeLegal(I->getOperand(0)->getType(), VT))
Eric Christopher543cf052010-09-01 22:16:27 +0000743 return false;
Eric Christopher318b6ee2010-09-02 00:53:56 +0000744
Eric Christopher1b61ef42010-09-02 01:48:11 +0000745 // Get the value to be stored into a register.
746 SrcReg = getRegForValue(Op0);
Eric Christopher318b6ee2010-09-02 00:53:56 +0000747 if (SrcReg == 0)
748 return false;
Eric Christopherac1a19e2010-09-09 01:06:51 +0000749
Eric Christopher318b6ee2010-09-02 00:53:56 +0000750 // If we're an alloca we know we have a frame index and can emit the store
751 // quickly.
Eric Christopher30b66332010-09-08 21:49:50 +0000752 if (ARMStoreAlloca(I, SrcReg, VT))
Eric Christopher318b6ee2010-09-02 00:53:56 +0000753 return true;
Eric Christopherac1a19e2010-09-09 01:06:51 +0000754
Eric Christopher318b6ee2010-09-02 00:53:56 +0000755 // Our register and offset with innocuous defaults.
756 unsigned Reg = 0;
757 int Offset = 0;
Eric Christopherac1a19e2010-09-09 01:06:51 +0000758
Eric Christopher318b6ee2010-09-02 00:53:56 +0000759 // See if we can handle this as Reg + Offset
760 if (!ARMComputeRegOffset(I->getOperand(1), Reg, Offset))
761 return false;
Eric Christopherac1a19e2010-09-09 01:06:51 +0000762
Eric Christopher318b6ee2010-09-02 00:53:56 +0000763 if (!ARMEmitStore(VT, SrcReg, Reg, Offset /* 0 */)) return false;
Eric Christopherac1a19e2010-09-09 01:06:51 +0000764
Eric Christophera5b1e682010-09-17 22:28:18 +0000765 return true;
766}
767
768static ARMCC::CondCodes getComparePred(CmpInst::Predicate Pred) {
769 switch (Pred) {
770 // Needs two compares...
771 case CmpInst::FCMP_ONE:
772 case CmpInst::FCMP_UEQ:
773 default:
774 assert(false && "Unhandled CmpInst::Predicate!");
775 return ARMCC::AL;
776 case CmpInst::ICMP_EQ:
777 case CmpInst::FCMP_OEQ:
778 return ARMCC::EQ;
779 case CmpInst::ICMP_SGT:
780 case CmpInst::FCMP_OGT:
781 return ARMCC::GT;
782 case CmpInst::ICMP_SGE:
783 case CmpInst::FCMP_OGE:
784 return ARMCC::GE;
785 case CmpInst::ICMP_UGT:
786 case CmpInst::FCMP_UGT:
787 return ARMCC::HI;
788 case CmpInst::FCMP_OLT:
789 return ARMCC::MI;
790 case CmpInst::ICMP_ULE:
791 case CmpInst::FCMP_OLE:
792 return ARMCC::LS;
793 case CmpInst::FCMP_ORD:
794 return ARMCC::VC;
795 case CmpInst::FCMP_UNO:
796 return ARMCC::VS;
797 case CmpInst::FCMP_UGE:
798 return ARMCC::PL;
799 case CmpInst::ICMP_SLT:
800 case CmpInst::FCMP_ULT:
801 return ARMCC::LT;
802 case CmpInst::ICMP_SLE:
803 case CmpInst::FCMP_ULE:
804 return ARMCC::LE;
805 case CmpInst::FCMP_UNE:
806 case CmpInst::ICMP_NE:
807 return ARMCC::NE;
808 case CmpInst::ICMP_UGE:
809 return ARMCC::HS;
810 case CmpInst::ICMP_ULT:
811 return ARMCC::LO;
812 }
Eric Christopher543cf052010-09-01 22:16:27 +0000813}
814
Eric Christopher43b62be2010-09-27 06:02:23 +0000815bool ARMFastISel::SelectBranch(const Instruction *I) {
Eric Christophere5734102010-09-03 00:35:47 +0000816 const BranchInst *BI = cast<BranchInst>(I);
817 MachineBasicBlock *TBB = FuncInfo.MBBMap[BI->getSuccessor(0)];
818 MachineBasicBlock *FBB = FuncInfo.MBBMap[BI->getSuccessor(1)];
Eric Christopherac1a19e2010-09-09 01:06:51 +0000819
Eric Christophere5734102010-09-03 00:35:47 +0000820 // Simple branch support.
Eric Christopher229207a2010-09-29 01:14:47 +0000821 // TODO: Try to avoid the re-computation in some places.
822 unsigned CondReg = getRegForValue(BI->getCondition());
Eric Christophere5734102010-09-03 00:35:47 +0000823 if (CondReg == 0) return false;
Eric Christopherac1a19e2010-09-09 01:06:51 +0000824
Eric Christopher229207a2010-09-29 01:14:47 +0000825 // Re-set the flags just in case.
826 unsigned CmpOpc = isThumb ? ARM::t2CMPri : ARM::CMPri;
827 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(CmpOpc))
828 .addReg(CondReg).addImm(1));
Eric Christophera5b1e682010-09-17 22:28:18 +0000829
Eric Christophere5734102010-09-03 00:35:47 +0000830 unsigned BrOpc = isThumb ? ARM::t2Bcc : ARM::Bcc;
Eric Christophere5734102010-09-03 00:35:47 +0000831 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(BrOpc))
Eric Christopher229207a2010-09-29 01:14:47 +0000832 .addMBB(TBB).addImm(ARMCC::EQ).addReg(ARM::CPSR);
Eric Christophere5734102010-09-03 00:35:47 +0000833 FastEmitBranch(FBB, DL);
834 FuncInfo.MBB->addSuccessor(TBB);
Eric Christophera5b1e682010-09-17 22:28:18 +0000835 return true;
Eric Christophere5734102010-09-03 00:35:47 +0000836}
837
Eric Christopher43b62be2010-09-27 06:02:23 +0000838bool ARMFastISel::SelectCmp(const Instruction *I) {
Eric Christopherd43393a2010-09-08 23:13:45 +0000839 const CmpInst *CI = cast<CmpInst>(I);
Eric Christopherac1a19e2010-09-09 01:06:51 +0000840
Eric Christopherd43393a2010-09-08 23:13:45 +0000841 EVT VT;
842 const Type *Ty = CI->getOperand(0)->getType();
843 if (!isTypeLegal(Ty, VT))
844 return false;
Eric Christopherac1a19e2010-09-09 01:06:51 +0000845
Eric Christopherd43393a2010-09-08 23:13:45 +0000846 bool isFloat = (Ty->isDoubleTy() || Ty->isFloatTy());
847 if (isFloat && !Subtarget->hasVFP2())
848 return false;
Eric Christopherac1a19e2010-09-09 01:06:51 +0000849
Eric Christopherd43393a2010-09-08 23:13:45 +0000850 unsigned CmpOpc;
Eric Christopher229207a2010-09-29 01:14:47 +0000851 unsigned CondReg;
Eric Christopherd43393a2010-09-08 23:13:45 +0000852 switch (VT.getSimpleVT().SimpleTy) {
853 default: return false;
854 // TODO: Verify compares.
855 case MVT::f32:
856 CmpOpc = ARM::VCMPES;
Eric Christopher229207a2010-09-29 01:14:47 +0000857 CondReg = ARM::FPSCR;
Eric Christopherd43393a2010-09-08 23:13:45 +0000858 break;
859 case MVT::f64:
860 CmpOpc = ARM::VCMPED;
Eric Christopher229207a2010-09-29 01:14:47 +0000861 CondReg = ARM::FPSCR;
Eric Christopherd43393a2010-09-08 23:13:45 +0000862 break;
863 case MVT::i32:
864 CmpOpc = isThumb ? ARM::t2CMPrr : ARM::CMPrr;
Eric Christopher229207a2010-09-29 01:14:47 +0000865 CondReg = ARM::CPSR;
Eric Christopherd43393a2010-09-08 23:13:45 +0000866 break;
867 }
868
Eric Christopher229207a2010-09-29 01:14:47 +0000869 // Get the compare predicate.
870 ARMCC::CondCodes ARMPred = getComparePred(CI->getPredicate());
871
872 // We may not handle every CC for now.
873 if (ARMPred == ARMCC::AL) return false;
874
Eric Christopherd43393a2010-09-08 23:13:45 +0000875 unsigned Arg1 = getRegForValue(CI->getOperand(0));
876 if (Arg1 == 0) return false;
Eric Christopherac1a19e2010-09-09 01:06:51 +0000877
Eric Christopherd43393a2010-09-08 23:13:45 +0000878 unsigned Arg2 = getRegForValue(CI->getOperand(1));
879 if (Arg2 == 0) return false;
Eric Christopherac1a19e2010-09-09 01:06:51 +0000880
Eric Christopherd43393a2010-09-08 23:13:45 +0000881 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(CmpOpc))
882 .addReg(Arg1).addReg(Arg2));
Eric Christopherac1a19e2010-09-09 01:06:51 +0000883
Eric Christopherdb12b2b2010-09-10 00:34:35 +0000884 // For floating point we need to move the result to a comparison register
885 // that we can then use for branches.
Eric Christopherd43393a2010-09-08 23:13:45 +0000886 if (isFloat)
887 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
888 TII.get(ARM::FMSTAT)));
Eric Christopherce07b542010-09-09 20:26:31 +0000889
Eric Christopher229207a2010-09-29 01:14:47 +0000890 // Now set a register based on the comparison. Explicitly set the predicates
891 // here.
892 unsigned MovCCOpc = isThumb ? ARM::tMOVCCi : ARM::MOVCCi;
893 unsigned DestReg = createResultReg(ARM::GPRRegisterClass);
894 Constant *Zero
Eric Christopher8cf6c602010-09-29 22:24:45 +0000895 = ConstantInt::get(Type::getInt32Ty(*Context), 0);
Eric Christopher229207a2010-09-29 01:14:47 +0000896 unsigned ZeroReg = TargetMaterializeConstant(Zero);
897 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(MovCCOpc), DestReg)
898 .addReg(ZeroReg).addImm(1)
899 .addImm(ARMPred).addReg(CondReg);
900
Eric Christophera5b1e682010-09-17 22:28:18 +0000901 UpdateValueMap(I, DestReg);
Eric Christopherd43393a2010-09-08 23:13:45 +0000902 return true;
903}
904
Eric Christopher43b62be2010-09-27 06:02:23 +0000905bool ARMFastISel::SelectFPExt(const Instruction *I) {
Eric Christopher46203602010-09-09 00:26:48 +0000906 // Make sure we have VFP and that we're extending float to double.
907 if (!Subtarget->hasVFP2()) return false;
Eric Christopherac1a19e2010-09-09 01:06:51 +0000908
Eric Christopher46203602010-09-09 00:26:48 +0000909 Value *V = I->getOperand(0);
910 if (!I->getType()->isDoubleTy() ||
911 !V->getType()->isFloatTy()) return false;
Eric Christopherac1a19e2010-09-09 01:06:51 +0000912
Eric Christopher46203602010-09-09 00:26:48 +0000913 unsigned Op = getRegForValue(V);
914 if (Op == 0) return false;
Eric Christopherac1a19e2010-09-09 01:06:51 +0000915
Eric Christopher46203602010-09-09 00:26:48 +0000916 unsigned Result = createResultReg(ARM::DPRRegisterClass);
Eric Christopherac1a19e2010-09-09 01:06:51 +0000917 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
Eric Christopheref2fdd22010-09-09 20:36:19 +0000918 TII.get(ARM::VCVTDS), Result)
Eric Christopherce07b542010-09-09 20:26:31 +0000919 .addReg(Op));
920 UpdateValueMap(I, Result);
921 return true;
922}
923
Eric Christopher43b62be2010-09-27 06:02:23 +0000924bool ARMFastISel::SelectFPTrunc(const Instruction *I) {
Eric Christopherce07b542010-09-09 20:26:31 +0000925 // Make sure we have VFP and that we're truncating double to float.
926 if (!Subtarget->hasVFP2()) return false;
927
928 Value *V = I->getOperand(0);
929 if (!I->getType()->isFloatTy() ||
930 !V->getType()->isDoubleTy()) return false;
931
932 unsigned Op = getRegForValue(V);
933 if (Op == 0) return false;
934
935 unsigned Result = createResultReg(ARM::SPRRegisterClass);
Eric Christopherce07b542010-09-09 20:26:31 +0000936 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
Eric Christopheref2fdd22010-09-09 20:36:19 +0000937 TII.get(ARM::VCVTSD), Result)
Eric Christopher46203602010-09-09 00:26:48 +0000938 .addReg(Op));
939 UpdateValueMap(I, Result);
940 return true;
941}
942
Eric Christopher43b62be2010-09-27 06:02:23 +0000943bool ARMFastISel::SelectSIToFP(const Instruction *I) {
Eric Christopher9a040492010-09-09 18:54:59 +0000944 // Make sure we have VFP.
945 if (!Subtarget->hasVFP2()) return false;
946
Eric Christopher9ee4ce22010-09-09 21:44:45 +0000947 EVT DstVT;
Eric Christopher9a040492010-09-09 18:54:59 +0000948 const Type *Ty = I->getType();
Eric Christopher9ee4ce22010-09-09 21:44:45 +0000949 if (!isTypeLegal(Ty, DstVT))
Eric Christopher9a040492010-09-09 18:54:59 +0000950 return false;
951
952 unsigned Op = getRegForValue(I->getOperand(0));
953 if (Op == 0) return false;
954
Eric Christopherdb12b2b2010-09-10 00:34:35 +0000955 // The conversion routine works on fp-reg to fp-reg and the operand above
956 // was an integer, move it to the fp registers if possible.
Eric Christopher9ee4ce22010-09-09 21:44:45 +0000957 unsigned FP = ARMMoveToFPReg(DstVT, Op);
958 if (FP == 0) return false;
959
Eric Christopher9a040492010-09-09 18:54:59 +0000960 unsigned Opc;
961 if (Ty->isFloatTy()) Opc = ARM::VSITOS;
962 else if (Ty->isDoubleTy()) Opc = ARM::VSITOD;
963 else return 0;
964
Eric Christopher9ee4ce22010-09-09 21:44:45 +0000965 unsigned ResultReg = createResultReg(TLI.getRegClassFor(DstVT));
Eric Christopher9a040492010-09-09 18:54:59 +0000966 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc),
967 ResultReg)
Eric Christopher9ee4ce22010-09-09 21:44:45 +0000968 .addReg(FP));
Eric Christopherce07b542010-09-09 20:26:31 +0000969 UpdateValueMap(I, ResultReg);
Eric Christopher9a040492010-09-09 18:54:59 +0000970 return true;
971}
972
Eric Christopher43b62be2010-09-27 06:02:23 +0000973bool ARMFastISel::SelectFPToSI(const Instruction *I) {
Eric Christopher9a040492010-09-09 18:54:59 +0000974 // Make sure we have VFP.
975 if (!Subtarget->hasVFP2()) return false;
976
Eric Christopherdb12b2b2010-09-10 00:34:35 +0000977 EVT DstVT;
Eric Christopher9a040492010-09-09 18:54:59 +0000978 const Type *RetTy = I->getType();
Eric Christopher920a2082010-09-10 00:35:09 +0000979 if (!isTypeLegal(RetTy, DstVT))
Eric Christopher9a040492010-09-09 18:54:59 +0000980 return false;
981
982 unsigned Op = getRegForValue(I->getOperand(0));
983 if (Op == 0) return false;
984
985 unsigned Opc;
986 const Type *OpTy = I->getOperand(0)->getType();
987 if (OpTy->isFloatTy()) Opc = ARM::VTOSIZS;
988 else if (OpTy->isDoubleTy()) Opc = ARM::VTOSIZD;
989 else return 0;
Eric Christopher9ee4ce22010-09-09 21:44:45 +0000990 EVT OpVT = TLI.getValueType(OpTy, true);
Eric Christopher9a040492010-09-09 18:54:59 +0000991
Eric Christopher9ee4ce22010-09-09 21:44:45 +0000992 unsigned ResultReg = createResultReg(TLI.getRegClassFor(OpVT));
Eric Christopher9a040492010-09-09 18:54:59 +0000993 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc),
994 ResultReg)
995 .addReg(Op));
Eric Christopher9ee4ce22010-09-09 21:44:45 +0000996
997 // This result needs to be in an integer register, but the conversion only
998 // takes place in fp-regs.
Eric Christopherdb12b2b2010-09-10 00:34:35 +0000999 unsigned IntReg = ARMMoveToIntReg(DstVT, ResultReg);
Eric Christopher9ee4ce22010-09-09 21:44:45 +00001000 if (IntReg == 0) return false;
1001
1002 UpdateValueMap(I, IntReg);
Eric Christopher9a040492010-09-09 18:54:59 +00001003 return true;
1004}
1005
Eric Christopher08637852010-09-30 22:34:19 +00001006bool ARMFastISel::SelectSDiv(const Instruction *I) {
1007 EVT VT;
1008 const Type *Ty = I->getType();
1009 if (!isTypeLegal(Ty, VT))
1010 return false;
1011
1012 // If we have integer div support we should have selected this automagically.
1013 // In case we have a real miss go ahead and return false and we'll pick
1014 // it up later.
1015 if (Subtarget->hasDivide()) return false;
1016
1017 // Otherwise emit a libcall.
1018 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
1019 if (VT == MVT::i16)
1020 LC = RTLIB::SDIV_I16;
1021 else if (VT == MVT::i32)
1022 LC = RTLIB::SDIV_I32;
1023 else if (VT == MVT::i64)
1024 LC = RTLIB::SDIV_I64;
1025 else if (VT == MVT::i128)
1026 LC = RTLIB::SDIV_I128;
1027 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported SDIV!");
1028
1029 return ARMEmitLibcall(I, LC);
1030}
1031
Eric Christopher43b62be2010-09-27 06:02:23 +00001032bool ARMFastISel::SelectBinaryOp(const Instruction *I, unsigned ISDOpcode) {
Eric Christopherbd6bf082010-09-09 01:02:03 +00001033 EVT VT = TLI.getValueType(I->getType(), true);
Eric Christopherac1a19e2010-09-09 01:06:51 +00001034
Eric Christopherbc39b822010-09-09 00:53:57 +00001035 // We can get here in the case when we want to use NEON for our fp
1036 // operations, but can't figure out how to. Just use the vfp instructions
1037 // if we have them.
1038 // FIXME: It'd be nice to use NEON instructions.
Eric Christopherbd6bf082010-09-09 01:02:03 +00001039 const Type *Ty = I->getType();
1040 bool isFloat = (Ty->isDoubleTy() || Ty->isFloatTy());
1041 if (isFloat && !Subtarget->hasVFP2())
1042 return false;
Eric Christopherac1a19e2010-09-09 01:06:51 +00001043
Eric Christopherbc39b822010-09-09 00:53:57 +00001044 unsigned Op1 = getRegForValue(I->getOperand(0));
1045 if (Op1 == 0) return false;
Eric Christopherac1a19e2010-09-09 01:06:51 +00001046
Eric Christopherbc39b822010-09-09 00:53:57 +00001047 unsigned Op2 = getRegForValue(I->getOperand(1));
1048 if (Op2 == 0) return false;
Eric Christopherac1a19e2010-09-09 01:06:51 +00001049
Eric Christopherbc39b822010-09-09 00:53:57 +00001050 unsigned Opc;
Eric Christopherbd6bf082010-09-09 01:02:03 +00001051 bool is64bit = VT.getSimpleVT().SimpleTy == MVT::f64 ||
1052 VT.getSimpleVT().SimpleTy == MVT::i64;
Eric Christopherbc39b822010-09-09 00:53:57 +00001053 switch (ISDOpcode) {
1054 default: return false;
1055 case ISD::FADD:
Eric Christopherbd6bf082010-09-09 01:02:03 +00001056 Opc = is64bit ? ARM::VADDD : ARM::VADDS;
Eric Christopherbc39b822010-09-09 00:53:57 +00001057 break;
1058 case ISD::FSUB:
Eric Christopherbd6bf082010-09-09 01:02:03 +00001059 Opc = is64bit ? ARM::VSUBD : ARM::VSUBS;
Eric Christopherbc39b822010-09-09 00:53:57 +00001060 break;
1061 case ISD::FMUL:
Eric Christopherbd6bf082010-09-09 01:02:03 +00001062 Opc = is64bit ? ARM::VMULD : ARM::VMULS;
Eric Christopherbc39b822010-09-09 00:53:57 +00001063 break;
1064 }
Eric Christopherbd6bf082010-09-09 01:02:03 +00001065 unsigned ResultReg = createResultReg(TLI.getRegClassFor(VT));
Eric Christopherbc39b822010-09-09 00:53:57 +00001066 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
1067 TII.get(Opc), ResultReg)
1068 .addReg(Op1).addReg(Op2));
Eric Christopherce07b542010-09-09 20:26:31 +00001069 UpdateValueMap(I, ResultReg);
Eric Christopherbc39b822010-09-09 00:53:57 +00001070 return true;
1071}
1072
Eric Christopherd10cd7b2010-09-10 23:18:12 +00001073// Call Handling Code
1074
1075// This is largely taken directly from CCAssignFnForNode - we don't support
1076// varargs in FastISel so that part has been removed.
1077// TODO: We may not support all of this.
1078CCAssignFn *ARMFastISel::CCAssignFnForCall(CallingConv::ID CC, bool Return) {
1079 switch (CC) {
1080 default:
1081 llvm_unreachable("Unsupported calling convention");
1082 case CallingConv::C:
1083 case CallingConv::Fast:
1084 // Use target triple & subtarget features to do actual dispatch.
1085 if (Subtarget->isAAPCS_ABI()) {
1086 if (Subtarget->hasVFP2() &&
1087 FloatABIType == FloatABI::Hard)
1088 return (Return ? RetCC_ARM_AAPCS_VFP: CC_ARM_AAPCS_VFP);
1089 else
1090 return (Return ? RetCC_ARM_AAPCS: CC_ARM_AAPCS);
1091 } else
1092 return (Return ? RetCC_ARM_APCS: CC_ARM_APCS);
1093 case CallingConv::ARM_AAPCS_VFP:
1094 return (Return ? RetCC_ARM_AAPCS_VFP: CC_ARM_AAPCS_VFP);
1095 case CallingConv::ARM_AAPCS:
1096 return (Return ? RetCC_ARM_AAPCS: CC_ARM_AAPCS);
1097 case CallingConv::ARM_APCS:
1098 return (Return ? RetCC_ARM_APCS: CC_ARM_APCS);
1099 }
1100}
1101
Eric Christophera9a7a1a2010-09-29 23:11:09 +00001102bool ARMFastISel::ProcessCallArgs(SmallVectorImpl<Value*> &Args,
1103 SmallVectorImpl<unsigned> &ArgRegs,
1104 SmallVectorImpl<EVT> &ArgVTs,
1105 SmallVectorImpl<ISD::ArgFlagsTy> &ArgFlags,
1106 SmallVectorImpl<unsigned> &RegArgs,
1107 CallingConv::ID CC,
1108 unsigned &NumBytes) {
1109 SmallVector<CCValAssign, 16> ArgLocs;
1110 CCState CCInfo(CC, false, TM, ArgLocs, *Context);
1111 CCInfo.AnalyzeCallOperands(ArgVTs, ArgFlags, CCAssignFnForCall(CC, false));
1112
1113 // Get a count of how many bytes are to be pushed on the stack.
1114 NumBytes = CCInfo.getNextStackOffset();
1115
1116 // Issue CALLSEQ_START
1117 unsigned AdjStackDown = TM.getRegisterInfo()->getCallFrameSetupOpcode();
1118 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(AdjStackDown))
1119 .addImm(NumBytes);
1120
1121 // Process the args.
1122 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
1123 CCValAssign &VA = ArgLocs[i];
1124 unsigned Arg = ArgRegs[VA.getValNo()];
1125 EVT ArgVT = ArgVTs[VA.getValNo()];
1126
Eric Christopherf9764fa2010-09-30 20:49:44 +00001127 // Handle arg promotion, etc.
Eric Christophera9a7a1a2010-09-29 23:11:09 +00001128 switch (VA.getLocInfo()) {
1129 case CCValAssign::Full: break;
1130 default:
Eric Christopherf9764fa2010-09-30 20:49:44 +00001131 assert(false && "Handle arg promotion.");
Eric Christophera9a7a1a2010-09-29 23:11:09 +00001132 return false;
1133 }
1134
1135 // Now copy/store arg to correct locations.
1136 if (VA.isRegLoc()) {
1137 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(TargetOpcode::COPY),
Eric Christopherf9764fa2010-09-30 20:49:44 +00001138 VA.getLocReg())
1139 .addReg(Arg);
Eric Christophera9a7a1a2010-09-29 23:11:09 +00001140 RegArgs.push_back(VA.getLocReg());
1141 } else {
1142 // Need to store
1143 return false;
1144 }
1145 }
1146
1147 return true;
1148}
1149
1150bool ARMFastISel::FinishCall(EVT RetVT, SmallVectorImpl<unsigned> &UsedRegs,
1151 const Instruction *I, CallingConv::ID CC,
1152 unsigned &NumBytes) {
1153 // Issue CALLSEQ_END
1154 unsigned AdjStackUp = TM.getRegisterInfo()->getCallFrameDestroyOpcode();
1155 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(AdjStackUp))
1156 .addImm(NumBytes).addImm(0);
1157
1158 // Now the return value.
1159 if (RetVT.getSimpleVT().SimpleTy != MVT::isVoid) {
1160 SmallVector<CCValAssign, 16> RVLocs;
1161 CCState CCInfo(CC, false, TM, RVLocs, *Context);
1162 CCInfo.AnalyzeCallResult(RetVT, CCAssignFnForCall(CC, true));
1163
1164 // Copy all of the result registers out of their specified physreg.
Eric Christopher14df8822010-10-01 00:00:11 +00001165 if (RVLocs.size() == 2 && RetVT.getSimpleVT().SimpleTy == MVT::f64) {
1166 // For this move we copy into two registers and then move into the
1167 // double fp reg we want.
1168 // TODO: Are the copies necessary?
1169 TargetRegisterClass *CopyRC = TLI.getRegClassFor(MVT::i32);
1170 unsigned Copy1 = createResultReg(CopyRC);
1171 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(TargetOpcode::COPY),
1172 Copy1).addReg(RVLocs[0].getLocReg());
1173 UsedRegs.push_back(RVLocs[0].getLocReg());
1174
1175 unsigned Copy2 = createResultReg(CopyRC);
1176 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(TargetOpcode::COPY),
1177 Copy2).addReg(RVLocs[1].getLocReg());
1178 UsedRegs.push_back(RVLocs[1].getLocReg());
1179
1180 EVT DestVT = RVLocs[0].getValVT();
1181 TargetRegisterClass* DstRC = TLI.getRegClassFor(DestVT);
1182 unsigned ResultReg = createResultReg(DstRC);
1183 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
1184 TII.get(ARM::VMOVDRR), ResultReg)
1185 .addReg(Copy1).addReg(Copy2));
1186
1187 // Finally update the result.
1188 UpdateValueMap(I, ResultReg);
1189 } else {
1190 assert(RVLocs.size() == 1 && "Can't handle non-double multi-reg retvals!");
1191 EVT CopyVT = RVLocs[0].getValVT();
1192 TargetRegisterClass* DstRC = TLI.getRegClassFor(CopyVT);
Eric Christophera9a7a1a2010-09-29 23:11:09 +00001193
Eric Christopher14df8822010-10-01 00:00:11 +00001194 unsigned ResultReg = createResultReg(DstRC);
1195 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(TargetOpcode::COPY),
1196 ResultReg).addReg(RVLocs[0].getLocReg());
1197 UsedRegs.push_back(RVLocs[0].getLocReg());
Eric Christophera9a7a1a2010-09-29 23:11:09 +00001198
Eric Christopher14df8822010-10-01 00:00:11 +00001199 // Finally update the result.
1200 UpdateValueMap(I, ResultReg);
1201 }
Eric Christophera9a7a1a2010-09-29 23:11:09 +00001202 }
1203
1204 return true;
1205}
1206
Eric Christopherbb3e5da2010-09-14 23:03:37 +00001207// A quick function that will emit a call for a named libcall in F with the
1208// vector of passed arguments for the Instruction in I. We can assume that we
1209// can emit a call for any libcall we can produce. This is an abridged version
1210// of the full call infrastructure since we won't need to worry about things
1211// like computed function pointers or strange arguments at call sites.
1212// TODO: Try to unify this and the normal call bits for ARM, then try to unify
1213// with X86.
Eric Christopher7ed8ec92010-09-28 01:21:42 +00001214bool ARMFastISel::ARMEmitLibcall(const Instruction *I, RTLIB::Libcall Call) {
1215 CallingConv::ID CC = TLI.getLibcallCallingConv(Call);
1216
Eric Christopherbb3e5da2010-09-14 23:03:37 +00001217 // Handle *simple* calls for now.
Eric Christopher7ed8ec92010-09-28 01:21:42 +00001218 const Type *RetTy = I->getType();
Eric Christopherbb3e5da2010-09-14 23:03:37 +00001219 EVT RetVT;
1220 if (RetTy->isVoidTy())
1221 RetVT = MVT::isVoid;
1222 else if (!isTypeLegal(RetTy, RetVT))
1223 return false;
1224
Eric Christopher7ed8ec92010-09-28 01:21:42 +00001225 // For now we're using BLX etc on the assumption that we have v5t ops.
1226 if (!Subtarget->hasV5TOps()) return false;
1227
Eric Christophera9a7a1a2010-09-29 23:11:09 +00001228 // Set up the argument vectors.
Eric Christopherbb3e5da2010-09-14 23:03:37 +00001229 SmallVector<Value*, 8> Args;
1230 SmallVector<unsigned, 8> ArgRegs;
1231 SmallVector<EVT, 8> ArgVTs;
1232 SmallVector<ISD::ArgFlagsTy, 8> ArgFlags;
1233 Args.reserve(I->getNumOperands());
1234 ArgRegs.reserve(I->getNumOperands());
1235 ArgVTs.reserve(I->getNumOperands());
1236 ArgFlags.reserve(I->getNumOperands());
Eric Christopher7ed8ec92010-09-28 01:21:42 +00001237 for (unsigned i = 0; i < I->getNumOperands(); ++i) {
Eric Christopherbb3e5da2010-09-14 23:03:37 +00001238 Value *Op = I->getOperand(i);
1239 unsigned Arg = getRegForValue(Op);
1240 if (Arg == 0) return false;
1241
1242 const Type *ArgTy = Op->getType();
1243 EVT ArgVT;
1244 if (!isTypeLegal(ArgTy, ArgVT)) return false;
1245
1246 ISD::ArgFlagsTy Flags;
1247 unsigned OriginalAlignment = TD.getABITypeAlignment(ArgTy);
1248 Flags.setOrigAlign(OriginalAlignment);
1249
1250 Args.push_back(Op);
1251 ArgRegs.push_back(Arg);
1252 ArgVTs.push_back(ArgVT);
1253 ArgFlags.push_back(Flags);
1254 }
1255
Eric Christophera9a7a1a2010-09-29 23:11:09 +00001256 // Handle the arguments now that we've gotten them.
Eric Christopherbb3e5da2010-09-14 23:03:37 +00001257 SmallVector<unsigned, 4> RegArgs;
Eric Christophera9a7a1a2010-09-29 23:11:09 +00001258 unsigned NumBytes;
1259 if (!ProcessCallArgs(Args, ArgRegs, ArgVTs, ArgFlags, RegArgs, CC, NumBytes))
1260 return false;
Eric Christopherbb3e5da2010-09-14 23:03:37 +00001261
Eric Christopher7ed8ec92010-09-28 01:21:42 +00001262 // Issue the call, BLXr9 for darwin, BLX otherwise. This uses V5 ops.
1263 // TODO: Turn this into the table of arm call ops.
Eric Christopherbb3e5da2010-09-14 23:03:37 +00001264 MachineInstrBuilder MIB;
Eric Christopherc1095562010-09-18 02:32:38 +00001265 unsigned CallOpc;
1266 if(isThumb)
Eric Christopher7ed8ec92010-09-28 01:21:42 +00001267 CallOpc = Subtarget->isTargetDarwin() ? ARM::tBLXi_r9 : ARM::tBLXi;
Eric Christopherc1095562010-09-18 02:32:38 +00001268 else
1269 CallOpc = Subtarget->isTargetDarwin() ? ARM::BLr9 : ARM::BL;
Eric Christopherbb3e5da2010-09-14 23:03:37 +00001270 MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(CallOpc))
Eric Christopher7ed8ec92010-09-28 01:21:42 +00001271 .addExternalSymbol(TLI.getLibcallName(Call));
1272
Eric Christopherbb3e5da2010-09-14 23:03:37 +00001273 // Add implicit physical register uses to the call.
1274 for (unsigned i = 0, e = RegArgs.size(); i != e; ++i)
1275 MIB.addReg(RegArgs[i]);
1276
Eric Christophera9a7a1a2010-09-29 23:11:09 +00001277 // Finish off the call including any return values.
1278 SmallVector<unsigned, 4> UsedRegs;
1279 if (!FinishCall(RetVT, UsedRegs, I, CC, NumBytes)) return false;
Eric Christopherbb3e5da2010-09-14 23:03:37 +00001280
1281 // Set all unused physreg defs as dead.
1282 static_cast<MachineInstr *>(MIB)->setPhysRegsDeadExcept(UsedRegs, TRI);
Eric Christophera9a7a1a2010-09-29 23:11:09 +00001283
Eric Christopherbb3e5da2010-09-14 23:03:37 +00001284 return true;
1285}
1286
Eric Christopherf9764fa2010-09-30 20:49:44 +00001287bool ARMFastISel::SelectCall(const Instruction *I) {
1288 const CallInst *CI = cast<CallInst>(I);
1289 const Value *Callee = CI->getCalledValue();
1290
1291 // Can't handle inline asm or worry about intrinsics yet.
1292 if (isa<InlineAsm>(Callee) || isa<IntrinsicInst>(CI)) return false;
1293
1294 // Only handle global variable Callees
1295 const GlobalValue *GV = dyn_cast<GlobalValue>(Callee);
1296 if (!GV) return false;
1297
1298 // Check the calling convention.
1299 ImmutableCallSite CS(CI);
1300 CallingConv::ID CC = CS.getCallingConv();
1301 // TODO: Avoid some calling conventions?
1302 if (CC != CallingConv::C) {
1303 errs() << "Can't handle calling convention: " << CC << "\n";
1304 return false;
1305 }
1306
1307 // Let SDISel handle vararg functions.
1308 const PointerType *PT = cast<PointerType>(CS.getCalledValue()->getType());
1309 const FunctionType *FTy = cast<FunctionType>(PT->getElementType());
1310 if (FTy->isVarArg())
1311 return false;
1312
1313 // Handle *simple* calls for now.
1314 const Type *RetTy = I->getType();
1315 EVT RetVT;
1316 if (RetTy->isVoidTy())
1317 RetVT = MVT::isVoid;
1318 else if (!isTypeLegal(RetTy, RetVT))
1319 return false;
1320
1321 // For now we're using BLX etc on the assumption that we have v5t ops.
1322 // TODO: Maybe?
1323 if (!Subtarget->hasV5TOps()) return false;
1324
1325 // Set up the argument vectors.
1326 SmallVector<Value*, 8> Args;
1327 SmallVector<unsigned, 8> ArgRegs;
1328 SmallVector<EVT, 8> ArgVTs;
1329 SmallVector<ISD::ArgFlagsTy, 8> ArgFlags;
1330 Args.reserve(CS.arg_size());
1331 ArgRegs.reserve(CS.arg_size());
1332 ArgVTs.reserve(CS.arg_size());
1333 ArgFlags.reserve(CS.arg_size());
1334 for (ImmutableCallSite::arg_iterator i = CS.arg_begin(), e = CS.arg_end();
1335 i != e; ++i) {
1336 unsigned Arg = getRegForValue(*i);
1337
1338 if (Arg == 0)
1339 return false;
1340 ISD::ArgFlagsTy Flags;
1341 unsigned AttrInd = i - CS.arg_begin() + 1;
1342 if (CS.paramHasAttr(AttrInd, Attribute::SExt))
1343 Flags.setSExt();
1344 if (CS.paramHasAttr(AttrInd, Attribute::ZExt))
1345 Flags.setZExt();
1346
1347 // FIXME: Only handle *easy* calls for now.
1348 if (CS.paramHasAttr(AttrInd, Attribute::InReg) ||
1349 CS.paramHasAttr(AttrInd, Attribute::StructRet) ||
1350 CS.paramHasAttr(AttrInd, Attribute::Nest) ||
1351 CS.paramHasAttr(AttrInd, Attribute::ByVal))
1352 return false;
1353
1354 const Type *ArgTy = (*i)->getType();
1355 EVT ArgVT;
1356 if (!isTypeLegal(ArgTy, ArgVT))
1357 return false;
1358 unsigned OriginalAlignment = TD.getABITypeAlignment(ArgTy);
1359 Flags.setOrigAlign(OriginalAlignment);
1360
1361 Args.push_back(*i);
1362 ArgRegs.push_back(Arg);
1363 ArgVTs.push_back(ArgVT);
1364 ArgFlags.push_back(Flags);
1365 }
1366
1367 // Handle the arguments now that we've gotten them.
1368 SmallVector<unsigned, 4> RegArgs;
1369 unsigned NumBytes;
1370 if (!ProcessCallArgs(Args, ArgRegs, ArgVTs, ArgFlags, RegArgs, CC, NumBytes))
1371 return false;
1372
1373 // Issue the call, BLXr9 for darwin, BLX otherwise. This uses V5 ops.
1374 // TODO: Turn this into the table of arm call ops.
1375 MachineInstrBuilder MIB;
1376 unsigned CallOpc;
1377 if(isThumb)
1378 CallOpc = Subtarget->isTargetDarwin() ? ARM::tBLXi_r9 : ARM::tBLXi;
1379 else
1380 CallOpc = Subtarget->isTargetDarwin() ? ARM::BLr9 : ARM::BL;
1381 MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(CallOpc))
1382 .addGlobalAddress(GV, 0, 0);
1383
1384 // Add implicit physical register uses to the call.
1385 for (unsigned i = 0, e = RegArgs.size(); i != e; ++i)
1386 MIB.addReg(RegArgs[i]);
1387
1388 // Finish off the call including any return values.
1389 SmallVector<unsigned, 4> UsedRegs;
1390 if (!FinishCall(RetVT, UsedRegs, I, CC, NumBytes)) return false;
1391
1392 // Set all unused physreg defs as dead.
1393 static_cast<MachineInstr *>(MIB)->setPhysRegsDeadExcept(UsedRegs, TRI);
1394
1395 return true;
1396
1397}
1398
Eric Christopher56d2b722010-09-02 23:43:26 +00001399// TODO: SoftFP support.
Eric Christopherab695882010-07-21 22:26:11 +00001400bool ARMFastISel::TargetSelectInstruction(const Instruction *I) {
Eric Christopher7fe55b72010-08-23 22:32:45 +00001401 // No Thumb-1 for now.
Eric Christophereaa204b2010-09-02 01:39:14 +00001402 if (isThumb && !AFI->isThumb2Function()) return false;
Eric Christopherac1a19e2010-09-09 01:06:51 +00001403
Eric Christopherab695882010-07-21 22:26:11 +00001404 switch (I->getOpcode()) {
Eric Christopher83007122010-08-23 21:44:12 +00001405 case Instruction::Load:
Eric Christopher43b62be2010-09-27 06:02:23 +00001406 return SelectLoad(I);
Eric Christopher543cf052010-09-01 22:16:27 +00001407 case Instruction::Store:
Eric Christopher43b62be2010-09-27 06:02:23 +00001408 return SelectStore(I);
Eric Christophere5734102010-09-03 00:35:47 +00001409 case Instruction::Br:
Eric Christopher43b62be2010-09-27 06:02:23 +00001410 return SelectBranch(I);
Eric Christopherd43393a2010-09-08 23:13:45 +00001411 case Instruction::ICmp:
1412 case Instruction::FCmp:
Eric Christopher43b62be2010-09-27 06:02:23 +00001413 return SelectCmp(I);
Eric Christopher46203602010-09-09 00:26:48 +00001414 case Instruction::FPExt:
Eric Christopher43b62be2010-09-27 06:02:23 +00001415 return SelectFPExt(I);
Eric Christopherce07b542010-09-09 20:26:31 +00001416 case Instruction::FPTrunc:
Eric Christopher43b62be2010-09-27 06:02:23 +00001417 return SelectFPTrunc(I);
Eric Christopher9a040492010-09-09 18:54:59 +00001418 case Instruction::SIToFP:
Eric Christopher43b62be2010-09-27 06:02:23 +00001419 return SelectSIToFP(I);
Eric Christopher9a040492010-09-09 18:54:59 +00001420 case Instruction::FPToSI:
Eric Christopher43b62be2010-09-27 06:02:23 +00001421 return SelectFPToSI(I);
Eric Christopherbc39b822010-09-09 00:53:57 +00001422 case Instruction::FAdd:
Eric Christopher43b62be2010-09-27 06:02:23 +00001423 return SelectBinaryOp(I, ISD::FADD);
Eric Christopherbc39b822010-09-09 00:53:57 +00001424 case Instruction::FSub:
Eric Christopher43b62be2010-09-27 06:02:23 +00001425 return SelectBinaryOp(I, ISD::FSUB);
Eric Christopherbc39b822010-09-09 00:53:57 +00001426 case Instruction::FMul:
Eric Christopher43b62be2010-09-27 06:02:23 +00001427 return SelectBinaryOp(I, ISD::FMUL);
Eric Christopherbb3e5da2010-09-14 23:03:37 +00001428 case Instruction::SDiv:
Eric Christopher43b62be2010-09-27 06:02:23 +00001429 return SelectSDiv(I);
Eric Christopherf9764fa2010-09-30 20:49:44 +00001430 case Instruction::Call:
1431 return SelectCall(I);
Eric Christopherab695882010-07-21 22:26:11 +00001432 default: break;
1433 }
1434 return false;
1435}
1436
1437namespace llvm {
1438 llvm::FastISel *ARM::createFastISel(FunctionLoweringInfo &funcInfo) {
Eric Christopher038fea52010-08-17 00:46:57 +00001439 if (EnableARMFastISel) return new ARMFastISel(funcInfo);
Evan Cheng09447952010-07-26 18:32:55 +00001440 return 0;
Eric Christopherab695882010-07-21 22:26:11 +00001441 }
1442}