blob: 628e2cf696d8514ca97eaa47e35ad5c24bc1015a [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"
Eric Christopherc9932f62010-10-01 23:24:42 +000022#include "ARMConstantPoolValue.h"
Eric Christopherab695882010-07-21 22:26:11 +000023#include "llvm/CallingConv.h"
24#include "llvm/DerivedTypes.h"
25#include "llvm/GlobalVariable.h"
26#include "llvm/Instructions.h"
27#include "llvm/IntrinsicInst.h"
Eric Christopherbb3e5da2010-09-14 23:03:37 +000028#include "llvm/Module.h"
Eric Christopherab695882010-07-21 22:26:11 +000029#include "llvm/CodeGen/Analysis.h"
30#include "llvm/CodeGen/FastISel.h"
31#include "llvm/CodeGen/FunctionLoweringInfo.h"
Eric Christopher0fe7d542010-08-17 01:25:29 +000032#include "llvm/CodeGen/MachineInstrBuilder.h"
33#include "llvm/CodeGen/MachineModuleInfo.h"
Eric Christopherab695882010-07-21 22:26:11 +000034#include "llvm/CodeGen/MachineConstantPool.h"
35#include "llvm/CodeGen/MachineFrameInfo.h"
Eric Christopherd56d61a2010-10-17 01:51:42 +000036#include "llvm/CodeGen/MachineMemOperand.h"
Eric Christopherab695882010-07-21 22:26:11 +000037#include "llvm/CodeGen/MachineRegisterInfo.h"
Eric Christopherd56d61a2010-10-17 01:51:42 +000038#include "llvm/CodeGen/PseudoSourceValue.h"
Eric Christopherab695882010-07-21 22:26:11 +000039#include "llvm/Support/CallSite.h"
Eric Christopher038fea52010-08-17 00:46:57 +000040#include "llvm/Support/CommandLine.h"
Eric Christopherab695882010-07-21 22:26:11 +000041#include "llvm/Support/ErrorHandling.h"
42#include "llvm/Support/GetElementPtrTypeIterator.h"
Eric Christopher0fe7d542010-08-17 01:25:29 +000043#include "llvm/Target/TargetData.h"
44#include "llvm/Target/TargetInstrInfo.h"
45#include "llvm/Target/TargetLowering.h"
46#include "llvm/Target/TargetMachine.h"
Eric Christopherab695882010-07-21 22:26:11 +000047#include "llvm/Target/TargetOptions.h"
48using namespace llvm;
49
Eric Christopher038fea52010-08-17 00:46:57 +000050static cl::opt<bool>
Eric Christopher8ff9a9d2010-10-11 20:26:21 +000051EnableARMFastISel("arm-fast-isel",
52 cl::desc("Turn on experimental ARM fast-isel support"),
Eric Christopherfeadddd2010-10-11 20:05:22 +000053 cl::init(false), cl::Hidden);
Eric Christopher038fea52010-08-17 00:46:57 +000054
Eric Christopherab695882010-07-21 22:26:11 +000055namespace {
56
57class ARMFastISel : public FastISel {
58
59 /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can
60 /// make the right decision when generating code for different targets.
61 const ARMSubtarget *Subtarget;
Eric Christopher0fe7d542010-08-17 01:25:29 +000062 const TargetMachine &TM;
63 const TargetInstrInfo &TII;
64 const TargetLowering &TLI;
Eric Christopherc9932f62010-10-01 23:24:42 +000065 ARMFunctionInfo *AFI;
Eric Christopherab695882010-07-21 22:26:11 +000066
Eric Christopher8cf6c602010-09-29 22:24:45 +000067 // Convenience variables to avoid some queries.
Eric Christophereaa204b2010-09-02 01:39:14 +000068 bool isThumb;
Eric Christopher8cf6c602010-09-29 22:24:45 +000069 LLVMContext *Context;
Eric Christophereaa204b2010-09-02 01:39:14 +000070
Eric Christopherab695882010-07-21 22:26:11 +000071 public:
Eric Christopherac1a19e2010-09-09 01:06:51 +000072 explicit ARMFastISel(FunctionLoweringInfo &funcInfo)
Eric Christopher0fe7d542010-08-17 01:25:29 +000073 : FastISel(funcInfo),
74 TM(funcInfo.MF->getTarget()),
75 TII(*TM.getInstrInfo()),
76 TLI(*TM.getTargetLowering()) {
Eric Christopherab695882010-07-21 22:26:11 +000077 Subtarget = &TM.getSubtarget<ARMSubtarget>();
Eric Christopher7fe55b72010-08-23 22:32:45 +000078 AFI = funcInfo.MF->getInfo<ARMFunctionInfo>();
Eric Christophereaa204b2010-09-02 01:39:14 +000079 isThumb = AFI->isThumbFunction();
Eric Christopher8cf6c602010-09-29 22:24:45 +000080 Context = &funcInfo.Fn->getContext();
Eric Christopherab695882010-07-21 22:26:11 +000081 }
82
Eric Christophercb592292010-08-20 00:20:31 +000083 // Code from FastISel.cpp.
Eric Christopher0fe7d542010-08-17 01:25:29 +000084 virtual unsigned FastEmitInst_(unsigned MachineInstOpcode,
85 const TargetRegisterClass *RC);
86 virtual unsigned FastEmitInst_r(unsigned MachineInstOpcode,
87 const TargetRegisterClass *RC,
88 unsigned Op0, bool Op0IsKill);
89 virtual unsigned FastEmitInst_rr(unsigned MachineInstOpcode,
90 const TargetRegisterClass *RC,
91 unsigned Op0, bool Op0IsKill,
92 unsigned Op1, bool Op1IsKill);
93 virtual unsigned FastEmitInst_ri(unsigned MachineInstOpcode,
94 const TargetRegisterClass *RC,
95 unsigned Op0, bool Op0IsKill,
96 uint64_t Imm);
97 virtual unsigned FastEmitInst_rf(unsigned MachineInstOpcode,
98 const TargetRegisterClass *RC,
99 unsigned Op0, bool Op0IsKill,
100 const ConstantFP *FPImm);
101 virtual unsigned FastEmitInst_i(unsigned MachineInstOpcode,
102 const TargetRegisterClass *RC,
103 uint64_t Imm);
104 virtual unsigned FastEmitInst_rri(unsigned MachineInstOpcode,
105 const TargetRegisterClass *RC,
106 unsigned Op0, bool Op0IsKill,
107 unsigned Op1, bool Op1IsKill,
108 uint64_t Imm);
109 virtual unsigned FastEmitInst_extractsubreg(MVT RetVT,
110 unsigned Op0, bool Op0IsKill,
111 uint32_t Idx);
Eric Christopherac1a19e2010-09-09 01:06:51 +0000112
Eric Christophercb592292010-08-20 00:20:31 +0000113 // Backend specific FastISel code.
Eric Christopherab695882010-07-21 22:26:11 +0000114 virtual bool TargetSelectInstruction(const Instruction *I);
Eric Christopher1b61ef42010-09-02 01:48:11 +0000115 virtual unsigned TargetMaterializeConstant(const Constant *C);
Eric Christopherf9764fa2010-09-30 20:49:44 +0000116 virtual unsigned TargetMaterializeAlloca(const AllocaInst *AI);
Eric Christopherab695882010-07-21 22:26:11 +0000117
118 #include "ARMGenFastISel.inc"
Eric Christopherac1a19e2010-09-09 01:06:51 +0000119
Eric Christopher83007122010-08-23 21:44:12 +0000120 // Instruction selection routines.
Eric Christopher44bff902010-09-10 23:10:30 +0000121 private:
Eric Christopher43b62be2010-09-27 06:02:23 +0000122 virtual bool SelectLoad(const Instruction *I);
123 virtual bool SelectStore(const Instruction *I);
124 virtual bool SelectBranch(const Instruction *I);
125 virtual bool SelectCmp(const Instruction *I);
126 virtual bool SelectFPExt(const Instruction *I);
127 virtual bool SelectFPTrunc(const Instruction *I);
128 virtual bool SelectBinaryOp(const Instruction *I, unsigned ISDOpcode);
129 virtual bool SelectSIToFP(const Instruction *I);
130 virtual bool SelectFPToSI(const Instruction *I);
131 virtual bool SelectSDiv(const Instruction *I);
Eric Christopher6a880d62010-10-11 08:37:26 +0000132 virtual bool SelectSRem(const Instruction *I);
Eric Christopherf9764fa2010-09-30 20:49:44 +0000133 virtual bool SelectCall(const Instruction *I);
Eric Christopher3bbd3962010-10-11 08:27:59 +0000134 virtual bool SelectSelect(const Instruction *I);
Eric Christopherab695882010-07-21 22:26:11 +0000135
Eric Christopher83007122010-08-23 21:44:12 +0000136 // Utility routines.
Eric Christopher456144e2010-08-19 00:37:05 +0000137 private:
Eric Christopherb1cc8482010-08-25 07:23:49 +0000138 bool isTypeLegal(const Type *Ty, EVT &VT);
Eric Christopher4e68c7c2010-09-01 18:01:32 +0000139 bool isLoadTypeLegal(const Type *Ty, EVT &VT);
Eric Christopher404be0c2010-10-17 11:08:44 +0000140 bool ARMEmitLoad(EVT VT, unsigned &ResultReg, unsigned Base, int Offset);
141 bool ARMEmitStore(EVT VT, unsigned SrcReg, unsigned Base, int Offset);
142 bool ARMComputeRegOffset(const Value *Obj, unsigned &Base, int &Offset);
143 void ARMSimplifyRegOffset(unsigned &Base, int &Offset, EVT VT);
Eric Christopher9ed58df2010-09-09 00:19:41 +0000144 unsigned ARMMaterializeFP(const ConstantFP *CFP, EVT VT);
Eric Christopher744c7c82010-09-28 22:47:54 +0000145 unsigned ARMMaterializeInt(const Constant *C, EVT VT);
Eric Christopherc9932f62010-10-01 23:24:42 +0000146 unsigned ARMMaterializeGV(const GlobalValue *GV, EVT VT);
Eric Christopheraa3ace12010-09-09 20:49:25 +0000147 unsigned ARMMoveToFPReg(EVT VT, unsigned SrcReg);
Eric Christopher9ee4ce22010-09-09 21:44:45 +0000148 unsigned ARMMoveToIntReg(EVT VT, unsigned SrcReg);
Eric Christopherac1a19e2010-09-09 01:06:51 +0000149
Eric Christopherd10cd7b2010-09-10 23:18:12 +0000150 // Call handling routines.
151 private:
152 CCAssignFn *CCAssignFnForCall(CallingConv::ID CC, bool Return);
Eric Christopherdccd2c32010-10-11 08:38:55 +0000153 bool ProcessCallArgs(SmallVectorImpl<Value*> &Args,
Eric Christophera9a7a1a2010-09-29 23:11:09 +0000154 SmallVectorImpl<unsigned> &ArgRegs,
155 SmallVectorImpl<EVT> &ArgVTs,
156 SmallVectorImpl<ISD::ArgFlagsTy> &ArgFlags,
157 SmallVectorImpl<unsigned> &RegArgs,
158 CallingConv::ID CC,
159 unsigned &NumBytes);
160 bool FinishCall(EVT RetVT, SmallVectorImpl<unsigned> &UsedRegs,
161 const Instruction *I, CallingConv::ID CC,
162 unsigned &NumBytes);
Eric Christopher7ed8ec92010-09-28 01:21:42 +0000163 bool ARMEmitLibcall(const Instruction *I, RTLIB::Libcall Call);
Eric Christopherd10cd7b2010-09-10 23:18:12 +0000164
165 // OptionalDef handling routines.
166 private:
Eric Christopher456144e2010-08-19 00:37:05 +0000167 bool DefinesOptionalPredicate(MachineInstr *MI, bool *CPSR);
168 const MachineInstrBuilder &AddOptionalDefs(const MachineInstrBuilder &MIB);
169};
Eric Christopherab695882010-07-21 22:26:11 +0000170
171} // end anonymous namespace
172
Eric Christopherd10cd7b2010-09-10 23:18:12 +0000173#include "ARMGenCallingConv.inc"
Eric Christopherab695882010-07-21 22:26:11 +0000174
Eric Christopher456144e2010-08-19 00:37:05 +0000175// DefinesOptionalPredicate - This is different from DefinesPredicate in that
176// we don't care about implicit defs here, just places we'll need to add a
177// default CCReg argument. Sets CPSR if we're setting CPSR instead of CCR.
178bool ARMFastISel::DefinesOptionalPredicate(MachineInstr *MI, bool *CPSR) {
179 const TargetInstrDesc &TID = MI->getDesc();
180 if (!TID.hasOptionalDef())
181 return false;
182
183 // Look to see if our OptionalDef is defining CPSR or CCR.
184 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
185 const MachineOperand &MO = MI->getOperand(i);
Eric Christopherf762fbe2010-08-20 00:36:24 +0000186 if (!MO.isReg() || !MO.isDef()) continue;
187 if (MO.getReg() == ARM::CPSR)
Eric Christopher456144e2010-08-19 00:37:05 +0000188 *CPSR = true;
189 }
190 return true;
191}
192
193// If the machine is predicable go ahead and add the predicate operands, if
194// it needs default CC operands add those.
195const MachineInstrBuilder &
196ARMFastISel::AddOptionalDefs(const MachineInstrBuilder &MIB) {
197 MachineInstr *MI = &*MIB;
198
199 // Do we use a predicate?
200 if (TII.isPredicable(MI))
201 AddDefaultPred(MIB);
Eric Christopherac1a19e2010-09-09 01:06:51 +0000202
Eric Christopher456144e2010-08-19 00:37:05 +0000203 // Do we optionally set a predicate? Preds is size > 0 iff the predicate
204 // defines CPSR. All other OptionalDefines in ARM are the CCR register.
Eric Christopher979e0a12010-08-19 15:35:27 +0000205 bool CPSR = false;
Eric Christopher456144e2010-08-19 00:37:05 +0000206 if (DefinesOptionalPredicate(MI, &CPSR)) {
207 if (CPSR)
208 AddDefaultT1CC(MIB);
209 else
210 AddDefaultCC(MIB);
211 }
212 return MIB;
213}
214
Eric Christopher0fe7d542010-08-17 01:25:29 +0000215unsigned ARMFastISel::FastEmitInst_(unsigned MachineInstOpcode,
216 const TargetRegisterClass* RC) {
217 unsigned ResultReg = createResultReg(RC);
218 const TargetInstrDesc &II = TII.get(MachineInstOpcode);
219
Eric Christopher456144e2010-08-19 00:37:05 +0000220 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg));
Eric Christopher0fe7d542010-08-17 01:25:29 +0000221 return ResultReg;
222}
223
224unsigned ARMFastISel::FastEmitInst_r(unsigned MachineInstOpcode,
225 const TargetRegisterClass *RC,
226 unsigned Op0, bool Op0IsKill) {
227 unsigned ResultReg = createResultReg(RC);
228 const TargetInstrDesc &II = TII.get(MachineInstOpcode);
229
230 if (II.getNumDefs() >= 1)
Eric Christopher456144e2010-08-19 00:37:05 +0000231 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
Eric Christopher0fe7d542010-08-17 01:25:29 +0000232 .addReg(Op0, Op0IsKill * RegState::Kill));
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));
Eric Christopher456144e2010-08-19 00:37:05 +0000236 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
Eric Christopher0fe7d542010-08-17 01:25:29 +0000237 TII.get(TargetOpcode::COPY), ResultReg)
238 .addReg(II.ImplicitDefs[0]));
239 }
240 return ResultReg;
241}
242
243unsigned ARMFastISel::FastEmitInst_rr(unsigned MachineInstOpcode,
244 const TargetRegisterClass *RC,
245 unsigned Op0, bool Op0IsKill,
246 unsigned Op1, bool Op1IsKill) {
247 unsigned ResultReg = createResultReg(RC);
248 const TargetInstrDesc &II = TII.get(MachineInstOpcode);
249
250 if (II.getNumDefs() >= 1)
Eric Christopher456144e2010-08-19 00:37:05 +0000251 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
Eric Christopher0fe7d542010-08-17 01:25:29 +0000252 .addReg(Op0, Op0IsKill * RegState::Kill)
253 .addReg(Op1, Op1IsKill * RegState::Kill));
254 else {
Eric Christopher456144e2010-08-19 00:37:05 +0000255 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
Eric Christopher0fe7d542010-08-17 01:25:29 +0000256 .addReg(Op0, Op0IsKill * RegState::Kill)
257 .addReg(Op1, Op1IsKill * RegState::Kill));
Eric Christopher456144e2010-08-19 00:37:05 +0000258 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
Eric Christopher0fe7d542010-08-17 01:25:29 +0000259 TII.get(TargetOpcode::COPY), ResultReg)
260 .addReg(II.ImplicitDefs[0]));
261 }
262 return ResultReg;
263}
264
265unsigned ARMFastISel::FastEmitInst_ri(unsigned MachineInstOpcode,
266 const TargetRegisterClass *RC,
267 unsigned Op0, bool Op0IsKill,
268 uint64_t Imm) {
269 unsigned ResultReg = createResultReg(RC);
270 const TargetInstrDesc &II = TII.get(MachineInstOpcode);
271
272 if (II.getNumDefs() >= 1)
Eric Christopher456144e2010-08-19 00:37:05 +0000273 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
Eric Christopher0fe7d542010-08-17 01:25:29 +0000274 .addReg(Op0, Op0IsKill * RegState::Kill)
275 .addImm(Imm));
276 else {
Eric Christopher456144e2010-08-19 00:37:05 +0000277 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
Eric Christopher0fe7d542010-08-17 01:25:29 +0000278 .addReg(Op0, Op0IsKill * RegState::Kill)
279 .addImm(Imm));
Eric Christopher456144e2010-08-19 00:37:05 +0000280 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
Eric Christopher0fe7d542010-08-17 01:25:29 +0000281 TII.get(TargetOpcode::COPY), ResultReg)
282 .addReg(II.ImplicitDefs[0]));
283 }
284 return ResultReg;
285}
286
287unsigned ARMFastISel::FastEmitInst_rf(unsigned MachineInstOpcode,
288 const TargetRegisterClass *RC,
289 unsigned Op0, bool Op0IsKill,
290 const ConstantFP *FPImm) {
291 unsigned ResultReg = createResultReg(RC);
292 const TargetInstrDesc &II = TII.get(MachineInstOpcode);
293
294 if (II.getNumDefs() >= 1)
Eric Christopher456144e2010-08-19 00:37:05 +0000295 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
Eric Christopher0fe7d542010-08-17 01:25:29 +0000296 .addReg(Op0, Op0IsKill * RegState::Kill)
297 .addFPImm(FPImm));
298 else {
Eric Christopher456144e2010-08-19 00:37:05 +0000299 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
Eric Christopher0fe7d542010-08-17 01:25:29 +0000300 .addReg(Op0, Op0IsKill * RegState::Kill)
301 .addFPImm(FPImm));
Eric Christopher456144e2010-08-19 00:37:05 +0000302 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
Eric Christopher0fe7d542010-08-17 01:25:29 +0000303 TII.get(TargetOpcode::COPY), ResultReg)
304 .addReg(II.ImplicitDefs[0]));
305 }
306 return ResultReg;
307}
308
309unsigned ARMFastISel::FastEmitInst_rri(unsigned MachineInstOpcode,
310 const TargetRegisterClass *RC,
311 unsigned Op0, bool Op0IsKill,
312 unsigned Op1, bool Op1IsKill,
313 uint64_t Imm) {
314 unsigned ResultReg = createResultReg(RC);
315 const TargetInstrDesc &II = TII.get(MachineInstOpcode);
316
317 if (II.getNumDefs() >= 1)
Eric Christopher456144e2010-08-19 00:37:05 +0000318 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
Eric Christopher0fe7d542010-08-17 01:25:29 +0000319 .addReg(Op0, Op0IsKill * RegState::Kill)
320 .addReg(Op1, Op1IsKill * RegState::Kill)
321 .addImm(Imm));
322 else {
Eric Christopher456144e2010-08-19 00:37:05 +0000323 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
Eric Christopher0fe7d542010-08-17 01:25:29 +0000324 .addReg(Op0, Op0IsKill * RegState::Kill)
325 .addReg(Op1, Op1IsKill * RegState::Kill)
326 .addImm(Imm));
Eric Christopher456144e2010-08-19 00:37:05 +0000327 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
Eric Christopher0fe7d542010-08-17 01:25:29 +0000328 TII.get(TargetOpcode::COPY), ResultReg)
329 .addReg(II.ImplicitDefs[0]));
330 }
331 return ResultReg;
332}
333
334unsigned ARMFastISel::FastEmitInst_i(unsigned MachineInstOpcode,
335 const TargetRegisterClass *RC,
336 uint64_t Imm) {
337 unsigned ResultReg = createResultReg(RC);
338 const TargetInstrDesc &II = TII.get(MachineInstOpcode);
Eric Christopherac1a19e2010-09-09 01:06:51 +0000339
Eric Christopher0fe7d542010-08-17 01:25:29 +0000340 if (II.getNumDefs() >= 1)
Eric Christopher456144e2010-08-19 00:37:05 +0000341 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
Eric Christopher0fe7d542010-08-17 01:25:29 +0000342 .addImm(Imm));
343 else {
Eric Christopher456144e2010-08-19 00:37:05 +0000344 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
Eric Christopher0fe7d542010-08-17 01:25:29 +0000345 .addImm(Imm));
Eric Christopher456144e2010-08-19 00:37:05 +0000346 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
Eric Christopher0fe7d542010-08-17 01:25:29 +0000347 TII.get(TargetOpcode::COPY), ResultReg)
348 .addReg(II.ImplicitDefs[0]));
349 }
350 return ResultReg;
351}
352
353unsigned ARMFastISel::FastEmitInst_extractsubreg(MVT RetVT,
354 unsigned Op0, bool Op0IsKill,
355 uint32_t Idx) {
356 unsigned ResultReg = createResultReg(TLI.getRegClassFor(RetVT));
357 assert(TargetRegisterInfo::isVirtualRegister(Op0) &&
358 "Cannot yet extract from physregs");
Eric Christopher456144e2010-08-19 00:37:05 +0000359 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt,
Eric Christopher0fe7d542010-08-17 01:25:29 +0000360 DL, TII.get(TargetOpcode::COPY), ResultReg)
361 .addReg(Op0, getKillRegState(Op0IsKill), Idx));
362 return ResultReg;
363}
364
Eric Christopherdb12b2b2010-09-10 00:34:35 +0000365// TODO: Don't worry about 64-bit now, but when this is fixed remove the
366// checks from the various callers.
Eric Christopheraa3ace12010-09-09 20:49:25 +0000367unsigned ARMFastISel::ARMMoveToFPReg(EVT VT, unsigned SrcReg) {
Eric Christopher9ee4ce22010-09-09 21:44:45 +0000368 if (VT.getSimpleVT().SimpleTy == MVT::f64) return 0;
Eric Christopherdccd2c32010-10-11 08:38:55 +0000369
Eric Christopher9ee4ce22010-09-09 21:44:45 +0000370 unsigned MoveReg = createResultReg(TLI.getRegClassFor(VT));
371 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
372 TII.get(ARM::VMOVRS), MoveReg)
373 .addReg(SrcReg));
374 return MoveReg;
375}
376
377unsigned ARMFastISel::ARMMoveToIntReg(EVT VT, unsigned SrcReg) {
Eric Christopher9ee4ce22010-09-09 21:44:45 +0000378 if (VT.getSimpleVT().SimpleTy == MVT::i64) return 0;
Eric Christopherdccd2c32010-10-11 08:38:55 +0000379
Eric Christopheraa3ace12010-09-09 20:49:25 +0000380 unsigned MoveReg = createResultReg(TLI.getRegClassFor(VT));
381 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
Eric Christopher9ee4ce22010-09-09 21:44:45 +0000382 TII.get(ARM::VMOVSR), MoveReg)
Eric Christopheraa3ace12010-09-09 20:49:25 +0000383 .addReg(SrcReg));
384 return MoveReg;
385}
386
Eric Christopher9ed58df2010-09-09 00:19:41 +0000387// For double width floating point we need to materialize two constants
388// (the high and the low) into integer registers then use a move to get
389// the combined constant into an FP reg.
390unsigned ARMFastISel::ARMMaterializeFP(const ConstantFP *CFP, EVT VT) {
391 const APFloat Val = CFP->getValueAPF();
392 bool is64bit = VT.getSimpleVT().SimpleTy == MVT::f64;
Eric Christopherac1a19e2010-09-09 01:06:51 +0000393
Eric Christopher9ed58df2010-09-09 00:19:41 +0000394 // This checks to see if we can use VFP3 instructions to materialize
395 // a constant, otherwise we have to go through the constant pool.
396 if (TLI.isFPImmLegal(Val, VT)) {
397 unsigned Opc = is64bit ? ARM::FCONSTD : ARM::FCONSTS;
398 unsigned DestReg = createResultReg(TLI.getRegClassFor(VT));
399 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc),
400 DestReg)
401 .addFPImm(CFP));
402 return DestReg;
403 }
Eric Christopherdccd2c32010-10-11 08:38:55 +0000404
Eric Christopherdb12b2b2010-09-10 00:34:35 +0000405 // Require VFP2 for loading fp constants.
Eric Christopher238bb162010-09-09 23:50:00 +0000406 if (!Subtarget->hasVFP2()) return false;
Eric Christopherdccd2c32010-10-11 08:38:55 +0000407
Eric Christopher238bb162010-09-09 23:50:00 +0000408 // MachineConstantPool wants an explicit alignment.
409 unsigned Align = TD.getPrefTypeAlignment(CFP->getType());
410 if (Align == 0) {
411 // TODO: Figure out if this is correct.
412 Align = TD.getTypeAllocSize(CFP->getType());
413 }
414 unsigned Idx = MCP.getConstantPoolIndex(cast<Constant>(CFP), Align);
415 unsigned DestReg = createResultReg(TLI.getRegClassFor(VT));
416 unsigned Opc = is64bit ? ARM::VLDRD : ARM::VLDRS;
Eric Christopherdccd2c32010-10-11 08:38:55 +0000417
Eric Christopherdb12b2b2010-09-10 00:34:35 +0000418 // The extra reg is for addrmode5.
Eric Christopherf5732c42010-09-28 00:35:09 +0000419 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc),
420 DestReg)
421 .addConstantPoolIndex(Idx)
Eric Christopher238bb162010-09-09 23:50:00 +0000422 .addReg(0));
423 return DestReg;
Eric Christopher9ed58df2010-09-09 00:19:41 +0000424}
425
Eric Christopher744c7c82010-09-28 22:47:54 +0000426unsigned ARMFastISel::ARMMaterializeInt(const Constant *C, EVT VT) {
Eric Christopherdccd2c32010-10-11 08:38:55 +0000427
Eric Christopher744c7c82010-09-28 22:47:54 +0000428 // For now 32-bit only.
429 if (VT.getSimpleVT().SimpleTy != MVT::i32) return false;
Eric Christopherdccd2c32010-10-11 08:38:55 +0000430
Eric Christopher56d2b722010-09-02 23:43:26 +0000431 // MachineConstantPool wants an explicit alignment.
432 unsigned Align = TD.getPrefTypeAlignment(C->getType());
433 if (Align == 0) {
434 // TODO: Figure out if this is correct.
435 Align = TD.getTypeAllocSize(C->getType());
436 }
437 unsigned Idx = MCP.getConstantPoolIndex(C, Align);
Eric Christopher744c7c82010-09-28 22:47:54 +0000438 unsigned DestReg = createResultReg(TLI.getRegClassFor(VT));
Eric Christopherdccd2c32010-10-11 08:38:55 +0000439
Eric Christopher56d2b722010-09-02 23:43:26 +0000440 if (isThumb)
441 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
Eric Christopherfd609802010-09-28 21:55:34 +0000442 TII.get(ARM::t2LDRpci), DestReg)
443 .addConstantPoolIndex(Idx));
Eric Christopher56d2b722010-09-02 23:43:26 +0000444 else
Eric Christopherdb12b2b2010-09-10 00:34:35 +0000445 // The extra reg and immediate are for addrmode2.
Eric Christopher56d2b722010-09-02 23:43:26 +0000446 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
Eric Christopherfd609802010-09-28 21:55:34 +0000447 TII.get(ARM::LDRcp), DestReg)
448 .addConstantPoolIndex(Idx)
Eric Christopher56d2b722010-09-02 23:43:26 +0000449 .addReg(0).addImm(0));
Eric Christopherac1a19e2010-09-09 01:06:51 +0000450
Eric Christopher56d2b722010-09-02 23:43:26 +0000451 return DestReg;
Eric Christopher1b61ef42010-09-02 01:48:11 +0000452}
453
Eric Christopherc9932f62010-10-01 23:24:42 +0000454unsigned ARMFastISel::ARMMaterializeGV(const GlobalValue *GV, EVT VT) {
Eric Christopher890dbbe2010-10-02 00:32:44 +0000455 // For now 32-bit only.
456 if (VT.getSimpleVT().SimpleTy != MVT::i32) return 0;
Eric Christopherdccd2c32010-10-11 08:38:55 +0000457
Eric Christopher890dbbe2010-10-02 00:32:44 +0000458 Reloc::Model RelocM = TM.getRelocationModel();
Eric Christopherdccd2c32010-10-11 08:38:55 +0000459
Eric Christopher890dbbe2010-10-02 00:32:44 +0000460 // TODO: No external globals for now.
461 if (Subtarget->GVIsIndirectSymbol(GV, RelocM)) return 0;
Eric Christopherdccd2c32010-10-11 08:38:55 +0000462
Eric Christopher890dbbe2010-10-02 00:32:44 +0000463 // TODO: Need more magic for ARM PIC.
464 if (!isThumb && (RelocM == Reloc::PIC_)) return 0;
Eric Christopherdccd2c32010-10-11 08:38:55 +0000465
Eric Christopher890dbbe2010-10-02 00:32:44 +0000466 // MachineConstantPool wants an explicit alignment.
467 unsigned Align = TD.getPrefTypeAlignment(GV->getType());
468 if (Align == 0) {
469 // TODO: Figure out if this is correct.
470 Align = TD.getTypeAllocSize(GV->getType());
471 }
Eric Christopherdccd2c32010-10-11 08:38:55 +0000472
Eric Christopher890dbbe2010-10-02 00:32:44 +0000473 // Grab index.
474 unsigned PCAdj = (RelocM != Reloc::PIC_) ? 0 : (Subtarget->isThumb() ? 4 : 8);
475 unsigned Id = AFI->createConstPoolEntryUId();
476 ARMConstantPoolValue *CPV = new ARMConstantPoolValue(GV, Id,
477 ARMCP::CPValue, PCAdj);
478 unsigned Idx = MCP.getConstantPoolIndex(CPV, Align);
Eric Christopherdccd2c32010-10-11 08:38:55 +0000479
Eric Christopher890dbbe2010-10-02 00:32:44 +0000480 // Load value.
481 MachineInstrBuilder MIB;
482 unsigned DestReg = createResultReg(TLI.getRegClassFor(VT));
483 if (isThumb) {
484 unsigned Opc = (RelocM != Reloc::PIC_) ? ARM::t2LDRpci : ARM::t2LDRpci_pic;
485 MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc), DestReg)
486 .addConstantPoolIndex(Idx);
487 if (RelocM == Reloc::PIC_)
488 MIB.addImm(Id);
489 } else {
490 // The extra reg and immediate are for addrmode2.
491 MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(ARM::LDRcp),
492 DestReg)
493 .addConstantPoolIndex(Idx)
494 .addReg(0).addImm(0);
495 }
496 AddOptionalDefs(MIB);
497 return DestReg;
Eric Christopherc9932f62010-10-01 23:24:42 +0000498}
499
Eric Christopher9ed58df2010-09-09 00:19:41 +0000500unsigned ARMFastISel::TargetMaterializeConstant(const Constant *C) {
501 EVT VT = TLI.getValueType(C->getType(), true);
502
503 // Only handle simple types.
504 if (!VT.isSimple()) return 0;
505
506 if (const ConstantFP *CFP = dyn_cast<ConstantFP>(C))
507 return ARMMaterializeFP(CFP, VT);
Eric Christopherc9932f62010-10-01 23:24:42 +0000508 else if (const GlobalValue *GV = dyn_cast<GlobalValue>(C))
509 return ARMMaterializeGV(GV, VT);
510 else if (isa<ConstantInt>(C))
511 return ARMMaterializeInt(C, VT);
Eric Christopherdccd2c32010-10-11 08:38:55 +0000512
Eric Christopherc9932f62010-10-01 23:24:42 +0000513 return 0;
Eric Christopher9ed58df2010-09-09 00:19:41 +0000514}
515
Eric Christopherf9764fa2010-09-30 20:49:44 +0000516unsigned ARMFastISel::TargetMaterializeAlloca(const AllocaInst *AI) {
517 // Don't handle dynamic allocas.
518 if (!FuncInfo.StaticAllocaMap.count(AI)) return 0;
Eric Christopherdccd2c32010-10-11 08:38:55 +0000519
Eric Christopherf9764fa2010-09-30 20:49:44 +0000520 EVT VT;
Eric Christopherec8bf972010-10-17 06:07:26 +0000521 if (!isLoadTypeLegal(AI->getType(), VT)) return false;
Eric Christopherdccd2c32010-10-11 08:38:55 +0000522
Eric Christopherf9764fa2010-09-30 20:49:44 +0000523 DenseMap<const AllocaInst*, int>::iterator SI =
524 FuncInfo.StaticAllocaMap.find(AI);
525
526 // This will get lowered later into the correct offsets and registers
527 // via rewriteXFrameIndex.
528 if (SI != FuncInfo.StaticAllocaMap.end()) {
529 TargetRegisterClass* RC = TLI.getRegClassFor(VT);
530 unsigned ResultReg = createResultReg(RC);
531 unsigned Opc = isThumb ? ARM::t2ADDri : ARM::ADDri;
532 AddOptionalDefs(BuildMI(*FuncInfo.MBB, *FuncInfo.InsertPt, DL,
533 TII.get(Opc), ResultReg)
534 .addFrameIndex(SI->second)
535 .addImm(0));
536 return ResultReg;
537 }
Eric Christopherdccd2c32010-10-11 08:38:55 +0000538
Eric Christopherf9764fa2010-09-30 20:49:44 +0000539 return 0;
540}
541
Eric Christopherb1cc8482010-08-25 07:23:49 +0000542bool ARMFastISel::isTypeLegal(const Type *Ty, EVT &VT) {
543 VT = TLI.getValueType(Ty, true);
Eric Christopherac1a19e2010-09-09 01:06:51 +0000544
Eric Christopherb1cc8482010-08-25 07:23:49 +0000545 // Only handle simple types.
546 if (VT == MVT::Other || !VT.isSimple()) return false;
Eric Christopherac1a19e2010-09-09 01:06:51 +0000547
Eric Christopherdc908042010-08-31 01:28:42 +0000548 // Handle all legal types, i.e. a register that will directly hold this
549 // value.
550 return TLI.isTypeLegal(VT);
Eric Christopherb1cc8482010-08-25 07:23:49 +0000551}
552
Eric Christopher4e68c7c2010-09-01 18:01:32 +0000553bool ARMFastISel::isLoadTypeLegal(const Type *Ty, EVT &VT) {
554 if (isTypeLegal(Ty, VT)) return true;
Eric Christopherac1a19e2010-09-09 01:06:51 +0000555
Eric Christopher4e68c7c2010-09-01 18:01:32 +0000556 // If this is a type than can be sign or zero-extended to a basic operation
557 // go ahead and accept it now.
558 if (VT == MVT::i8 || VT == MVT::i16)
559 return true;
Eric Christopherac1a19e2010-09-09 01:06:51 +0000560
Eric Christopher4e68c7c2010-09-01 18:01:32 +0000561 return false;
562}
563
Eric Christophercb0b04b2010-08-24 00:07:24 +0000564// Computes the Reg+Offset to get to an object.
Eric Christopher404be0c2010-10-17 11:08:44 +0000565bool ARMFastISel::ARMComputeRegOffset(const Value *Obj, unsigned &Base,
Eric Christopher83007122010-08-23 21:44:12 +0000566 int &Offset) {
567 // Some boilerplate from the X86 FastISel.
568 const User *U = NULL;
Eric Christopher83007122010-08-23 21:44:12 +0000569 unsigned Opcode = Instruction::UserOp1;
Eric Christophercb0b04b2010-08-24 00:07:24 +0000570 if (const Instruction *I = dyn_cast<Instruction>(Obj)) {
Eric Christopher83007122010-08-23 21:44:12 +0000571 // Don't walk into other basic blocks; it's possible we haven't
572 // visited them yet, so the instructions may not yet be assigned
573 // virtual registers.
574 if (FuncInfo.MBBMap[I->getParent()] != FuncInfo.MBB)
575 return false;
Eric Christopher83007122010-08-23 21:44:12 +0000576 Opcode = I->getOpcode();
577 U = I;
Eric Christophercb0b04b2010-08-24 00:07:24 +0000578 } else if (const ConstantExpr *C = dyn_cast<ConstantExpr>(Obj)) {
Eric Christopher83007122010-08-23 21:44:12 +0000579 Opcode = C->getOpcode();
580 U = C;
581 }
582
Eric Christophercb0b04b2010-08-24 00:07:24 +0000583 if (const PointerType *Ty = dyn_cast<PointerType>(Obj->getType()))
Eric Christopher83007122010-08-23 21:44:12 +0000584 if (Ty->getAddressSpace() > 255)
585 // Fast instruction selection doesn't support the special
586 // address spaces.
587 return false;
Eric Christopherac1a19e2010-09-09 01:06:51 +0000588
Eric Christopher83007122010-08-23 21:44:12 +0000589 switch (Opcode) {
Eric Christopherac1a19e2010-09-09 01:06:51 +0000590 default:
Eric Christopher83007122010-08-23 21:44:12 +0000591 break;
Eric Christopher55324332010-10-12 00:43:21 +0000592 case Instruction::BitCast: {
593 // Look through bitcasts.
Eric Christophera3224252010-10-15 21:32:12 +0000594 return ARMComputeRegOffset(U->getOperand(0), Base, Offset);
Eric Christopher55324332010-10-12 00:43:21 +0000595 }
596 case Instruction::IntToPtr: {
597 // Look past no-op inttoptrs.
598 if (TLI.getValueType(U->getOperand(0)->getType()) == TLI.getPointerTy())
Eric Christophera3224252010-10-15 21:32:12 +0000599 return ARMComputeRegOffset(U->getOperand(0), Base, Offset);
Eric Christopher55324332010-10-12 00:43:21 +0000600 break;
601 }
602 case Instruction::PtrToInt: {
603 // Look past no-op ptrtoints.
604 if (TLI.getValueType(U->getType()) == TLI.getPointerTy())
Eric Christophera3224252010-10-15 21:32:12 +0000605 return ARMComputeRegOffset(U->getOperand(0), Base, Offset);
Eric Christopher55324332010-10-12 00:43:21 +0000606 break;
607 }
Eric Christophereae84392010-10-14 09:29:41 +0000608 case Instruction::GetElementPtr: {
609 int SavedOffset = Offset;
Eric Christopher404be0c2010-10-17 11:08:44 +0000610 unsigned SavedBase = Base;
Eric Christophereae84392010-10-14 09:29:41 +0000611 int TmpOffset = Offset;
Eric Christopher2896df82010-10-15 18:02:07 +0000612
Eric Christophereae84392010-10-14 09:29:41 +0000613 // Iterate through the GEP folding the constants into offsets where
614 // we can.
615 gep_type_iterator GTI = gep_type_begin(U);
616 for (User::const_op_iterator i = U->op_begin() + 1, e = U->op_end();
617 i != e; ++i, ++GTI) {
618 const Value *Op = *i;
619 if (const StructType *STy = dyn_cast<StructType>(*GTI)) {
620 const StructLayout *SL = TD.getStructLayout(STy);
621 unsigned Idx = cast<ConstantInt>(Op)->getZExtValue();
622 TmpOffset += SL->getElementOffset(Idx);
623 } else {
Eric Christopher2896df82010-10-15 18:02:07 +0000624 uint64_t S = TD.getTypeAllocSize(GTI.getIndexedType());
625 SmallVector<const Value *, 4> Worklist;
626 Worklist.push_back(Op);
627 do {
628 Op = Worklist.pop_back_val();
629 if (const ConstantInt *CI = dyn_cast<ConstantInt>(Op)) {
630 // Constant-offset addressing.
631 TmpOffset += CI->getSExtValue() * S;
Eric Christopherdc0b0ef2010-10-17 01:41:46 +0000632 } else if (isa<AddOperator>(Op) &&
Eric Christopher2896df82010-10-15 18:02:07 +0000633 isa<ConstantInt>(cast<AddOperator>(Op)->getOperand(1))) {
634 // An add with a constant operand. Fold the constant.
635 ConstantInt *CI =
636 cast<ConstantInt>(cast<AddOperator>(Op)->getOperand(1));
637 TmpOffset += CI->getSExtValue() * S;
638 // Add the other operand back to the work list.
639 Worklist.push_back(cast<AddOperator>(Op)->getOperand(0));
640 } else
641 goto unsupported_gep;
642 } while (!Worklist.empty());
Eric Christophereae84392010-10-14 09:29:41 +0000643 }
644 }
Eric Christopher2896df82010-10-15 18:02:07 +0000645
646 // Try to grab the base operand now.
Eric Christophereae84392010-10-14 09:29:41 +0000647 Offset = TmpOffset;
Eric Christophera3224252010-10-15 21:32:12 +0000648 if (ARMComputeRegOffset(U->getOperand(0), Base, Offset)) return true;
Eric Christopher2896df82010-10-15 18:02:07 +0000649
650 // We failed, restore everything and try the other options.
Eric Christophereae84392010-10-14 09:29:41 +0000651 Offset = SavedOffset;
Eric Christophera3224252010-10-15 21:32:12 +0000652 Base = SavedBase;
Eric Christopher2896df82010-10-15 18:02:07 +0000653
Eric Christophereae84392010-10-14 09:29:41 +0000654 unsupported_gep:
Eric Christophereae84392010-10-14 09:29:41 +0000655 break;
656 }
Eric Christopher83007122010-08-23 21:44:12 +0000657 case Instruction::Alloca: {
Eric Christopher15418772010-10-12 05:39:06 +0000658 const AllocaInst *AI = cast<AllocaInst>(Obj);
Eric Christopherd56d61a2010-10-17 01:51:42 +0000659 unsigned Reg = TargetMaterializeAlloca(AI);
660
661 if (Reg == 0) return false;
662
Eric Christopher404be0c2010-10-17 11:08:44 +0000663 Base = Reg;
Eric Christopherd56d61a2010-10-17 01:51:42 +0000664 return true;
Eric Christopher83007122010-08-23 21:44:12 +0000665 }
666 }
Eric Christopherac1a19e2010-09-09 01:06:51 +0000667
Eric Christophera9c57512010-10-13 21:41:51 +0000668 // Materialize the global variable's address into a reg which can
669 // then be used later to load the variable.
Eric Christophercb0b04b2010-08-24 00:07:24 +0000670 if (const GlobalValue *GV = dyn_cast<GlobalValue>(Obj)) {
Eric Christopherede42b02010-10-13 09:11:46 +0000671 unsigned Tmp = ARMMaterializeGV(GV, TLI.getValueType(Obj->getType()));
672 if (Tmp == 0) return false;
Eric Christopher2896df82010-10-15 18:02:07 +0000673
Eric Christopher404be0c2010-10-17 11:08:44 +0000674 Base = Tmp;
Eric Christopherede42b02010-10-13 09:11:46 +0000675 return true;
Eric Christophercb0b04b2010-08-24 00:07:24 +0000676 }
Eric Christopherac1a19e2010-09-09 01:06:51 +0000677
Eric Christophercb0b04b2010-08-24 00:07:24 +0000678 // Try to get this in a register if nothing else has worked.
Eric Christopher404be0c2010-10-17 11:08:44 +0000679 if (Base == 0) Base = getRegForValue(Obj);
680 return Base != 0;
Eric Christophereae84392010-10-14 09:29:41 +0000681}
682
Eric Christopher404be0c2010-10-17 11:08:44 +0000683void ARMFastISel::ARMSimplifyRegOffset(unsigned &Base, int &Offset, EVT VT) {
Eric Christopher318b6ee2010-09-02 00:53:56 +0000684
Eric Christopher404be0c2010-10-17 11:08:44 +0000685 assert (Base != ARM::SP && "How'd we get a stack pointer here?");
686
Eric Christopher318b6ee2010-09-02 00:53:56 +0000687 // Since the offset may be too large for the load instruction
688 // get the reg+offset into a register.
Eric Christopher404be0c2010-10-17 11:08:44 +0000689 if (Offset != 0) {
Eric Christopher318b6ee2010-09-02 00:53:56 +0000690 ARMCC::CondCodes Pred = ARMCC::AL;
691 unsigned PredReg = 0;
692
Eric Christopher2896df82010-10-15 18:02:07 +0000693 TargetRegisterClass *RC = isThumb ? ARM::tGPRRegisterClass :
694 ARM::GPRRegisterClass;
695 unsigned BaseReg = createResultReg(RC);
696
Eric Christophereaa204b2010-09-02 01:39:14 +0000697 if (!isThumb)
Eric Christopher318b6ee2010-09-02 00:53:56 +0000698 emitARMRegPlusImmediate(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
Eric Christopher404be0c2010-10-17 11:08:44 +0000699 BaseReg, Base, Offset, Pred, PredReg,
Eric Christopher318b6ee2010-09-02 00:53:56 +0000700 static_cast<const ARMBaseInstrInfo&>(TII));
701 else {
702 assert(AFI->isThumb2Function());
703 emitT2RegPlusImmediate(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
Eric Christopher404be0c2010-10-17 11:08:44 +0000704 BaseReg, Base, Offset, Pred, PredReg,
Eric Christopher318b6ee2010-09-02 00:53:56 +0000705 static_cast<const ARMBaseInstrInfo&>(TII));
706 }
Eric Christophereae84392010-10-14 09:29:41 +0000707 Offset = 0;
Eric Christopher404be0c2010-10-17 11:08:44 +0000708 Base = BaseReg;
Eric Christopher318b6ee2010-09-02 00:53:56 +0000709 }
Eric Christopher83007122010-08-23 21:44:12 +0000710}
711
Eric Christopherb1cc8482010-08-25 07:23:49 +0000712bool ARMFastISel::ARMEmitLoad(EVT VT, unsigned &ResultReg,
Eric Christopher404be0c2010-10-17 11:08:44 +0000713 unsigned Base, int Offset) {
Eric Christopherac1a19e2010-09-09 01:06:51 +0000714
Eric Christopherb1cc8482010-08-25 07:23:49 +0000715 assert(VT.isSimple() && "Non-simple types are invalid here!");
Eric Christopherdc908042010-08-31 01:28:42 +0000716 unsigned Opc;
Eric Christopheree56ea62010-10-07 05:50:44 +0000717 TargetRegisterClass *RC;
Eric Christopher6dab1372010-09-18 01:59:37 +0000718 bool isFloat = false;
Eric Christopherb1cc8482010-08-25 07:23:49 +0000719 switch (VT.getSimpleVT().SimpleTy) {
Eric Christopherac1a19e2010-09-09 01:06:51 +0000720 default:
Eric Christopher98de5b42010-09-29 00:49:09 +0000721 // This is mostly going to be Neon/vector support.
Eric Christopher548d1bb2010-08-30 23:48:26 +0000722 return false;
Eric Christopher4e68c7c2010-09-01 18:01:32 +0000723 case MVT::i16:
Eric Christopher45c60712010-10-17 01:40:27 +0000724 Opc = isThumb ? ARM::t2LDRHi12 : ARM::LDRH;
Eric Christopher7a56f332010-10-08 01:13:17 +0000725 RC = ARM::GPRRegisterClass;
Eric Christopher4e68c7c2010-09-01 18:01:32 +0000726 VT = MVT::i32;
727 break;
728 case MVT::i8:
Eric Christopher45c60712010-10-17 01:40:27 +0000729 Opc = isThumb ? ARM::t2LDRBi12 : ARM::LDRB;
Eric Christopher7a56f332010-10-08 01:13:17 +0000730 RC = ARM::GPRRegisterClass;
Eric Christopher4e68c7c2010-09-01 18:01:32 +0000731 VT = MVT::i32;
732 break;
Eric Christopherdc908042010-08-31 01:28:42 +0000733 case MVT::i32:
Eric Christopher45c60712010-10-17 01:40:27 +0000734 Opc = isThumb ? ARM::t2LDRi12 : ARM::LDR;
Eric Christopher7a56f332010-10-08 01:13:17 +0000735 RC = ARM::GPRRegisterClass;
Eric Christopherdc908042010-08-31 01:28:42 +0000736 break;
Eric Christopher6dab1372010-09-18 01:59:37 +0000737 case MVT::f32:
738 Opc = ARM::VLDRS;
Eric Christopheree56ea62010-10-07 05:50:44 +0000739 RC = TLI.getRegClassFor(VT);
Eric Christopher6dab1372010-09-18 01:59:37 +0000740 isFloat = true;
741 break;
742 case MVT::f64:
743 Opc = ARM::VLDRD;
Eric Christopheree56ea62010-10-07 05:50:44 +0000744 RC = TLI.getRegClassFor(VT);
Eric Christopher6dab1372010-09-18 01:59:37 +0000745 isFloat = true;
746 break;
Eric Christopherb1cc8482010-08-25 07:23:49 +0000747 }
Eric Christopherac1a19e2010-09-09 01:06:51 +0000748
Eric Christopheree56ea62010-10-07 05:50:44 +0000749 ResultReg = createResultReg(RC);
Eric Christopher404be0c2010-10-17 11:08:44 +0000750
751 // All SP loads should already have been lowered to another reg.
752 assert(Base != ARM::SP && "No stack stores this late!");
Eric Christopherac1a19e2010-09-09 01:06:51 +0000753
Eric Christopher7a56f332010-10-08 01:13:17 +0000754 // For now with the additions above the offset should be zero - thus we
Eric Christopher7208dbf2010-10-17 01:42:53 +0000755 // can always fit into an i12.
Eric Christopher404be0c2010-10-17 11:08:44 +0000756 assert(Offset == 0 && "Offset should be zero at this point!");
Eric Christopherdccd2c32010-10-11 08:38:55 +0000757
Eric Christopher7a56f332010-10-08 01:13:17 +0000758 // The thumb and floating point instructions both take 2 operands, ARM takes
759 // another register.
Eric Christopher404be0c2010-10-17 11:08:44 +0000760 if (isFloat || isThumb)
Eric Christopher6dab1372010-09-18 01:59:37 +0000761 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
762 TII.get(Opc), ResultReg)
Eric Christopher404be0c2010-10-17 11:08:44 +0000763 .addReg(Base).addImm(Offset));
Eric Christopherdc908042010-08-31 01:28:42 +0000764 else
765 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
766 TII.get(Opc), ResultReg)
Eric Christopher404be0c2010-10-17 11:08:44 +0000767 .addReg(Base).addReg(0).addImm(Offset));
Eric Christopherdc908042010-08-31 01:28:42 +0000768 return true;
Eric Christopherb1cc8482010-08-25 07:23:49 +0000769}
770
Eric Christopher43b62be2010-09-27 06:02:23 +0000771bool ARMFastISel::SelectLoad(const Instruction *I) {
Eric Christopherdb12b2b2010-09-10 00:34:35 +0000772 // Verify we have a legal type before going any further.
773 EVT VT;
774 if (!isLoadTypeLegal(I->getType(), VT))
775 return false;
776
Eric Christopherdb12b2b2010-09-10 00:34:35 +0000777 // Our register and offset with innocuous defaults.
Eric Christopher404be0c2010-10-17 11:08:44 +0000778 unsigned Base = 0;
Eric Christopherdb12b2b2010-09-10 00:34:35 +0000779 int Offset = 0;
780
781 // See if we can handle this as Reg + Offset
Eric Christophera3224252010-10-15 21:32:12 +0000782 if (!ARMComputeRegOffset(I->getOperand(0), Base, Offset))
Eric Christopherdb12b2b2010-09-10 00:34:35 +0000783 return false;
784
Eric Christophera3224252010-10-15 21:32:12 +0000785 ARMSimplifyRegOffset(Base, Offset, VT);
Eric Christophereae84392010-10-14 09:29:41 +0000786
Eric Christopherdb12b2b2010-09-10 00:34:35 +0000787 unsigned ResultReg;
Eric Christophera3224252010-10-15 21:32:12 +0000788 if (!ARMEmitLoad(VT, ResultReg, Base, Offset)) return false;
Eric Christopherdb12b2b2010-09-10 00:34:35 +0000789
790 UpdateValueMap(I, ResultReg);
791 return true;
792}
793
Eric Christopher318b6ee2010-09-02 00:53:56 +0000794bool ARMFastISel::ARMEmitStore(EVT VT, unsigned SrcReg,
Eric Christopher404be0c2010-10-17 11:08:44 +0000795 unsigned Base, int Offset) {
Eric Christopher318b6ee2010-09-02 00:53:56 +0000796 unsigned StrOpc;
Eric Christopherb74558a2010-09-18 01:23:38 +0000797 bool isFloat = false;
Eric Christopher15418772010-10-12 05:39:06 +0000798 // VT is set here only for use in the alloca stores below - those are promoted
799 // to reg size always.
Eric Christopher318b6ee2010-09-02 00:53:56 +0000800 switch (VT.getSimpleVT().SimpleTy) {
801 default: return false;
802 case MVT::i1:
Eric Christopher2896df82010-10-15 18:02:07 +0000803 case MVT::i8:
Eric Christopher15418772010-10-12 05:39:06 +0000804 VT = MVT::i32;
Eric Christopher45c60712010-10-17 01:40:27 +0000805 StrOpc = isThumb ? ARM::t2STRBi12 : ARM::STRB;
Eric Christopher15418772010-10-12 05:39:06 +0000806 break;
807 case MVT::i16:
808 VT = MVT::i32;
Eric Christopher45c60712010-10-17 01:40:27 +0000809 StrOpc = isThumb ? ARM::t2STRHi12 : ARM::STRH;
Eric Christopher15418772010-10-12 05:39:06 +0000810 break;
Eric Christopher47650ec2010-10-16 01:10:35 +0000811 case MVT::i32:
Eric Christopher45c60712010-10-17 01:40:27 +0000812 StrOpc = isThumb ? ARM::t2STRi12 : ARM::STR;
Eric Christopher47650ec2010-10-16 01:10:35 +0000813 break;
Eric Christopher56d2b722010-09-02 23:43:26 +0000814 case MVT::f32:
815 if (!Subtarget->hasVFP2()) return false;
816 StrOpc = ARM::VSTRS;
Eric Christopherb74558a2010-09-18 01:23:38 +0000817 isFloat = true;
Eric Christopher56d2b722010-09-02 23:43:26 +0000818 break;
819 case MVT::f64:
820 if (!Subtarget->hasVFP2()) return false;
821 StrOpc = ARM::VSTRD;
Eric Christopherb74558a2010-09-18 01:23:38 +0000822 isFloat = true;
Eric Christopher56d2b722010-09-02 23:43:26 +0000823 break;
Eric Christopher318b6ee2010-09-02 00:53:56 +0000824 }
Eric Christopherac1a19e2010-09-09 01:06:51 +0000825
Eric Christopher404be0c2010-10-17 11:08:44 +0000826 // All SP stores should already have been lowered to another reg.
827 assert(Base != ARM::SP && "No stack stores this late!");
828
829 // For now with the additions above the offset should be zero - thus we
830 // can always fit into an i12.
831 assert(Offset == 0 && "Offset should be zero at this point!");
832
Eric Christopherb74558a2010-09-18 01:23:38 +0000833 // The thumb addressing mode has operands swapped from the arm addressing
834 // mode, the floating point one only has two operands.
Eric Christopher404be0c2010-10-17 11:08:44 +0000835 if (isFloat || isThumb)
Eric Christopherb74558a2010-09-18 01:23:38 +0000836 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
Eric Christopher45547b82010-10-01 20:46:04 +0000837 TII.get(StrOpc))
Eric Christopher404be0c2010-10-17 11:08:44 +0000838 .addReg(SrcReg).addReg(Base).addImm(Offset));
Eric Christopher318b6ee2010-09-02 00:53:56 +0000839 else
840 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
Eric Christopher45547b82010-10-01 20:46:04 +0000841 TII.get(StrOpc))
Eric Christopher404be0c2010-10-17 11:08:44 +0000842 .addReg(SrcReg).addReg(Base).addReg(0).addImm(Offset));
Eric Christopherac1a19e2010-09-09 01:06:51 +0000843
Eric Christopher318b6ee2010-09-02 00:53:56 +0000844 return true;
845}
846
Eric Christopher43b62be2010-09-27 06:02:23 +0000847bool ARMFastISel::SelectStore(const Instruction *I) {
Eric Christopher318b6ee2010-09-02 00:53:56 +0000848 Value *Op0 = I->getOperand(0);
849 unsigned SrcReg = 0;
850
Eric Christopher543cf052010-09-01 22:16:27 +0000851 // Yay type legalization
852 EVT VT;
Eric Christopher318b6ee2010-09-02 00:53:56 +0000853 if (!isLoadTypeLegal(I->getOperand(0)->getType(), VT))
Eric Christopher543cf052010-09-01 22:16:27 +0000854 return false;
Eric Christopher318b6ee2010-09-02 00:53:56 +0000855
Eric Christopher1b61ef42010-09-02 01:48:11 +0000856 // Get the value to be stored into a register.
857 SrcReg = getRegForValue(Op0);
Eric Christopher318b6ee2010-09-02 00:53:56 +0000858 if (SrcReg == 0)
859 return false;
Eric Christopherac1a19e2010-09-09 01:06:51 +0000860
Eric Christopher318b6ee2010-09-02 00:53:56 +0000861 // Our register and offset with innocuous defaults.
Eric Christopher404be0c2010-10-17 11:08:44 +0000862 unsigned Base = 0;
Eric Christopher318b6ee2010-09-02 00:53:56 +0000863 int Offset = 0;
Eric Christopherac1a19e2010-09-09 01:06:51 +0000864
Eric Christopher318b6ee2010-09-02 00:53:56 +0000865 // See if we can handle this as Reg + Offset
Eric Christophera3224252010-10-15 21:32:12 +0000866 if (!ARMComputeRegOffset(I->getOperand(1), Base, Offset))
Eric Christopher318b6ee2010-09-02 00:53:56 +0000867 return false;
Eric Christopherac1a19e2010-09-09 01:06:51 +0000868
Eric Christophera3224252010-10-15 21:32:12 +0000869 ARMSimplifyRegOffset(Base, Offset, VT);
Eric Christophereae84392010-10-14 09:29:41 +0000870
Eric Christophera3224252010-10-15 21:32:12 +0000871 if (!ARMEmitStore(VT, SrcReg, Base, Offset)) return false;
Eric Christopherac1a19e2010-09-09 01:06:51 +0000872
Eric Christophera5b1e682010-09-17 22:28:18 +0000873 return true;
874}
875
876static ARMCC::CondCodes getComparePred(CmpInst::Predicate Pred) {
877 switch (Pred) {
878 // Needs two compares...
879 case CmpInst::FCMP_ONE:
Eric Christopherdccd2c32010-10-11 08:38:55 +0000880 case CmpInst::FCMP_UEQ:
Eric Christophera5b1e682010-09-17 22:28:18 +0000881 default:
882 assert(false && "Unhandled CmpInst::Predicate!");
883 return ARMCC::AL;
884 case CmpInst::ICMP_EQ:
885 case CmpInst::FCMP_OEQ:
886 return ARMCC::EQ;
887 case CmpInst::ICMP_SGT:
888 case CmpInst::FCMP_OGT:
889 return ARMCC::GT;
890 case CmpInst::ICMP_SGE:
891 case CmpInst::FCMP_OGE:
892 return ARMCC::GE;
893 case CmpInst::ICMP_UGT:
894 case CmpInst::FCMP_UGT:
895 return ARMCC::HI;
896 case CmpInst::FCMP_OLT:
897 return ARMCC::MI;
898 case CmpInst::ICMP_ULE:
899 case CmpInst::FCMP_OLE:
900 return ARMCC::LS;
901 case CmpInst::FCMP_ORD:
902 return ARMCC::VC;
903 case CmpInst::FCMP_UNO:
904 return ARMCC::VS;
905 case CmpInst::FCMP_UGE:
906 return ARMCC::PL;
907 case CmpInst::ICMP_SLT:
908 case CmpInst::FCMP_ULT:
Eric Christopherdccd2c32010-10-11 08:38:55 +0000909 return ARMCC::LT;
Eric Christophera5b1e682010-09-17 22:28:18 +0000910 case CmpInst::ICMP_SLE:
911 case CmpInst::FCMP_ULE:
912 return ARMCC::LE;
913 case CmpInst::FCMP_UNE:
914 case CmpInst::ICMP_NE:
915 return ARMCC::NE;
916 case CmpInst::ICMP_UGE:
917 return ARMCC::HS;
918 case CmpInst::ICMP_ULT:
919 return ARMCC::LO;
920 }
Eric Christopher543cf052010-09-01 22:16:27 +0000921}
922
Eric Christopher43b62be2010-09-27 06:02:23 +0000923bool ARMFastISel::SelectBranch(const Instruction *I) {
Eric Christophere5734102010-09-03 00:35:47 +0000924 const BranchInst *BI = cast<BranchInst>(I);
925 MachineBasicBlock *TBB = FuncInfo.MBBMap[BI->getSuccessor(0)];
926 MachineBasicBlock *FBB = FuncInfo.MBBMap[BI->getSuccessor(1)];
Eric Christopherac1a19e2010-09-09 01:06:51 +0000927
Eric Christophere5734102010-09-03 00:35:47 +0000928 // Simple branch support.
Eric Christopher229207a2010-09-29 01:14:47 +0000929 // TODO: Try to avoid the re-computation in some places.
930 unsigned CondReg = getRegForValue(BI->getCondition());
Eric Christophere5734102010-09-03 00:35:47 +0000931 if (CondReg == 0) return false;
Eric Christopherac1a19e2010-09-09 01:06:51 +0000932
Eric Christopher229207a2010-09-29 01:14:47 +0000933 // Re-set the flags just in case.
934 unsigned CmpOpc = isThumb ? ARM::t2CMPri : ARM::CMPri;
935 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(CmpOpc))
936 .addReg(CondReg).addImm(1));
Eric Christopherdccd2c32010-10-11 08:38:55 +0000937
Eric Christophere5734102010-09-03 00:35:47 +0000938 unsigned BrOpc = isThumb ? ARM::t2Bcc : ARM::Bcc;
Eric Christophere5734102010-09-03 00:35:47 +0000939 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(BrOpc))
Eric Christopher229207a2010-09-29 01:14:47 +0000940 .addMBB(TBB).addImm(ARMCC::EQ).addReg(ARM::CPSR);
Eric Christophere5734102010-09-03 00:35:47 +0000941 FastEmitBranch(FBB, DL);
942 FuncInfo.MBB->addSuccessor(TBB);
Eric Christopherdccd2c32010-10-11 08:38:55 +0000943 return true;
Eric Christophere5734102010-09-03 00:35:47 +0000944}
945
Eric Christopher43b62be2010-09-27 06:02:23 +0000946bool ARMFastISel::SelectCmp(const Instruction *I) {
Eric Christopherd43393a2010-09-08 23:13:45 +0000947 const CmpInst *CI = cast<CmpInst>(I);
Eric Christopherac1a19e2010-09-09 01:06:51 +0000948
Eric Christopherd43393a2010-09-08 23:13:45 +0000949 EVT VT;
950 const Type *Ty = CI->getOperand(0)->getType();
951 if (!isTypeLegal(Ty, VT))
952 return false;
Eric Christopherac1a19e2010-09-09 01:06:51 +0000953
Eric Christopherd43393a2010-09-08 23:13:45 +0000954 bool isFloat = (Ty->isDoubleTy() || Ty->isFloatTy());
955 if (isFloat && !Subtarget->hasVFP2())
956 return false;
Eric Christopherac1a19e2010-09-09 01:06:51 +0000957
Eric Christopherd43393a2010-09-08 23:13:45 +0000958 unsigned CmpOpc;
Eric Christopher229207a2010-09-29 01:14:47 +0000959 unsigned CondReg;
Eric Christopherd43393a2010-09-08 23:13:45 +0000960 switch (VT.getSimpleVT().SimpleTy) {
961 default: return false;
962 // TODO: Verify compares.
963 case MVT::f32:
964 CmpOpc = ARM::VCMPES;
Eric Christopher229207a2010-09-29 01:14:47 +0000965 CondReg = ARM::FPSCR;
Eric Christopherd43393a2010-09-08 23:13:45 +0000966 break;
967 case MVT::f64:
968 CmpOpc = ARM::VCMPED;
Eric Christopher229207a2010-09-29 01:14:47 +0000969 CondReg = ARM::FPSCR;
Eric Christopherd43393a2010-09-08 23:13:45 +0000970 break;
971 case MVT::i32:
972 CmpOpc = isThumb ? ARM::t2CMPrr : ARM::CMPrr;
Eric Christopher229207a2010-09-29 01:14:47 +0000973 CondReg = ARM::CPSR;
Eric Christopherd43393a2010-09-08 23:13:45 +0000974 break;
975 }
976
Eric Christopher229207a2010-09-29 01:14:47 +0000977 // Get the compare predicate.
978 ARMCC::CondCodes ARMPred = getComparePred(CI->getPredicate());
Eric Christopherdccd2c32010-10-11 08:38:55 +0000979
Eric Christopher229207a2010-09-29 01:14:47 +0000980 // We may not handle every CC for now.
981 if (ARMPred == ARMCC::AL) return false;
982
Eric Christopherd43393a2010-09-08 23:13:45 +0000983 unsigned Arg1 = getRegForValue(CI->getOperand(0));
984 if (Arg1 == 0) return false;
Eric Christopherac1a19e2010-09-09 01:06:51 +0000985
Eric Christopherd43393a2010-09-08 23:13:45 +0000986 unsigned Arg2 = getRegForValue(CI->getOperand(1));
987 if (Arg2 == 0) return false;
Eric Christopherac1a19e2010-09-09 01:06:51 +0000988
Eric Christopherd43393a2010-09-08 23:13:45 +0000989 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(CmpOpc))
990 .addReg(Arg1).addReg(Arg2));
Eric Christopherac1a19e2010-09-09 01:06:51 +0000991
Eric Christopherdb12b2b2010-09-10 00:34:35 +0000992 // For floating point we need to move the result to a comparison register
993 // that we can then use for branches.
Eric Christopherd43393a2010-09-08 23:13:45 +0000994 if (isFloat)
995 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
996 TII.get(ARM::FMSTAT)));
Eric Christopherce07b542010-09-09 20:26:31 +0000997
Eric Christopher229207a2010-09-29 01:14:47 +0000998 // Now set a register based on the comparison. Explicitly set the predicates
999 // here.
Eric Christopher338c2532010-10-07 05:31:49 +00001000 unsigned MovCCOpc = isThumb ? ARM::t2MOVCCi : ARM::MOVCCi;
Eric Christopherdccd2c32010-10-11 08:38:55 +00001001 TargetRegisterClass *RC = isThumb ? ARM::rGPRRegisterClass
Eric Christopher5d18d922010-10-07 05:39:19 +00001002 : ARM::GPRRegisterClass;
1003 unsigned DestReg = createResultReg(RC);
Eric Christopherdccd2c32010-10-11 08:38:55 +00001004 Constant *Zero
Eric Christopher8cf6c602010-09-29 22:24:45 +00001005 = ConstantInt::get(Type::getInt32Ty(*Context), 0);
Eric Christopher229207a2010-09-29 01:14:47 +00001006 unsigned ZeroReg = TargetMaterializeConstant(Zero);
1007 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(MovCCOpc), DestReg)
1008 .addReg(ZeroReg).addImm(1)
1009 .addImm(ARMPred).addReg(CondReg);
1010
Eric Christophera5b1e682010-09-17 22:28:18 +00001011 UpdateValueMap(I, DestReg);
Eric Christopherd43393a2010-09-08 23:13:45 +00001012 return true;
1013}
1014
Eric Christopher43b62be2010-09-27 06:02:23 +00001015bool ARMFastISel::SelectFPExt(const Instruction *I) {
Eric Christopher46203602010-09-09 00:26:48 +00001016 // Make sure we have VFP and that we're extending float to double.
1017 if (!Subtarget->hasVFP2()) return false;
Eric Christopherac1a19e2010-09-09 01:06:51 +00001018
Eric Christopher46203602010-09-09 00:26:48 +00001019 Value *V = I->getOperand(0);
1020 if (!I->getType()->isDoubleTy() ||
1021 !V->getType()->isFloatTy()) return false;
Eric Christopherac1a19e2010-09-09 01:06:51 +00001022
Eric Christopher46203602010-09-09 00:26:48 +00001023 unsigned Op = getRegForValue(V);
1024 if (Op == 0) return false;
Eric Christopherac1a19e2010-09-09 01:06:51 +00001025
Eric Christopher46203602010-09-09 00:26:48 +00001026 unsigned Result = createResultReg(ARM::DPRRegisterClass);
Eric Christopherac1a19e2010-09-09 01:06:51 +00001027 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
Eric Christopheref2fdd22010-09-09 20:36:19 +00001028 TII.get(ARM::VCVTDS), Result)
Eric Christopherce07b542010-09-09 20:26:31 +00001029 .addReg(Op));
1030 UpdateValueMap(I, Result);
1031 return true;
1032}
1033
Eric Christopher43b62be2010-09-27 06:02:23 +00001034bool ARMFastISel::SelectFPTrunc(const Instruction *I) {
Eric Christopherce07b542010-09-09 20:26:31 +00001035 // Make sure we have VFP and that we're truncating double to float.
1036 if (!Subtarget->hasVFP2()) return false;
1037
1038 Value *V = I->getOperand(0);
Eric Christopher022b7fb2010-10-05 23:13:24 +00001039 if (!(I->getType()->isFloatTy() &&
1040 V->getType()->isDoubleTy())) return false;
Eric Christopherce07b542010-09-09 20:26:31 +00001041
1042 unsigned Op = getRegForValue(V);
1043 if (Op == 0) return false;
1044
1045 unsigned Result = createResultReg(ARM::SPRRegisterClass);
Eric Christopherce07b542010-09-09 20:26:31 +00001046 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
Eric Christopheref2fdd22010-09-09 20:36:19 +00001047 TII.get(ARM::VCVTSD), Result)
Eric Christopher46203602010-09-09 00:26:48 +00001048 .addReg(Op));
1049 UpdateValueMap(I, Result);
1050 return true;
1051}
1052
Eric Christopher43b62be2010-09-27 06:02:23 +00001053bool ARMFastISel::SelectSIToFP(const Instruction *I) {
Eric Christopher9a040492010-09-09 18:54:59 +00001054 // Make sure we have VFP.
1055 if (!Subtarget->hasVFP2()) return false;
Eric Christopherdccd2c32010-10-11 08:38:55 +00001056
Eric Christopher9ee4ce22010-09-09 21:44:45 +00001057 EVT DstVT;
Eric Christopher9a040492010-09-09 18:54:59 +00001058 const Type *Ty = I->getType();
Eric Christopher9ee4ce22010-09-09 21:44:45 +00001059 if (!isTypeLegal(Ty, DstVT))
Eric Christopher9a040492010-09-09 18:54:59 +00001060 return false;
Eric Christopherdccd2c32010-10-11 08:38:55 +00001061
Eric Christopher9a040492010-09-09 18:54:59 +00001062 unsigned Op = getRegForValue(I->getOperand(0));
1063 if (Op == 0) return false;
Eric Christopherdccd2c32010-10-11 08:38:55 +00001064
Eric Christopherdb12b2b2010-09-10 00:34:35 +00001065 // The conversion routine works on fp-reg to fp-reg and the operand above
1066 // was an integer, move it to the fp registers if possible.
Eric Christopher022b7fb2010-10-05 23:13:24 +00001067 unsigned FP = ARMMoveToFPReg(MVT::f32, Op);
Eric Christopher9ee4ce22010-09-09 21:44:45 +00001068 if (FP == 0) return false;
Eric Christopherdccd2c32010-10-11 08:38:55 +00001069
Eric Christopher9a040492010-09-09 18:54:59 +00001070 unsigned Opc;
1071 if (Ty->isFloatTy()) Opc = ARM::VSITOS;
1072 else if (Ty->isDoubleTy()) Opc = ARM::VSITOD;
1073 else return 0;
Eric Christopherdccd2c32010-10-11 08:38:55 +00001074
Eric Christopher9ee4ce22010-09-09 21:44:45 +00001075 unsigned ResultReg = createResultReg(TLI.getRegClassFor(DstVT));
Eric Christopher9a040492010-09-09 18:54:59 +00001076 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc),
1077 ResultReg)
Eric Christopher9ee4ce22010-09-09 21:44:45 +00001078 .addReg(FP));
Eric Christopherce07b542010-09-09 20:26:31 +00001079 UpdateValueMap(I, ResultReg);
Eric Christopher9a040492010-09-09 18:54:59 +00001080 return true;
1081}
1082
Eric Christopher43b62be2010-09-27 06:02:23 +00001083bool ARMFastISel::SelectFPToSI(const Instruction *I) {
Eric Christopher9a040492010-09-09 18:54:59 +00001084 // Make sure we have VFP.
1085 if (!Subtarget->hasVFP2()) return false;
Eric Christopherdccd2c32010-10-11 08:38:55 +00001086
Eric Christopherdb12b2b2010-09-10 00:34:35 +00001087 EVT DstVT;
Eric Christopher9a040492010-09-09 18:54:59 +00001088 const Type *RetTy = I->getType();
Eric Christopher920a2082010-09-10 00:35:09 +00001089 if (!isTypeLegal(RetTy, DstVT))
Eric Christopher9a040492010-09-09 18:54:59 +00001090 return false;
Eric Christopherdccd2c32010-10-11 08:38:55 +00001091
Eric Christopher9a040492010-09-09 18:54:59 +00001092 unsigned Op = getRegForValue(I->getOperand(0));
1093 if (Op == 0) return false;
Eric Christopherdccd2c32010-10-11 08:38:55 +00001094
Eric Christopher9a040492010-09-09 18:54:59 +00001095 unsigned Opc;
1096 const Type *OpTy = I->getOperand(0)->getType();
1097 if (OpTy->isFloatTy()) Opc = ARM::VTOSIZS;
1098 else if (OpTy->isDoubleTy()) Opc = ARM::VTOSIZD;
1099 else return 0;
Eric Christopherdccd2c32010-10-11 08:38:55 +00001100
Eric Christopher022b7fb2010-10-05 23:13:24 +00001101 // f64->s32 or f32->s32 both need an intermediate f32 reg.
1102 unsigned ResultReg = createResultReg(TLI.getRegClassFor(MVT::f32));
Eric Christopher9a040492010-09-09 18:54:59 +00001103 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc),
1104 ResultReg)
1105 .addReg(Op));
Eric Christopherdccd2c32010-10-11 08:38:55 +00001106
Eric Christopher9ee4ce22010-09-09 21:44:45 +00001107 // This result needs to be in an integer register, but the conversion only
1108 // takes place in fp-regs.
Eric Christopherdb12b2b2010-09-10 00:34:35 +00001109 unsigned IntReg = ARMMoveToIntReg(DstVT, ResultReg);
Eric Christopher9ee4ce22010-09-09 21:44:45 +00001110 if (IntReg == 0) return false;
Eric Christopherdccd2c32010-10-11 08:38:55 +00001111
Eric Christopher9ee4ce22010-09-09 21:44:45 +00001112 UpdateValueMap(I, IntReg);
Eric Christopher9a040492010-09-09 18:54:59 +00001113 return true;
1114}
1115
Eric Christopher3bbd3962010-10-11 08:27:59 +00001116bool ARMFastISel::SelectSelect(const Instruction *I) {
1117 EVT VT = TLI.getValueType(I->getType(), /*HandleUnknown=*/true);
1118 if (VT == MVT::Other || !isTypeLegal(I->getType(), VT))
1119 return false;
1120
1121 // Things need to be register sized for register moves.
1122 if (VT.getSimpleVT().SimpleTy != MVT::i32) return false;
1123 const TargetRegisterClass *RC = TLI.getRegClassFor(VT);
1124
1125 unsigned CondReg = getRegForValue(I->getOperand(0));
1126 if (CondReg == 0) return false;
1127 unsigned Op1Reg = getRegForValue(I->getOperand(1));
1128 if (Op1Reg == 0) return false;
1129 unsigned Op2Reg = getRegForValue(I->getOperand(2));
1130 if (Op2Reg == 0) return false;
1131
1132 unsigned CmpOpc = isThumb ? ARM::t2TSTri : ARM::TSTri;
1133 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(CmpOpc))
1134 .addReg(CondReg).addImm(1));
1135 unsigned ResultReg = createResultReg(RC);
1136 unsigned MovCCOpc = isThumb ? ARM::t2MOVCCr : ARM::MOVCCr;
1137 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(MovCCOpc), ResultReg)
1138 .addReg(Op1Reg).addReg(Op2Reg)
1139 .addImm(ARMCC::EQ).addReg(ARM::CPSR);
1140 UpdateValueMap(I, ResultReg);
1141 return true;
1142}
1143
Eric Christopher08637852010-09-30 22:34:19 +00001144bool ARMFastISel::SelectSDiv(const Instruction *I) {
1145 EVT VT;
1146 const Type *Ty = I->getType();
1147 if (!isTypeLegal(Ty, VT))
1148 return false;
1149
1150 // If we have integer div support we should have selected this automagically.
1151 // In case we have a real miss go ahead and return false and we'll pick
1152 // it up later.
Eric Christopherdccd2c32010-10-11 08:38:55 +00001153 if (Subtarget->hasDivide()) return false;
1154
Eric Christopher08637852010-09-30 22:34:19 +00001155 // Otherwise emit a libcall.
1156 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
Eric Christopher7bdc4de2010-10-11 08:31:54 +00001157 if (VT == MVT::i8)
1158 LC = RTLIB::SDIV_I8;
1159 else if (VT == MVT::i16)
Eric Christopher08637852010-09-30 22:34:19 +00001160 LC = RTLIB::SDIV_I16;
1161 else if (VT == MVT::i32)
1162 LC = RTLIB::SDIV_I32;
1163 else if (VT == MVT::i64)
1164 LC = RTLIB::SDIV_I64;
1165 else if (VT == MVT::i128)
1166 LC = RTLIB::SDIV_I128;
1167 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported SDIV!");
Eric Christopherdccd2c32010-10-11 08:38:55 +00001168
Eric Christopher08637852010-09-30 22:34:19 +00001169 return ARMEmitLibcall(I, LC);
1170}
1171
Eric Christopher6a880d62010-10-11 08:37:26 +00001172bool ARMFastISel::SelectSRem(const Instruction *I) {
1173 EVT VT;
1174 const Type *Ty = I->getType();
1175 if (!isTypeLegal(Ty, VT))
1176 return false;
1177
1178 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
1179 if (VT == MVT::i8)
1180 LC = RTLIB::SREM_I8;
1181 else if (VT == MVT::i16)
1182 LC = RTLIB::SREM_I16;
1183 else if (VT == MVT::i32)
1184 LC = RTLIB::SREM_I32;
1185 else if (VT == MVT::i64)
1186 LC = RTLIB::SREM_I64;
1187 else if (VT == MVT::i128)
1188 LC = RTLIB::SREM_I128;
Eric Christophera1640d92010-10-11 08:40:05 +00001189 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported SREM!");
Eric Christopher2896df82010-10-15 18:02:07 +00001190
Eric Christopher6a880d62010-10-11 08:37:26 +00001191 return ARMEmitLibcall(I, LC);
1192}
1193
Eric Christopher43b62be2010-09-27 06:02:23 +00001194bool ARMFastISel::SelectBinaryOp(const Instruction *I, unsigned ISDOpcode) {
Eric Christopherbd6bf082010-09-09 01:02:03 +00001195 EVT VT = TLI.getValueType(I->getType(), true);
Eric Christopherac1a19e2010-09-09 01:06:51 +00001196
Eric Christopherbc39b822010-09-09 00:53:57 +00001197 // We can get here in the case when we want to use NEON for our fp
1198 // operations, but can't figure out how to. Just use the vfp instructions
1199 // if we have them.
1200 // FIXME: It'd be nice to use NEON instructions.
Eric Christopherbd6bf082010-09-09 01:02:03 +00001201 const Type *Ty = I->getType();
1202 bool isFloat = (Ty->isDoubleTy() || Ty->isFloatTy());
1203 if (isFloat && !Subtarget->hasVFP2())
1204 return false;
Eric Christopherac1a19e2010-09-09 01:06:51 +00001205
Eric Christopherbc39b822010-09-09 00:53:57 +00001206 unsigned Op1 = getRegForValue(I->getOperand(0));
1207 if (Op1 == 0) return false;
Eric Christopherac1a19e2010-09-09 01:06:51 +00001208
Eric Christopherbc39b822010-09-09 00:53:57 +00001209 unsigned Op2 = getRegForValue(I->getOperand(1));
1210 if (Op2 == 0) return false;
Eric Christopherac1a19e2010-09-09 01:06:51 +00001211
Eric Christopherbc39b822010-09-09 00:53:57 +00001212 unsigned Opc;
Eric Christopherbd6bf082010-09-09 01:02:03 +00001213 bool is64bit = VT.getSimpleVT().SimpleTy == MVT::f64 ||
1214 VT.getSimpleVT().SimpleTy == MVT::i64;
Eric Christopherbc39b822010-09-09 00:53:57 +00001215 switch (ISDOpcode) {
1216 default: return false;
1217 case ISD::FADD:
Eric Christopherbd6bf082010-09-09 01:02:03 +00001218 Opc = is64bit ? ARM::VADDD : ARM::VADDS;
Eric Christopherbc39b822010-09-09 00:53:57 +00001219 break;
1220 case ISD::FSUB:
Eric Christopherbd6bf082010-09-09 01:02:03 +00001221 Opc = is64bit ? ARM::VSUBD : ARM::VSUBS;
Eric Christopherbc39b822010-09-09 00:53:57 +00001222 break;
1223 case ISD::FMUL:
Eric Christopherbd6bf082010-09-09 01:02:03 +00001224 Opc = is64bit ? ARM::VMULD : ARM::VMULS;
Eric Christopherbc39b822010-09-09 00:53:57 +00001225 break;
1226 }
Eric Christopherbd6bf082010-09-09 01:02:03 +00001227 unsigned ResultReg = createResultReg(TLI.getRegClassFor(VT));
Eric Christopherbc39b822010-09-09 00:53:57 +00001228 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
1229 TII.get(Opc), ResultReg)
1230 .addReg(Op1).addReg(Op2));
Eric Christopherce07b542010-09-09 20:26:31 +00001231 UpdateValueMap(I, ResultReg);
Eric Christopherbc39b822010-09-09 00:53:57 +00001232 return true;
1233}
1234
Eric Christopherd10cd7b2010-09-10 23:18:12 +00001235// Call Handling Code
1236
1237// This is largely taken directly from CCAssignFnForNode - we don't support
1238// varargs in FastISel so that part has been removed.
1239// TODO: We may not support all of this.
1240CCAssignFn *ARMFastISel::CCAssignFnForCall(CallingConv::ID CC, bool Return) {
1241 switch (CC) {
1242 default:
1243 llvm_unreachable("Unsupported calling convention");
1244 case CallingConv::C:
1245 case CallingConv::Fast:
1246 // Use target triple & subtarget features to do actual dispatch.
1247 if (Subtarget->isAAPCS_ABI()) {
1248 if (Subtarget->hasVFP2() &&
1249 FloatABIType == FloatABI::Hard)
1250 return (Return ? RetCC_ARM_AAPCS_VFP: CC_ARM_AAPCS_VFP);
1251 else
1252 return (Return ? RetCC_ARM_AAPCS: CC_ARM_AAPCS);
1253 } else
1254 return (Return ? RetCC_ARM_APCS: CC_ARM_APCS);
1255 case CallingConv::ARM_AAPCS_VFP:
1256 return (Return ? RetCC_ARM_AAPCS_VFP: CC_ARM_AAPCS_VFP);
1257 case CallingConv::ARM_AAPCS:
1258 return (Return ? RetCC_ARM_AAPCS: CC_ARM_AAPCS);
1259 case CallingConv::ARM_APCS:
1260 return (Return ? RetCC_ARM_APCS: CC_ARM_APCS);
1261 }
1262}
1263
Eric Christophera9a7a1a2010-09-29 23:11:09 +00001264bool ARMFastISel::ProcessCallArgs(SmallVectorImpl<Value*> &Args,
1265 SmallVectorImpl<unsigned> &ArgRegs,
1266 SmallVectorImpl<EVT> &ArgVTs,
1267 SmallVectorImpl<ISD::ArgFlagsTy> &ArgFlags,
1268 SmallVectorImpl<unsigned> &RegArgs,
1269 CallingConv::ID CC,
1270 unsigned &NumBytes) {
1271 SmallVector<CCValAssign, 16> ArgLocs;
1272 CCState CCInfo(CC, false, TM, ArgLocs, *Context);
1273 CCInfo.AnalyzeCallOperands(ArgVTs, ArgFlags, CCAssignFnForCall(CC, false));
1274
1275 // Get a count of how many bytes are to be pushed on the stack.
1276 NumBytes = CCInfo.getNextStackOffset();
1277
1278 // Issue CALLSEQ_START
1279 unsigned AdjStackDown = TM.getRegisterInfo()->getCallFrameSetupOpcode();
Eric Christopherfb0b8922010-10-11 21:20:02 +00001280 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
1281 TII.get(AdjStackDown))
1282 .addImm(NumBytes));
Eric Christophera9a7a1a2010-09-29 23:11:09 +00001283
1284 // Process the args.
1285 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
1286 CCValAssign &VA = ArgLocs[i];
1287 unsigned Arg = ArgRegs[VA.getValNo()];
1288 EVT ArgVT = ArgVTs[VA.getValNo()];
1289
Eric Christopherf9764fa2010-09-30 20:49:44 +00001290 // Handle arg promotion, etc.
Eric Christophera9a7a1a2010-09-29 23:11:09 +00001291 switch (VA.getLocInfo()) {
1292 case CCValAssign::Full: break;
1293 default:
Eric Christopher11077342010-10-07 05:14:08 +00001294 // TODO: Handle arg promotion.
Eric Christophera9a7a1a2010-09-29 23:11:09 +00001295 return false;
1296 }
1297
1298 // Now copy/store arg to correct locations.
Eric Christopherfb0b8922010-10-11 21:20:02 +00001299 // TODO: We need custom lowering for f64 args.
1300 if (VA.isRegLoc() && !VA.needsCustom()) {
Eric Christophera9a7a1a2010-09-29 23:11:09 +00001301 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(TargetOpcode::COPY),
Eric Christopherf9764fa2010-09-30 20:49:44 +00001302 VA.getLocReg())
1303 .addReg(Arg);
Eric Christophera9a7a1a2010-09-29 23:11:09 +00001304 RegArgs.push_back(VA.getLocReg());
1305 } else {
1306 // Need to store
1307 return false;
1308 }
1309 }
Eric Christopherdccd2c32010-10-11 08:38:55 +00001310
Eric Christophera9a7a1a2010-09-29 23:11:09 +00001311 return true;
1312}
1313
1314bool ARMFastISel::FinishCall(EVT RetVT, SmallVectorImpl<unsigned> &UsedRegs,
1315 const Instruction *I, CallingConv::ID CC,
1316 unsigned &NumBytes) {
1317 // Issue CALLSEQ_END
1318 unsigned AdjStackUp = TM.getRegisterInfo()->getCallFrameDestroyOpcode();
Eric Christopherfb0b8922010-10-11 21:20:02 +00001319 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
1320 TII.get(AdjStackUp))
1321 .addImm(NumBytes).addImm(0));
Eric Christophera9a7a1a2010-09-29 23:11:09 +00001322
1323 // Now the return value.
1324 if (RetVT.getSimpleVT().SimpleTy != MVT::isVoid) {
1325 SmallVector<CCValAssign, 16> RVLocs;
1326 CCState CCInfo(CC, false, TM, RVLocs, *Context);
1327 CCInfo.AnalyzeCallResult(RetVT, CCAssignFnForCall(CC, true));
1328
1329 // Copy all of the result registers out of their specified physreg.
Eric Christopher14df8822010-10-01 00:00:11 +00001330 if (RVLocs.size() == 2 && RetVT.getSimpleVT().SimpleTy == MVT::f64) {
1331 // For this move we copy into two registers and then move into the
1332 // double fp reg we want.
1333 // TODO: Are the copies necessary?
1334 TargetRegisterClass *CopyRC = TLI.getRegClassFor(MVT::i32);
1335 unsigned Copy1 = createResultReg(CopyRC);
1336 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(TargetOpcode::COPY),
1337 Copy1).addReg(RVLocs[0].getLocReg());
1338 UsedRegs.push_back(RVLocs[0].getLocReg());
Eric Christopherdccd2c32010-10-11 08:38:55 +00001339
Eric Christopher14df8822010-10-01 00:00:11 +00001340 unsigned Copy2 = createResultReg(CopyRC);
1341 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(TargetOpcode::COPY),
1342 Copy2).addReg(RVLocs[1].getLocReg());
1343 UsedRegs.push_back(RVLocs[1].getLocReg());
Eric Christopherdccd2c32010-10-11 08:38:55 +00001344
Eric Christopher14df8822010-10-01 00:00:11 +00001345 EVT DestVT = RVLocs[0].getValVT();
1346 TargetRegisterClass* DstRC = TLI.getRegClassFor(DestVT);
1347 unsigned ResultReg = createResultReg(DstRC);
1348 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
1349 TII.get(ARM::VMOVDRR), ResultReg)
1350 .addReg(Copy1).addReg(Copy2));
Eric Christopherdccd2c32010-10-11 08:38:55 +00001351
1352 // Finally update the result.
Eric Christopher14df8822010-10-01 00:00:11 +00001353 UpdateValueMap(I, ResultReg);
1354 } else {
Jim Grosbach95369592010-10-13 23:34:31 +00001355 assert(RVLocs.size() == 1 &&"Can't handle non-double multi-reg retvals!");
Eric Christopher14df8822010-10-01 00:00:11 +00001356 EVT CopyVT = RVLocs[0].getValVT();
1357 TargetRegisterClass* DstRC = TLI.getRegClassFor(CopyVT);
Eric Christophera9a7a1a2010-09-29 23:11:09 +00001358
Eric Christopher14df8822010-10-01 00:00:11 +00001359 unsigned ResultReg = createResultReg(DstRC);
1360 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(TargetOpcode::COPY),
1361 ResultReg).addReg(RVLocs[0].getLocReg());
1362 UsedRegs.push_back(RVLocs[0].getLocReg());
Eric Christophera9a7a1a2010-09-29 23:11:09 +00001363
Eric Christopherdccd2c32010-10-11 08:38:55 +00001364 // Finally update the result.
Eric Christopher14df8822010-10-01 00:00:11 +00001365 UpdateValueMap(I, ResultReg);
1366 }
Eric Christophera9a7a1a2010-09-29 23:11:09 +00001367 }
1368
Eric Christopherdccd2c32010-10-11 08:38:55 +00001369 return true;
Eric Christophera9a7a1a2010-09-29 23:11:09 +00001370}
1371
Eric Christopherbb3e5da2010-09-14 23:03:37 +00001372// A quick function that will emit a call for a named libcall in F with the
1373// vector of passed arguments for the Instruction in I. We can assume that we
Eric Christopherdccd2c32010-10-11 08:38:55 +00001374// can emit a call for any libcall we can produce. This is an abridged version
1375// of the full call infrastructure since we won't need to worry about things
Eric Christopherbb3e5da2010-09-14 23:03:37 +00001376// like computed function pointers or strange arguments at call sites.
1377// TODO: Try to unify this and the normal call bits for ARM, then try to unify
1378// with X86.
Eric Christopher7ed8ec92010-09-28 01:21:42 +00001379bool ARMFastISel::ARMEmitLibcall(const Instruction *I, RTLIB::Libcall Call) {
1380 CallingConv::ID CC = TLI.getLibcallCallingConv(Call);
Eric Christopherdccd2c32010-10-11 08:38:55 +00001381
Eric Christopherbb3e5da2010-09-14 23:03:37 +00001382 // Handle *simple* calls for now.
Eric Christopher7ed8ec92010-09-28 01:21:42 +00001383 const Type *RetTy = I->getType();
Eric Christopherbb3e5da2010-09-14 23:03:37 +00001384 EVT RetVT;
1385 if (RetTy->isVoidTy())
1386 RetVT = MVT::isVoid;
1387 else if (!isTypeLegal(RetTy, RetVT))
1388 return false;
Eric Christopherdccd2c32010-10-11 08:38:55 +00001389
Eric Christopher7ed8ec92010-09-28 01:21:42 +00001390 // For now we're using BLX etc on the assumption that we have v5t ops.
1391 if (!Subtarget->hasV5TOps()) return false;
Eric Christopherdccd2c32010-10-11 08:38:55 +00001392
Eric Christophera9a7a1a2010-09-29 23:11:09 +00001393 // Set up the argument vectors.
Eric Christopherbb3e5da2010-09-14 23:03:37 +00001394 SmallVector<Value*, 8> Args;
1395 SmallVector<unsigned, 8> ArgRegs;
1396 SmallVector<EVT, 8> ArgVTs;
1397 SmallVector<ISD::ArgFlagsTy, 8> ArgFlags;
1398 Args.reserve(I->getNumOperands());
1399 ArgRegs.reserve(I->getNumOperands());
1400 ArgVTs.reserve(I->getNumOperands());
1401 ArgFlags.reserve(I->getNumOperands());
Eric Christopher7ed8ec92010-09-28 01:21:42 +00001402 for (unsigned i = 0; i < I->getNumOperands(); ++i) {
Eric Christopherbb3e5da2010-09-14 23:03:37 +00001403 Value *Op = I->getOperand(i);
1404 unsigned Arg = getRegForValue(Op);
1405 if (Arg == 0) return false;
Eric Christopherdccd2c32010-10-11 08:38:55 +00001406
Eric Christopherbb3e5da2010-09-14 23:03:37 +00001407 const Type *ArgTy = Op->getType();
1408 EVT ArgVT;
1409 if (!isTypeLegal(ArgTy, ArgVT)) return false;
Eric Christopherdccd2c32010-10-11 08:38:55 +00001410
Eric Christopherbb3e5da2010-09-14 23:03:37 +00001411 ISD::ArgFlagsTy Flags;
1412 unsigned OriginalAlignment = TD.getABITypeAlignment(ArgTy);
1413 Flags.setOrigAlign(OriginalAlignment);
Eric Christopherdccd2c32010-10-11 08:38:55 +00001414
Eric Christopherbb3e5da2010-09-14 23:03:37 +00001415 Args.push_back(Op);
1416 ArgRegs.push_back(Arg);
1417 ArgVTs.push_back(ArgVT);
1418 ArgFlags.push_back(Flags);
1419 }
Eric Christopherdccd2c32010-10-11 08:38:55 +00001420
Eric Christophera9a7a1a2010-09-29 23:11:09 +00001421 // Handle the arguments now that we've gotten them.
Eric Christopherbb3e5da2010-09-14 23:03:37 +00001422 SmallVector<unsigned, 4> RegArgs;
Eric Christophera9a7a1a2010-09-29 23:11:09 +00001423 unsigned NumBytes;
1424 if (!ProcessCallArgs(Args, ArgRegs, ArgVTs, ArgFlags, RegArgs, CC, NumBytes))
1425 return false;
Eric Christopherdccd2c32010-10-11 08:38:55 +00001426
Eric Christopher7ed8ec92010-09-28 01:21:42 +00001427 // Issue the call, BLXr9 for darwin, BLX otherwise. This uses V5 ops.
Eric Christopherdccd2c32010-10-11 08:38:55 +00001428 // TODO: Turn this into the table of arm call ops.
Eric Christopherbb3e5da2010-09-14 23:03:37 +00001429 MachineInstrBuilder MIB;
Eric Christopherc1095562010-09-18 02:32:38 +00001430 unsigned CallOpc;
1431 if(isThumb)
Eric Christopher7ed8ec92010-09-28 01:21:42 +00001432 CallOpc = Subtarget->isTargetDarwin() ? ARM::tBLXi_r9 : ARM::tBLXi;
Eric Christopherc1095562010-09-18 02:32:38 +00001433 else
1434 CallOpc = Subtarget->isTargetDarwin() ? ARM::BLr9 : ARM::BL;
Eric Christopherbb3e5da2010-09-14 23:03:37 +00001435 MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(CallOpc))
Eric Christopher7ed8ec92010-09-28 01:21:42 +00001436 .addExternalSymbol(TLI.getLibcallName(Call));
Eric Christopherdccd2c32010-10-11 08:38:55 +00001437
Eric Christopherbb3e5da2010-09-14 23:03:37 +00001438 // Add implicit physical register uses to the call.
1439 for (unsigned i = 0, e = RegArgs.size(); i != e; ++i)
1440 MIB.addReg(RegArgs[i]);
Eric Christopherdccd2c32010-10-11 08:38:55 +00001441
Eric Christophera9a7a1a2010-09-29 23:11:09 +00001442 // Finish off the call including any return values.
Eric Christopherdccd2c32010-10-11 08:38:55 +00001443 SmallVector<unsigned, 4> UsedRegs;
Eric Christophera9a7a1a2010-09-29 23:11:09 +00001444 if (!FinishCall(RetVT, UsedRegs, I, CC, NumBytes)) return false;
Eric Christopherdccd2c32010-10-11 08:38:55 +00001445
Eric Christopherbb3e5da2010-09-14 23:03:37 +00001446 // Set all unused physreg defs as dead.
1447 static_cast<MachineInstr *>(MIB)->setPhysRegsDeadExcept(UsedRegs, TRI);
Eric Christopherdccd2c32010-10-11 08:38:55 +00001448
Eric Christopherbb3e5da2010-09-14 23:03:37 +00001449 return true;
1450}
1451
Eric Christopherf9764fa2010-09-30 20:49:44 +00001452bool ARMFastISel::SelectCall(const Instruction *I) {
1453 const CallInst *CI = cast<CallInst>(I);
1454 const Value *Callee = CI->getCalledValue();
1455
1456 // Can't handle inline asm or worry about intrinsics yet.
1457 if (isa<InlineAsm>(Callee) || isa<IntrinsicInst>(CI)) return false;
1458
Eric Christophere6ca6772010-10-01 21:33:12 +00001459 // Only handle global variable Callees that are direct calls.
Eric Christopherf9764fa2010-09-30 20:49:44 +00001460 const GlobalValue *GV = dyn_cast<GlobalValue>(Callee);
Eric Christophere6ca6772010-10-01 21:33:12 +00001461 if (!GV || Subtarget->GVIsIndirectSymbol(GV, TM.getRelocationModel()))
1462 return false;
Eric Christopherdccd2c32010-10-11 08:38:55 +00001463
Eric Christopherf9764fa2010-09-30 20:49:44 +00001464 // Check the calling convention.
1465 ImmutableCallSite CS(CI);
1466 CallingConv::ID CC = CS.getCallingConv();
1467 // TODO: Avoid some calling conventions?
1468 if (CC != CallingConv::C) {
Eric Christophere540a6f2010-10-05 23:50:58 +00001469 // errs() << "Can't handle calling convention: " << CC << "\n";
Eric Christopherf9764fa2010-09-30 20:49:44 +00001470 return false;
1471 }
Eric Christopherdccd2c32010-10-11 08:38:55 +00001472
Eric Christopherf9764fa2010-09-30 20:49:44 +00001473 // Let SDISel handle vararg functions.
1474 const PointerType *PT = cast<PointerType>(CS.getCalledValue()->getType());
1475 const FunctionType *FTy = cast<FunctionType>(PT->getElementType());
1476 if (FTy->isVarArg())
1477 return false;
Eric Christopherdccd2c32010-10-11 08:38:55 +00001478
Eric Christopherf9764fa2010-09-30 20:49:44 +00001479 // Handle *simple* calls for now.
1480 const Type *RetTy = I->getType();
1481 EVT RetVT;
1482 if (RetTy->isVoidTy())
1483 RetVT = MVT::isVoid;
1484 else if (!isTypeLegal(RetTy, RetVT))
1485 return false;
Eric Christopherdccd2c32010-10-11 08:38:55 +00001486
Eric Christopherf9764fa2010-09-30 20:49:44 +00001487 // For now we're using BLX etc on the assumption that we have v5t ops.
1488 // TODO: Maybe?
1489 if (!Subtarget->hasV5TOps()) return false;
Eric Christopherdccd2c32010-10-11 08:38:55 +00001490
Eric Christopherf9764fa2010-09-30 20:49:44 +00001491 // Set up the argument vectors.
1492 SmallVector<Value*, 8> Args;
1493 SmallVector<unsigned, 8> ArgRegs;
1494 SmallVector<EVT, 8> ArgVTs;
1495 SmallVector<ISD::ArgFlagsTy, 8> ArgFlags;
1496 Args.reserve(CS.arg_size());
1497 ArgRegs.reserve(CS.arg_size());
1498 ArgVTs.reserve(CS.arg_size());
1499 ArgFlags.reserve(CS.arg_size());
1500 for (ImmutableCallSite::arg_iterator i = CS.arg_begin(), e = CS.arg_end();
1501 i != e; ++i) {
1502 unsigned Arg = getRegForValue(*i);
Eric Christopherdccd2c32010-10-11 08:38:55 +00001503
Eric Christopherf9764fa2010-09-30 20:49:44 +00001504 if (Arg == 0)
1505 return false;
1506 ISD::ArgFlagsTy Flags;
1507 unsigned AttrInd = i - CS.arg_begin() + 1;
1508 if (CS.paramHasAttr(AttrInd, Attribute::SExt))
1509 Flags.setSExt();
1510 if (CS.paramHasAttr(AttrInd, Attribute::ZExt))
1511 Flags.setZExt();
1512
1513 // FIXME: Only handle *easy* calls for now.
1514 if (CS.paramHasAttr(AttrInd, Attribute::InReg) ||
1515 CS.paramHasAttr(AttrInd, Attribute::StructRet) ||
1516 CS.paramHasAttr(AttrInd, Attribute::Nest) ||
1517 CS.paramHasAttr(AttrInd, Attribute::ByVal))
1518 return false;
1519
1520 const Type *ArgTy = (*i)->getType();
1521 EVT ArgVT;
1522 if (!isTypeLegal(ArgTy, ArgVT))
1523 return false;
1524 unsigned OriginalAlignment = TD.getABITypeAlignment(ArgTy);
1525 Flags.setOrigAlign(OriginalAlignment);
Eric Christopherdccd2c32010-10-11 08:38:55 +00001526
Eric Christopherf9764fa2010-09-30 20:49:44 +00001527 Args.push_back(*i);
1528 ArgRegs.push_back(Arg);
1529 ArgVTs.push_back(ArgVT);
1530 ArgFlags.push_back(Flags);
1531 }
Eric Christopherdccd2c32010-10-11 08:38:55 +00001532
Eric Christopherf9764fa2010-09-30 20:49:44 +00001533 // Handle the arguments now that we've gotten them.
1534 SmallVector<unsigned, 4> RegArgs;
1535 unsigned NumBytes;
1536 if (!ProcessCallArgs(Args, ArgRegs, ArgVTs, ArgFlags, RegArgs, CC, NumBytes))
1537 return false;
Eric Christopherdccd2c32010-10-11 08:38:55 +00001538
Eric Christopherf9764fa2010-09-30 20:49:44 +00001539 // Issue the call, BLXr9 for darwin, BLX otherwise. This uses V5 ops.
Eric Christopherdccd2c32010-10-11 08:38:55 +00001540 // TODO: Turn this into the table of arm call ops.
Eric Christopherf9764fa2010-09-30 20:49:44 +00001541 MachineInstrBuilder MIB;
1542 unsigned CallOpc;
1543 if(isThumb)
1544 CallOpc = Subtarget->isTargetDarwin() ? ARM::tBLXi_r9 : ARM::tBLXi;
1545 else
1546 CallOpc = Subtarget->isTargetDarwin() ? ARM::BLr9 : ARM::BL;
1547 MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(CallOpc))
1548 .addGlobalAddress(GV, 0, 0);
Eric Christopherdccd2c32010-10-11 08:38:55 +00001549
Eric Christopherf9764fa2010-09-30 20:49:44 +00001550 // Add implicit physical register uses to the call.
1551 for (unsigned i = 0, e = RegArgs.size(); i != e; ++i)
1552 MIB.addReg(RegArgs[i]);
Eric Christopherdccd2c32010-10-11 08:38:55 +00001553
Eric Christopherf9764fa2010-09-30 20:49:44 +00001554 // Finish off the call including any return values.
Eric Christopherdccd2c32010-10-11 08:38:55 +00001555 SmallVector<unsigned, 4> UsedRegs;
Eric Christopherf9764fa2010-09-30 20:49:44 +00001556 if (!FinishCall(RetVT, UsedRegs, I, CC, NumBytes)) return false;
Eric Christopherdccd2c32010-10-11 08:38:55 +00001557
Eric Christopherf9764fa2010-09-30 20:49:44 +00001558 // Set all unused physreg defs as dead.
1559 static_cast<MachineInstr *>(MIB)->setPhysRegsDeadExcept(UsedRegs, TRI);
Eric Christopherdccd2c32010-10-11 08:38:55 +00001560
Eric Christopherf9764fa2010-09-30 20:49:44 +00001561 return true;
Eric Christopherdccd2c32010-10-11 08:38:55 +00001562
Eric Christopherf9764fa2010-09-30 20:49:44 +00001563}
1564
Eric Christopher56d2b722010-09-02 23:43:26 +00001565// TODO: SoftFP support.
Eric Christopherab695882010-07-21 22:26:11 +00001566bool ARMFastISel::TargetSelectInstruction(const Instruction *I) {
Eric Christopher7fe55b72010-08-23 22:32:45 +00001567 // No Thumb-1 for now.
Eric Christophereaa204b2010-09-02 01:39:14 +00001568 if (isThumb && !AFI->isThumb2Function()) return false;
Eric Christopherac1a19e2010-09-09 01:06:51 +00001569
Eric Christopherab695882010-07-21 22:26:11 +00001570 switch (I->getOpcode()) {
Eric Christopher83007122010-08-23 21:44:12 +00001571 case Instruction::Load:
Eric Christopher43b62be2010-09-27 06:02:23 +00001572 return SelectLoad(I);
Eric Christopher543cf052010-09-01 22:16:27 +00001573 case Instruction::Store:
Eric Christopher43b62be2010-09-27 06:02:23 +00001574 return SelectStore(I);
Eric Christophere5734102010-09-03 00:35:47 +00001575 case Instruction::Br:
Eric Christopher43b62be2010-09-27 06:02:23 +00001576 return SelectBranch(I);
Eric Christopherd43393a2010-09-08 23:13:45 +00001577 case Instruction::ICmp:
1578 case Instruction::FCmp:
Eric Christopher43b62be2010-09-27 06:02:23 +00001579 return SelectCmp(I);
Eric Christopher46203602010-09-09 00:26:48 +00001580 case Instruction::FPExt:
Eric Christopher43b62be2010-09-27 06:02:23 +00001581 return SelectFPExt(I);
Eric Christopherce07b542010-09-09 20:26:31 +00001582 case Instruction::FPTrunc:
Eric Christopher43b62be2010-09-27 06:02:23 +00001583 return SelectFPTrunc(I);
Eric Christopher9a040492010-09-09 18:54:59 +00001584 case Instruction::SIToFP:
Eric Christopher43b62be2010-09-27 06:02:23 +00001585 return SelectSIToFP(I);
Eric Christopher9a040492010-09-09 18:54:59 +00001586 case Instruction::FPToSI:
Eric Christopher43b62be2010-09-27 06:02:23 +00001587 return SelectFPToSI(I);
Eric Christopherbc39b822010-09-09 00:53:57 +00001588 case Instruction::FAdd:
Eric Christopher43b62be2010-09-27 06:02:23 +00001589 return SelectBinaryOp(I, ISD::FADD);
Eric Christopherbc39b822010-09-09 00:53:57 +00001590 case Instruction::FSub:
Eric Christopher43b62be2010-09-27 06:02:23 +00001591 return SelectBinaryOp(I, ISD::FSUB);
Eric Christopherbc39b822010-09-09 00:53:57 +00001592 case Instruction::FMul:
Eric Christopher43b62be2010-09-27 06:02:23 +00001593 return SelectBinaryOp(I, ISD::FMUL);
Eric Christopherbb3e5da2010-09-14 23:03:37 +00001594 case Instruction::SDiv:
Eric Christopher43b62be2010-09-27 06:02:23 +00001595 return SelectSDiv(I);
Eric Christopher6a880d62010-10-11 08:37:26 +00001596 case Instruction::SRem:
1597 return SelectSRem(I);
Eric Christopherf9764fa2010-09-30 20:49:44 +00001598 case Instruction::Call:
1599 return SelectCall(I);
Eric Christopher3bbd3962010-10-11 08:27:59 +00001600 case Instruction::Select:
1601 return SelectSelect(I);
Eric Christopherab695882010-07-21 22:26:11 +00001602 default: break;
1603 }
1604 return false;
1605}
1606
1607namespace llvm {
1608 llvm::FastISel *ARM::createFastISel(FunctionLoweringInfo &funcInfo) {
Eric Christopherfeadddd2010-10-11 20:05:22 +00001609 // Completely untested on non-darwin.
1610 const TargetMachine &TM = funcInfo.MF->getTarget();
1611 const ARMSubtarget *Subtarget = &TM.getSubtarget<ARMSubtarget>();
Eric Christopher8ff9a9d2010-10-11 20:26:21 +00001612 if (Subtarget->isTargetDarwin() && EnableARMFastISel)
Eric Christopherfeadddd2010-10-11 20:05:22 +00001613 return new ARMFastISel(funcInfo);
Evan Cheng09447952010-07-26 18:32:55 +00001614 return 0;
Eric Christopherab695882010-07-21 22:26:11 +00001615 }
1616}