Add FPTrunc, fix some bugs where I forgot to update the value map.
[oota-llvm.git] / lib / Target / ARM / ARMFastISel.cpp
1 //===-- 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"
17 #include "ARMBaseInstrInfo.h"
18 #include "ARMRegisterInfo.h"
19 #include "ARMTargetMachine.h"
20 #include "ARMSubtarget.h"
21 #include "llvm/CallingConv.h"
22 #include "llvm/DerivedTypes.h"
23 #include "llvm/GlobalVariable.h"
24 #include "llvm/Instructions.h"
25 #include "llvm/IntrinsicInst.h"
26 #include "llvm/CodeGen/Analysis.h"
27 #include "llvm/CodeGen/FastISel.h"
28 #include "llvm/CodeGen/FunctionLoweringInfo.h"
29 #include "llvm/CodeGen/MachineInstrBuilder.h"
30 #include "llvm/CodeGen/MachineModuleInfo.h"
31 #include "llvm/CodeGen/MachineConstantPool.h"
32 #include "llvm/CodeGen/MachineFrameInfo.h"
33 #include "llvm/CodeGen/MachineRegisterInfo.h"
34 #include "llvm/Support/CallSite.h"
35 #include "llvm/Support/CommandLine.h"
36 #include "llvm/Support/ErrorHandling.h"
37 #include "llvm/Support/GetElementPtrTypeIterator.h"
38 #include "llvm/Target/TargetData.h"
39 #include "llvm/Target/TargetInstrInfo.h"
40 #include "llvm/Target/TargetLowering.h"
41 #include "llvm/Target/TargetMachine.h"
42 #include "llvm/Target/TargetOptions.h"
43 using namespace llvm;
44
45 static cl::opt<bool>
46 EnableARMFastISel("arm-fast-isel",
47                   cl::desc("Turn on experimental ARM fast-isel support"),
48                   cl::init(false), cl::Hidden);
49
50 namespace {
51
52 class ARMFastISel : public FastISel {
53
54   /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can
55   /// make the right decision when generating code for different targets.
56   const ARMSubtarget *Subtarget;
57   const TargetMachine &TM;
58   const TargetInstrInfo &TII;
59   const TargetLowering &TLI;
60   const ARMFunctionInfo *AFI;
61
62   // Convenience variable to avoid checking all the time.
63   bool isThumb;
64
65   public:
66     explicit ARMFastISel(FunctionLoweringInfo &funcInfo)
67     : FastISel(funcInfo),
68       TM(funcInfo.MF->getTarget()),
69       TII(*TM.getInstrInfo()),
70       TLI(*TM.getTargetLowering()) {
71       Subtarget = &TM.getSubtarget<ARMSubtarget>();
72       AFI = funcInfo.MF->getInfo<ARMFunctionInfo>();
73       isThumb = AFI->isThumbFunction();
74     }
75
76     // Code from FastISel.cpp.
77     virtual unsigned FastEmitInst_(unsigned MachineInstOpcode,
78                                    const TargetRegisterClass *RC);
79     virtual unsigned FastEmitInst_r(unsigned MachineInstOpcode,
80                                     const TargetRegisterClass *RC,
81                                     unsigned Op0, bool Op0IsKill);
82     virtual unsigned FastEmitInst_rr(unsigned MachineInstOpcode,
83                                      const TargetRegisterClass *RC,
84                                      unsigned Op0, bool Op0IsKill,
85                                      unsigned Op1, bool Op1IsKill);
86     virtual unsigned FastEmitInst_ri(unsigned MachineInstOpcode,
87                                      const TargetRegisterClass *RC,
88                                      unsigned Op0, bool Op0IsKill,
89                                      uint64_t Imm);
90     virtual unsigned FastEmitInst_rf(unsigned MachineInstOpcode,
91                                      const TargetRegisterClass *RC,
92                                      unsigned Op0, bool Op0IsKill,
93                                      const ConstantFP *FPImm);
94     virtual unsigned FastEmitInst_i(unsigned MachineInstOpcode,
95                                     const TargetRegisterClass *RC,
96                                     uint64_t Imm);
97     virtual unsigned FastEmitInst_rri(unsigned MachineInstOpcode,
98                                       const TargetRegisterClass *RC,
99                                       unsigned Op0, bool Op0IsKill,
100                                       unsigned Op1, bool Op1IsKill,
101                                       uint64_t Imm);
102     virtual unsigned FastEmitInst_extractsubreg(MVT RetVT,
103                                                 unsigned Op0, bool Op0IsKill,
104                                                 uint32_t Idx);
105
106     // Backend specific FastISel code.
107     virtual bool TargetSelectInstruction(const Instruction *I);
108     virtual unsigned TargetMaterializeConstant(const Constant *C);
109
110   #include "ARMGenFastISel.inc"
111
112     // Instruction selection routines.
113     virtual bool ARMSelectLoad(const Instruction *I);
114     virtual bool ARMSelectStore(const Instruction *I);
115     virtual bool ARMSelectBranch(const Instruction *I);
116     virtual bool ARMSelectCmp(const Instruction *I);
117     virtual bool ARMSelectFPExt(const Instruction *I);
118     virtual bool ARMSelectFPTrunc(const Instruction *I);
119     virtual bool ARMSelectBinaryOp(const Instruction *I, unsigned ISDOpcode);
120     virtual bool ARMSelectSIToFP(const Instruction *I);
121     virtual bool ARMSelectFPToSI(const Instruction *I);
122
123     // Utility routines.
124   private:
125     bool isTypeLegal(const Type *Ty, EVT &VT);
126     bool isLoadTypeLegal(const Type *Ty, EVT &VT);
127     bool ARMEmitLoad(EVT VT, unsigned &ResultReg, unsigned Reg, int Offset);
128     bool ARMEmitStore(EVT VT, unsigned SrcReg, unsigned Reg, int Offset);
129     bool ARMLoadAlloca(const Instruction *I, EVT VT);
130     bool ARMStoreAlloca(const Instruction *I, unsigned SrcReg, EVT VT);
131     bool ARMComputeRegOffset(const Value *Obj, unsigned &Reg, int &Offset);
132     unsigned ARMMaterializeFP(const ConstantFP *CFP, EVT VT);
133     unsigned ARMMaterializeInt(const Constant *C);
134
135     bool DefinesOptionalPredicate(MachineInstr *MI, bool *CPSR);
136     const MachineInstrBuilder &AddOptionalDefs(const MachineInstrBuilder &MIB);
137 };
138
139 } // end anonymous namespace
140
141 // #include "ARMGenCallingConv.inc"
142
143 // DefinesOptionalPredicate - This is different from DefinesPredicate in that
144 // we don't care about implicit defs here, just places we'll need to add a
145 // default CCReg argument. Sets CPSR if we're setting CPSR instead of CCR.
146 bool ARMFastISel::DefinesOptionalPredicate(MachineInstr *MI, bool *CPSR) {
147   const TargetInstrDesc &TID = MI->getDesc();
148   if (!TID.hasOptionalDef())
149     return false;
150
151   // Look to see if our OptionalDef is defining CPSR or CCR.
152   for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
153     const MachineOperand &MO = MI->getOperand(i);
154     if (!MO.isReg() || !MO.isDef()) continue;
155     if (MO.getReg() == ARM::CPSR)
156       *CPSR = true;
157   }
158   return true;
159 }
160
161 // If the machine is predicable go ahead and add the predicate operands, if
162 // it needs default CC operands add those.
163 const MachineInstrBuilder &
164 ARMFastISel::AddOptionalDefs(const MachineInstrBuilder &MIB) {
165   MachineInstr *MI = &*MIB;
166
167   // Do we use a predicate?
168   if (TII.isPredicable(MI))
169     AddDefaultPred(MIB);
170
171   // Do we optionally set a predicate?  Preds is size > 0 iff the predicate
172   // defines CPSR. All other OptionalDefines in ARM are the CCR register.
173   bool CPSR = false;
174   if (DefinesOptionalPredicate(MI, &CPSR)) {
175     if (CPSR)
176       AddDefaultT1CC(MIB);
177     else
178       AddDefaultCC(MIB);
179   }
180   return MIB;
181 }
182
183 unsigned ARMFastISel::FastEmitInst_(unsigned MachineInstOpcode,
184                                     const TargetRegisterClass* RC) {
185   unsigned ResultReg = createResultReg(RC);
186   const TargetInstrDesc &II = TII.get(MachineInstOpcode);
187
188   AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg));
189   return ResultReg;
190 }
191
192 unsigned ARMFastISel::FastEmitInst_r(unsigned MachineInstOpcode,
193                                      const TargetRegisterClass *RC,
194                                      unsigned Op0, bool Op0IsKill) {
195   unsigned ResultReg = createResultReg(RC);
196   const TargetInstrDesc &II = TII.get(MachineInstOpcode);
197
198   if (II.getNumDefs() >= 1)
199     AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
200                    .addReg(Op0, Op0IsKill * RegState::Kill));
201   else {
202     AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
203                    .addReg(Op0, Op0IsKill * RegState::Kill));
204     AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
205                    TII.get(TargetOpcode::COPY), ResultReg)
206                    .addReg(II.ImplicitDefs[0]));
207   }
208   return ResultReg;
209 }
210
211 unsigned ARMFastISel::FastEmitInst_rr(unsigned MachineInstOpcode,
212                                       const TargetRegisterClass *RC,
213                                       unsigned Op0, bool Op0IsKill,
214                                       unsigned Op1, bool Op1IsKill) {
215   unsigned ResultReg = createResultReg(RC);
216   const TargetInstrDesc &II = TII.get(MachineInstOpcode);
217
218   if (II.getNumDefs() >= 1)
219     AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
220                    .addReg(Op0, Op0IsKill * RegState::Kill)
221                    .addReg(Op1, Op1IsKill * RegState::Kill));
222   else {
223     AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
224                    .addReg(Op0, Op0IsKill * RegState::Kill)
225                    .addReg(Op1, Op1IsKill * RegState::Kill));
226     AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
227                            TII.get(TargetOpcode::COPY), ResultReg)
228                    .addReg(II.ImplicitDefs[0]));
229   }
230   return ResultReg;
231 }
232
233 unsigned ARMFastISel::FastEmitInst_ri(unsigned MachineInstOpcode,
234                                       const TargetRegisterClass *RC,
235                                       unsigned Op0, bool Op0IsKill,
236                                       uint64_t Imm) {
237   unsigned ResultReg = createResultReg(RC);
238   const TargetInstrDesc &II = TII.get(MachineInstOpcode);
239
240   if (II.getNumDefs() >= 1)
241     AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
242                    .addReg(Op0, Op0IsKill * RegState::Kill)
243                    .addImm(Imm));
244   else {
245     AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
246                    .addReg(Op0, Op0IsKill * RegState::Kill)
247                    .addImm(Imm));
248     AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
249                            TII.get(TargetOpcode::COPY), ResultReg)
250                    .addReg(II.ImplicitDefs[0]));
251   }
252   return ResultReg;
253 }
254
255 unsigned ARMFastISel::FastEmitInst_rf(unsigned MachineInstOpcode,
256                                       const TargetRegisterClass *RC,
257                                       unsigned Op0, bool Op0IsKill,
258                                       const ConstantFP *FPImm) {
259   unsigned ResultReg = createResultReg(RC);
260   const TargetInstrDesc &II = TII.get(MachineInstOpcode);
261
262   if (II.getNumDefs() >= 1)
263     AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
264                    .addReg(Op0, Op0IsKill * RegState::Kill)
265                    .addFPImm(FPImm));
266   else {
267     AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
268                    .addReg(Op0, Op0IsKill * RegState::Kill)
269                    .addFPImm(FPImm));
270     AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
271                            TII.get(TargetOpcode::COPY), ResultReg)
272                    .addReg(II.ImplicitDefs[0]));
273   }
274   return ResultReg;
275 }
276
277 unsigned ARMFastISel::FastEmitInst_rri(unsigned MachineInstOpcode,
278                                        const TargetRegisterClass *RC,
279                                        unsigned Op0, bool Op0IsKill,
280                                        unsigned Op1, bool Op1IsKill,
281                                        uint64_t Imm) {
282   unsigned ResultReg = createResultReg(RC);
283   const TargetInstrDesc &II = TII.get(MachineInstOpcode);
284
285   if (II.getNumDefs() >= 1)
286     AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
287                    .addReg(Op0, Op0IsKill * RegState::Kill)
288                    .addReg(Op1, Op1IsKill * RegState::Kill)
289                    .addImm(Imm));
290   else {
291     AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
292                    .addReg(Op0, Op0IsKill * RegState::Kill)
293                    .addReg(Op1, Op1IsKill * RegState::Kill)
294                    .addImm(Imm));
295     AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
296                            TII.get(TargetOpcode::COPY), ResultReg)
297                    .addReg(II.ImplicitDefs[0]));
298   }
299   return ResultReg;
300 }
301
302 unsigned ARMFastISel::FastEmitInst_i(unsigned MachineInstOpcode,
303                                      const TargetRegisterClass *RC,
304                                      uint64_t Imm) {
305   unsigned ResultReg = createResultReg(RC);
306   const TargetInstrDesc &II = TII.get(MachineInstOpcode);
307
308   if (II.getNumDefs() >= 1)
309     AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
310                    .addImm(Imm));
311   else {
312     AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
313                    .addImm(Imm));
314     AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
315                            TII.get(TargetOpcode::COPY), ResultReg)
316                    .addReg(II.ImplicitDefs[0]));
317   }
318   return ResultReg;
319 }
320
321 unsigned ARMFastISel::FastEmitInst_extractsubreg(MVT RetVT,
322                                                  unsigned Op0, bool Op0IsKill,
323                                                  uint32_t Idx) {
324   unsigned ResultReg = createResultReg(TLI.getRegClassFor(RetVT));
325   assert(TargetRegisterInfo::isVirtualRegister(Op0) &&
326          "Cannot yet extract from physregs");
327   AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt,
328                          DL, TII.get(TargetOpcode::COPY), ResultReg)
329                  .addReg(Op0, getKillRegState(Op0IsKill), Idx));
330   return ResultReg;
331 }
332
333 // For double width floating point we need to materialize two constants
334 // (the high and the low) into integer registers then use a move to get
335 // the combined constant into an FP reg.
336 unsigned ARMFastISel::ARMMaterializeFP(const ConstantFP *CFP, EVT VT) {
337   const APFloat Val = CFP->getValueAPF();
338   bool is64bit = VT.getSimpleVT().SimpleTy == MVT::f64;
339
340   // This checks to see if we can use VFP3 instructions to materialize
341   // a constant, otherwise we have to go through the constant pool.
342   if (TLI.isFPImmLegal(Val, VT)) {
343     unsigned Opc = is64bit ? ARM::FCONSTD : ARM::FCONSTS;
344     unsigned DestReg = createResultReg(TLI.getRegClassFor(VT));
345     AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc),
346                             DestReg)
347                     .addFPImm(CFP));
348     return DestReg;
349   }
350
351   // No 64-bit at the moment.
352   if (is64bit) return 0;
353
354   // Load this from the constant pool.
355   unsigned DestReg = ARMMaterializeInt(cast<Constant>(CFP));
356
357   // If we have a floating point constant we expect it in a floating point
358   // register.
359   unsigned MoveReg = createResultReg(TLI.getRegClassFor(VT));
360   AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
361                           TII.get(ARM::VMOVRS), MoveReg)
362                   .addReg(DestReg));
363   return MoveReg;
364 }
365
366 unsigned ARMFastISel::ARMMaterializeInt(const Constant *C) {
367   // MachineConstantPool wants an explicit alignment.
368   unsigned Align = TD.getPrefTypeAlignment(C->getType());
369   if (Align == 0) {
370     // TODO: Figure out if this is correct.
371     Align = TD.getTypeAllocSize(C->getType());
372   }
373   unsigned Idx = MCP.getConstantPoolIndex(C, Align);
374
375   unsigned DestReg = createResultReg(TLI.getRegClassFor(MVT::i32));
376   if (isThumb)
377     AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
378                             TII.get(ARM::t2LDRpci))
379                     .addReg(DestReg).addConstantPoolIndex(Idx));
380   else
381     AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
382                             TII.get(ARM::LDRcp))
383                             .addReg(DestReg).addConstantPoolIndex(Idx)
384                     .addReg(0).addImm(0));
385
386   return DestReg;
387 }
388
389 unsigned ARMFastISel::TargetMaterializeConstant(const Constant *C) {
390   EVT VT = TLI.getValueType(C->getType(), true);
391
392   // Only handle simple types.
393   if (!VT.isSimple()) return 0;
394
395   if (const ConstantFP *CFP = dyn_cast<ConstantFP>(C))
396     return ARMMaterializeFP(CFP, VT);
397   return ARMMaterializeInt(C);
398 }
399
400 bool ARMFastISel::isTypeLegal(const Type *Ty, EVT &VT) {
401   VT = TLI.getValueType(Ty, true);
402
403   // Only handle simple types.
404   if (VT == MVT::Other || !VT.isSimple()) return false;
405
406   // Handle all legal types, i.e. a register that will directly hold this
407   // value.
408   return TLI.isTypeLegal(VT);
409 }
410
411 bool ARMFastISel::isLoadTypeLegal(const Type *Ty, EVT &VT) {
412   if (isTypeLegal(Ty, VT)) return true;
413
414   // If this is a type than can be sign or zero-extended to a basic operation
415   // go ahead and accept it now.
416   if (VT == MVT::i8 || VT == MVT::i16)
417     return true;
418
419   return false;
420 }
421
422 // Computes the Reg+Offset to get to an object.
423 bool ARMFastISel::ARMComputeRegOffset(const Value *Obj, unsigned &Reg,
424                                       int &Offset) {
425   // Some boilerplate from the X86 FastISel.
426   const User *U = NULL;
427   unsigned Opcode = Instruction::UserOp1;
428   if (const Instruction *I = dyn_cast<Instruction>(Obj)) {
429     // Don't walk into other basic blocks; it's possible we haven't
430     // visited them yet, so the instructions may not yet be assigned
431     // virtual registers.
432     if (FuncInfo.MBBMap[I->getParent()] != FuncInfo.MBB)
433       return false;
434
435     Opcode = I->getOpcode();
436     U = I;
437   } else if (const ConstantExpr *C = dyn_cast<ConstantExpr>(Obj)) {
438     Opcode = C->getOpcode();
439     U = C;
440   }
441
442   if (const PointerType *Ty = dyn_cast<PointerType>(Obj->getType()))
443     if (Ty->getAddressSpace() > 255)
444       // Fast instruction selection doesn't support the special
445       // address spaces.
446       return false;
447
448   switch (Opcode) {
449     default:
450     //errs() << "Failing Opcode is: " << *Op1 << "\n";
451     break;
452     case Instruction::Alloca: {
453       assert(false && "Alloca should have been handled earlier!");
454       return false;
455     }
456   }
457
458   if (const GlobalValue *GV = dyn_cast<GlobalValue>(Obj)) {
459     //errs() << "Failing GV is: " << GV << "\n";
460     (void)GV;
461     return false;
462   }
463
464   // Try to get this in a register if nothing else has worked.
465   Reg = getRegForValue(Obj);
466   if (Reg == 0) return false;
467
468   // Since the offset may be too large for the load instruction
469   // get the reg+offset into a register.
470   // TODO: Verify the additions work, otherwise we'll need to add the
471   // offset instead of 0 to the instructions and do all sorts of operand
472   // munging.
473   // TODO: Optimize this somewhat.
474   if (Offset != 0) {
475     ARMCC::CondCodes Pred = ARMCC::AL;
476     unsigned PredReg = 0;
477
478     if (!isThumb)
479       emitARMRegPlusImmediate(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
480                               Reg, Reg, Offset, Pred, PredReg,
481                               static_cast<const ARMBaseInstrInfo&>(TII));
482     else {
483       assert(AFI->isThumb2Function());
484       emitT2RegPlusImmediate(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
485                              Reg, Reg, Offset, Pred, PredReg,
486                              static_cast<const ARMBaseInstrInfo&>(TII));
487     }
488   }
489
490   return true;
491 }
492
493 bool ARMFastISel::ARMLoadAlloca(const Instruction *I, EVT VT) {
494   Value *Op0 = I->getOperand(0);
495
496   // Verify it's an alloca.
497   if (const AllocaInst *AI = dyn_cast<AllocaInst>(Op0)) {
498     DenseMap<const AllocaInst*, int>::iterator SI =
499       FuncInfo.StaticAllocaMap.find(AI);
500
501     if (SI != FuncInfo.StaticAllocaMap.end()) {
502       TargetRegisterClass* RC = TLI.getRegClassFor(VT);
503       unsigned ResultReg = createResultReg(RC);
504       TII.loadRegFromStackSlot(*FuncInfo.MBB, *FuncInfo.InsertPt,
505                                ResultReg, SI->second, RC,
506                                TM.getRegisterInfo());
507       UpdateValueMap(I, ResultReg);
508       return true;
509     }
510   }
511   return false;
512 }
513
514 bool ARMFastISel::ARMEmitLoad(EVT VT, unsigned &ResultReg,
515                               unsigned Reg, int Offset) {
516
517   assert(VT.isSimple() && "Non-simple types are invalid here!");
518   unsigned Opc;
519
520   switch (VT.getSimpleVT().SimpleTy) {
521     default:
522       assert(false && "Trying to emit for an unhandled type!");
523       return false;
524     case MVT::i16:
525       Opc = isThumb ? ARM::tLDRH : ARM::LDRH;
526       VT = MVT::i32;
527       break;
528     case MVT::i8:
529       Opc = isThumb ? ARM::tLDRB : ARM::LDRB;
530       VT = MVT::i32;
531       break;
532     case MVT::i32:
533       Opc = isThumb ? ARM::tLDR : ARM::LDR;
534       break;
535   }
536
537   ResultReg = createResultReg(TLI.getRegClassFor(VT));
538
539   // TODO: Fix the Addressing modes so that these can share some code.
540   // Since this is a Thumb1 load this will work in Thumb1 or 2 mode.
541   if (isThumb)
542     AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
543                             TII.get(Opc), ResultReg)
544                     .addReg(Reg).addImm(Offset).addReg(0));
545   else
546     AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
547                             TII.get(Opc), ResultReg)
548                     .addReg(Reg).addReg(0).addImm(Offset));
549   return true;
550 }
551
552 bool ARMFastISel::ARMStoreAlloca(const Instruction *I, unsigned SrcReg, EVT VT){
553   Value *Op1 = I->getOperand(1);
554
555   // Verify it's an alloca.
556   if (const AllocaInst *AI = dyn_cast<AllocaInst>(Op1)) {
557     DenseMap<const AllocaInst*, int>::iterator SI =
558       FuncInfo.StaticAllocaMap.find(AI);
559
560     if (SI != FuncInfo.StaticAllocaMap.end()) {
561       TargetRegisterClass* RC = TLI.getRegClassFor(VT);
562       assert(SrcReg != 0 && "Nothing to store!");
563       TII.storeRegToStackSlot(*FuncInfo.MBB, *FuncInfo.InsertPt,
564                               SrcReg, true /*isKill*/, SI->second, RC,
565                               TM.getRegisterInfo());
566       return true;
567     }
568   }
569   return false;
570 }
571
572 bool ARMFastISel::ARMEmitStore(EVT VT, unsigned SrcReg,
573                                unsigned DstReg, int Offset) {
574   unsigned StrOpc;
575   switch (VT.getSimpleVT().SimpleTy) {
576     default: return false;
577     case MVT::i1:
578     case MVT::i8: StrOpc = isThumb ? ARM::tSTRB : ARM::STRB; break;
579     case MVT::i16: StrOpc = isThumb ? ARM::tSTRH : ARM::STRH; break;
580     case MVT::i32: StrOpc = isThumb ? ARM::tSTR : ARM::STR; break;
581     case MVT::f32:
582       if (!Subtarget->hasVFP2()) return false;
583       StrOpc = ARM::VSTRS;
584       break;
585     case MVT::f64:
586       if (!Subtarget->hasVFP2()) return false;
587       StrOpc = ARM::VSTRD;
588       break;
589   }
590
591   if (isThumb)
592     AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
593                             TII.get(StrOpc), SrcReg)
594                     .addReg(DstReg).addImm(Offset).addReg(0));
595   else
596     AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
597                             TII.get(StrOpc), SrcReg)
598                     .addReg(DstReg).addReg(0).addImm(Offset));
599
600   return true;
601 }
602
603 bool ARMFastISel::ARMSelectStore(const Instruction *I) {
604   Value *Op0 = I->getOperand(0);
605   unsigned SrcReg = 0;
606
607   // Yay type legalization
608   EVT VT;
609   if (!isLoadTypeLegal(I->getOperand(0)->getType(), VT))
610     return false;
611
612   // Get the value to be stored into a register.
613   SrcReg = getRegForValue(Op0);
614   if (SrcReg == 0)
615     return false;
616
617   // If we're an alloca we know we have a frame index and can emit the store
618   // quickly.
619   if (ARMStoreAlloca(I, SrcReg, VT))
620     return true;
621
622   // Our register and offset with innocuous defaults.
623   unsigned Reg = 0;
624   int Offset = 0;
625
626   // See if we can handle this as Reg + Offset
627   if (!ARMComputeRegOffset(I->getOperand(1), Reg, Offset))
628     return false;
629
630   if (!ARMEmitStore(VT, SrcReg, Reg, Offset /* 0 */)) return false;
631
632   return false;
633 }
634
635 bool ARMFastISel::ARMSelectLoad(const Instruction *I) {
636   // Verify we have a legal type before going any further.
637   EVT VT;
638   if (!isLoadTypeLegal(I->getType(), VT))
639     return false;
640
641   // If we're an alloca we know we have a frame index and can emit the load
642   // directly in short order.
643   if (ARMLoadAlloca(I, VT))
644     return true;
645
646   // Our register and offset with innocuous defaults.
647   unsigned Reg = 0;
648   int Offset = 0;
649
650   // See if we can handle this as Reg + Offset
651   if (!ARMComputeRegOffset(I->getOperand(0), Reg, Offset))
652     return false;
653
654   unsigned ResultReg;
655   if (!ARMEmitLoad(VT, ResultReg, Reg, Offset /* 0 */)) return false;
656
657   UpdateValueMap(I, ResultReg);
658   return true;
659 }
660
661 bool ARMFastISel::ARMSelectBranch(const Instruction *I) {
662   const BranchInst *BI = cast<BranchInst>(I);
663   MachineBasicBlock *TBB = FuncInfo.MBBMap[BI->getSuccessor(0)];
664   MachineBasicBlock *FBB = FuncInfo.MBBMap[BI->getSuccessor(1)];
665
666   // Simple branch support.
667   unsigned CondReg = getRegForValue(BI->getCondition());
668   if (CondReg == 0) return false;
669
670   unsigned CmpOpc = isThumb ? ARM::t2CMPrr : ARM::CMPrr;
671   unsigned BrOpc = isThumb ? ARM::t2Bcc : ARM::Bcc;
672   AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(CmpOpc))
673                   .addReg(CondReg).addReg(CondReg));
674   BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(BrOpc))
675                   .addMBB(TBB).addImm(ARMCC::NE).addReg(ARM::CPSR);
676   FastEmitBranch(FBB, DL);
677   FuncInfo.MBB->addSuccessor(TBB);
678   return true;
679 }
680
681 bool ARMFastISel::ARMSelectCmp(const Instruction *I) {
682   const CmpInst *CI = cast<CmpInst>(I);
683
684   EVT VT;
685   const Type *Ty = CI->getOperand(0)->getType();
686   if (!isTypeLegal(Ty, VT))
687     return false;
688
689   bool isFloat = (Ty->isDoubleTy() || Ty->isFloatTy());
690   if (isFloat && !Subtarget->hasVFP2())
691     return false;
692
693   unsigned CmpOpc;
694   switch (VT.getSimpleVT().SimpleTy) {
695     default: return false;
696     // TODO: Verify compares.
697     case MVT::f32:
698       CmpOpc = ARM::VCMPES;
699       break;
700     case MVT::f64:
701       CmpOpc = ARM::VCMPED;
702       break;
703     case MVT::i32:
704       CmpOpc = isThumb ? ARM::t2CMPrr : ARM::CMPrr;
705       break;
706   }
707
708   unsigned Arg1 = getRegForValue(CI->getOperand(0));
709   if (Arg1 == 0) return false;
710
711   unsigned Arg2 = getRegForValue(CI->getOperand(1));
712   if (Arg2 == 0) return false;
713
714   AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(CmpOpc))
715                   .addReg(Arg1).addReg(Arg2));
716
717   // For floating point we need to move the result to a register we can
718   // actually do something with.
719   if (isFloat)
720     AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
721                             TII.get(ARM::FMSTAT)));
722
723   // TODO: How to update the value map when there's no result reg?
724   return true;
725 }
726
727 bool ARMFastISel::ARMSelectFPExt(const Instruction *I) {
728   // Make sure we have VFP and that we're extending float to double.
729   if (!Subtarget->hasVFP2()) return false;
730
731   Value *V = I->getOperand(0);
732   if (!I->getType()->isDoubleTy() ||
733       !V->getType()->isFloatTy()) return false;
734
735   unsigned Op = getRegForValue(V);
736   if (Op == 0) return false;
737
738   unsigned Result = createResultReg(ARM::DPRRegisterClass);
739
740   AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
741                           TII.get(ARM::VCVTSD), Result)
742                   .addReg(Op));
743   UpdateValueMap(I, Result);
744   return true;
745 }
746
747 bool ARMFastISel::ARMSelectFPTrunc(const Instruction *I) {
748   // Make sure we have VFP and that we're truncating double to float.
749   if (!Subtarget->hasVFP2()) return false;
750
751   Value *V = I->getOperand(0);
752   if (!I->getType()->isFloatTy() ||
753       !V->getType()->isDoubleTy()) return false;
754
755   unsigned Op = getRegForValue(V);
756   if (Op == 0) return false;
757
758   unsigned Result = createResultReg(ARM::SPRRegisterClass);
759
760   AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
761                           TII.get(ARM::VCVTDS), Result)
762                   .addReg(Op));
763   UpdateValueMap(I, Result);
764   return true;
765 }
766
767 bool ARMFastISel::ARMSelectSIToFP(const Instruction *I) {
768   // Make sure we have VFP.
769   if (!Subtarget->hasVFP2()) return false;
770   
771   EVT VT;
772   const Type *Ty = I->getType();
773   if (!isTypeLegal(Ty, VT))
774     return false;
775   
776   unsigned Op = getRegForValue(I->getOperand(0));
777   if (Op == 0) return false;
778   
779   unsigned Opc;
780   if (Ty->isFloatTy()) Opc = ARM::VSITOS;
781   else if (Ty->isDoubleTy()) Opc = ARM::VSITOD;
782   else return 0;
783   
784   unsigned ResultReg = createResultReg(TLI.getRegClassFor(VT));
785   AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc),
786                           ResultReg)
787                   .addReg(Op));
788   UpdateValueMap(I, ResultReg);
789   return true;
790 }
791
792 bool ARMFastISel::ARMSelectFPToSI(const Instruction *I) {
793   // Make sure we have VFP.
794   if (!Subtarget->hasVFP2()) return false;
795   
796   EVT VT;
797   const Type *RetTy = I->getType();
798   if (!isTypeLegal(RetTy, VT))
799     return false;
800   
801   unsigned Op = getRegForValue(I->getOperand(0));
802   if (Op == 0) return false;
803   
804   unsigned Opc;
805   const Type *OpTy = I->getOperand(0)->getType();
806   if (OpTy->isFloatTy()) Opc = ARM::VTOSIZS;
807   else if (OpTy->isDoubleTy()) Opc = ARM::VTOSIZD;
808   else return 0;
809   
810   unsigned ResultReg = createResultReg(TLI.getRegClassFor(VT));
811   AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc),
812                           ResultReg)
813                   .addReg(Op));
814   UpdateValueMap(I, ResultReg);
815   return true;
816 }
817
818 bool ARMFastISel::ARMSelectBinaryOp(const Instruction *I, unsigned ISDOpcode) {
819   EVT VT  = TLI.getValueType(I->getType(), true);
820
821   // We can get here in the case when we want to use NEON for our fp
822   // operations, but can't figure out how to. Just use the vfp instructions
823   // if we have them.
824   // FIXME: It'd be nice to use NEON instructions.
825   const Type *Ty = I->getType();
826   bool isFloat = (Ty->isDoubleTy() || Ty->isFloatTy());
827   if (isFloat && !Subtarget->hasVFP2())
828     return false;
829
830   unsigned Op1 = getRegForValue(I->getOperand(0));
831   if (Op1 == 0) return false;
832
833   unsigned Op2 = getRegForValue(I->getOperand(1));
834   if (Op2 == 0) return false;
835
836   unsigned Opc;
837   bool is64bit = VT.getSimpleVT().SimpleTy == MVT::f64 ||
838                  VT.getSimpleVT().SimpleTy == MVT::i64;
839   switch (ISDOpcode) {
840     default: return false;
841     case ISD::FADD:
842       Opc = is64bit ? ARM::VADDD : ARM::VADDS;
843       break;
844     case ISD::FSUB:
845       Opc = is64bit ? ARM::VSUBD : ARM::VSUBS;
846       break;
847     case ISD::FMUL:
848       Opc = is64bit ? ARM::VMULD : ARM::VMULS;
849       break;
850   }
851   unsigned ResultReg = createResultReg(TLI.getRegClassFor(VT));
852   AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
853                           TII.get(Opc), ResultReg)
854                   .addReg(Op1).addReg(Op2));
855   UpdateValueMap(I, ResultReg);
856   return true;
857 }
858
859 // TODO: SoftFP support.
860 bool ARMFastISel::TargetSelectInstruction(const Instruction *I) {
861   // No Thumb-1 for now.
862   if (isThumb && !AFI->isThumb2Function()) return false;
863
864   switch (I->getOpcode()) {
865     case Instruction::Load:
866       return ARMSelectLoad(I);
867     case Instruction::Store:
868       return ARMSelectStore(I);
869     case Instruction::Br:
870       return ARMSelectBranch(I);
871     case Instruction::ICmp:
872     case Instruction::FCmp:
873       return ARMSelectCmp(I);
874     case Instruction::FPExt:
875       return ARMSelectFPExt(I);
876     case Instruction::FPTrunc:
877       return ARMSelectFPTrunc(I);
878     case Instruction::SIToFP:
879       return ARMSelectSIToFP(I);
880     case Instruction::FPToSI:
881       return ARMSelectFPToSI(I);
882     case Instruction::FAdd:
883       return ARMSelectBinaryOp(I, ISD::FADD);
884     case Instruction::FSub:
885       return ARMSelectBinaryOp(I, ISD::FSUB);
886     case Instruction::FMul:
887       return ARMSelectBinaryOp(I, ISD::FMUL);
888     default: break;
889   }
890   return false;
891 }
892
893 namespace llvm {
894   llvm::FastISel *ARM::createFastISel(FunctionLoweringInfo &funcInfo) {
895     if (EnableARMFastISel) return new ARMFastISel(funcInfo);
896     return 0;
897   }
898 }