ARMFastISel.cpp revision 251662
1212793Sdim//===-- ARMFastISel.cpp - ARM FastISel implementation ---------------------===//
2212793Sdim//
3212793Sdim//                     The LLVM Compiler Infrastructure
4212793Sdim//
5212793Sdim// This file is distributed under the University of Illinois Open Source
6212793Sdim// License. See LICENSE.TXT for details.
7212793Sdim//
8212793Sdim//===----------------------------------------------------------------------===//
9212793Sdim//
10212793Sdim// This file defines the ARM-specific support for the FastISel class. Some
11212793Sdim// of the target-specific code is generated by tablegen in the file
12212793Sdim// ARMGenFastISel.inc, which is #included here.
13212793Sdim//
14212793Sdim//===----------------------------------------------------------------------===//
15212793Sdim
16212793Sdim#include "ARM.h"
17212793Sdim#include "ARMBaseInstrInfo.h"
18218893Sdim#include "ARMCallingConv.h"
19249423Sdim#include "ARMConstantPoolValue.h"
20249423Sdim#include "ARMSubtarget.h"
21212793Sdim#include "ARMTargetMachine.h"
22226633Sdim#include "MCTargetDesc/ARMAddressingModes.h"
23212793Sdim#include "llvm/CodeGen/Analysis.h"
24212793Sdim#include "llvm/CodeGen/FastISel.h"
25212793Sdim#include "llvm/CodeGen/FunctionLoweringInfo.h"
26212793Sdim#include "llvm/CodeGen/MachineConstantPool.h"
27212793Sdim#include "llvm/CodeGen/MachineFrameInfo.h"
28249423Sdim#include "llvm/CodeGen/MachineInstrBuilder.h"
29218893Sdim#include "llvm/CodeGen/MachineMemOperand.h"
30249423Sdim#include "llvm/CodeGen/MachineModuleInfo.h"
31212793Sdim#include "llvm/CodeGen/MachineRegisterInfo.h"
32249423Sdim#include "llvm/IR/CallingConv.h"
33249423Sdim#include "llvm/IR/DataLayout.h"
34249423Sdim#include "llvm/IR/DerivedTypes.h"
35249423Sdim#include "llvm/IR/GlobalVariable.h"
36249423Sdim#include "llvm/IR/Instructions.h"
37249423Sdim#include "llvm/IR/IntrinsicInst.h"
38249423Sdim#include "llvm/IR/Module.h"
39249423Sdim#include "llvm/IR/Operator.h"
40212793Sdim#include "llvm/Support/CallSite.h"
41212793Sdim#include "llvm/Support/CommandLine.h"
42212793Sdim#include "llvm/Support/ErrorHandling.h"
43212793Sdim#include "llvm/Support/GetElementPtrTypeIterator.h"
44212793Sdim#include "llvm/Target/TargetInstrInfo.h"
45212793Sdim#include "llvm/Target/TargetLowering.h"
46212793Sdim#include "llvm/Target/TargetMachine.h"
47212793Sdim#include "llvm/Target/TargetOptions.h"
48212793Sdimusing namespace llvm;
49212793Sdim
50218893Sdimextern cl::opt<bool> EnableARMLongCalls;
51218893Sdim
52212793Sdimnamespace {
53212793Sdim
54218893Sdim  // All possible address modes, plus some.
55218893Sdim  typedef struct Address {
56218893Sdim    enum {
57218893Sdim      RegBase,
58218893Sdim      FrameIndexBase
59218893Sdim    } BaseType;
60218893Sdim
61218893Sdim    union {
62218893Sdim      unsigned Reg;
63218893Sdim      int FI;
64218893Sdim    } Base;
65218893Sdim
66218893Sdim    int Offset;
67218893Sdim
68218893Sdim    // Innocuous defaults for our address.
69218893Sdim    Address()
70223017Sdim     : BaseType(RegBase), Offset(0) {
71218893Sdim       Base.Reg = 0;
72218893Sdim     }
73218893Sdim  } Address;
74218893Sdim
75212793Sdimclass ARMFastISel : public FastISel {
76212793Sdim
77212793Sdim  /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can
78212793Sdim  /// make the right decision when generating code for different targets.
79212793Sdim  const ARMSubtarget *Subtarget;
80212793Sdim  const TargetMachine &TM;
81212793Sdim  const TargetInstrInfo &TII;
82212793Sdim  const TargetLowering &TLI;
83218893Sdim  ARMFunctionInfo *AFI;
84212793Sdim
85218893Sdim  // Convenience variables to avoid some queries.
86234353Sdim  bool isThumb2;
87218893Sdim  LLVMContext *Context;
88212793Sdim
89212793Sdim  public:
90239462Sdim    explicit ARMFastISel(FunctionLoweringInfo &funcInfo,
91239462Sdim                         const TargetLibraryInfo *libInfo)
92239462Sdim    : FastISel(funcInfo, libInfo),
93212793Sdim      TM(funcInfo.MF->getTarget()),
94212793Sdim      TII(*TM.getInstrInfo()),
95212793Sdim      TLI(*TM.getTargetLowering()) {
96212793Sdim      Subtarget = &TM.getSubtarget<ARMSubtarget>();
97212793Sdim      AFI = funcInfo.MF->getInfo<ARMFunctionInfo>();
98234353Sdim      isThumb2 = AFI->isThumbFunction();
99218893Sdim      Context = &funcInfo.Fn->getContext();
100212793Sdim    }
101212793Sdim
102212793Sdim    // Code from FastISel.cpp.
103243830Sdim  private:
104243830Sdim    unsigned FastEmitInst_(unsigned MachineInstOpcode,
105243830Sdim                           const TargetRegisterClass *RC);
106243830Sdim    unsigned FastEmitInst_r(unsigned MachineInstOpcode,
107243830Sdim                            const TargetRegisterClass *RC,
108243830Sdim                            unsigned Op0, bool Op0IsKill);
109243830Sdim    unsigned FastEmitInst_rr(unsigned MachineInstOpcode,
110243830Sdim                             const TargetRegisterClass *RC,
111243830Sdim                             unsigned Op0, bool Op0IsKill,
112243830Sdim                             unsigned Op1, bool Op1IsKill);
113243830Sdim    unsigned FastEmitInst_rrr(unsigned MachineInstOpcode,
114243830Sdim                              const TargetRegisterClass *RC,
115243830Sdim                              unsigned Op0, bool Op0IsKill,
116243830Sdim                              unsigned Op1, bool Op1IsKill,
117243830Sdim                              unsigned Op2, bool Op2IsKill);
118243830Sdim    unsigned FastEmitInst_ri(unsigned MachineInstOpcode,
119243830Sdim                             const TargetRegisterClass *RC,
120243830Sdim                             unsigned Op0, bool Op0IsKill,
121243830Sdim                             uint64_t Imm);
122243830Sdim    unsigned FastEmitInst_rf(unsigned MachineInstOpcode,
123243830Sdim                             const TargetRegisterClass *RC,
124243830Sdim                             unsigned Op0, bool Op0IsKill,
125243830Sdim                             const ConstantFP *FPImm);
126243830Sdim    unsigned FastEmitInst_rri(unsigned MachineInstOpcode,
127243830Sdim                              const TargetRegisterClass *RC,
128243830Sdim                              unsigned Op0, bool Op0IsKill,
129243830Sdim                              unsigned Op1, bool Op1IsKill,
130243830Sdim                              uint64_t Imm);
131243830Sdim    unsigned FastEmitInst_i(unsigned MachineInstOpcode,
132243830Sdim                            const TargetRegisterClass *RC,
133243830Sdim                            uint64_t Imm);
134243830Sdim    unsigned FastEmitInst_ii(unsigned MachineInstOpcode,
135243830Sdim                             const TargetRegisterClass *RC,
136243830Sdim                             uint64_t Imm1, uint64_t Imm2);
137221345Sdim
138243830Sdim    unsigned FastEmitInst_extractsubreg(MVT RetVT,
139243830Sdim                                        unsigned Op0, bool Op0IsKill,
140243830Sdim                                        uint32_t Idx);
141218893Sdim
142212793Sdim    // Backend specific FastISel code.
143243830Sdim  private:
144212793Sdim    virtual bool TargetSelectInstruction(const Instruction *I);
145212793Sdim    virtual unsigned TargetMaterializeConstant(const Constant *C);
146218893Sdim    virtual unsigned TargetMaterializeAlloca(const AllocaInst *AI);
147251662Sdim    virtual bool tryToFoldLoadIntoMI(MachineInstr *MI, unsigned OpNo,
148251662Sdim                                     const LoadInst *LI);
149249423Sdim    virtual bool FastLowerArguments();
150243830Sdim  private:
151212793Sdim  #include "ARMGenFastISel.inc"
152218893Sdim
153212793Sdim    // Instruction selection routines.
154218893Sdim  private:
155218893Sdim    bool SelectLoad(const Instruction *I);
156218893Sdim    bool SelectStore(const Instruction *I);
157218893Sdim    bool SelectBranch(const Instruction *I);
158234353Sdim    bool SelectIndirectBr(const Instruction *I);
159218893Sdim    bool SelectCmp(const Instruction *I);
160218893Sdim    bool SelectFPExt(const Instruction *I);
161218893Sdim    bool SelectFPTrunc(const Instruction *I);
162234353Sdim    bool SelectBinaryIntOp(const Instruction *I, unsigned ISDOpcode);
163234353Sdim    bool SelectBinaryFPOp(const Instruction *I, unsigned ISDOpcode);
164234353Sdim    bool SelectIToFP(const Instruction *I, bool isSigned);
165234353Sdim    bool SelectFPToI(const Instruction *I, bool isSigned);
166234353Sdim    bool SelectDiv(const Instruction *I, bool isSigned);
167234353Sdim    bool SelectRem(const Instruction *I, bool isSigned);
168234353Sdim    bool SelectCall(const Instruction *I, const char *IntrMemName);
169234353Sdim    bool SelectIntrinsicCall(const IntrinsicInst &I);
170218893Sdim    bool SelectSelect(const Instruction *I);
171218893Sdim    bool SelectRet(const Instruction *I);
172234353Sdim    bool SelectTrunc(const Instruction *I);
173234353Sdim    bool SelectIntExt(const Instruction *I);
174239462Sdim    bool SelectShift(const Instruction *I, ARM_AM::ShiftOpc ShiftTy);
175212793Sdim
176212793Sdim    // Utility routines.
177212793Sdim  private:
178226633Sdim    bool isTypeLegal(Type *Ty, MVT &VT);
179226633Sdim    bool isLoadTypeLegal(Type *Ty, MVT &VT);
180234353Sdim    bool ARMEmitCmp(const Value *Src1Value, const Value *Src2Value,
181234353Sdim                    bool isZExt);
182249423Sdim    bool ARMEmitLoad(MVT VT, unsigned &ResultReg, Address &Addr,
183234353Sdim                     unsigned Alignment = 0, bool isZExt = true,
184234353Sdim                     bool allocReg = true);
185249423Sdim    bool ARMEmitStore(MVT VT, unsigned SrcReg, Address &Addr,
186234353Sdim                      unsigned Alignment = 0);
187218893Sdim    bool ARMComputeAddress(const Value *Obj, Address &Addr);
188249423Sdim    void ARMSimplifyAddress(Address &Addr, MVT VT, bool useAM3);
189234353Sdim    bool ARMIsMemCpySmall(uint64_t Len);
190249423Sdim    bool ARMTryEmitSmallMemCpy(Address Dest, Address Src, uint64_t Len,
191249423Sdim                               unsigned Alignment);
192249423Sdim    unsigned ARMEmitIntExt(MVT SrcVT, unsigned SrcReg, MVT DestVT, bool isZExt);
193249423Sdim    unsigned ARMMaterializeFP(const ConstantFP *CFP, MVT VT);
194249423Sdim    unsigned ARMMaterializeInt(const Constant *C, MVT VT);
195249423Sdim    unsigned ARMMaterializeGV(const GlobalValue *GV, MVT VT);
196249423Sdim    unsigned ARMMoveToFPReg(MVT VT, unsigned SrcReg);
197249423Sdim    unsigned ARMMoveToIntReg(MVT VT, unsigned SrcReg);
198239462Sdim    unsigned ARMSelectCallOp(bool UseReg);
199249423Sdim    unsigned ARMLowerPICELF(const GlobalValue *GV, unsigned Align, MVT VT);
200218893Sdim
201218893Sdim    // Call handling routines.
202218893Sdim  private:
203239462Sdim    CCAssignFn *CCAssignFnForCall(CallingConv::ID CC,
204239462Sdim                                  bool Return,
205239462Sdim                                  bool isVarArg);
206218893Sdim    bool ProcessCallArgs(SmallVectorImpl<Value*> &Args,
207218893Sdim                         SmallVectorImpl<unsigned> &ArgRegs,
208218893Sdim                         SmallVectorImpl<MVT> &ArgVTs,
209218893Sdim                         SmallVectorImpl<ISD::ArgFlagsTy> &ArgFlags,
210218893Sdim                         SmallVectorImpl<unsigned> &RegArgs,
211218893Sdim                         CallingConv::ID CC,
212239462Sdim                         unsigned &NumBytes,
213239462Sdim                         bool isVarArg);
214239462Sdim    unsigned getLibcallReg(const Twine &Name);
215218893Sdim    bool FinishCall(MVT RetVT, SmallVectorImpl<unsigned> &UsedRegs,
216218893Sdim                    const Instruction *I, CallingConv::ID CC,
217239462Sdim                    unsigned &NumBytes, bool isVarArg);
218218893Sdim    bool ARMEmitLibcall(const Instruction *I, RTLIB::Libcall Call);
219218893Sdim
220218893Sdim    // OptionalDef handling routines.
221218893Sdim  private:
222221345Sdim    bool isARMNEONPred(const MachineInstr *MI);
223212793Sdim    bool DefinesOptionalPredicate(MachineInstr *MI, bool *CPSR);
224212793Sdim    const MachineInstrBuilder &AddOptionalDefs(const MachineInstrBuilder &MIB);
225249423Sdim    void AddLoadStoreOperands(MVT VT, Address &Addr,
226223017Sdim                              const MachineInstrBuilder &MIB,
227234353Sdim                              unsigned Flags, bool useAM3);
228212793Sdim};
229212793Sdim
230212793Sdim} // end anonymous namespace
231212793Sdim
232218893Sdim#include "ARMGenCallingConv.inc"
233212793Sdim
234212793Sdim// DefinesOptionalPredicate - This is different from DefinesPredicate in that
235212793Sdim// we don't care about implicit defs here, just places we'll need to add a
236212793Sdim// default CCReg argument. Sets CPSR if we're setting CPSR instead of CCR.
237212793Sdimbool ARMFastISel::DefinesOptionalPredicate(MachineInstr *MI, bool *CPSR) {
238234353Sdim  if (!MI->hasOptionalDef())
239212793Sdim    return false;
240212793Sdim
241212793Sdim  // Look to see if our OptionalDef is defining CPSR or CCR.
242212793Sdim  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
243212793Sdim    const MachineOperand &MO = MI->getOperand(i);
244212793Sdim    if (!MO.isReg() || !MO.isDef()) continue;
245212793Sdim    if (MO.getReg() == ARM::CPSR)
246212793Sdim      *CPSR = true;
247212793Sdim  }
248212793Sdim  return true;
249212793Sdim}
250212793Sdim
251221345Sdimbool ARMFastISel::isARMNEONPred(const MachineInstr *MI) {
252224145Sdim  const MCInstrDesc &MCID = MI->getDesc();
253221345Sdim
254221345Sdim  // If we're a thumb2 or not NEON function we were handled via isPredicable.
255224145Sdim  if ((MCID.TSFlags & ARMII::DomainMask) != ARMII::DomainNEON ||
256221345Sdim       AFI->isThumb2Function())
257221345Sdim    return false;
258221345Sdim
259224145Sdim  for (unsigned i = 0, e = MCID.getNumOperands(); i != e; ++i)
260224145Sdim    if (MCID.OpInfo[i].isPredicate())
261221345Sdim      return true;
262221345Sdim
263221345Sdim  return false;
264221345Sdim}
265221345Sdim
266212793Sdim// If the machine is predicable go ahead and add the predicate operands, if
267212793Sdim// it needs default CC operands add those.
268218893Sdim// TODO: If we want to support thumb1 then we'll need to deal with optional
269218893Sdim// CPSR defs that need to be added before the remaining operands. See s_cc_out
270218893Sdim// for descriptions why.
271212793Sdimconst MachineInstrBuilder &
272212793SdimARMFastISel::AddOptionalDefs(const MachineInstrBuilder &MIB) {
273212793Sdim  MachineInstr *MI = &*MIB;
274212793Sdim
275221345Sdim  // Do we use a predicate? or...
276221345Sdim  // Are we NEON in ARM mode and have a predicate operand? If so, I know
277221345Sdim  // we're not predicable but add it anyways.
278221345Sdim  if (TII.isPredicable(MI) || isARMNEONPred(MI))
279212793Sdim    AddDefaultPred(MIB);
280218893Sdim
281212793Sdim  // Do we optionally set a predicate?  Preds is size > 0 iff the predicate
282212793Sdim  // defines CPSR. All other OptionalDefines in ARM are the CCR register.
283212793Sdim  bool CPSR = false;
284212793Sdim  if (DefinesOptionalPredicate(MI, &CPSR)) {
285212793Sdim    if (CPSR)
286212793Sdim      AddDefaultT1CC(MIB);
287212793Sdim    else
288212793Sdim      AddDefaultCC(MIB);
289212793Sdim  }
290212793Sdim  return MIB;
291212793Sdim}
292212793Sdim
293212793Sdimunsigned ARMFastISel::FastEmitInst_(unsigned MachineInstOpcode,
294212793Sdim                                    const TargetRegisterClass* RC) {
295212793Sdim  unsigned ResultReg = createResultReg(RC);
296224145Sdim  const MCInstrDesc &II = TII.get(MachineInstOpcode);
297212793Sdim
298212793Sdim  AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg));
299212793Sdim  return ResultReg;
300212793Sdim}
301212793Sdim
302212793Sdimunsigned ARMFastISel::FastEmitInst_r(unsigned MachineInstOpcode,
303212793Sdim                                     const TargetRegisterClass *RC,
304212793Sdim                                     unsigned Op0, bool Op0IsKill) {
305212793Sdim  unsigned ResultReg = createResultReg(RC);
306224145Sdim  const MCInstrDesc &II = TII.get(MachineInstOpcode);
307212793Sdim
308234353Sdim  if (II.getNumDefs() >= 1) {
309212793Sdim    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
310212793Sdim                   .addReg(Op0, Op0IsKill * RegState::Kill));
311234353Sdim  } else {
312212793Sdim    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
313212793Sdim                   .addReg(Op0, Op0IsKill * RegState::Kill));
314212793Sdim    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
315212793Sdim                   TII.get(TargetOpcode::COPY), ResultReg)
316212793Sdim                   .addReg(II.ImplicitDefs[0]));
317212793Sdim  }
318212793Sdim  return ResultReg;
319212793Sdim}
320212793Sdim
321212793Sdimunsigned ARMFastISel::FastEmitInst_rr(unsigned MachineInstOpcode,
322212793Sdim                                      const TargetRegisterClass *RC,
323212793Sdim                                      unsigned Op0, bool Op0IsKill,
324212793Sdim                                      unsigned Op1, bool Op1IsKill) {
325212793Sdim  unsigned ResultReg = createResultReg(RC);
326224145Sdim  const MCInstrDesc &II = TII.get(MachineInstOpcode);
327212793Sdim
328234353Sdim  if (II.getNumDefs() >= 1) {
329212793Sdim    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
330212793Sdim                   .addReg(Op0, Op0IsKill * RegState::Kill)
331212793Sdim                   .addReg(Op1, Op1IsKill * RegState::Kill));
332234353Sdim  } else {
333212793Sdim    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
334212793Sdim                   .addReg(Op0, Op0IsKill * RegState::Kill)
335212793Sdim                   .addReg(Op1, Op1IsKill * RegState::Kill));
336212793Sdim    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
337212793Sdim                           TII.get(TargetOpcode::COPY), ResultReg)
338212793Sdim                   .addReg(II.ImplicitDefs[0]));
339212793Sdim  }
340212793Sdim  return ResultReg;
341212793Sdim}
342212793Sdim
343221345Sdimunsigned ARMFastISel::FastEmitInst_rrr(unsigned MachineInstOpcode,
344221345Sdim                                       const TargetRegisterClass *RC,
345221345Sdim                                       unsigned Op0, bool Op0IsKill,
346221345Sdim                                       unsigned Op1, bool Op1IsKill,
347221345Sdim                                       unsigned Op2, bool Op2IsKill) {
348221345Sdim  unsigned ResultReg = createResultReg(RC);
349224145Sdim  const MCInstrDesc &II = TII.get(MachineInstOpcode);
350221345Sdim
351234353Sdim  if (II.getNumDefs() >= 1) {
352221345Sdim    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
353221345Sdim                   .addReg(Op0, Op0IsKill * RegState::Kill)
354221345Sdim                   .addReg(Op1, Op1IsKill * RegState::Kill)
355221345Sdim                   .addReg(Op2, Op2IsKill * RegState::Kill));
356234353Sdim  } else {
357221345Sdim    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
358221345Sdim                   .addReg(Op0, Op0IsKill * RegState::Kill)
359221345Sdim                   .addReg(Op1, Op1IsKill * RegState::Kill)
360221345Sdim                   .addReg(Op2, Op2IsKill * RegState::Kill));
361221345Sdim    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
362221345Sdim                           TII.get(TargetOpcode::COPY), ResultReg)
363221345Sdim                   .addReg(II.ImplicitDefs[0]));
364221345Sdim  }
365221345Sdim  return ResultReg;
366221345Sdim}
367221345Sdim
368212793Sdimunsigned ARMFastISel::FastEmitInst_ri(unsigned MachineInstOpcode,
369212793Sdim                                      const TargetRegisterClass *RC,
370212793Sdim                                      unsigned Op0, bool Op0IsKill,
371212793Sdim                                      uint64_t Imm) {
372212793Sdim  unsigned ResultReg = createResultReg(RC);
373224145Sdim  const MCInstrDesc &II = TII.get(MachineInstOpcode);
374212793Sdim
375234353Sdim  if (II.getNumDefs() >= 1) {
376212793Sdim    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
377212793Sdim                   .addReg(Op0, Op0IsKill * RegState::Kill)
378212793Sdim                   .addImm(Imm));
379234353Sdim  } else {
380212793Sdim    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
381212793Sdim                   .addReg(Op0, Op0IsKill * RegState::Kill)
382212793Sdim                   .addImm(Imm));
383212793Sdim    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
384212793Sdim                           TII.get(TargetOpcode::COPY), ResultReg)
385212793Sdim                   .addReg(II.ImplicitDefs[0]));
386212793Sdim  }
387212793Sdim  return ResultReg;
388212793Sdim}
389212793Sdim
390212793Sdimunsigned ARMFastISel::FastEmitInst_rf(unsigned MachineInstOpcode,
391212793Sdim                                      const TargetRegisterClass *RC,
392212793Sdim                                      unsigned Op0, bool Op0IsKill,
393212793Sdim                                      const ConstantFP *FPImm) {
394212793Sdim  unsigned ResultReg = createResultReg(RC);
395224145Sdim  const MCInstrDesc &II = TII.get(MachineInstOpcode);
396212793Sdim
397234353Sdim  if (II.getNumDefs() >= 1) {
398212793Sdim    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
399212793Sdim                   .addReg(Op0, Op0IsKill * RegState::Kill)
400212793Sdim                   .addFPImm(FPImm));
401234353Sdim  } else {
402212793Sdim    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
403212793Sdim                   .addReg(Op0, Op0IsKill * RegState::Kill)
404212793Sdim                   .addFPImm(FPImm));
405212793Sdim    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
406212793Sdim                           TII.get(TargetOpcode::COPY), ResultReg)
407212793Sdim                   .addReg(II.ImplicitDefs[0]));
408212793Sdim  }
409212793Sdim  return ResultReg;
410212793Sdim}
411212793Sdim
412212793Sdimunsigned ARMFastISel::FastEmitInst_rri(unsigned MachineInstOpcode,
413212793Sdim                                       const TargetRegisterClass *RC,
414212793Sdim                                       unsigned Op0, bool Op0IsKill,
415212793Sdim                                       unsigned Op1, bool Op1IsKill,
416212793Sdim                                       uint64_t Imm) {
417212793Sdim  unsigned ResultReg = createResultReg(RC);
418224145Sdim  const MCInstrDesc &II = TII.get(MachineInstOpcode);
419212793Sdim
420234353Sdim  if (II.getNumDefs() >= 1) {
421212793Sdim    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
422212793Sdim                   .addReg(Op0, Op0IsKill * RegState::Kill)
423212793Sdim                   .addReg(Op1, Op1IsKill * RegState::Kill)
424212793Sdim                   .addImm(Imm));
425234353Sdim  } else {
426212793Sdim    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
427212793Sdim                   .addReg(Op0, Op0IsKill * RegState::Kill)
428212793Sdim                   .addReg(Op1, Op1IsKill * RegState::Kill)
429212793Sdim                   .addImm(Imm));
430212793Sdim    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
431212793Sdim                           TII.get(TargetOpcode::COPY), ResultReg)
432212793Sdim                   .addReg(II.ImplicitDefs[0]));
433212793Sdim  }
434212793Sdim  return ResultReg;
435212793Sdim}
436212793Sdim
437212793Sdimunsigned ARMFastISel::FastEmitInst_i(unsigned MachineInstOpcode,
438212793Sdim                                     const TargetRegisterClass *RC,
439212793Sdim                                     uint64_t Imm) {
440212793Sdim  unsigned ResultReg = createResultReg(RC);
441224145Sdim  const MCInstrDesc &II = TII.get(MachineInstOpcode);
442218893Sdim
443234353Sdim  if (II.getNumDefs() >= 1) {
444212793Sdim    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
445212793Sdim                   .addImm(Imm));
446234353Sdim  } else {
447212793Sdim    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
448212793Sdim                   .addImm(Imm));
449212793Sdim    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
450212793Sdim                           TII.get(TargetOpcode::COPY), ResultReg)
451212793Sdim                   .addReg(II.ImplicitDefs[0]));
452212793Sdim  }
453212793Sdim  return ResultReg;
454212793Sdim}
455212793Sdim
456221345Sdimunsigned ARMFastISel::FastEmitInst_ii(unsigned MachineInstOpcode,
457221345Sdim                                      const TargetRegisterClass *RC,
458221345Sdim                                      uint64_t Imm1, uint64_t Imm2) {
459221345Sdim  unsigned ResultReg = createResultReg(RC);
460224145Sdim  const MCInstrDesc &II = TII.get(MachineInstOpcode);
461223017Sdim
462234353Sdim  if (II.getNumDefs() >= 1) {
463221345Sdim    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
464221345Sdim                    .addImm(Imm1).addImm(Imm2));
465234353Sdim  } else {
466221345Sdim    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
467221345Sdim                    .addImm(Imm1).addImm(Imm2));
468223017Sdim    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
469221345Sdim                            TII.get(TargetOpcode::COPY),
470221345Sdim                            ResultReg)
471221345Sdim                    .addReg(II.ImplicitDefs[0]));
472221345Sdim  }
473221345Sdim  return ResultReg;
474221345Sdim}
475221345Sdim
476212793Sdimunsigned ARMFastISel::FastEmitInst_extractsubreg(MVT RetVT,
477212793Sdim                                                 unsigned Op0, bool Op0IsKill,
478212793Sdim                                                 uint32_t Idx) {
479212793Sdim  unsigned ResultReg = createResultReg(TLI.getRegClassFor(RetVT));
480212793Sdim  assert(TargetRegisterInfo::isVirtualRegister(Op0) &&
481212793Sdim         "Cannot yet extract from physregs");
482234353Sdim
483212793Sdim  AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt,
484234353Sdim                          DL, TII.get(TargetOpcode::COPY), ResultReg)
485234353Sdim                  .addReg(Op0, getKillRegState(Op0IsKill), Idx));
486212793Sdim  return ResultReg;
487212793Sdim}
488212793Sdim
489218893Sdim// TODO: Don't worry about 64-bit now, but when this is fixed remove the
490218893Sdim// checks from the various callers.
491249423Sdimunsigned ARMFastISel::ARMMoveToFPReg(MVT VT, unsigned SrcReg) {
492218893Sdim  if (VT == MVT::f64) return 0;
493212793Sdim
494218893Sdim  unsigned MoveReg = createResultReg(TLI.getRegClassFor(VT));
495218893Sdim  AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
496234353Sdim                          TII.get(ARM::VMOVSR), MoveReg)
497218893Sdim                  .addReg(SrcReg));
498218893Sdim  return MoveReg;
499218893Sdim}
500212793Sdim
501249423Sdimunsigned ARMFastISel::ARMMoveToIntReg(MVT VT, unsigned SrcReg) {
502218893Sdim  if (VT == MVT::i64) return 0;
503218893Sdim
504218893Sdim  unsigned MoveReg = createResultReg(TLI.getRegClassFor(VT));
505218893Sdim  AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
506234353Sdim                          TII.get(ARM::VMOVRS), MoveReg)
507218893Sdim                  .addReg(SrcReg));
508218893Sdim  return MoveReg;
509218893Sdim}
510218893Sdim
511218893Sdim// For double width floating point we need to materialize two constants
512218893Sdim// (the high and the low) into integer registers then use a move to get
513218893Sdim// the combined constant into an FP reg.
514249423Sdimunsigned ARMFastISel::ARMMaterializeFP(const ConstantFP *CFP, MVT VT) {
515218893Sdim  const APFloat Val = CFP->getValueAPF();
516218893Sdim  bool is64bit = VT == MVT::f64;
517218893Sdim
518218893Sdim  // This checks to see if we can use VFP3 instructions to materialize
519218893Sdim  // a constant, otherwise we have to go through the constant pool.
520218893Sdim  if (TLI.isFPImmLegal(Val, VT)) {
521226633Sdim    int Imm;
522226633Sdim    unsigned Opc;
523226633Sdim    if (is64bit) {
524226633Sdim      Imm = ARM_AM::getFP64Imm(Val);
525226633Sdim      Opc = ARM::FCONSTD;
526226633Sdim    } else {
527226633Sdim      Imm = ARM_AM::getFP32Imm(Val);
528226633Sdim      Opc = ARM::FCONSTS;
529226633Sdim    }
530218893Sdim    unsigned DestReg = createResultReg(TLI.getRegClassFor(VT));
531218893Sdim    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc),
532218893Sdim                            DestReg)
533226633Sdim                    .addImm(Imm));
534218893Sdim    return DestReg;
535218893Sdim  }
536218893Sdim
537218893Sdim  // Require VFP2 for loading fp constants.
538218893Sdim  if (!Subtarget->hasVFP2()) return false;
539218893Sdim
540212793Sdim  // MachineConstantPool wants an explicit alignment.
541218893Sdim  unsigned Align = TD.getPrefTypeAlignment(CFP->getType());
542218893Sdim  if (Align == 0) {
543218893Sdim    // TODO: Figure out if this is correct.
544218893Sdim    Align = TD.getTypeAllocSize(CFP->getType());
545218893Sdim  }
546218893Sdim  unsigned Idx = MCP.getConstantPoolIndex(cast<Constant>(CFP), Align);
547218893Sdim  unsigned DestReg = createResultReg(TLI.getRegClassFor(VT));
548218893Sdim  unsigned Opc = is64bit ? ARM::VLDRD : ARM::VLDRS;
549218893Sdim
550218893Sdim  // The extra reg is for addrmode5.
551218893Sdim  AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc),
552218893Sdim                          DestReg)
553218893Sdim                  .addConstantPoolIndex(Idx)
554218893Sdim                  .addReg(0));
555218893Sdim  return DestReg;
556218893Sdim}
557218893Sdim
558249423Sdimunsigned ARMFastISel::ARMMaterializeInt(const Constant *C, MVT VT) {
559218893Sdim
560234353Sdim  if (VT != MVT::i32 && VT != MVT::i16 && VT != MVT::i8 && VT != MVT::i1)
561234353Sdim    return false;
562218893Sdim
563218893Sdim  // If we can do this in a single instruction without a constant pool entry
564218893Sdim  // do so now.
565218893Sdim  const ConstantInt *CI = cast<ConstantInt>(C);
566234353Sdim  if (Subtarget->hasV6T2Ops() && isUInt<16>(CI->getZExtValue())) {
567234353Sdim    unsigned Opc = isThumb2 ? ARM::t2MOVi16 : ARM::MOVi16;
568249423Sdim    const TargetRegisterClass *RC = isThumb2 ? &ARM::rGPRRegClass :
569249423Sdim      &ARM::GPRRegClass;
570249423Sdim    unsigned ImmReg = createResultReg(RC);
571218893Sdim    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
572234353Sdim                            TII.get(Opc), ImmReg)
573234353Sdim                    .addImm(CI->getZExtValue()));
574234353Sdim    return ImmReg;
575218893Sdim  }
576218893Sdim
577234353Sdim  // Use MVN to emit negative constants.
578234353Sdim  if (VT == MVT::i32 && Subtarget->hasV6T2Ops() && CI->isNegative()) {
579234353Sdim    unsigned Imm = (unsigned)~(CI->getSExtValue());
580234353Sdim    bool UseImm = isThumb2 ? (ARM_AM::getT2SOImmVal(Imm) != -1) :
581234353Sdim      (ARM_AM::getSOImmVal(Imm) != -1);
582234353Sdim    if (UseImm) {
583234353Sdim      unsigned Opc = isThumb2 ? ARM::t2MVNi : ARM::MVNi;
584234353Sdim      unsigned ImmReg = createResultReg(TLI.getRegClassFor(MVT::i32));
585234353Sdim      AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
586234353Sdim                              TII.get(Opc), ImmReg)
587234353Sdim                      .addImm(Imm));
588234353Sdim      return ImmReg;
589234353Sdim    }
590234353Sdim  }
591234353Sdim
592234353Sdim  // Load from constant pool.  For now 32-bit only.
593234353Sdim  if (VT != MVT::i32)
594234353Sdim    return false;
595234353Sdim
596234353Sdim  unsigned DestReg = createResultReg(TLI.getRegClassFor(VT));
597234353Sdim
598218893Sdim  // MachineConstantPool wants an explicit alignment.
599212793Sdim  unsigned Align = TD.getPrefTypeAlignment(C->getType());
600212793Sdim  if (Align == 0) {
601212793Sdim    // TODO: Figure out if this is correct.
602212793Sdim    Align = TD.getTypeAllocSize(C->getType());
603212793Sdim  }
604212793Sdim  unsigned Idx = MCP.getConstantPoolIndex(C, Align);
605212793Sdim
606234353Sdim  if (isThumb2)
607212793Sdim    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
608218893Sdim                            TII.get(ARM::t2LDRpci), DestReg)
609218893Sdim                    .addConstantPoolIndex(Idx));
610212793Sdim  else
611218893Sdim    // The extra immediate is for addrmode2.
612212793Sdim    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
613218893Sdim                            TII.get(ARM::LDRcp), DestReg)
614218893Sdim                    .addConstantPoolIndex(Idx)
615218893Sdim                    .addImm(0));
616218893Sdim
617212793Sdim  return DestReg;
618212793Sdim}
619212793Sdim
620249423Sdimunsigned ARMFastISel::ARMMaterializeGV(const GlobalValue *GV, MVT VT) {
621218893Sdim  // For now 32-bit only.
622218893Sdim  if (VT != MVT::i32) return 0;
623218893Sdim
624218893Sdim  Reloc::Model RelocM = TM.getRelocationModel();
625243830Sdim  bool IsIndirect = Subtarget->GVIsIndirectSymbol(GV, RelocM);
626243830Sdim  const TargetRegisterClass *RC = isThumb2 ?
627243830Sdim    (const TargetRegisterClass*)&ARM::rGPRRegClass :
628243830Sdim    (const TargetRegisterClass*)&ARM::GPRRegClass;
629243830Sdim  unsigned DestReg = createResultReg(RC);
630218893Sdim
631234353Sdim  // Use movw+movt when possible, it avoids constant pool entries.
632234353Sdim  // Darwin targets don't support movt with Reloc::Static, see
633234353Sdim  // ARMTargetLowering::LowerGlobalAddressDarwin.  Other targets only support
634234353Sdim  // static movt relocations.
635234353Sdim  if (Subtarget->useMovt() &&
636234353Sdim      Subtarget->isTargetDarwin() == (RelocM != Reloc::Static)) {
637234353Sdim    unsigned Opc;
638234353Sdim    switch (RelocM) {
639234353Sdim    case Reloc::PIC_:
640234353Sdim      Opc = isThumb2 ? ARM::t2MOV_ga_pcrel : ARM::MOV_ga_pcrel;
641234353Sdim      break;
642234353Sdim    case Reloc::DynamicNoPIC:
643234353Sdim      Opc = isThumb2 ? ARM::t2MOV_ga_dyn : ARM::MOV_ga_dyn;
644234353Sdim      break;
645234353Sdim    default:
646234353Sdim      Opc = isThumb2 ? ARM::t2MOVi32imm : ARM::MOVi32imm;
647234353Sdim      break;
648234353Sdim    }
649234353Sdim    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc),
650234353Sdim                            DestReg).addGlobalAddress(GV));
651234353Sdim  } else {
652234353Sdim    // MachineConstantPool wants an explicit alignment.
653234353Sdim    unsigned Align = TD.getPrefTypeAlignment(GV->getType());
654234353Sdim    if (Align == 0) {
655234353Sdim      // TODO: Figure out if this is correct.
656234353Sdim      Align = TD.getTypeAllocSize(GV->getType());
657234353Sdim    }
658218893Sdim
659243830Sdim    if (Subtarget->isTargetELF() && RelocM == Reloc::PIC_)
660243830Sdim      return ARMLowerPICELF(GV, Align, VT);
661243830Sdim
662234353Sdim    // Grab index.
663234353Sdim    unsigned PCAdj = (RelocM != Reloc::PIC_) ? 0 :
664234353Sdim      (Subtarget->isThumb() ? 4 : 8);
665234353Sdim    unsigned Id = AFI->createPICLabelUId();
666234353Sdim    ARMConstantPoolValue *CPV = ARMConstantPoolConstant::Create(GV, Id,
667234353Sdim                                                                ARMCP::CPValue,
668234353Sdim                                                                PCAdj);
669234353Sdim    unsigned Idx = MCP.getConstantPoolIndex(CPV, Align);
670234353Sdim
671234353Sdim    // Load value.
672234353Sdim    MachineInstrBuilder MIB;
673234353Sdim    if (isThumb2) {
674234353Sdim      unsigned Opc = (RelocM!=Reloc::PIC_) ? ARM::t2LDRpci : ARM::t2LDRpci_pic;
675234353Sdim      MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc), DestReg)
676234353Sdim        .addConstantPoolIndex(Idx);
677234353Sdim      if (RelocM == Reloc::PIC_)
678234353Sdim        MIB.addImm(Id);
679243830Sdim      AddOptionalDefs(MIB);
680234353Sdim    } else {
681234353Sdim      // The extra immediate is for addrmode2.
682234353Sdim      MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(ARM::LDRcp),
683234353Sdim                    DestReg)
684234353Sdim        .addConstantPoolIndex(Idx)
685234353Sdim        .addImm(0);
686243830Sdim      AddOptionalDefs(MIB);
687243830Sdim
688243830Sdim      if (RelocM == Reloc::PIC_) {
689243830Sdim        unsigned Opc = IsIndirect ? ARM::PICLDR : ARM::PICADD;
690243830Sdim        unsigned NewDestReg = createResultReg(TLI.getRegClassFor(VT));
691243830Sdim
692243830Sdim        MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt,
693243830Sdim                                          DL, TII.get(Opc), NewDestReg)
694243830Sdim                                  .addReg(DestReg)
695243830Sdim                                  .addImm(Id);
696243830Sdim        AddOptionalDefs(MIB);
697243830Sdim        return NewDestReg;
698243830Sdim      }
699234353Sdim    }
700218893Sdim  }
701223017Sdim
702243830Sdim  if (IsIndirect) {
703234353Sdim    MachineInstrBuilder MIB;
704223017Sdim    unsigned NewDestReg = createResultReg(TLI.getRegClassFor(VT));
705234353Sdim    if (isThumb2)
706226633Sdim      MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
707226633Sdim                    TII.get(ARM::t2LDRi12), NewDestReg)
708223017Sdim            .addReg(DestReg)
709223017Sdim            .addImm(0);
710223017Sdim    else
711223017Sdim      MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(ARM::LDRi12),
712223017Sdim                    NewDestReg)
713223017Sdim            .addReg(DestReg)
714223017Sdim            .addImm(0);
715223017Sdim    DestReg = NewDestReg;
716223017Sdim    AddOptionalDefs(MIB);
717223017Sdim  }
718223017Sdim
719218893Sdim  return DestReg;
720218893Sdim}
721218893Sdim
722218893Sdimunsigned ARMFastISel::TargetMaterializeConstant(const Constant *C) {
723249423Sdim  EVT CEVT = TLI.getValueType(C->getType(), true);
724218893Sdim
725212793Sdim  // Only handle simple types.
726249423Sdim  if (!CEVT.isSimple()) return 0;
727249423Sdim  MVT VT = CEVT.getSimpleVT();
728218893Sdim
729218893Sdim  if (const ConstantFP *CFP = dyn_cast<ConstantFP>(C))
730218893Sdim    return ARMMaterializeFP(CFP, VT);
731218893Sdim  else if (const GlobalValue *GV = dyn_cast<GlobalValue>(C))
732218893Sdim    return ARMMaterializeGV(GV, VT);
733218893Sdim  else if (isa<ConstantInt>(C))
734218893Sdim    return ARMMaterializeInt(C, VT);
735218893Sdim
736218893Sdim  return 0;
737218893Sdim}
738218893Sdim
739234353Sdim// TODO: unsigned ARMFastISel::TargetMaterializeFloatZero(const ConstantFP *CF);
740234353Sdim
741218893Sdimunsigned ARMFastISel::TargetMaterializeAlloca(const AllocaInst *AI) {
742218893Sdim  // Don't handle dynamic allocas.
743218893Sdim  if (!FuncInfo.StaticAllocaMap.count(AI)) return 0;
744218893Sdim
745218893Sdim  MVT VT;
746239462Sdim  if (!isLoadTypeLegal(AI->getType(), VT)) return 0;
747218893Sdim
748218893Sdim  DenseMap<const AllocaInst*, int>::iterator SI =
749218893Sdim    FuncInfo.StaticAllocaMap.find(AI);
750218893Sdim
751218893Sdim  // This will get lowered later into the correct offsets and registers
752218893Sdim  // via rewriteXFrameIndex.
753218893Sdim  if (SI != FuncInfo.StaticAllocaMap.end()) {
754234353Sdim    const TargetRegisterClass* RC = TLI.getRegClassFor(VT);
755218893Sdim    unsigned ResultReg = createResultReg(RC);
756234353Sdim    unsigned Opc = isThumb2 ? ARM::t2ADDri : ARM::ADDri;
757234353Sdim    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
758218893Sdim                            TII.get(Opc), ResultReg)
759218893Sdim                            .addFrameIndex(SI->second)
760218893Sdim                            .addImm(0));
761218893Sdim    return ResultReg;
762218893Sdim  }
763218893Sdim
764218893Sdim  return 0;
765218893Sdim}
766218893Sdim
767226633Sdimbool ARMFastISel::isTypeLegal(Type *Ty, MVT &VT) {
768218893Sdim  EVT evt = TLI.getValueType(Ty, true);
769218893Sdim
770218893Sdim  // Only handle simple types.
771218893Sdim  if (evt == MVT::Other || !evt.isSimple()) return false;
772218893Sdim  VT = evt.getSimpleVT();
773218893Sdim
774212793Sdim  // Handle all legal types, i.e. a register that will directly hold this
775212793Sdim  // value.
776212793Sdim  return TLI.isTypeLegal(VT);
777212793Sdim}
778212793Sdim
779226633Sdimbool ARMFastISel::isLoadTypeLegal(Type *Ty, MVT &VT) {
780212793Sdim  if (isTypeLegal(Ty, VT)) return true;
781218893Sdim
782212793Sdim  // If this is a type than can be sign or zero-extended to a basic operation
783212793Sdim  // go ahead and accept it now.
784234353Sdim  if (VT == MVT::i1 || VT == MVT::i8 || VT == MVT::i16)
785212793Sdim    return true;
786218893Sdim
787212793Sdim  return false;
788212793Sdim}
789212793Sdim
790218893Sdim// Computes the address to get to an object.
791218893Sdimbool ARMFastISel::ARMComputeAddress(const Value *Obj, Address &Addr) {
792212793Sdim  // Some boilerplate from the X86 FastISel.
793212793Sdim  const User *U = NULL;
794212793Sdim  unsigned Opcode = Instruction::UserOp1;
795212793Sdim  if (const Instruction *I = dyn_cast<Instruction>(Obj)) {
796218893Sdim    // Don't walk into other basic blocks unless the object is an alloca from
797218893Sdim    // another block, otherwise it may not have a virtual register assigned.
798218893Sdim    if (FuncInfo.StaticAllocaMap.count(static_cast<const AllocaInst *>(Obj)) ||
799218893Sdim        FuncInfo.MBBMap[I->getParent()] == FuncInfo.MBB) {
800218893Sdim      Opcode = I->getOpcode();
801218893Sdim      U = I;
802218893Sdim    }
803212793Sdim  } else if (const ConstantExpr *C = dyn_cast<ConstantExpr>(Obj)) {
804212793Sdim    Opcode = C->getOpcode();
805212793Sdim    U = C;
806212793Sdim  }
807212793Sdim
808226633Sdim  if (PointerType *Ty = dyn_cast<PointerType>(Obj->getType()))
809212793Sdim    if (Ty->getAddressSpace() > 255)
810212793Sdim      // Fast instruction selection doesn't support the special
811212793Sdim      // address spaces.
812212793Sdim      return false;
813218893Sdim
814212793Sdim  switch (Opcode) {
815218893Sdim    default:
816212793Sdim    break;
817218893Sdim    case Instruction::BitCast: {
818218893Sdim      // Look through bitcasts.
819218893Sdim      return ARMComputeAddress(U->getOperand(0), Addr);
820218893Sdim    }
821218893Sdim    case Instruction::IntToPtr: {
822218893Sdim      // Look past no-op inttoptrs.
823218893Sdim      if (TLI.getValueType(U->getOperand(0)->getType()) == TLI.getPointerTy())
824218893Sdim        return ARMComputeAddress(U->getOperand(0), Addr);
825218893Sdim      break;
826218893Sdim    }
827218893Sdim    case Instruction::PtrToInt: {
828218893Sdim      // Look past no-op ptrtoints.
829218893Sdim      if (TLI.getValueType(U->getType()) == TLI.getPointerTy())
830218893Sdim        return ARMComputeAddress(U->getOperand(0), Addr);
831218893Sdim      break;
832218893Sdim    }
833218893Sdim    case Instruction::GetElementPtr: {
834218893Sdim      Address SavedAddr = Addr;
835218893Sdim      int TmpOffset = Addr.Offset;
836218893Sdim
837218893Sdim      // Iterate through the GEP folding the constants into offsets where
838218893Sdim      // we can.
839218893Sdim      gep_type_iterator GTI = gep_type_begin(U);
840218893Sdim      for (User::const_op_iterator i = U->op_begin() + 1, e = U->op_end();
841218893Sdim           i != e; ++i, ++GTI) {
842218893Sdim        const Value *Op = *i;
843226633Sdim        if (StructType *STy = dyn_cast<StructType>(*GTI)) {
844218893Sdim          const StructLayout *SL = TD.getStructLayout(STy);
845218893Sdim          unsigned Idx = cast<ConstantInt>(Op)->getZExtValue();
846218893Sdim          TmpOffset += SL->getElementOffset(Idx);
847218893Sdim        } else {
848218893Sdim          uint64_t S = TD.getTypeAllocSize(GTI.getIndexedType());
849221345Sdim          for (;;) {
850218893Sdim            if (const ConstantInt *CI = dyn_cast<ConstantInt>(Op)) {
851218893Sdim              // Constant-offset addressing.
852218893Sdim              TmpOffset += CI->getSExtValue() * S;
853221345Sdim              break;
854221345Sdim            }
855221345Sdim            if (isa<AddOperator>(Op) &&
856221345Sdim                (!isa<Instruction>(Op) ||
857221345Sdim                 FuncInfo.MBBMap[cast<Instruction>(Op)->getParent()]
858221345Sdim                 == FuncInfo.MBB) &&
859221345Sdim                isa<ConstantInt>(cast<AddOperator>(Op)->getOperand(1))) {
860221345Sdim              // An add (in the same block) with a constant operand. Fold the
861221345Sdim              // constant.
862218893Sdim              ConstantInt *CI =
863221345Sdim              cast<ConstantInt>(cast<AddOperator>(Op)->getOperand(1));
864218893Sdim              TmpOffset += CI->getSExtValue() * S;
865221345Sdim              // Iterate on the other operand.
866221345Sdim              Op = cast<AddOperator>(Op)->getOperand(0);
867221345Sdim              continue;
868221345Sdim            }
869221345Sdim            // Unsupported
870221345Sdim            goto unsupported_gep;
871221345Sdim          }
872218893Sdim        }
873218893Sdim      }
874218893Sdim
875218893Sdim      // Try to grab the base operand now.
876218893Sdim      Addr.Offset = TmpOffset;
877218893Sdim      if (ARMComputeAddress(U->getOperand(0), Addr)) return true;
878218893Sdim
879218893Sdim      // We failed, restore everything and try the other options.
880218893Sdim      Addr = SavedAddr;
881218893Sdim
882218893Sdim      unsupported_gep:
883218893Sdim      break;
884218893Sdim    }
885212793Sdim    case Instruction::Alloca: {
886218893Sdim      const AllocaInst *AI = cast<AllocaInst>(Obj);
887218893Sdim      DenseMap<const AllocaInst*, int>::iterator SI =
888218893Sdim        FuncInfo.StaticAllocaMap.find(AI);
889218893Sdim      if (SI != FuncInfo.StaticAllocaMap.end()) {
890218893Sdim        Addr.BaseType = Address::FrameIndexBase;
891218893Sdim        Addr.Base.FI = SI->second;
892218893Sdim        return true;
893218893Sdim      }
894218893Sdim      break;
895212793Sdim    }
896212793Sdim  }
897218893Sdim
898212793Sdim  // Try to get this in a register if nothing else has worked.
899218893Sdim  if (Addr.Base.Reg == 0) Addr.Base.Reg = getRegForValue(Obj);
900218893Sdim  return Addr.Base.Reg != 0;
901218893Sdim}
902212793Sdim
903249423Sdimvoid ARMFastISel::ARMSimplifyAddress(Address &Addr, MVT VT, bool useAM3) {
904218893Sdim  bool needsLowering = false;
905249423Sdim  switch (VT.SimpleTy) {
906234353Sdim    default: llvm_unreachable("Unhandled load/store type!");
907218893Sdim    case MVT::i1:
908218893Sdim    case MVT::i8:
909218893Sdim    case MVT::i16:
910218893Sdim    case MVT::i32:
911234353Sdim      if (!useAM3) {
912234353Sdim        // Integer loads/stores handle 12-bit offsets.
913234353Sdim        needsLowering = ((Addr.Offset & 0xfff) != Addr.Offset);
914234353Sdim        // Handle negative offsets.
915234353Sdim        if (needsLowering && isThumb2)
916234353Sdim          needsLowering = !(Subtarget->hasV6T2Ops() && Addr.Offset < 0 &&
917234353Sdim                            Addr.Offset > -256);
918234353Sdim      } else {
919234353Sdim        // ARM halfword load/stores and signed byte loads use +/-imm8 offsets.
920234353Sdim        needsLowering = (Addr.Offset > 255 || Addr.Offset < -255);
921234353Sdim      }
922218893Sdim      break;
923218893Sdim    case MVT::f32:
924218893Sdim    case MVT::f64:
925218893Sdim      // Floating point operands handle 8-bit offsets.
926218893Sdim      needsLowering = ((Addr.Offset & 0xff) != Addr.Offset);
927218893Sdim      break;
928218893Sdim  }
929218893Sdim
930218893Sdim  // If this is a stack pointer and the offset needs to be simplified then
931218893Sdim  // put the alloca address into a register, set the base type back to
932218893Sdim  // register and continue. This should almost never happen.
933218893Sdim  if (needsLowering && Addr.BaseType == Address::FrameIndexBase) {
934239462Sdim    const TargetRegisterClass *RC = isThumb2 ?
935239462Sdim      (const TargetRegisterClass*)&ARM::tGPRRegClass :
936239462Sdim      (const TargetRegisterClass*)&ARM::GPRRegClass;
937218893Sdim    unsigned ResultReg = createResultReg(RC);
938234353Sdim    unsigned Opc = isThumb2 ? ARM::t2ADDri : ARM::ADDri;
939234353Sdim    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
940218893Sdim                            TII.get(Opc), ResultReg)
941218893Sdim                            .addFrameIndex(Addr.Base.FI)
942218893Sdim                            .addImm(0));
943218893Sdim    Addr.Base.Reg = ResultReg;
944218893Sdim    Addr.BaseType = Address::RegBase;
945218893Sdim  }
946218893Sdim
947218893Sdim  // Since the offset is too large for the load/store instruction
948212793Sdim  // get the reg+offset into a register.
949218893Sdim  if (needsLowering) {
950221345Sdim    Addr.Base.Reg = FastEmit_ri_(MVT::i32, ISD::ADD, Addr.Base.Reg,
951221345Sdim                                 /*Op0IsKill*/false, Addr.Offset, MVT::i32);
952218893Sdim    Addr.Offset = 0;
953212793Sdim  }
954212793Sdim}
955212793Sdim
956249423Sdimvoid ARMFastISel::AddLoadStoreOperands(MVT VT, Address &Addr,
957223017Sdim                                       const MachineInstrBuilder &MIB,
958234353Sdim                                       unsigned Flags, bool useAM3) {
959218893Sdim  // addrmode5 output depends on the selection dag addressing dividing the
960218893Sdim  // offset by 4 that it then later multiplies. Do this here as well.
961249423Sdim  if (VT.SimpleTy == MVT::f32 || VT.SimpleTy == MVT::f64)
962218893Sdim    Addr.Offset /= 4;
963221345Sdim
964218893Sdim  // Frame base works a bit differently. Handle it separately.
965218893Sdim  if (Addr.BaseType == Address::FrameIndexBase) {
966218893Sdim    int FI = Addr.Base.FI;
967218893Sdim    int Offset = Addr.Offset;
968218893Sdim    MachineMemOperand *MMO =
969218893Sdim          FuncInfo.MF->getMachineMemOperand(
970218893Sdim                                  MachinePointerInfo::getFixedStack(FI, Offset),
971223017Sdim                                  Flags,
972218893Sdim                                  MFI.getObjectSize(FI),
973218893Sdim                                  MFI.getObjectAlignment(FI));
974218893Sdim    // Now add the rest of the operands.
975218893Sdim    MIB.addFrameIndex(FI);
976212793Sdim
977234353Sdim    // ARM halfword load/stores and signed byte loads need an additional
978234353Sdim    // operand.
979234353Sdim    if (useAM3) {
980234353Sdim      signed Imm = (Addr.Offset < 0) ? (0x100 | -Addr.Offset) : Addr.Offset;
981234353Sdim      MIB.addReg(0);
982234353Sdim      MIB.addImm(Imm);
983234353Sdim    } else {
984234353Sdim      MIB.addImm(Addr.Offset);
985234353Sdim    }
986218893Sdim    MIB.addMemOperand(MMO);
987218893Sdim  } else {
988218893Sdim    // Now add the rest of the operands.
989218893Sdim    MIB.addReg(Addr.Base.Reg);
990221345Sdim
991234353Sdim    // ARM halfword load/stores and signed byte loads need an additional
992234353Sdim    // operand.
993234353Sdim    if (useAM3) {
994234353Sdim      signed Imm = (Addr.Offset < 0) ? (0x100 | -Addr.Offset) : Addr.Offset;
995234353Sdim      MIB.addReg(0);
996234353Sdim      MIB.addImm(Imm);
997234353Sdim    } else {
998234353Sdim      MIB.addImm(Addr.Offset);
999234353Sdim    }
1000212793Sdim  }
1001218893Sdim  AddOptionalDefs(MIB);
1002212793Sdim}
1003212793Sdim
1004249423Sdimbool ARMFastISel::ARMEmitLoad(MVT VT, unsigned &ResultReg, Address &Addr,
1005234353Sdim                              unsigned Alignment, bool isZExt, bool allocReg) {
1006212793Sdim  unsigned Opc;
1007234353Sdim  bool useAM3 = false;
1008234353Sdim  bool needVMOV = false;
1009234353Sdim  const TargetRegisterClass *RC;
1010249423Sdim  switch (VT.SimpleTy) {
1011218893Sdim    // This is mostly going to be Neon/vector support.
1012218893Sdim    default: return false;
1013234353Sdim    case MVT::i1:
1014234353Sdim    case MVT::i8:
1015234353Sdim      if (isThumb2) {
1016234353Sdim        if (Addr.Offset < 0 && Addr.Offset > -256 && Subtarget->hasV6T2Ops())
1017234353Sdim          Opc = isZExt ? ARM::t2LDRBi8 : ARM::t2LDRSBi8;
1018234353Sdim        else
1019234353Sdim          Opc = isZExt ? ARM::t2LDRBi12 : ARM::t2LDRSBi12;
1020234353Sdim      } else {
1021234353Sdim        if (isZExt) {
1022234353Sdim          Opc = ARM::LDRBi12;
1023234353Sdim        } else {
1024234353Sdim          Opc = ARM::LDRSB;
1025234353Sdim          useAM3 = true;
1026234353Sdim        }
1027234353Sdim      }
1028239462Sdim      RC = &ARM::GPRRegClass;
1029212793Sdim      break;
1030234353Sdim    case MVT::i16:
1031243830Sdim      if (Alignment && Alignment < 2 && !Subtarget->allowsUnalignedMem())
1032243830Sdim        return false;
1033243830Sdim
1034234353Sdim      if (isThumb2) {
1035234353Sdim        if (Addr.Offset < 0 && Addr.Offset > -256 && Subtarget->hasV6T2Ops())
1036234353Sdim          Opc = isZExt ? ARM::t2LDRHi8 : ARM::t2LDRSHi8;
1037234353Sdim        else
1038234353Sdim          Opc = isZExt ? ARM::t2LDRHi12 : ARM::t2LDRSHi12;
1039234353Sdim      } else {
1040234353Sdim        Opc = isZExt ? ARM::LDRH : ARM::LDRSH;
1041234353Sdim        useAM3 = true;
1042234353Sdim      }
1043239462Sdim      RC = &ARM::GPRRegClass;
1044212793Sdim      break;
1045212793Sdim    case MVT::i32:
1046243830Sdim      if (Alignment && Alignment < 4 && !Subtarget->allowsUnalignedMem())
1047243830Sdim        return false;
1048243830Sdim
1049234353Sdim      if (isThumb2) {
1050234353Sdim        if (Addr.Offset < 0 && Addr.Offset > -256 && Subtarget->hasV6T2Ops())
1051234353Sdim          Opc = ARM::t2LDRi8;
1052234353Sdim        else
1053234353Sdim          Opc = ARM::t2LDRi12;
1054234353Sdim      } else {
1055234353Sdim        Opc = ARM::LDRi12;
1056234353Sdim      }
1057239462Sdim      RC = &ARM::GPRRegClass;
1058212793Sdim      break;
1059218893Sdim    case MVT::f32:
1060234353Sdim      if (!Subtarget->hasVFP2()) return false;
1061234353Sdim      // Unaligned loads need special handling. Floats require word-alignment.
1062234353Sdim      if (Alignment && Alignment < 4) {
1063234353Sdim        needVMOV = true;
1064234353Sdim        VT = MVT::i32;
1065234353Sdim        Opc = isThumb2 ? ARM::t2LDRi12 : ARM::LDRi12;
1066239462Sdim        RC = &ARM::GPRRegClass;
1067234353Sdim      } else {
1068234353Sdim        Opc = ARM::VLDRS;
1069234353Sdim        RC = TLI.getRegClassFor(VT);
1070234353Sdim      }
1071218893Sdim      break;
1072218893Sdim    case MVT::f64:
1073234353Sdim      if (!Subtarget->hasVFP2()) return false;
1074234353Sdim      // FIXME: Unaligned loads need special handling.  Doublewords require
1075234353Sdim      // word-alignment.
1076234353Sdim      if (Alignment && Alignment < 4)
1077234353Sdim        return false;
1078234353Sdim
1079218893Sdim      Opc = ARM::VLDRD;
1080218893Sdim      RC = TLI.getRegClassFor(VT);
1081218893Sdim      break;
1082212793Sdim  }
1083218893Sdim  // Simplify this down to something we can handle.
1084234353Sdim  ARMSimplifyAddress(Addr, VT, useAM3);
1085218893Sdim
1086218893Sdim  // Create the base instruction, then add the operands.
1087234353Sdim  if (allocReg)
1088234353Sdim    ResultReg = createResultReg(RC);
1089234353Sdim  assert (ResultReg > 255 && "Expected an allocated virtual register.");
1090218893Sdim  MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
1091218893Sdim                                    TII.get(Opc), ResultReg);
1092234353Sdim  AddLoadStoreOperands(VT, Addr, MIB, MachineMemOperand::MOLoad, useAM3);
1093234353Sdim
1094234353Sdim  // If we had an unaligned load of a float we've converted it to an regular
1095234353Sdim  // load.  Now we must move from the GRP to the FP register.
1096234353Sdim  if (needVMOV) {
1097234353Sdim    unsigned MoveReg = createResultReg(TLI.getRegClassFor(MVT::f32));
1098234353Sdim    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
1099234353Sdim                            TII.get(ARM::VMOVSR), MoveReg)
1100234353Sdim                    .addReg(ResultReg));
1101234353Sdim    ResultReg = MoveReg;
1102234353Sdim  }
1103212793Sdim  return true;
1104212793Sdim}
1105212793Sdim
1106218893Sdimbool ARMFastISel::SelectLoad(const Instruction *I) {
1107226633Sdim  // Atomic loads need special handling.
1108226633Sdim  if (cast<LoadInst>(I)->isAtomic())
1109226633Sdim    return false;
1110226633Sdim
1111218893Sdim  // Verify we have a legal type before going any further.
1112218893Sdim  MVT VT;
1113218893Sdim  if (!isLoadTypeLegal(I->getType(), VT))
1114218893Sdim    return false;
1115212793Sdim
1116218893Sdim  // See if we can handle this address.
1117218893Sdim  Address Addr;
1118218893Sdim  if (!ARMComputeAddress(I->getOperand(0), Addr)) return false;
1119212793Sdim
1120218893Sdim  unsigned ResultReg;
1121234353Sdim  if (!ARMEmitLoad(VT, ResultReg, Addr, cast<LoadInst>(I)->getAlignment()))
1122234353Sdim    return false;
1123218893Sdim  UpdateValueMap(I, ResultReg);
1124218893Sdim  return true;
1125212793Sdim}
1126212793Sdim
1127249423Sdimbool ARMFastISel::ARMEmitStore(MVT VT, unsigned SrcReg, Address &Addr,
1128234353Sdim                               unsigned Alignment) {
1129212793Sdim  unsigned StrOpc;
1130234353Sdim  bool useAM3 = false;
1131249423Sdim  switch (VT.SimpleTy) {
1132218893Sdim    // This is mostly going to be Neon/vector support.
1133212793Sdim    default: return false;
1134218893Sdim    case MVT::i1: {
1135239462Sdim      unsigned Res = createResultReg(isThumb2 ?
1136239462Sdim        (const TargetRegisterClass*)&ARM::tGPRRegClass :
1137239462Sdim        (const TargetRegisterClass*)&ARM::GPRRegClass);
1138234353Sdim      unsigned Opc = isThumb2 ? ARM::t2ANDri : ARM::ANDri;
1139218893Sdim      AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
1140218893Sdim                              TII.get(Opc), Res)
1141218893Sdim                      .addReg(SrcReg).addImm(1));
1142218893Sdim      SrcReg = Res;
1143218893Sdim    } // Fallthrough here.
1144218893Sdim    case MVT::i8:
1145234353Sdim      if (isThumb2) {
1146234353Sdim        if (Addr.Offset < 0 && Addr.Offset > -256 && Subtarget->hasV6T2Ops())
1147234353Sdim          StrOpc = ARM::t2STRBi8;
1148234353Sdim        else
1149234353Sdim          StrOpc = ARM::t2STRBi12;
1150234353Sdim      } else {
1151234353Sdim        StrOpc = ARM::STRBi12;
1152234353Sdim      }
1153218893Sdim      break;
1154218893Sdim    case MVT::i16:
1155243830Sdim      if (Alignment && Alignment < 2 && !Subtarget->allowsUnalignedMem())
1156243830Sdim        return false;
1157243830Sdim
1158234353Sdim      if (isThumb2) {
1159234353Sdim        if (Addr.Offset < 0 && Addr.Offset > -256 && Subtarget->hasV6T2Ops())
1160234353Sdim          StrOpc = ARM::t2STRHi8;
1161234353Sdim        else
1162234353Sdim          StrOpc = ARM::t2STRHi12;
1163234353Sdim      } else {
1164234353Sdim        StrOpc = ARM::STRH;
1165234353Sdim        useAM3 = true;
1166234353Sdim      }
1167218893Sdim      break;
1168218893Sdim    case MVT::i32:
1169243830Sdim      if (Alignment && Alignment < 4 && !Subtarget->allowsUnalignedMem())
1170243830Sdim        return false;
1171243830Sdim
1172234353Sdim      if (isThumb2) {
1173234353Sdim        if (Addr.Offset < 0 && Addr.Offset > -256 && Subtarget->hasV6T2Ops())
1174234353Sdim          StrOpc = ARM::t2STRi8;
1175234353Sdim        else
1176234353Sdim          StrOpc = ARM::t2STRi12;
1177234353Sdim      } else {
1178234353Sdim        StrOpc = ARM::STRi12;
1179234353Sdim      }
1180218893Sdim      break;
1181212793Sdim    case MVT::f32:
1182212793Sdim      if (!Subtarget->hasVFP2()) return false;
1183234353Sdim      // Unaligned stores need special handling. Floats require word-alignment.
1184234353Sdim      if (Alignment && Alignment < 4) {
1185234353Sdim        unsigned MoveReg = createResultReg(TLI.getRegClassFor(MVT::i32));
1186234353Sdim        AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
1187234353Sdim                                TII.get(ARM::VMOVRS), MoveReg)
1188234353Sdim                        .addReg(SrcReg));
1189234353Sdim        SrcReg = MoveReg;
1190234353Sdim        VT = MVT::i32;
1191234353Sdim        StrOpc = isThumb2 ? ARM::t2STRi12 : ARM::STRi12;
1192234353Sdim      } else {
1193234353Sdim        StrOpc = ARM::VSTRS;
1194234353Sdim      }
1195212793Sdim      break;
1196212793Sdim    case MVT::f64:
1197212793Sdim      if (!Subtarget->hasVFP2()) return false;
1198234353Sdim      // FIXME: Unaligned stores need special handling.  Doublewords require
1199234353Sdim      // word-alignment.
1200234353Sdim      if (Alignment && Alignment < 4)
1201234353Sdim          return false;
1202234353Sdim
1203212793Sdim      StrOpc = ARM::VSTRD;
1204212793Sdim      break;
1205212793Sdim  }
1206218893Sdim  // Simplify this down to something we can handle.
1207234353Sdim  ARMSimplifyAddress(Addr, VT, useAM3);
1208218893Sdim
1209218893Sdim  // Create the base instruction, then add the operands.
1210218893Sdim  MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
1211218893Sdim                                    TII.get(StrOpc))
1212234353Sdim                            .addReg(SrcReg);
1213234353Sdim  AddLoadStoreOperands(VT, Addr, MIB, MachineMemOperand::MOStore, useAM3);
1214212793Sdim  return true;
1215212793Sdim}
1216212793Sdim
1217218893Sdimbool ARMFastISel::SelectStore(const Instruction *I) {
1218212793Sdim  Value *Op0 = I->getOperand(0);
1219212793Sdim  unsigned SrcReg = 0;
1220212793Sdim
1221226633Sdim  // Atomic stores need special handling.
1222226633Sdim  if (cast<StoreInst>(I)->isAtomic())
1223226633Sdim    return false;
1224226633Sdim
1225218893Sdim  // Verify we have a legal type before going any further.
1226218893Sdim  MVT VT;
1227212793Sdim  if (!isLoadTypeLegal(I->getOperand(0)->getType(), VT))
1228212793Sdim    return false;
1229212793Sdim
1230212793Sdim  // Get the value to be stored into a register.
1231212793Sdim  SrcReg = getRegForValue(Op0);
1232218893Sdim  if (SrcReg == 0) return false;
1233218893Sdim
1234218893Sdim  // See if we can handle this address.
1235218893Sdim  Address Addr;
1236218893Sdim  if (!ARMComputeAddress(I->getOperand(1), Addr))
1237212793Sdim    return false;
1238212793Sdim
1239234353Sdim  if (!ARMEmitStore(VT, SrcReg, Addr, cast<StoreInst>(I)->getAlignment()))
1240234353Sdim    return false;
1241212793Sdim  return true;
1242212793Sdim}
1243212793Sdim
1244218893Sdimstatic ARMCC::CondCodes getComparePred(CmpInst::Predicate Pred) {
1245218893Sdim  switch (Pred) {
1246218893Sdim    // Needs two compares...
1247218893Sdim    case CmpInst::FCMP_ONE:
1248218893Sdim    case CmpInst::FCMP_UEQ:
1249218893Sdim    default:
1250218893Sdim      // AL is our "false" for now. The other two need more compares.
1251218893Sdim      return ARMCC::AL;
1252218893Sdim    case CmpInst::ICMP_EQ:
1253218893Sdim    case CmpInst::FCMP_OEQ:
1254218893Sdim      return ARMCC::EQ;
1255218893Sdim    case CmpInst::ICMP_SGT:
1256218893Sdim    case CmpInst::FCMP_OGT:
1257218893Sdim      return ARMCC::GT;
1258218893Sdim    case CmpInst::ICMP_SGE:
1259218893Sdim    case CmpInst::FCMP_OGE:
1260218893Sdim      return ARMCC::GE;
1261218893Sdim    case CmpInst::ICMP_UGT:
1262218893Sdim    case CmpInst::FCMP_UGT:
1263218893Sdim      return ARMCC::HI;
1264218893Sdim    case CmpInst::FCMP_OLT:
1265218893Sdim      return ARMCC::MI;
1266218893Sdim    case CmpInst::ICMP_ULE:
1267218893Sdim    case CmpInst::FCMP_OLE:
1268218893Sdim      return ARMCC::LS;
1269218893Sdim    case CmpInst::FCMP_ORD:
1270218893Sdim      return ARMCC::VC;
1271218893Sdim    case CmpInst::FCMP_UNO:
1272218893Sdim      return ARMCC::VS;
1273218893Sdim    case CmpInst::FCMP_UGE:
1274218893Sdim      return ARMCC::PL;
1275218893Sdim    case CmpInst::ICMP_SLT:
1276218893Sdim    case CmpInst::FCMP_ULT:
1277218893Sdim      return ARMCC::LT;
1278218893Sdim    case CmpInst::ICMP_SLE:
1279218893Sdim    case CmpInst::FCMP_ULE:
1280218893Sdim      return ARMCC::LE;
1281218893Sdim    case CmpInst::FCMP_UNE:
1282218893Sdim    case CmpInst::ICMP_NE:
1283218893Sdim      return ARMCC::NE;
1284218893Sdim    case CmpInst::ICMP_UGE:
1285218893Sdim      return ARMCC::HS;
1286218893Sdim    case CmpInst::ICMP_ULT:
1287218893Sdim      return ARMCC::LO;
1288218893Sdim  }
1289218893Sdim}
1290218893Sdim
1291218893Sdimbool ARMFastISel::SelectBranch(const Instruction *I) {
1292212793Sdim  const BranchInst *BI = cast<BranchInst>(I);
1293212793Sdim  MachineBasicBlock *TBB = FuncInfo.MBBMap[BI->getSuccessor(0)];
1294212793Sdim  MachineBasicBlock *FBB = FuncInfo.MBBMap[BI->getSuccessor(1)];
1295218893Sdim
1296212793Sdim  // Simple branch support.
1297218893Sdim
1298218893Sdim  // If we can, avoid recomputing the compare - redoing it could lead to wonky
1299218893Sdim  // behavior.
1300218893Sdim  if (const CmpInst *CI = dyn_cast<CmpInst>(BI->getCondition())) {
1301234353Sdim    if (CI->hasOneUse() && (CI->getParent() == I->getParent())) {
1302218893Sdim
1303218893Sdim      // Get the compare predicate.
1304221345Sdim      // Try to take advantage of fallthrough opportunities.
1305221345Sdim      CmpInst::Predicate Predicate = CI->getPredicate();
1306221345Sdim      if (FuncInfo.MBB->isLayoutSuccessor(TBB)) {
1307221345Sdim        std::swap(TBB, FBB);
1308221345Sdim        Predicate = CmpInst::getInversePredicate(Predicate);
1309221345Sdim      }
1310218893Sdim
1311221345Sdim      ARMCC::CondCodes ARMPred = getComparePred(Predicate);
1312221345Sdim
1313218893Sdim      // We may not handle every CC for now.
1314218893Sdim      if (ARMPred == ARMCC::AL) return false;
1315218893Sdim
1316234353Sdim      // Emit the compare.
1317234353Sdim      if (!ARMEmitCmp(CI->getOperand(0), CI->getOperand(1), CI->isUnsigned()))
1318234353Sdim        return false;
1319218893Sdim
1320234353Sdim      unsigned BrOpc = isThumb2 ? ARM::t2Bcc : ARM::Bcc;
1321218893Sdim      BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(BrOpc))
1322218893Sdim      .addMBB(TBB).addImm(ARMPred).addReg(ARM::CPSR);
1323218893Sdim      FastEmitBranch(FBB, DL);
1324218893Sdim      FuncInfo.MBB->addSuccessor(TBB);
1325218893Sdim      return true;
1326218893Sdim    }
1327221345Sdim  } else if (TruncInst *TI = dyn_cast<TruncInst>(BI->getCondition())) {
1328221345Sdim    MVT SourceVT;
1329221345Sdim    if (TI->hasOneUse() && TI->getParent() == I->getParent() &&
1330223017Sdim        (isLoadTypeLegal(TI->getOperand(0)->getType(), SourceVT))) {
1331234353Sdim      unsigned TstOpc = isThumb2 ? ARM::t2TSTri : ARM::TSTri;
1332221345Sdim      unsigned OpReg = getRegForValue(TI->getOperand(0));
1333221345Sdim      AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
1334221345Sdim                              TII.get(TstOpc))
1335221345Sdim                      .addReg(OpReg).addImm(1));
1336221345Sdim
1337221345Sdim      unsigned CCMode = ARMCC::NE;
1338221345Sdim      if (FuncInfo.MBB->isLayoutSuccessor(TBB)) {
1339221345Sdim        std::swap(TBB, FBB);
1340221345Sdim        CCMode = ARMCC::EQ;
1341221345Sdim      }
1342221345Sdim
1343234353Sdim      unsigned BrOpc = isThumb2 ? ARM::t2Bcc : ARM::Bcc;
1344221345Sdim      BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(BrOpc))
1345221345Sdim      .addMBB(TBB).addImm(CCMode).addReg(ARM::CPSR);
1346221345Sdim
1347221345Sdim      FastEmitBranch(FBB, DL);
1348221345Sdim      FuncInfo.MBB->addSuccessor(TBB);
1349221345Sdim      return true;
1350221345Sdim    }
1351234353Sdim  } else if (const ConstantInt *CI =
1352234353Sdim             dyn_cast<ConstantInt>(BI->getCondition())) {
1353234353Sdim    uint64_t Imm = CI->getZExtValue();
1354234353Sdim    MachineBasicBlock *Target = (Imm == 0) ? FBB : TBB;
1355234353Sdim    FastEmitBranch(Target, DL);
1356234353Sdim    return true;
1357218893Sdim  }
1358218893Sdim
1359218893Sdim  unsigned CmpReg = getRegForValue(BI->getCondition());
1360218893Sdim  if (CmpReg == 0) return false;
1361218893Sdim
1362221345Sdim  // We've been divorced from our compare!  Our block was split, and
1363221345Sdim  // now our compare lives in a predecessor block.  We musn't
1364221345Sdim  // re-compare here, as the children of the compare aren't guaranteed
1365221345Sdim  // live across the block boundary (we *could* check for this).
1366221345Sdim  // Regardless, the compare has been done in the predecessor block,
1367221345Sdim  // and it left a value for us in a virtual register.  Ergo, we test
1368221345Sdim  // the one-bit value left in the virtual register.
1369234353Sdim  unsigned TstOpc = isThumb2 ? ARM::t2TSTri : ARM::TSTri;
1370221345Sdim  AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(TstOpc))
1371221345Sdim                  .addReg(CmpReg).addImm(1));
1372218893Sdim
1373221345Sdim  unsigned CCMode = ARMCC::NE;
1374221345Sdim  if (FuncInfo.MBB->isLayoutSuccessor(TBB)) {
1375221345Sdim    std::swap(TBB, FBB);
1376221345Sdim    CCMode = ARMCC::EQ;
1377221345Sdim  }
1378221345Sdim
1379234353Sdim  unsigned BrOpc = isThumb2 ? ARM::t2Bcc : ARM::Bcc;
1380212793Sdim  BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(BrOpc))
1381221345Sdim                  .addMBB(TBB).addImm(CCMode).addReg(ARM::CPSR);
1382212793Sdim  FastEmitBranch(FBB, DL);
1383212793Sdim  FuncInfo.MBB->addSuccessor(TBB);
1384212793Sdim  return true;
1385212793Sdim}
1386212793Sdim
1387234353Sdimbool ARMFastISel::SelectIndirectBr(const Instruction *I) {
1388234353Sdim  unsigned AddrReg = getRegForValue(I->getOperand(0));
1389234353Sdim  if (AddrReg == 0) return false;
1390218893Sdim
1391234353Sdim  unsigned Opc = isThumb2 ? ARM::tBRIND : ARM::BX;
1392234353Sdim  AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc))
1393234353Sdim                  .addReg(AddrReg));
1394243830Sdim
1395243830Sdim  const IndirectBrInst *IB = cast<IndirectBrInst>(I);
1396243830Sdim  for (unsigned i = 0, e = IB->getNumSuccessors(); i != e; ++i)
1397243830Sdim    FuncInfo.MBB->addSuccessor(FuncInfo.MBBMap[IB->getSuccessor(i)]);
1398243830Sdim
1399239462Sdim  return true;
1400234353Sdim}
1401218893Sdim
1402234353Sdimbool ARMFastISel::ARMEmitCmp(const Value *Src1Value, const Value *Src2Value,
1403234353Sdim                             bool isZExt) {
1404234353Sdim  Type *Ty = Src1Value->getType();
1405249423Sdim  EVT SrcEVT = TLI.getValueType(Ty, true);
1406249423Sdim  if (!SrcEVT.isSimple()) return false;
1407249423Sdim  MVT SrcVT = SrcEVT.getSimpleVT();
1408234353Sdim
1409234353Sdim  bool isFloat = (Ty->isFloatTy() || Ty->isDoubleTy());
1410218893Sdim  if (isFloat && !Subtarget->hasVFP2())
1411218893Sdim    return false;
1412218893Sdim
1413234353Sdim  // Check to see if the 2nd operand is a constant that we can encode directly
1414234353Sdim  // in the compare.
1415234353Sdim  int Imm = 0;
1416234353Sdim  bool UseImm = false;
1417234353Sdim  bool isNegativeImm = false;
1418234353Sdim  // FIXME: At -O0 we don't have anything that canonicalizes operand order.
1419234353Sdim  // Thus, Src1Value may be a ConstantInt, but we're missing it.
1420234353Sdim  if (const ConstantInt *ConstInt = dyn_cast<ConstantInt>(Src2Value)) {
1421234353Sdim    if (SrcVT == MVT::i32 || SrcVT == MVT::i16 || SrcVT == MVT::i8 ||
1422234353Sdim        SrcVT == MVT::i1) {
1423234353Sdim      const APInt &CIVal = ConstInt->getValue();
1424234353Sdim      Imm = (isZExt) ? (int)CIVal.getZExtValue() : (int)CIVal.getSExtValue();
1425234353Sdim      // For INT_MIN/LONG_MIN (i.e., 0x80000000) we need to use a cmp, rather
1426234353Sdim      // then a cmn, because there is no way to represent 2147483648 as a
1427234353Sdim      // signed 32-bit int.
1428234353Sdim      if (Imm < 0 && Imm != (int)0x80000000) {
1429234353Sdim        isNegativeImm = true;
1430234353Sdim        Imm = -Imm;
1431234353Sdim      }
1432234353Sdim      UseImm = isThumb2 ? (ARM_AM::getT2SOImmVal(Imm) != -1) :
1433234353Sdim        (ARM_AM::getSOImmVal(Imm) != -1);
1434234353Sdim    }
1435234353Sdim  } else if (const ConstantFP *ConstFP = dyn_cast<ConstantFP>(Src2Value)) {
1436234353Sdim    if (SrcVT == MVT::f32 || SrcVT == MVT::f64)
1437234353Sdim      if (ConstFP->isZero() && !ConstFP->isNegative())
1438234353Sdim        UseImm = true;
1439234353Sdim  }
1440234353Sdim
1441218893Sdim  unsigned CmpOpc;
1442234353Sdim  bool isICmp = true;
1443234353Sdim  bool needsExt = false;
1444249423Sdim  switch (SrcVT.SimpleTy) {
1445218893Sdim    default: return false;
1446218893Sdim    // TODO: Verify compares.
1447218893Sdim    case MVT::f32:
1448234353Sdim      isICmp = false;
1449234353Sdim      CmpOpc = UseImm ? ARM::VCMPEZS : ARM::VCMPES;
1450218893Sdim      break;
1451218893Sdim    case MVT::f64:
1452234353Sdim      isICmp = false;
1453234353Sdim      CmpOpc = UseImm ? ARM::VCMPEZD : ARM::VCMPED;
1454218893Sdim      break;
1455234353Sdim    case MVT::i1:
1456234353Sdim    case MVT::i8:
1457234353Sdim    case MVT::i16:
1458234353Sdim      needsExt = true;
1459234353Sdim    // Intentional fall-through.
1460218893Sdim    case MVT::i32:
1461234353Sdim      if (isThumb2) {
1462234353Sdim        if (!UseImm)
1463234353Sdim          CmpOpc = ARM::t2CMPrr;
1464234353Sdim        else
1465239462Sdim          CmpOpc = isNegativeImm ? ARM::t2CMNri : ARM::t2CMPri;
1466234353Sdim      } else {
1467234353Sdim        if (!UseImm)
1468234353Sdim          CmpOpc = ARM::CMPrr;
1469234353Sdim        else
1470239462Sdim          CmpOpc = isNegativeImm ? ARM::CMNri : ARM::CMPri;
1471234353Sdim      }
1472218893Sdim      break;
1473218893Sdim  }
1474218893Sdim
1475234353Sdim  unsigned SrcReg1 = getRegForValue(Src1Value);
1476234353Sdim  if (SrcReg1 == 0) return false;
1477218893Sdim
1478234353Sdim  unsigned SrcReg2 = 0;
1479234353Sdim  if (!UseImm) {
1480234353Sdim    SrcReg2 = getRegForValue(Src2Value);
1481234353Sdim    if (SrcReg2 == 0) return false;
1482234353Sdim  }
1483218893Sdim
1484234353Sdim  // We have i1, i8, or i16, we need to either zero extend or sign extend.
1485234353Sdim  if (needsExt) {
1486234353Sdim    SrcReg1 = ARMEmitIntExt(SrcVT, SrcReg1, MVT::i32, isZExt);
1487234353Sdim    if (SrcReg1 == 0) return false;
1488234353Sdim    if (!UseImm) {
1489234353Sdim      SrcReg2 = ARMEmitIntExt(SrcVT, SrcReg2, MVT::i32, isZExt);
1490234353Sdim      if (SrcReg2 == 0) return false;
1491234353Sdim    }
1492234353Sdim  }
1493218893Sdim
1494234353Sdim  if (!UseImm) {
1495234353Sdim    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
1496234353Sdim                            TII.get(CmpOpc))
1497234353Sdim                    .addReg(SrcReg1).addReg(SrcReg2));
1498234353Sdim  } else {
1499234353Sdim    MachineInstrBuilder MIB;
1500234353Sdim    MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(CmpOpc))
1501234353Sdim      .addReg(SrcReg1);
1502218893Sdim
1503234353Sdim    // Only add immediate for icmp as the immediate for fcmp is an implicit 0.0.
1504234353Sdim    if (isICmp)
1505234353Sdim      MIB.addImm(Imm);
1506234353Sdim    AddOptionalDefs(MIB);
1507234353Sdim  }
1508218893Sdim
1509218893Sdim  // For floating point we need to move the result to a comparison register
1510218893Sdim  // that we can then use for branches.
1511234353Sdim  if (Ty->isFloatTy() || Ty->isDoubleTy())
1512218893Sdim    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
1513218893Sdim                            TII.get(ARM::FMSTAT)));
1514234353Sdim  return true;
1515234353Sdim}
1516218893Sdim
1517234353Sdimbool ARMFastISel::SelectCmp(const Instruction *I) {
1518234353Sdim  const CmpInst *CI = cast<CmpInst>(I);
1519234353Sdim
1520234353Sdim  // Get the compare predicate.
1521234353Sdim  ARMCC::CondCodes ARMPred = getComparePred(CI->getPredicate());
1522234353Sdim
1523234353Sdim  // We may not handle every CC for now.
1524234353Sdim  if (ARMPred == ARMCC::AL) return false;
1525234353Sdim
1526234353Sdim  // Emit the compare.
1527234353Sdim  if (!ARMEmitCmp(CI->getOperand(0), CI->getOperand(1), CI->isUnsigned()))
1528234353Sdim    return false;
1529234353Sdim
1530218893Sdim  // Now set a register based on the comparison. Explicitly set the predicates
1531218893Sdim  // here.
1532234353Sdim  unsigned MovCCOpc = isThumb2 ? ARM::t2MOVCCi : ARM::MOVCCi;
1533239462Sdim  const TargetRegisterClass *RC = isThumb2 ?
1534239462Sdim    (const TargetRegisterClass*)&ARM::rGPRRegClass :
1535239462Sdim    (const TargetRegisterClass*)&ARM::GPRRegClass;
1536218893Sdim  unsigned DestReg = createResultReg(RC);
1537234353Sdim  Constant *Zero = ConstantInt::get(Type::getInt32Ty(*Context), 0);
1538218893Sdim  unsigned ZeroReg = TargetMaterializeConstant(Zero);
1539234353Sdim  // ARMEmitCmp emits a FMSTAT when necessary, so it's always safe to use CPSR.
1540218893Sdim  BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(MovCCOpc), DestReg)
1541218893Sdim          .addReg(ZeroReg).addImm(1)
1542234353Sdim          .addImm(ARMPred).addReg(ARM::CPSR);
1543218893Sdim
1544218893Sdim  UpdateValueMap(I, DestReg);
1545218893Sdim  return true;
1546218893Sdim}
1547218893Sdim
1548218893Sdimbool ARMFastISel::SelectFPExt(const Instruction *I) {
1549218893Sdim  // Make sure we have VFP and that we're extending float to double.
1550218893Sdim  if (!Subtarget->hasVFP2()) return false;
1551218893Sdim
1552218893Sdim  Value *V = I->getOperand(0);
1553218893Sdim  if (!I->getType()->isDoubleTy() ||
1554218893Sdim      !V->getType()->isFloatTy()) return false;
1555218893Sdim
1556218893Sdim  unsigned Op = getRegForValue(V);
1557218893Sdim  if (Op == 0) return false;
1558218893Sdim
1559239462Sdim  unsigned Result = createResultReg(&ARM::DPRRegClass);
1560218893Sdim  AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
1561218893Sdim                          TII.get(ARM::VCVTDS), Result)
1562218893Sdim                  .addReg(Op));
1563218893Sdim  UpdateValueMap(I, Result);
1564218893Sdim  return true;
1565218893Sdim}
1566218893Sdim
1567218893Sdimbool ARMFastISel::SelectFPTrunc(const Instruction *I) {
1568218893Sdim  // Make sure we have VFP and that we're truncating double to float.
1569218893Sdim  if (!Subtarget->hasVFP2()) return false;
1570218893Sdim
1571218893Sdim  Value *V = I->getOperand(0);
1572218893Sdim  if (!(I->getType()->isFloatTy() &&
1573218893Sdim        V->getType()->isDoubleTy())) return false;
1574218893Sdim
1575218893Sdim  unsigned Op = getRegForValue(V);
1576218893Sdim  if (Op == 0) return false;
1577218893Sdim
1578239462Sdim  unsigned Result = createResultReg(&ARM::SPRRegClass);
1579218893Sdim  AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
1580218893Sdim                          TII.get(ARM::VCVTSD), Result)
1581218893Sdim                  .addReg(Op));
1582218893Sdim  UpdateValueMap(I, Result);
1583218893Sdim  return true;
1584218893Sdim}
1585218893Sdim
1586234353Sdimbool ARMFastISel::SelectIToFP(const Instruction *I, bool isSigned) {
1587218893Sdim  // Make sure we have VFP.
1588218893Sdim  if (!Subtarget->hasVFP2()) return false;
1589218893Sdim
1590218893Sdim  MVT DstVT;
1591226633Sdim  Type *Ty = I->getType();
1592218893Sdim  if (!isTypeLegal(Ty, DstVT))
1593218893Sdim    return false;
1594218893Sdim
1595234353Sdim  Value *Src = I->getOperand(0);
1596249423Sdim  EVT SrcEVT = TLI.getValueType(Src->getType(), true);
1597249423Sdim  if (!SrcEVT.isSimple())
1598249423Sdim    return false;
1599249423Sdim  MVT SrcVT = SrcEVT.getSimpleVT();
1600234353Sdim  if (SrcVT != MVT::i32 && SrcVT != MVT::i16 && SrcVT != MVT::i8)
1601223017Sdim    return false;
1602223017Sdim
1603234353Sdim  unsigned SrcReg = getRegForValue(Src);
1604234353Sdim  if (SrcReg == 0) return false;
1605218893Sdim
1606234353Sdim  // Handle sign-extension.
1607234353Sdim  if (SrcVT == MVT::i16 || SrcVT == MVT::i8) {
1608249423Sdim    SrcReg = ARMEmitIntExt(SrcVT, SrcReg, MVT::i32,
1609234353Sdim                                       /*isZExt*/!isSigned);
1610234353Sdim    if (SrcReg == 0) return false;
1611234353Sdim  }
1612234353Sdim
1613218893Sdim  // The conversion routine works on fp-reg to fp-reg and the operand above
1614218893Sdim  // was an integer, move it to the fp registers if possible.
1615234353Sdim  unsigned FP = ARMMoveToFPReg(MVT::f32, SrcReg);
1616218893Sdim  if (FP == 0) return false;
1617218893Sdim
1618218893Sdim  unsigned Opc;
1619234353Sdim  if (Ty->isFloatTy()) Opc = isSigned ? ARM::VSITOS : ARM::VUITOS;
1620234353Sdim  else if (Ty->isDoubleTy()) Opc = isSigned ? ARM::VSITOD : ARM::VUITOD;
1621226633Sdim  else return false;
1622218893Sdim
1623218893Sdim  unsigned ResultReg = createResultReg(TLI.getRegClassFor(DstVT));
1624218893Sdim  AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc),
1625218893Sdim                          ResultReg)
1626218893Sdim                  .addReg(FP));
1627218893Sdim  UpdateValueMap(I, ResultReg);
1628218893Sdim  return true;
1629218893Sdim}
1630218893Sdim
1631234353Sdimbool ARMFastISel::SelectFPToI(const Instruction *I, bool isSigned) {
1632218893Sdim  // Make sure we have VFP.
1633218893Sdim  if (!Subtarget->hasVFP2()) return false;
1634218893Sdim
1635218893Sdim  MVT DstVT;
1636226633Sdim  Type *RetTy = I->getType();
1637218893Sdim  if (!isTypeLegal(RetTy, DstVT))
1638218893Sdim    return false;
1639218893Sdim
1640218893Sdim  unsigned Op = getRegForValue(I->getOperand(0));
1641218893Sdim  if (Op == 0) return false;
1642218893Sdim
1643218893Sdim  unsigned Opc;
1644226633Sdim  Type *OpTy = I->getOperand(0)->getType();
1645234353Sdim  if (OpTy->isFloatTy()) Opc = isSigned ? ARM::VTOSIZS : ARM::VTOUIZS;
1646234353Sdim  else if (OpTy->isDoubleTy()) Opc = isSigned ? ARM::VTOSIZD : ARM::VTOUIZD;
1647226633Sdim  else return false;
1648218893Sdim
1649234353Sdim  // f64->s32/u32 or f32->s32/u32 both need an intermediate f32 reg.
1650218893Sdim  unsigned ResultReg = createResultReg(TLI.getRegClassFor(MVT::f32));
1651218893Sdim  AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc),
1652218893Sdim                          ResultReg)
1653218893Sdim                  .addReg(Op));
1654218893Sdim
1655218893Sdim  // This result needs to be in an integer register, but the conversion only
1656218893Sdim  // takes place in fp-regs.
1657218893Sdim  unsigned IntReg = ARMMoveToIntReg(DstVT, ResultReg);
1658218893Sdim  if (IntReg == 0) return false;
1659218893Sdim
1660218893Sdim  UpdateValueMap(I, IntReg);
1661218893Sdim  return true;
1662218893Sdim}
1663218893Sdim
1664218893Sdimbool ARMFastISel::SelectSelect(const Instruction *I) {
1665218893Sdim  MVT VT;
1666218893Sdim  if (!isTypeLegal(I->getType(), VT))
1667218893Sdim    return false;
1668218893Sdim
1669218893Sdim  // Things need to be register sized for register moves.
1670218893Sdim  if (VT != MVT::i32) return false;
1671218893Sdim
1672218893Sdim  unsigned CondReg = getRegForValue(I->getOperand(0));
1673218893Sdim  if (CondReg == 0) return false;
1674218893Sdim  unsigned Op1Reg = getRegForValue(I->getOperand(1));
1675218893Sdim  if (Op1Reg == 0) return false;
1676218893Sdim
1677234353Sdim  // Check to see if we can use an immediate in the conditional move.
1678234353Sdim  int Imm = 0;
1679234353Sdim  bool UseImm = false;
1680234353Sdim  bool isNegativeImm = false;
1681234353Sdim  if (const ConstantInt *ConstInt = dyn_cast<ConstantInt>(I->getOperand(2))) {
1682234353Sdim    assert (VT == MVT::i32 && "Expecting an i32.");
1683234353Sdim    Imm = (int)ConstInt->getValue().getZExtValue();
1684234353Sdim    if (Imm < 0) {
1685234353Sdim      isNegativeImm = true;
1686234353Sdim      Imm = ~Imm;
1687234353Sdim    }
1688234353Sdim    UseImm = isThumb2 ? (ARM_AM::getT2SOImmVal(Imm) != -1) :
1689234353Sdim      (ARM_AM::getSOImmVal(Imm) != -1);
1690234353Sdim  }
1691234353Sdim
1692234353Sdim  unsigned Op2Reg = 0;
1693234353Sdim  if (!UseImm) {
1694234353Sdim    Op2Reg = getRegForValue(I->getOperand(2));
1695234353Sdim    if (Op2Reg == 0) return false;
1696234353Sdim  }
1697234353Sdim
1698234353Sdim  unsigned CmpOpc = isThumb2 ? ARM::t2CMPri : ARM::CMPri;
1699218893Sdim  AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(CmpOpc))
1700234353Sdim                  .addReg(CondReg).addImm(0));
1701234353Sdim
1702234353Sdim  unsigned MovCCOpc;
1703249423Sdim  const TargetRegisterClass *RC;
1704234353Sdim  if (!UseImm) {
1705249423Sdim    RC = isThumb2 ? &ARM::tGPRRegClass : &ARM::GPRRegClass;
1706234353Sdim    MovCCOpc = isThumb2 ? ARM::t2MOVCCr : ARM::MOVCCr;
1707234353Sdim  } else {
1708249423Sdim    RC = isThumb2 ? &ARM::rGPRRegClass : &ARM::GPRRegClass;
1709249423Sdim    if (!isNegativeImm)
1710234353Sdim      MovCCOpc = isThumb2 ? ARM::t2MOVCCi : ARM::MOVCCi;
1711249423Sdim    else
1712234353Sdim      MovCCOpc = isThumb2 ? ARM::t2MVNCCi : ARM::MVNCCi;
1713234353Sdim  }
1714218893Sdim  unsigned ResultReg = createResultReg(RC);
1715234353Sdim  if (!UseImm)
1716234353Sdim    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(MovCCOpc), ResultReg)
1717234353Sdim    .addReg(Op2Reg).addReg(Op1Reg).addImm(ARMCC::NE).addReg(ARM::CPSR);
1718234353Sdim  else
1719234353Sdim    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(MovCCOpc), ResultReg)
1720234353Sdim    .addReg(Op1Reg).addImm(Imm).addImm(ARMCC::EQ).addReg(ARM::CPSR);
1721218893Sdim  UpdateValueMap(I, ResultReg);
1722218893Sdim  return true;
1723218893Sdim}
1724218893Sdim
1725234353Sdimbool ARMFastISel::SelectDiv(const Instruction *I, bool isSigned) {
1726218893Sdim  MVT VT;
1727226633Sdim  Type *Ty = I->getType();
1728218893Sdim  if (!isTypeLegal(Ty, VT))
1729218893Sdim    return false;
1730218893Sdim
1731218893Sdim  // If we have integer div support we should have selected this automagically.
1732218893Sdim  // In case we have a real miss go ahead and return false and we'll pick
1733218893Sdim  // it up later.
1734218893Sdim  if (Subtarget->hasDivide()) return false;
1735218893Sdim
1736218893Sdim  // Otherwise emit a libcall.
1737218893Sdim  RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
1738218893Sdim  if (VT == MVT::i8)
1739234353Sdim    LC = isSigned ? RTLIB::SDIV_I8 : RTLIB::UDIV_I8;
1740218893Sdim  else if (VT == MVT::i16)
1741234353Sdim    LC = isSigned ? RTLIB::SDIV_I16 : RTLIB::UDIV_I16;
1742218893Sdim  else if (VT == MVT::i32)
1743234353Sdim    LC = isSigned ? RTLIB::SDIV_I32 : RTLIB::UDIV_I32;
1744218893Sdim  else if (VT == MVT::i64)
1745234353Sdim    LC = isSigned ? RTLIB::SDIV_I64 : RTLIB::UDIV_I64;
1746218893Sdim  else if (VT == MVT::i128)
1747234353Sdim    LC = isSigned ? RTLIB::SDIV_I128 : RTLIB::UDIV_I128;
1748218893Sdim  assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported SDIV!");
1749218893Sdim
1750218893Sdim  return ARMEmitLibcall(I, LC);
1751218893Sdim}
1752218893Sdim
1753234353Sdimbool ARMFastISel::SelectRem(const Instruction *I, bool isSigned) {
1754218893Sdim  MVT VT;
1755226633Sdim  Type *Ty = I->getType();
1756218893Sdim  if (!isTypeLegal(Ty, VT))
1757218893Sdim    return false;
1758218893Sdim
1759218893Sdim  RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
1760218893Sdim  if (VT == MVT::i8)
1761234353Sdim    LC = isSigned ? RTLIB::SREM_I8 : RTLIB::UREM_I8;
1762218893Sdim  else if (VT == MVT::i16)
1763234353Sdim    LC = isSigned ? RTLIB::SREM_I16 : RTLIB::UREM_I16;
1764218893Sdim  else if (VT == MVT::i32)
1765234353Sdim    LC = isSigned ? RTLIB::SREM_I32 : RTLIB::UREM_I32;
1766218893Sdim  else if (VT == MVT::i64)
1767234353Sdim    LC = isSigned ? RTLIB::SREM_I64 : RTLIB::UREM_I64;
1768218893Sdim  else if (VT == MVT::i128)
1769234353Sdim    LC = isSigned ? RTLIB::SREM_I128 : RTLIB::UREM_I128;
1770218893Sdim  assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported SREM!");
1771218893Sdim
1772218893Sdim  return ARMEmitLibcall(I, LC);
1773218893Sdim}
1774218893Sdim
1775234353Sdimbool ARMFastISel::SelectBinaryIntOp(const Instruction *I, unsigned ISDOpcode) {
1776234353Sdim  EVT DestVT  = TLI.getValueType(I->getType(), true);
1777234353Sdim
1778234353Sdim  // We can get here in the case when we have a binary operation on a non-legal
1779234353Sdim  // type and the target independent selector doesn't know how to handle it.
1780234353Sdim  if (DestVT != MVT::i16 && DestVT != MVT::i8 && DestVT != MVT::i1)
1781234353Sdim    return false;
1782239462Sdim
1783234353Sdim  unsigned Opc;
1784234353Sdim  switch (ISDOpcode) {
1785234353Sdim    default: return false;
1786234353Sdim    case ISD::ADD:
1787234353Sdim      Opc = isThumb2 ? ARM::t2ADDrr : ARM::ADDrr;
1788234353Sdim      break;
1789234353Sdim    case ISD::OR:
1790234353Sdim      Opc = isThumb2 ? ARM::t2ORRrr : ARM::ORRrr;
1791234353Sdim      break;
1792234353Sdim    case ISD::SUB:
1793234353Sdim      Opc = isThumb2 ? ARM::t2SUBrr : ARM::SUBrr;
1794234353Sdim      break;
1795234353Sdim  }
1796234353Sdim
1797234353Sdim  unsigned SrcReg1 = getRegForValue(I->getOperand(0));
1798234353Sdim  if (SrcReg1 == 0) return false;
1799234353Sdim
1800234353Sdim  // TODO: Often the 2nd operand is an immediate, which can be encoded directly
1801234353Sdim  // in the instruction, rather then materializing the value in a register.
1802234353Sdim  unsigned SrcReg2 = getRegForValue(I->getOperand(1));
1803234353Sdim  if (SrcReg2 == 0) return false;
1804234353Sdim
1805234353Sdim  unsigned ResultReg = createResultReg(TLI.getRegClassFor(MVT::i32));
1806234353Sdim  AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
1807234353Sdim                          TII.get(Opc), ResultReg)
1808234353Sdim                  .addReg(SrcReg1).addReg(SrcReg2));
1809234353Sdim  UpdateValueMap(I, ResultReg);
1810234353Sdim  return true;
1811234353Sdim}
1812234353Sdim
1813234353Sdimbool ARMFastISel::SelectBinaryFPOp(const Instruction *I, unsigned ISDOpcode) {
1814249423Sdim  EVT FPVT = TLI.getValueType(I->getType(), true);
1815249423Sdim  if (!FPVT.isSimple()) return false;
1816249423Sdim  MVT VT = FPVT.getSimpleVT();
1817218893Sdim
1818218893Sdim  // We can get here in the case when we want to use NEON for our fp
1819218893Sdim  // operations, but can't figure out how to. Just use the vfp instructions
1820218893Sdim  // if we have them.
1821218893Sdim  // FIXME: It'd be nice to use NEON instructions.
1822226633Sdim  Type *Ty = I->getType();
1823218893Sdim  bool isFloat = (Ty->isDoubleTy() || Ty->isFloatTy());
1824218893Sdim  if (isFloat && !Subtarget->hasVFP2())
1825218893Sdim    return false;
1826218893Sdim
1827218893Sdim  unsigned Opc;
1828218893Sdim  bool is64bit = VT == MVT::f64 || VT == MVT::i64;
1829218893Sdim  switch (ISDOpcode) {
1830218893Sdim    default: return false;
1831218893Sdim    case ISD::FADD:
1832218893Sdim      Opc = is64bit ? ARM::VADDD : ARM::VADDS;
1833218893Sdim      break;
1834218893Sdim    case ISD::FSUB:
1835218893Sdim      Opc = is64bit ? ARM::VSUBD : ARM::VSUBS;
1836218893Sdim      break;
1837218893Sdim    case ISD::FMUL:
1838218893Sdim      Opc = is64bit ? ARM::VMULD : ARM::VMULS;
1839218893Sdim      break;
1840218893Sdim  }
1841234353Sdim  unsigned Op1 = getRegForValue(I->getOperand(0));
1842234353Sdim  if (Op1 == 0) return false;
1843234353Sdim
1844234353Sdim  unsigned Op2 = getRegForValue(I->getOperand(1));
1845234353Sdim  if (Op2 == 0) return false;
1846234353Sdim
1847249423Sdim  unsigned ResultReg = createResultReg(TLI.getRegClassFor(VT.SimpleTy));
1848218893Sdim  AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
1849218893Sdim                          TII.get(Opc), ResultReg)
1850218893Sdim                  .addReg(Op1).addReg(Op2));
1851218893Sdim  UpdateValueMap(I, ResultReg);
1852218893Sdim  return true;
1853218893Sdim}
1854218893Sdim
1855218893Sdim// Call Handling Code
1856218893Sdim
1857239462Sdim// This is largely taken directly from CCAssignFnForNode
1858218893Sdim// TODO: We may not support all of this.
1859239462SdimCCAssignFn *ARMFastISel::CCAssignFnForCall(CallingConv::ID CC,
1860239462Sdim                                           bool Return,
1861239462Sdim                                           bool isVarArg) {
1862218893Sdim  switch (CC) {
1863218893Sdim  default:
1864218893Sdim    llvm_unreachable("Unsupported calling convention");
1865218893Sdim  case CallingConv::Fast:
1866239462Sdim    if (Subtarget->hasVFP2() && !isVarArg) {
1867239462Sdim      if (!Subtarget->isAAPCS_ABI())
1868239462Sdim        return (Return ? RetFastCC_ARM_APCS : FastCC_ARM_APCS);
1869239462Sdim      // For AAPCS ABI targets, just use VFP variant of the calling convention.
1870239462Sdim      return (Return ? RetCC_ARM_AAPCS_VFP : CC_ARM_AAPCS_VFP);
1871239462Sdim    }
1872218893Sdim    // Fallthrough
1873218893Sdim  case CallingConv::C:
1874218893Sdim    // Use target triple & subtarget features to do actual dispatch.
1875218893Sdim    if (Subtarget->isAAPCS_ABI()) {
1876218893Sdim      if (Subtarget->hasVFP2() &&
1877239462Sdim          TM.Options.FloatABIType == FloatABI::Hard && !isVarArg)
1878218893Sdim        return (Return ? RetCC_ARM_AAPCS_VFP: CC_ARM_AAPCS_VFP);
1879218893Sdim      else
1880218893Sdim        return (Return ? RetCC_ARM_AAPCS: CC_ARM_AAPCS);
1881218893Sdim    } else
1882218893Sdim        return (Return ? RetCC_ARM_APCS: CC_ARM_APCS);
1883218893Sdim  case CallingConv::ARM_AAPCS_VFP:
1884239462Sdim    if (!isVarArg)
1885239462Sdim      return (Return ? RetCC_ARM_AAPCS_VFP: CC_ARM_AAPCS_VFP);
1886239462Sdim    // Fall through to soft float variant, variadic functions don't
1887239462Sdim    // use hard floating point ABI.
1888218893Sdim  case CallingConv::ARM_AAPCS:
1889218893Sdim    return (Return ? RetCC_ARM_AAPCS: CC_ARM_AAPCS);
1890218893Sdim  case CallingConv::ARM_APCS:
1891218893Sdim    return (Return ? RetCC_ARM_APCS: CC_ARM_APCS);
1892239462Sdim  case CallingConv::GHC:
1893239462Sdim    if (Return)
1894239462Sdim      llvm_unreachable("Can't return in GHC call convention");
1895239462Sdim    else
1896239462Sdim      return CC_ARM_APCS_GHC;
1897218893Sdim  }
1898218893Sdim}
1899218893Sdim
1900218893Sdimbool ARMFastISel::ProcessCallArgs(SmallVectorImpl<Value*> &Args,
1901218893Sdim                                  SmallVectorImpl<unsigned> &ArgRegs,
1902218893Sdim                                  SmallVectorImpl<MVT> &ArgVTs,
1903218893Sdim                                  SmallVectorImpl<ISD::ArgFlagsTy> &ArgFlags,
1904218893Sdim                                  SmallVectorImpl<unsigned> &RegArgs,
1905218893Sdim                                  CallingConv::ID CC,
1906239462Sdim                                  unsigned &NumBytes,
1907239462Sdim                                  bool isVarArg) {
1908218893Sdim  SmallVector<CCValAssign, 16> ArgLocs;
1909239462Sdim  CCState CCInfo(CC, isVarArg, *FuncInfo.MF, TM, ArgLocs, *Context);
1910239462Sdim  CCInfo.AnalyzeCallOperands(ArgVTs, ArgFlags,
1911239462Sdim                             CCAssignFnForCall(CC, false, isVarArg));
1912218893Sdim
1913234353Sdim  // Check that we can handle all of the arguments. If we can't, then bail out
1914234353Sdim  // now before we add code to the MBB.
1915234353Sdim  for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
1916234353Sdim    CCValAssign &VA = ArgLocs[i];
1917234353Sdim    MVT ArgVT = ArgVTs[VA.getValNo()];
1918234353Sdim
1919234353Sdim    // We don't handle NEON/vector parameters yet.
1920234353Sdim    if (ArgVT.isVector() || ArgVT.getSizeInBits() > 64)
1921234353Sdim      return false;
1922234353Sdim
1923234353Sdim    // Now copy/store arg to correct locations.
1924234353Sdim    if (VA.isRegLoc() && !VA.needsCustom()) {
1925234353Sdim      continue;
1926234353Sdim    } else if (VA.needsCustom()) {
1927234353Sdim      // TODO: We need custom lowering for vector (v2f64) args.
1928234353Sdim      if (VA.getLocVT() != MVT::f64 ||
1929234353Sdim          // TODO: Only handle register args for now.
1930234353Sdim          !VA.isRegLoc() || !ArgLocs[++i].isRegLoc())
1931234353Sdim        return false;
1932234353Sdim    } else {
1933234353Sdim      switch (static_cast<EVT>(ArgVT).getSimpleVT().SimpleTy) {
1934234353Sdim      default:
1935234353Sdim        return false;
1936234353Sdim      case MVT::i1:
1937234353Sdim      case MVT::i8:
1938234353Sdim      case MVT::i16:
1939234353Sdim      case MVT::i32:
1940234353Sdim        break;
1941234353Sdim      case MVT::f32:
1942234353Sdim        if (!Subtarget->hasVFP2())
1943234353Sdim          return false;
1944234353Sdim        break;
1945234353Sdim      case MVT::f64:
1946234353Sdim        if (!Subtarget->hasVFP2())
1947234353Sdim          return false;
1948234353Sdim        break;
1949234353Sdim      }
1950234353Sdim    }
1951234353Sdim  }
1952234353Sdim
1953234353Sdim  // At the point, we are able to handle the call's arguments in fast isel.
1954234353Sdim
1955218893Sdim  // Get a count of how many bytes are to be pushed on the stack.
1956218893Sdim  NumBytes = CCInfo.getNextStackOffset();
1957218893Sdim
1958218893Sdim  // Issue CALLSEQ_START
1959224145Sdim  unsigned AdjStackDown = TII.getCallFrameSetupOpcode();
1960218893Sdim  AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
1961218893Sdim                          TII.get(AdjStackDown))
1962218893Sdim                  .addImm(NumBytes));
1963218893Sdim
1964218893Sdim  // Process the args.
1965218893Sdim  for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
1966218893Sdim    CCValAssign &VA = ArgLocs[i];
1967218893Sdim    unsigned Arg = ArgRegs[VA.getValNo()];
1968218893Sdim    MVT ArgVT = ArgVTs[VA.getValNo()];
1969218893Sdim
1970234353Sdim    assert((!ArgVT.isVector() && ArgVT.getSizeInBits() <= 64) &&
1971234353Sdim           "We don't handle NEON/vector parameters yet.");
1972218893Sdim
1973218893Sdim    // Handle arg promotion, etc.
1974218893Sdim    switch (VA.getLocInfo()) {
1975218893Sdim      case CCValAssign::Full: break;
1976218893Sdim      case CCValAssign::SExt: {
1977234353Sdim        MVT DestVT = VA.getLocVT();
1978234353Sdim        Arg = ARMEmitIntExt(ArgVT, Arg, DestVT, /*isZExt*/false);
1979234353Sdim        assert (Arg != 0 && "Failed to emit a sext");
1980234353Sdim        ArgVT = DestVT;
1981218893Sdim        break;
1982218893Sdim      }
1983234353Sdim      case CCValAssign::AExt:
1984234353Sdim        // Intentional fall-through.  Handle AExt and ZExt.
1985218893Sdim      case CCValAssign::ZExt: {
1986234353Sdim        MVT DestVT = VA.getLocVT();
1987234353Sdim        Arg = ARMEmitIntExt(ArgVT, Arg, DestVT, /*isZExt*/true);
1988234353Sdim        assert (Arg != 0 && "Failed to emit a sext");
1989234353Sdim        ArgVT = DestVT;
1990218893Sdim        break;
1991218893Sdim      }
1992218893Sdim      case CCValAssign::BCvt: {
1993218893Sdim        unsigned BC = FastEmit_r(ArgVT, VA.getLocVT(), ISD::BITCAST, Arg,
1994218893Sdim                                 /*TODO: Kill=*/false);
1995218893Sdim        assert(BC != 0 && "Failed to emit a bitcast!");
1996218893Sdim        Arg = BC;
1997218893Sdim        ArgVT = VA.getLocVT();
1998218893Sdim        break;
1999218893Sdim      }
2000218893Sdim      default: llvm_unreachable("Unknown arg promotion!");
2001218893Sdim    }
2002218893Sdim
2003218893Sdim    // Now copy/store arg to correct locations.
2004218893Sdim    if (VA.isRegLoc() && !VA.needsCustom()) {
2005218893Sdim      BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(TargetOpcode::COPY),
2006218893Sdim              VA.getLocReg())
2007234353Sdim        .addReg(Arg);
2008218893Sdim      RegArgs.push_back(VA.getLocReg());
2009218893Sdim    } else if (VA.needsCustom()) {
2010218893Sdim      // TODO: We need custom lowering for vector (v2f64) args.
2011234353Sdim      assert(VA.getLocVT() == MVT::f64 &&
2012234353Sdim             "Custom lowering for v2f64 args not available");
2013218893Sdim
2014218893Sdim      CCValAssign &NextVA = ArgLocs[++i];
2015218893Sdim
2016234353Sdim      assert(VA.isRegLoc() && NextVA.isRegLoc() &&
2017234353Sdim             "We only handle register args!");
2018218893Sdim
2019218893Sdim      AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
2020218893Sdim                              TII.get(ARM::VMOVRRD), VA.getLocReg())
2021218893Sdim                      .addReg(NextVA.getLocReg(), RegState::Define)
2022218893Sdim                      .addReg(Arg));
2023218893Sdim      RegArgs.push_back(VA.getLocReg());
2024218893Sdim      RegArgs.push_back(NextVA.getLocReg());
2025218893Sdim    } else {
2026218893Sdim      assert(VA.isMemLoc());
2027218893Sdim      // Need to store on the stack.
2028218893Sdim      Address Addr;
2029218893Sdim      Addr.BaseType = Address::RegBase;
2030218893Sdim      Addr.Base.Reg = ARM::SP;
2031218893Sdim      Addr.Offset = VA.getLocMemOffset();
2032218893Sdim
2033234353Sdim      bool EmitRet = ARMEmitStore(ArgVT, Arg, Addr); (void)EmitRet;
2034234353Sdim      assert(EmitRet && "Could not emit a store for argument!");
2035218893Sdim    }
2036218893Sdim  }
2037234353Sdim
2038218893Sdim  return true;
2039218893Sdim}
2040218893Sdim
2041218893Sdimbool ARMFastISel::FinishCall(MVT RetVT, SmallVectorImpl<unsigned> &UsedRegs,
2042218893Sdim                             const Instruction *I, CallingConv::ID CC,
2043239462Sdim                             unsigned &NumBytes, bool isVarArg) {
2044218893Sdim  // Issue CALLSEQ_END
2045224145Sdim  unsigned AdjStackUp = TII.getCallFrameDestroyOpcode();
2046218893Sdim  AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
2047218893Sdim                          TII.get(AdjStackUp))
2048218893Sdim                  .addImm(NumBytes).addImm(0));
2049218893Sdim
2050218893Sdim  // Now the return value.
2051218893Sdim  if (RetVT != MVT::isVoid) {
2052218893Sdim    SmallVector<CCValAssign, 16> RVLocs;
2053239462Sdim    CCState CCInfo(CC, isVarArg, *FuncInfo.MF, TM, RVLocs, *Context);
2054239462Sdim    CCInfo.AnalyzeCallResult(RetVT, CCAssignFnForCall(CC, true, isVarArg));
2055218893Sdim
2056218893Sdim    // Copy all of the result registers out of their specified physreg.
2057218893Sdim    if (RVLocs.size() == 2 && RetVT == MVT::f64) {
2058218893Sdim      // For this move we copy into two registers and then move into the
2059218893Sdim      // double fp reg we want.
2060249423Sdim      MVT DestVT = RVLocs[0].getValVT();
2061234353Sdim      const TargetRegisterClass* DstRC = TLI.getRegClassFor(DestVT);
2062218893Sdim      unsigned ResultReg = createResultReg(DstRC);
2063218893Sdim      AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
2064218893Sdim                              TII.get(ARM::VMOVDRR), ResultReg)
2065218893Sdim                      .addReg(RVLocs[0].getLocReg())
2066218893Sdim                      .addReg(RVLocs[1].getLocReg()));
2067218893Sdim
2068218893Sdim      UsedRegs.push_back(RVLocs[0].getLocReg());
2069218893Sdim      UsedRegs.push_back(RVLocs[1].getLocReg());
2070218893Sdim
2071218893Sdim      // Finally update the result.
2072218893Sdim      UpdateValueMap(I, ResultReg);
2073218893Sdim    } else {
2074218893Sdim      assert(RVLocs.size() == 1 &&"Can't handle non-double multi-reg retvals!");
2075249423Sdim      MVT CopyVT = RVLocs[0].getValVT();
2076218893Sdim
2077234353Sdim      // Special handling for extended integers.
2078234353Sdim      if (RetVT == MVT::i1 || RetVT == MVT::i8 || RetVT == MVT::i16)
2079234353Sdim        CopyVT = MVT::i32;
2080234353Sdim
2081234353Sdim      const TargetRegisterClass* DstRC = TLI.getRegClassFor(CopyVT);
2082234353Sdim
2083218893Sdim      unsigned ResultReg = createResultReg(DstRC);
2084218893Sdim      BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(TargetOpcode::COPY),
2085218893Sdim              ResultReg).addReg(RVLocs[0].getLocReg());
2086218893Sdim      UsedRegs.push_back(RVLocs[0].getLocReg());
2087218893Sdim
2088218893Sdim      // Finally update the result.
2089218893Sdim      UpdateValueMap(I, ResultReg);
2090218893Sdim    }
2091218893Sdim  }
2092218893Sdim
2093218893Sdim  return true;
2094218893Sdim}
2095218893Sdim
2096218893Sdimbool ARMFastISel::SelectRet(const Instruction *I) {
2097218893Sdim  const ReturnInst *Ret = cast<ReturnInst>(I);
2098218893Sdim  const Function &F = *I->getParent()->getParent();
2099218893Sdim
2100218893Sdim  if (!FuncInfo.CanLowerReturn)
2101218893Sdim    return false;
2102218893Sdim
2103249423Sdim  // Build a list of return value registers.
2104249423Sdim  SmallVector<unsigned, 4> RetRegs;
2105249423Sdim
2106218893Sdim  CallingConv::ID CC = F.getCallingConv();
2107218893Sdim  if (Ret->getNumOperands() > 0) {
2108218893Sdim    SmallVector<ISD::OutputArg, 4> Outs;
2109249423Sdim    GetReturnInfo(F.getReturnType(), F.getAttributes(), Outs, TLI);
2110218893Sdim
2111218893Sdim    // Analyze operands of the call, assigning locations to each operand.
2112218893Sdim    SmallVector<CCValAssign, 16> ValLocs;
2113226633Sdim    CCState CCInfo(CC, F.isVarArg(), *FuncInfo.MF, TM, ValLocs,I->getContext());
2114239462Sdim    CCInfo.AnalyzeReturn(Outs, CCAssignFnForCall(CC, true /* is Ret */,
2115239462Sdim                                                 F.isVarArg()));
2116218893Sdim
2117218893Sdim    const Value *RV = Ret->getOperand(0);
2118218893Sdim    unsigned Reg = getRegForValue(RV);
2119218893Sdim    if (Reg == 0)
2120218893Sdim      return false;
2121218893Sdim
2122218893Sdim    // Only handle a single return value for now.
2123218893Sdim    if (ValLocs.size() != 1)
2124218893Sdim      return false;
2125218893Sdim
2126218893Sdim    CCValAssign &VA = ValLocs[0];
2127218893Sdim
2128218893Sdim    // Don't bother handling odd stuff for now.
2129218893Sdim    if (VA.getLocInfo() != CCValAssign::Full)
2130218893Sdim      return false;
2131218893Sdim    // Only handle register returns for now.
2132218893Sdim    if (!VA.isRegLoc())
2133218893Sdim      return false;
2134218893Sdim
2135234353Sdim    unsigned SrcReg = Reg + VA.getValNo();
2136249423Sdim    EVT RVEVT = TLI.getValueType(RV->getType());
2137249423Sdim    if (!RVEVT.isSimple()) return false;
2138249423Sdim    MVT RVVT = RVEVT.getSimpleVT();
2139249423Sdim    MVT DestVT = VA.getValVT();
2140234353Sdim    // Special handling for extended integers.
2141234353Sdim    if (RVVT != DestVT) {
2142234353Sdim      if (RVVT != MVT::i1 && RVVT != MVT::i8 && RVVT != MVT::i16)
2143234353Sdim        return false;
2144234353Sdim
2145234353Sdim      assert(DestVT == MVT::i32 && "ARM should always ext to i32");
2146234353Sdim
2147234353Sdim      // Perform extension if flagged as either zext or sext.  Otherwise, do
2148234353Sdim      // nothing.
2149234353Sdim      if (Outs[0].Flags.isZExt() || Outs[0].Flags.isSExt()) {
2150234353Sdim        SrcReg = ARMEmitIntExt(RVVT, SrcReg, DestVT, Outs[0].Flags.isZExt());
2151234353Sdim        if (SrcReg == 0) return false;
2152234353Sdim      }
2153234353Sdim    }
2154234353Sdim
2155218893Sdim    // Make the copy.
2156218893Sdim    unsigned DstReg = VA.getLocReg();
2157218893Sdim    const TargetRegisterClass* SrcRC = MRI.getRegClass(SrcReg);
2158218893Sdim    // Avoid a cross-class copy. This is very unlikely.
2159218893Sdim    if (!SrcRC->contains(DstReg))
2160218893Sdim      return false;
2161218893Sdim    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(TargetOpcode::COPY),
2162218893Sdim            DstReg).addReg(SrcReg);
2163218893Sdim
2164249423Sdim    // Add register to return instruction.
2165249423Sdim    RetRegs.push_back(VA.getLocReg());
2166218893Sdim  }
2167218893Sdim
2168234353Sdim  unsigned RetOpc = isThumb2 ? ARM::tBX_RET : ARM::BX_RET;
2169249423Sdim  MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
2170249423Sdim                                    TII.get(RetOpc));
2171249423Sdim  AddOptionalDefs(MIB);
2172249423Sdim  for (unsigned i = 0, e = RetRegs.size(); i != e; ++i)
2173249423Sdim    MIB.addReg(RetRegs[i], RegState::Implicit);
2174218893Sdim  return true;
2175218893Sdim}
2176218893Sdim
2177239462Sdimunsigned ARMFastISel::ARMSelectCallOp(bool UseReg) {
2178239462Sdim  if (UseReg)
2179239462Sdim    return isThumb2 ? ARM::tBLXr : ARM::BLX;
2180239462Sdim  else
2181239462Sdim    return isThumb2 ? ARM::tBL : ARM::BL;
2182219077Sdim}
2183219077Sdim
2184239462Sdimunsigned ARMFastISel::getLibcallReg(const Twine &Name) {
2185239462Sdim  GlobalValue *GV = new GlobalVariable(Type::getInt32Ty(*Context), false,
2186239462Sdim                                       GlobalValue::ExternalLinkage, 0, Name);
2187249423Sdim  EVT LCREVT = TLI.getValueType(GV->getType());
2188249423Sdim  if (!LCREVT.isSimple()) return 0;
2189249423Sdim  return ARMMaterializeGV(GV, LCREVT.getSimpleVT());
2190239462Sdim}
2191239462Sdim
2192218893Sdim// A quick function that will emit a call for a named libcall in F with the
2193218893Sdim// vector of passed arguments for the Instruction in I. We can assume that we
2194218893Sdim// can emit a call for any libcall we can produce. This is an abridged version
2195218893Sdim// of the full call infrastructure since we won't need to worry about things
2196218893Sdim// like computed function pointers or strange arguments at call sites.
2197218893Sdim// TODO: Try to unify this and the normal call bits for ARM, then try to unify
2198218893Sdim// with X86.
2199218893Sdimbool ARMFastISel::ARMEmitLibcall(const Instruction *I, RTLIB::Libcall Call) {
2200218893Sdim  CallingConv::ID CC = TLI.getLibcallCallingConv(Call);
2201218893Sdim
2202218893Sdim  // Handle *simple* calls for now.
2203226633Sdim  Type *RetTy = I->getType();
2204218893Sdim  MVT RetVT;
2205218893Sdim  if (RetTy->isVoidTy())
2206218893Sdim    RetVT = MVT::isVoid;
2207218893Sdim  else if (!isTypeLegal(RetTy, RetVT))
2208218893Sdim    return false;
2209218893Sdim
2210239462Sdim  // Can't handle non-double multi-reg retvals.
2211239462Sdim  if (RetVT != MVT::isVoid && RetVT != MVT::i32) {
2212239462Sdim    SmallVector<CCValAssign, 16> RVLocs;
2213239462Sdim    CCState CCInfo(CC, false, *FuncInfo.MF, TM, RVLocs, *Context);
2214239462Sdim    CCInfo.AnalyzeCallResult(RetVT, CCAssignFnForCall(CC, true, false));
2215239462Sdim    if (RVLocs.size() >= 2 && RetVT != MVT::f64)
2216239462Sdim      return false;
2217239462Sdim  }
2218218893Sdim
2219218893Sdim  // Set up the argument vectors.
2220218893Sdim  SmallVector<Value*, 8> Args;
2221218893Sdim  SmallVector<unsigned, 8> ArgRegs;
2222218893Sdim  SmallVector<MVT, 8> ArgVTs;
2223218893Sdim  SmallVector<ISD::ArgFlagsTy, 8> ArgFlags;
2224218893Sdim  Args.reserve(I->getNumOperands());
2225218893Sdim  ArgRegs.reserve(I->getNumOperands());
2226218893Sdim  ArgVTs.reserve(I->getNumOperands());
2227218893Sdim  ArgFlags.reserve(I->getNumOperands());
2228218893Sdim  for (unsigned i = 0; i < I->getNumOperands(); ++i) {
2229218893Sdim    Value *Op = I->getOperand(i);
2230218893Sdim    unsigned Arg = getRegForValue(Op);
2231218893Sdim    if (Arg == 0) return false;
2232218893Sdim
2233226633Sdim    Type *ArgTy = Op->getType();
2234218893Sdim    MVT ArgVT;
2235218893Sdim    if (!isTypeLegal(ArgTy, ArgVT)) return false;
2236218893Sdim
2237218893Sdim    ISD::ArgFlagsTy Flags;
2238218893Sdim    unsigned OriginalAlignment = TD.getABITypeAlignment(ArgTy);
2239218893Sdim    Flags.setOrigAlign(OriginalAlignment);
2240218893Sdim
2241218893Sdim    Args.push_back(Op);
2242218893Sdim    ArgRegs.push_back(Arg);
2243218893Sdim    ArgVTs.push_back(ArgVT);
2244218893Sdim    ArgFlags.push_back(Flags);
2245218893Sdim  }
2246218893Sdim
2247218893Sdim  // Handle the arguments now that we've gotten them.
2248218893Sdim  SmallVector<unsigned, 4> RegArgs;
2249218893Sdim  unsigned NumBytes;
2250239462Sdim  if (!ProcessCallArgs(Args, ArgRegs, ArgVTs, ArgFlags,
2251239462Sdim                       RegArgs, CC, NumBytes, false))
2252218893Sdim    return false;
2253218893Sdim
2254239462Sdim  unsigned CalleeReg = 0;
2255239462Sdim  if (EnableARMLongCalls) {
2256239462Sdim    CalleeReg = getLibcallReg(TLI.getLibcallName(Call));
2257239462Sdim    if (CalleeReg == 0) return false;
2258239462Sdim  }
2259239462Sdim
2260234353Sdim  // Issue the call.
2261239462Sdim  unsigned CallOpc = ARMSelectCallOp(EnableARMLongCalls);
2262239462Sdim  MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt,
2263239462Sdim                                    DL, TII.get(CallOpc));
2264243830Sdim  // BL / BLX don't take a predicate, but tBL / tBLX do.
2265243830Sdim  if (isThumb2)
2266239462Sdim    AddDefaultPred(MIB);
2267243830Sdim  if (EnableARMLongCalls)
2268243830Sdim    MIB.addReg(CalleeReg);
2269243830Sdim  else
2270243830Sdim    MIB.addExternalSymbol(TLI.getLibcallName(Call));
2271239462Sdim
2272218893Sdim  // Add implicit physical register uses to the call.
2273218893Sdim  for (unsigned i = 0, e = RegArgs.size(); i != e; ++i)
2274243830Sdim    MIB.addReg(RegArgs[i], RegState::Implicit);
2275218893Sdim
2276234353Sdim  // Add a register mask with the call-preserved registers.
2277234353Sdim  // Proper defs for return values will be added by setPhysRegsDeadExcept().
2278234353Sdim  MIB.addRegMask(TRI.getCallPreservedMask(CC));
2279234353Sdim
2280218893Sdim  // Finish off the call including any return values.
2281218893Sdim  SmallVector<unsigned, 4> UsedRegs;
2282239462Sdim  if (!FinishCall(RetVT, UsedRegs, I, CC, NumBytes, false)) return false;
2283218893Sdim
2284218893Sdim  // Set all unused physreg defs as dead.
2285218893Sdim  static_cast<MachineInstr *>(MIB)->setPhysRegsDeadExcept(UsedRegs, TRI);
2286218893Sdim
2287218893Sdim  return true;
2288218893Sdim}
2289218893Sdim
2290234353Sdimbool ARMFastISel::SelectCall(const Instruction *I,
2291234353Sdim                             const char *IntrMemName = 0) {
2292218893Sdim  const CallInst *CI = cast<CallInst>(I);
2293218893Sdim  const Value *Callee = CI->getCalledValue();
2294218893Sdim
2295234353Sdim  // Can't handle inline asm.
2296234353Sdim  if (isa<InlineAsm>(Callee)) return false;
2297218893Sdim
2298249423Sdim  // Allow SelectionDAG isel to handle tail calls.
2299249423Sdim  if (CI->isTailCall()) return false;
2300249423Sdim
2301218893Sdim  // Check the calling convention.
2302218893Sdim  ImmutableCallSite CS(CI);
2303218893Sdim  CallingConv::ID CC = CS.getCallingConv();
2304218893Sdim
2305218893Sdim  // TODO: Avoid some calling conventions?
2306218893Sdim
2307226633Sdim  PointerType *PT = cast<PointerType>(CS.getCalledValue()->getType());
2308226633Sdim  FunctionType *FTy = cast<FunctionType>(PT->getElementType());
2309239462Sdim  bool isVarArg = FTy->isVarArg();
2310218893Sdim
2311218893Sdim  // Handle *simple* calls for now.
2312226633Sdim  Type *RetTy = I->getType();
2313218893Sdim  MVT RetVT;
2314218893Sdim  if (RetTy->isVoidTy())
2315218893Sdim    RetVT = MVT::isVoid;
2316234353Sdim  else if (!isTypeLegal(RetTy, RetVT) && RetVT != MVT::i16 &&
2317234353Sdim           RetVT != MVT::i8  && RetVT != MVT::i1)
2318218893Sdim    return false;
2319218893Sdim
2320239462Sdim  // Can't handle non-double multi-reg retvals.
2321239462Sdim  if (RetVT != MVT::isVoid && RetVT != MVT::i1 && RetVT != MVT::i8 &&
2322239462Sdim      RetVT != MVT::i16 && RetVT != MVT::i32) {
2323239462Sdim    SmallVector<CCValAssign, 16> RVLocs;
2324239462Sdim    CCState CCInfo(CC, isVarArg, *FuncInfo.MF, TM, RVLocs, *Context);
2325239462Sdim    CCInfo.AnalyzeCallResult(RetVT, CCAssignFnForCall(CC, true, isVarArg));
2326239462Sdim    if (RVLocs.size() >= 2 && RetVT != MVT::f64)
2327239462Sdim      return false;
2328239462Sdim  }
2329221345Sdim
2330218893Sdim  // Set up the argument vectors.
2331218893Sdim  SmallVector<Value*, 8> Args;
2332218893Sdim  SmallVector<unsigned, 8> ArgRegs;
2333218893Sdim  SmallVector<MVT, 8> ArgVTs;
2334218893Sdim  SmallVector<ISD::ArgFlagsTy, 8> ArgFlags;
2335234353Sdim  unsigned arg_size = CS.arg_size();
2336234353Sdim  Args.reserve(arg_size);
2337234353Sdim  ArgRegs.reserve(arg_size);
2338234353Sdim  ArgVTs.reserve(arg_size);
2339234353Sdim  ArgFlags.reserve(arg_size);
2340218893Sdim  for (ImmutableCallSite::arg_iterator i = CS.arg_begin(), e = CS.arg_end();
2341218893Sdim       i != e; ++i) {
2342234353Sdim    // If we're lowering a memory intrinsic instead of a regular call, skip the
2343234353Sdim    // last two arguments, which shouldn't be passed to the underlying function.
2344234353Sdim    if (IntrMemName && e-i <= 2)
2345234353Sdim      break;
2346218893Sdim
2347218893Sdim    ISD::ArgFlagsTy Flags;
2348218893Sdim    unsigned AttrInd = i - CS.arg_begin() + 1;
2349249423Sdim    if (CS.paramHasAttr(AttrInd, Attribute::SExt))
2350218893Sdim      Flags.setSExt();
2351249423Sdim    if (CS.paramHasAttr(AttrInd, Attribute::ZExt))
2352218893Sdim      Flags.setZExt();
2353218893Sdim
2354234353Sdim    // FIXME: Only handle *easy* calls for now.
2355249423Sdim    if (CS.paramHasAttr(AttrInd, Attribute::InReg) ||
2356249423Sdim        CS.paramHasAttr(AttrInd, Attribute::StructRet) ||
2357249423Sdim        CS.paramHasAttr(AttrInd, Attribute::Nest) ||
2358249423Sdim        CS.paramHasAttr(AttrInd, Attribute::ByVal))
2359218893Sdim      return false;
2360218893Sdim
2361226633Sdim    Type *ArgTy = (*i)->getType();
2362218893Sdim    MVT ArgVT;
2363234353Sdim    if (!isTypeLegal(ArgTy, ArgVT) && ArgVT != MVT::i16 && ArgVT != MVT::i8 &&
2364234353Sdim        ArgVT != MVT::i1)
2365218893Sdim      return false;
2366234353Sdim
2367234353Sdim    unsigned Arg = getRegForValue(*i);
2368234353Sdim    if (Arg == 0)
2369234353Sdim      return false;
2370234353Sdim
2371218893Sdim    unsigned OriginalAlignment = TD.getABITypeAlignment(ArgTy);
2372218893Sdim    Flags.setOrigAlign(OriginalAlignment);
2373218893Sdim
2374218893Sdim    Args.push_back(*i);
2375218893Sdim    ArgRegs.push_back(Arg);
2376218893Sdim    ArgVTs.push_back(ArgVT);
2377218893Sdim    ArgFlags.push_back(Flags);
2378218893Sdim  }
2379218893Sdim
2380218893Sdim  // Handle the arguments now that we've gotten them.
2381218893Sdim  SmallVector<unsigned, 4> RegArgs;
2382218893Sdim  unsigned NumBytes;
2383239462Sdim  if (!ProcessCallArgs(Args, ArgRegs, ArgVTs, ArgFlags,
2384239462Sdim                       RegArgs, CC, NumBytes, isVarArg))
2385218893Sdim    return false;
2386218893Sdim
2387239462Sdim  bool UseReg = false;
2388239462Sdim  const GlobalValue *GV = dyn_cast<GlobalValue>(Callee);
2389239462Sdim  if (!GV || EnableARMLongCalls) UseReg = true;
2390239462Sdim
2391239462Sdim  unsigned CalleeReg = 0;
2392239462Sdim  if (UseReg) {
2393239462Sdim    if (IntrMemName)
2394239462Sdim      CalleeReg = getLibcallReg(IntrMemName);
2395239462Sdim    else
2396239462Sdim      CalleeReg = getRegForValue(Callee);
2397239462Sdim
2398239462Sdim    if (CalleeReg == 0) return false;
2399239462Sdim  }
2400239462Sdim
2401234353Sdim  // Issue the call.
2402239462Sdim  unsigned CallOpc = ARMSelectCallOp(UseReg);
2403239462Sdim  MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt,
2404239462Sdim                                    DL, TII.get(CallOpc));
2405239462Sdim
2406243830Sdim  // ARM calls don't take a predicate, but tBL / tBLX do.
2407243830Sdim  if(isThumb2)
2408239462Sdim    AddDefaultPred(MIB);
2409243830Sdim  if (UseReg)
2410243830Sdim    MIB.addReg(CalleeReg);
2411243830Sdim  else if (!IntrMemName)
2412243830Sdim    MIB.addGlobalAddress(GV, 0, 0);
2413243830Sdim  else
2414243830Sdim    MIB.addExternalSymbol(IntrMemName, 0);
2415239462Sdim
2416218893Sdim  // Add implicit physical register uses to the call.
2417218893Sdim  for (unsigned i = 0, e = RegArgs.size(); i != e; ++i)
2418243830Sdim    MIB.addReg(RegArgs[i], RegState::Implicit);
2419218893Sdim
2420234353Sdim  // Add a register mask with the call-preserved registers.
2421234353Sdim  // Proper defs for return values will be added by setPhysRegsDeadExcept().
2422234353Sdim  MIB.addRegMask(TRI.getCallPreservedMask(CC));
2423234353Sdim
2424218893Sdim  // Finish off the call including any return values.
2425218893Sdim  SmallVector<unsigned, 4> UsedRegs;
2426239462Sdim  if (!FinishCall(RetVT, UsedRegs, I, CC, NumBytes, isVarArg))
2427239462Sdim    return false;
2428218893Sdim
2429218893Sdim  // Set all unused physreg defs as dead.
2430218893Sdim  static_cast<MachineInstr *>(MIB)->setPhysRegsDeadExcept(UsedRegs, TRI);
2431218893Sdim
2432218893Sdim  return true;
2433234353Sdim}
2434218893Sdim
2435234353Sdimbool ARMFastISel::ARMIsMemCpySmall(uint64_t Len) {
2436234353Sdim  return Len <= 16;
2437218893Sdim}
2438218893Sdim
2439234353Sdimbool ARMFastISel::ARMTryEmitSmallMemCpy(Address Dest, Address Src,
2440249423Sdim                                        uint64_t Len, unsigned Alignment) {
2441234353Sdim  // Make sure we don't bloat code by inlining very large memcpy's.
2442234353Sdim  if (!ARMIsMemCpySmall(Len))
2443234353Sdim    return false;
2444223017Sdim
2445234353Sdim  while (Len) {
2446234353Sdim    MVT VT;
2447249423Sdim    if (!Alignment || Alignment >= 4) {
2448249423Sdim      if (Len >= 4)
2449249423Sdim        VT = MVT::i32;
2450249423Sdim      else if (Len >= 2)
2451249423Sdim        VT = MVT::i16;
2452249423Sdim      else {
2453249423Sdim        assert (Len == 1 && "Expected a length of 1!");
2454249423Sdim        VT = MVT::i8;
2455249423Sdim      }
2456249423Sdim    } else {
2457249423Sdim      // Bound based on alignment.
2458249423Sdim      if (Len >= 2 && Alignment == 2)
2459249423Sdim        VT = MVT::i16;
2460249423Sdim      else {
2461249423Sdim        VT = MVT::i8;
2462249423Sdim      }
2463234353Sdim    }
2464223017Sdim
2465234353Sdim    bool RV;
2466234353Sdim    unsigned ResultReg;
2467234353Sdim    RV = ARMEmitLoad(VT, ResultReg, Src);
2468234353Sdim    assert (RV == true && "Should be able to handle this load.");
2469234353Sdim    RV = ARMEmitStore(VT, ResultReg, Dest);
2470234353Sdim    assert (RV == true && "Should be able to handle this store.");
2471234353Sdim    (void)RV;
2472234353Sdim
2473234353Sdim    unsigned Size = VT.getSizeInBits()/8;
2474234353Sdim    Len -= Size;
2475234353Sdim    Dest.Offset += Size;
2476234353Sdim    Src.Offset += Size;
2477234353Sdim  }
2478234353Sdim
2479234353Sdim  return true;
2480234353Sdim}
2481234353Sdim
2482234353Sdimbool ARMFastISel::SelectIntrinsicCall(const IntrinsicInst &I) {
2483234353Sdim  // FIXME: Handle more intrinsics.
2484234353Sdim  switch (I.getIntrinsicID()) {
2485234353Sdim  default: return false;
2486239462Sdim  case Intrinsic::frameaddress: {
2487239462Sdim    MachineFrameInfo *MFI = FuncInfo.MF->getFrameInfo();
2488239462Sdim    MFI->setFrameAddressIsTaken(true);
2489239462Sdim
2490239462Sdim    unsigned LdrOpc;
2491239462Sdim    const TargetRegisterClass *RC;
2492239462Sdim    if (isThumb2) {
2493239462Sdim      LdrOpc =  ARM::t2LDRi12;
2494239462Sdim      RC = (const TargetRegisterClass*)&ARM::tGPRRegClass;
2495239462Sdim    } else {
2496239462Sdim      LdrOpc =  ARM::LDRi12;
2497239462Sdim      RC = (const TargetRegisterClass*)&ARM::GPRRegClass;
2498239462Sdim    }
2499239462Sdim
2500239462Sdim    const ARMBaseRegisterInfo *RegInfo =
2501239462Sdim          static_cast<const ARMBaseRegisterInfo*>(TM.getRegisterInfo());
2502239462Sdim    unsigned FramePtr = RegInfo->getFrameRegister(*(FuncInfo.MF));
2503239462Sdim    unsigned SrcReg = FramePtr;
2504239462Sdim
2505239462Sdim    // Recursively load frame address
2506239462Sdim    // ldr r0 [fp]
2507239462Sdim    // ldr r0 [r0]
2508239462Sdim    // ldr r0 [r0]
2509239462Sdim    // ...
2510239462Sdim    unsigned DestReg;
2511239462Sdim    unsigned Depth = cast<ConstantInt>(I.getOperand(0))->getZExtValue();
2512239462Sdim    while (Depth--) {
2513239462Sdim      DestReg = createResultReg(RC);
2514239462Sdim      AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
2515239462Sdim                              TII.get(LdrOpc), DestReg)
2516239462Sdim                      .addReg(SrcReg).addImm(0));
2517239462Sdim      SrcReg = DestReg;
2518239462Sdim    }
2519239462Sdim    UpdateValueMap(&I, SrcReg);
2520239462Sdim    return true;
2521239462Sdim  }
2522234353Sdim  case Intrinsic::memcpy:
2523234353Sdim  case Intrinsic::memmove: {
2524234353Sdim    const MemTransferInst &MTI = cast<MemTransferInst>(I);
2525234353Sdim    // Don't handle volatile.
2526234353Sdim    if (MTI.isVolatile())
2527223017Sdim      return false;
2528234353Sdim
2529234353Sdim    // Disable inlining for memmove before calls to ComputeAddress.  Otherwise,
2530234353Sdim    // we would emit dead code because we don't currently handle memmoves.
2531234353Sdim    bool isMemCpy = (I.getIntrinsicID() == Intrinsic::memcpy);
2532234353Sdim    if (isa<ConstantInt>(MTI.getLength()) && isMemCpy) {
2533234353Sdim      // Small memcpy's are common enough that we want to do them without a call
2534234353Sdim      // if possible.
2535234353Sdim      uint64_t Len = cast<ConstantInt>(MTI.getLength())->getZExtValue();
2536234353Sdim      if (ARMIsMemCpySmall(Len)) {
2537234353Sdim        Address Dest, Src;
2538234353Sdim        if (!ARMComputeAddress(MTI.getRawDest(), Dest) ||
2539234353Sdim            !ARMComputeAddress(MTI.getRawSource(), Src))
2540234353Sdim          return false;
2541249423Sdim        unsigned Alignment = MTI.getAlignment();
2542249423Sdim        if (ARMTryEmitSmallMemCpy(Dest, Src, Len, Alignment))
2543234353Sdim          return true;
2544234353Sdim      }
2545234353Sdim    }
2546239462Sdim
2547234353Sdim    if (!MTI.getLength()->getType()->isIntegerTy(32))
2548223017Sdim      return false;
2549239462Sdim
2550234353Sdim    if (MTI.getSourceAddressSpace() > 255 || MTI.getDestAddressSpace() > 255)
2551234353Sdim      return false;
2552223017Sdim
2553234353Sdim    const char *IntrMemName = isa<MemCpyInst>(I) ? "memcpy" : "memmove";
2554234353Sdim    return SelectCall(&I, IntrMemName);
2555234353Sdim  }
2556234353Sdim  case Intrinsic::memset: {
2557234353Sdim    const MemSetInst &MSI = cast<MemSetInst>(I);
2558234353Sdim    // Don't handle volatile.
2559234353Sdim    if (MSI.isVolatile())
2560234353Sdim      return false;
2561239462Sdim
2562234353Sdim    if (!MSI.getLength()->getType()->isIntegerTy(32))
2563234353Sdim      return false;
2564239462Sdim
2565234353Sdim    if (MSI.getDestAddressSpace() > 255)
2566234353Sdim      return false;
2567239462Sdim
2568234353Sdim    return SelectCall(&I, "memset");
2569234353Sdim  }
2570239462Sdim  case Intrinsic::trap: {
2571249423Sdim    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(
2572249423Sdim      Subtarget->useNaClTrap() ? ARM::TRAPNaCl : ARM::TRAP));
2573239462Sdim    return true;
2574234353Sdim  }
2575239462Sdim  }
2576234353Sdim}
2577223017Sdim
2578234353Sdimbool ARMFastISel::SelectTrunc(const Instruction *I) {
2579239462Sdim  // The high bits for a type smaller than the register size are assumed to be
2580234353Sdim  // undefined.
2581234353Sdim  Value *Op = I->getOperand(0);
2582234353Sdim
2583234353Sdim  EVT SrcVT, DestVT;
2584234353Sdim  SrcVT = TLI.getValueType(Op->getType(), true);
2585234353Sdim  DestVT = TLI.getValueType(I->getType(), true);
2586234353Sdim
2587234353Sdim  if (SrcVT != MVT::i32 && SrcVT != MVT::i16 && SrcVT != MVT::i8)
2588223017Sdim    return false;
2589234353Sdim  if (DestVT != MVT::i16 && DestVT != MVT::i8 && DestVT != MVT::i1)
2590234353Sdim    return false;
2591223017Sdim
2592234353Sdim  unsigned SrcReg = getRegForValue(Op);
2593234353Sdim  if (!SrcReg) return false;
2594234353Sdim
2595234353Sdim  // Because the high bits are undefined, a truncate doesn't generate
2596234353Sdim  // any code.
2597234353Sdim  UpdateValueMap(I, SrcReg);
2598234353Sdim  return true;
2599234353Sdim}
2600234353Sdim
2601249423Sdimunsigned ARMFastISel::ARMEmitIntExt(MVT SrcVT, unsigned SrcReg, MVT DestVT,
2602234353Sdim                                    bool isZExt) {
2603234353Sdim  if (DestVT != MVT::i32 && DestVT != MVT::i16 && DestVT != MVT::i8)
2604234353Sdim    return 0;
2605234353Sdim
2606223017Sdim  unsigned Opc;
2607223017Sdim  bool isBoolZext = false;
2608251662Sdim  const TargetRegisterClass *RC;
2609249423Sdim  switch (SrcVT.SimpleTy) {
2610234353Sdim  default: return 0;
2611223017Sdim  case MVT::i16:
2612234353Sdim    if (!Subtarget->hasV6Ops()) return 0;
2613249423Sdim    RC = isThumb2 ? &ARM::rGPRRegClass : &ARM::GPRnopcRegClass;
2614234353Sdim    if (isZExt)
2615234353Sdim      Opc = isThumb2 ? ARM::t2UXTH : ARM::UXTH;
2616223017Sdim    else
2617234353Sdim      Opc = isThumb2 ? ARM::t2SXTH : ARM::SXTH;
2618223017Sdim    break;
2619223017Sdim  case MVT::i8:
2620234353Sdim    if (!Subtarget->hasV6Ops()) return 0;
2621249423Sdim    RC = isThumb2 ? &ARM::rGPRRegClass : &ARM::GPRnopcRegClass;
2622234353Sdim    if (isZExt)
2623234353Sdim      Opc = isThumb2 ? ARM::t2UXTB : ARM::UXTB;
2624223017Sdim    else
2625234353Sdim      Opc = isThumb2 ? ARM::t2SXTB : ARM::SXTB;
2626223017Sdim    break;
2627223017Sdim  case MVT::i1:
2628234353Sdim    if (isZExt) {
2629249423Sdim      RC = isThumb2 ? &ARM::rGPRRegClass : &ARM::GPRRegClass;
2630234353Sdim      Opc = isThumb2 ? ARM::t2ANDri : ARM::ANDri;
2631223017Sdim      isBoolZext = true;
2632223017Sdim      break;
2633223017Sdim    }
2634234353Sdim    return 0;
2635223017Sdim  }
2636223017Sdim
2637249423Sdim  unsigned ResultReg = createResultReg(RC);
2638223017Sdim  MachineInstrBuilder MIB;
2639234353Sdim  MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc), ResultReg)
2640223017Sdim        .addReg(SrcReg);
2641223017Sdim  if (isBoolZext)
2642223017Sdim    MIB.addImm(1);
2643226633Sdim  else
2644226633Sdim    MIB.addImm(0);
2645223017Sdim  AddOptionalDefs(MIB);
2646234353Sdim  return ResultReg;
2647234353Sdim}
2648234353Sdim
2649234353Sdimbool ARMFastISel::SelectIntExt(const Instruction *I) {
2650234353Sdim  // On ARM, in general, integer casts don't involve legal types; this code
2651234353Sdim  // handles promotable integers.
2652234353Sdim  Type *DestTy = I->getType();
2653234353Sdim  Value *Src = I->getOperand(0);
2654234353Sdim  Type *SrcTy = Src->getType();
2655234353Sdim
2656234353Sdim  bool isZExt = isa<ZExtInst>(I);
2657234353Sdim  unsigned SrcReg = getRegForValue(Src);
2658234353Sdim  if (!SrcReg) return false;
2659234353Sdim
2660249423Sdim  EVT SrcEVT, DestEVT;
2661249423Sdim  SrcEVT = TLI.getValueType(SrcTy, true);
2662249423Sdim  DestEVT = TLI.getValueType(DestTy, true);
2663249423Sdim  if (!SrcEVT.isSimple()) return false;
2664249423Sdim  if (!DestEVT.isSimple()) return false;
2665249423Sdim
2666249423Sdim  MVT SrcVT = SrcEVT.getSimpleVT();
2667249423Sdim  MVT DestVT = DestEVT.getSimpleVT();
2668234353Sdim  unsigned ResultReg = ARMEmitIntExt(SrcVT, SrcReg, DestVT, isZExt);
2669234353Sdim  if (ResultReg == 0) return false;
2670234353Sdim  UpdateValueMap(I, ResultReg);
2671223017Sdim  return true;
2672223017Sdim}
2673223017Sdim
2674239462Sdimbool ARMFastISel::SelectShift(const Instruction *I,
2675239462Sdim                              ARM_AM::ShiftOpc ShiftTy) {
2676239462Sdim  // We handle thumb2 mode by target independent selector
2677239462Sdim  // or SelectionDAG ISel.
2678239462Sdim  if (isThumb2)
2679239462Sdim    return false;
2680239462Sdim
2681239462Sdim  // Only handle i32 now.
2682239462Sdim  EVT DestVT = TLI.getValueType(I->getType(), true);
2683239462Sdim  if (DestVT != MVT::i32)
2684239462Sdim    return false;
2685239462Sdim
2686239462Sdim  unsigned Opc = ARM::MOVsr;
2687239462Sdim  unsigned ShiftImm;
2688239462Sdim  Value *Src2Value = I->getOperand(1);
2689239462Sdim  if (const ConstantInt *CI = dyn_cast<ConstantInt>(Src2Value)) {
2690239462Sdim    ShiftImm = CI->getZExtValue();
2691239462Sdim
2692239462Sdim    // Fall back to selection DAG isel if the shift amount
2693239462Sdim    // is zero or greater than the width of the value type.
2694239462Sdim    if (ShiftImm == 0 || ShiftImm >=32)
2695239462Sdim      return false;
2696239462Sdim
2697239462Sdim    Opc = ARM::MOVsi;
2698239462Sdim  }
2699239462Sdim
2700239462Sdim  Value *Src1Value = I->getOperand(0);
2701239462Sdim  unsigned Reg1 = getRegForValue(Src1Value);
2702239462Sdim  if (Reg1 == 0) return false;
2703239462Sdim
2704243830Sdim  unsigned Reg2 = 0;
2705239462Sdim  if (Opc == ARM::MOVsr) {
2706239462Sdim    Reg2 = getRegForValue(Src2Value);
2707239462Sdim    if (Reg2 == 0) return false;
2708239462Sdim  }
2709239462Sdim
2710239462Sdim  unsigned ResultReg = createResultReg(TLI.getRegClassFor(MVT::i32));
2711239462Sdim  if(ResultReg == 0) return false;
2712239462Sdim
2713239462Sdim  MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
2714239462Sdim                                    TII.get(Opc), ResultReg)
2715239462Sdim                            .addReg(Reg1);
2716239462Sdim
2717239462Sdim  if (Opc == ARM::MOVsi)
2718239462Sdim    MIB.addImm(ARM_AM::getSORegOpc(ShiftTy, ShiftImm));
2719239462Sdim  else if (Opc == ARM::MOVsr) {
2720239462Sdim    MIB.addReg(Reg2);
2721239462Sdim    MIB.addImm(ARM_AM::getSORegOpc(ShiftTy, 0));
2722239462Sdim  }
2723239462Sdim
2724239462Sdim  AddOptionalDefs(MIB);
2725239462Sdim  UpdateValueMap(I, ResultReg);
2726239462Sdim  return true;
2727239462Sdim}
2728239462Sdim
2729212793Sdim// TODO: SoftFP support.
2730212793Sdimbool ARMFastISel::TargetSelectInstruction(const Instruction *I) {
2731218893Sdim
2732212793Sdim  switch (I->getOpcode()) {
2733212793Sdim    case Instruction::Load:
2734218893Sdim      return SelectLoad(I);
2735212793Sdim    case Instruction::Store:
2736218893Sdim      return SelectStore(I);
2737212793Sdim    case Instruction::Br:
2738218893Sdim      return SelectBranch(I);
2739234353Sdim    case Instruction::IndirectBr:
2740234353Sdim      return SelectIndirectBr(I);
2741218893Sdim    case Instruction::ICmp:
2742218893Sdim    case Instruction::FCmp:
2743218893Sdim      return SelectCmp(I);
2744218893Sdim    case Instruction::FPExt:
2745218893Sdim      return SelectFPExt(I);
2746218893Sdim    case Instruction::FPTrunc:
2747218893Sdim      return SelectFPTrunc(I);
2748218893Sdim    case Instruction::SIToFP:
2749234353Sdim      return SelectIToFP(I, /*isSigned*/ true);
2750234353Sdim    case Instruction::UIToFP:
2751234353Sdim      return SelectIToFP(I, /*isSigned*/ false);
2752218893Sdim    case Instruction::FPToSI:
2753234353Sdim      return SelectFPToI(I, /*isSigned*/ true);
2754234353Sdim    case Instruction::FPToUI:
2755234353Sdim      return SelectFPToI(I, /*isSigned*/ false);
2756234353Sdim    case Instruction::Add:
2757234353Sdim      return SelectBinaryIntOp(I, ISD::ADD);
2758234353Sdim    case Instruction::Or:
2759234353Sdim      return SelectBinaryIntOp(I, ISD::OR);
2760234353Sdim    case Instruction::Sub:
2761234353Sdim      return SelectBinaryIntOp(I, ISD::SUB);
2762218893Sdim    case Instruction::FAdd:
2763234353Sdim      return SelectBinaryFPOp(I, ISD::FADD);
2764218893Sdim    case Instruction::FSub:
2765234353Sdim      return SelectBinaryFPOp(I, ISD::FSUB);
2766218893Sdim    case Instruction::FMul:
2767234353Sdim      return SelectBinaryFPOp(I, ISD::FMUL);
2768218893Sdim    case Instruction::SDiv:
2769234353Sdim      return SelectDiv(I, /*isSigned*/ true);
2770234353Sdim    case Instruction::UDiv:
2771234353Sdim      return SelectDiv(I, /*isSigned*/ false);
2772218893Sdim    case Instruction::SRem:
2773234353Sdim      return SelectRem(I, /*isSigned*/ true);
2774234353Sdim    case Instruction::URem:
2775234353Sdim      return SelectRem(I, /*isSigned*/ false);
2776218893Sdim    case Instruction::Call:
2777234353Sdim      if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I))
2778234353Sdim        return SelectIntrinsicCall(*II);
2779218893Sdim      return SelectCall(I);
2780218893Sdim    case Instruction::Select:
2781218893Sdim      return SelectSelect(I);
2782218893Sdim    case Instruction::Ret:
2783218893Sdim      return SelectRet(I);
2784223017Sdim    case Instruction::Trunc:
2785234353Sdim      return SelectTrunc(I);
2786223017Sdim    case Instruction::ZExt:
2787223017Sdim    case Instruction::SExt:
2788234353Sdim      return SelectIntExt(I);
2789239462Sdim    case Instruction::Shl:
2790239462Sdim      return SelectShift(I, ARM_AM::lsl);
2791239462Sdim    case Instruction::LShr:
2792239462Sdim      return SelectShift(I, ARM_AM::lsr);
2793239462Sdim    case Instruction::AShr:
2794239462Sdim      return SelectShift(I, ARM_AM::asr);
2795212793Sdim    default: break;
2796212793Sdim  }
2797212793Sdim  return false;
2798212793Sdim}
2799212793Sdim
2800251662Sdim/// \brief The specified machine instr operand is a vreg, and that
2801234353Sdim/// vreg is being provided by the specified load instruction.  If possible,
2802234353Sdim/// try to fold the load as an operand to the instruction, returning true if
2803234353Sdim/// successful.
2804251662Sdimbool ARMFastISel::tryToFoldLoadIntoMI(MachineInstr *MI, unsigned OpNo,
2805251662Sdim                                      const LoadInst *LI) {
2806234353Sdim  // Verify we have a legal type before going any further.
2807234353Sdim  MVT VT;
2808234353Sdim  if (!isLoadTypeLegal(LI->getType(), VT))
2809234353Sdim    return false;
2810234353Sdim
2811234353Sdim  // Combine load followed by zero- or sign-extend.
2812234353Sdim  // ldrb r1, [r0]       ldrb r1, [r0]
2813234353Sdim  // uxtb r2, r1     =>
2814234353Sdim  // mov  r3, r2         mov  r3, r1
2815234353Sdim  bool isZExt = true;
2816234353Sdim  switch(MI->getOpcode()) {
2817234353Sdim    default: return false;
2818234353Sdim    case ARM::SXTH:
2819234353Sdim    case ARM::t2SXTH:
2820234353Sdim      isZExt = false;
2821234353Sdim    case ARM::UXTH:
2822234353Sdim    case ARM::t2UXTH:
2823234353Sdim      if (VT != MVT::i16)
2824234353Sdim        return false;
2825234353Sdim    break;
2826234353Sdim    case ARM::SXTB:
2827234353Sdim    case ARM::t2SXTB:
2828234353Sdim      isZExt = false;
2829234353Sdim    case ARM::UXTB:
2830234353Sdim    case ARM::t2UXTB:
2831234353Sdim      if (VT != MVT::i8)
2832234353Sdim        return false;
2833234353Sdim    break;
2834234353Sdim  }
2835234353Sdim  // See if we can handle this address.
2836234353Sdim  Address Addr;
2837234353Sdim  if (!ARMComputeAddress(LI->getOperand(0), Addr)) return false;
2838239462Sdim
2839234353Sdim  unsigned ResultReg = MI->getOperand(0).getReg();
2840234353Sdim  if (!ARMEmitLoad(VT, ResultReg, Addr, LI->getAlignment(), isZExt, false))
2841234353Sdim    return false;
2842234353Sdim  MI->eraseFromParent();
2843234353Sdim  return true;
2844234353Sdim}
2845234353Sdim
2846243830Sdimunsigned ARMFastISel::ARMLowerPICELF(const GlobalValue *GV,
2847249423Sdim                                     unsigned Align, MVT VT) {
2848243830Sdim  bool UseGOTOFF = GV->hasLocalLinkage() || GV->hasHiddenVisibility();
2849243830Sdim  ARMConstantPoolConstant *CPV =
2850243830Sdim    ARMConstantPoolConstant::Create(GV, UseGOTOFF ? ARMCP::GOTOFF : ARMCP::GOT);
2851243830Sdim  unsigned Idx = MCP.getConstantPoolIndex(CPV, Align);
2852243830Sdim
2853243830Sdim  unsigned Opc;
2854243830Sdim  unsigned DestReg1 = createResultReg(TLI.getRegClassFor(VT));
2855243830Sdim  // Load value.
2856243830Sdim  if (isThumb2) {
2857243830Sdim    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
2858243830Sdim                            TII.get(ARM::t2LDRpci), DestReg1)
2859243830Sdim                    .addConstantPoolIndex(Idx));
2860243830Sdim    Opc = UseGOTOFF ? ARM::t2ADDrr : ARM::t2LDRs;
2861243830Sdim  } else {
2862243830Sdim    // The extra immediate is for addrmode2.
2863243830Sdim    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt,
2864243830Sdim                            DL, TII.get(ARM::LDRcp), DestReg1)
2865243830Sdim                    .addConstantPoolIndex(Idx).addImm(0));
2866243830Sdim    Opc = UseGOTOFF ? ARM::ADDrr : ARM::LDRrs;
2867243830Sdim  }
2868243830Sdim
2869243830Sdim  unsigned GlobalBaseReg = AFI->getGlobalBaseReg();
2870243830Sdim  if (GlobalBaseReg == 0) {
2871243830Sdim    GlobalBaseReg = MRI.createVirtualRegister(TLI.getRegClassFor(VT));
2872243830Sdim    AFI->setGlobalBaseReg(GlobalBaseReg);
2873243830Sdim  }
2874243830Sdim
2875243830Sdim  unsigned DestReg2 = createResultReg(TLI.getRegClassFor(VT));
2876243830Sdim  MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt,
2877243830Sdim                                    DL, TII.get(Opc), DestReg2)
2878243830Sdim                            .addReg(DestReg1)
2879243830Sdim                            .addReg(GlobalBaseReg);
2880243830Sdim  if (!UseGOTOFF)
2881243830Sdim    MIB.addImm(0);
2882243830Sdim  AddOptionalDefs(MIB);
2883243830Sdim
2884243830Sdim  return DestReg2;
2885243830Sdim}
2886243830Sdim
2887249423Sdimbool ARMFastISel::FastLowerArguments() {
2888249423Sdim  if (!FuncInfo.CanLowerReturn)
2889249423Sdim    return false;
2890249423Sdim
2891249423Sdim  const Function *F = FuncInfo.Fn;
2892249423Sdim  if (F->isVarArg())
2893249423Sdim    return false;
2894249423Sdim
2895249423Sdim  CallingConv::ID CC = F->getCallingConv();
2896249423Sdim  switch (CC) {
2897249423Sdim  default:
2898249423Sdim    return false;
2899249423Sdim  case CallingConv::Fast:
2900249423Sdim  case CallingConv::C:
2901249423Sdim  case CallingConv::ARM_AAPCS_VFP:
2902249423Sdim  case CallingConv::ARM_AAPCS:
2903249423Sdim  case CallingConv::ARM_APCS:
2904249423Sdim    break;
2905249423Sdim  }
2906249423Sdim
2907249423Sdim  // Only handle simple cases. i.e. Up to 4 i8/i16/i32 scalar arguments
2908249423Sdim  // which are passed in r0 - r3.
2909249423Sdim  unsigned Idx = 1;
2910249423Sdim  for (Function::const_arg_iterator I = F->arg_begin(), E = F->arg_end();
2911249423Sdim       I != E; ++I, ++Idx) {
2912249423Sdim    if (Idx > 4)
2913249423Sdim      return false;
2914249423Sdim
2915249423Sdim    if (F->getAttributes().hasAttribute(Idx, Attribute::InReg) ||
2916249423Sdim        F->getAttributes().hasAttribute(Idx, Attribute::StructRet) ||
2917249423Sdim        F->getAttributes().hasAttribute(Idx, Attribute::ByVal))
2918249423Sdim      return false;
2919249423Sdim
2920249423Sdim    Type *ArgTy = I->getType();
2921249423Sdim    if (ArgTy->isStructTy() || ArgTy->isArrayTy() || ArgTy->isVectorTy())
2922249423Sdim      return false;
2923249423Sdim
2924249423Sdim    EVT ArgVT = TLI.getValueType(ArgTy);
2925249423Sdim    if (!ArgVT.isSimple()) return false;
2926249423Sdim    switch (ArgVT.getSimpleVT().SimpleTy) {
2927249423Sdim    case MVT::i8:
2928249423Sdim    case MVT::i16:
2929249423Sdim    case MVT::i32:
2930249423Sdim      break;
2931249423Sdim    default:
2932249423Sdim      return false;
2933249423Sdim    }
2934249423Sdim  }
2935249423Sdim
2936249423Sdim
2937249423Sdim  static const uint16_t GPRArgRegs[] = {
2938249423Sdim    ARM::R0, ARM::R1, ARM::R2, ARM::R3
2939249423Sdim  };
2940249423Sdim
2941249423Sdim  const TargetRegisterClass *RC = TLI.getRegClassFor(MVT::i32);
2942249423Sdim  Idx = 0;
2943249423Sdim  for (Function::const_arg_iterator I = F->arg_begin(), E = F->arg_end();
2944249423Sdim       I != E; ++I, ++Idx) {
2945249423Sdim    if (I->use_empty())
2946249423Sdim      continue;
2947249423Sdim    unsigned SrcReg = GPRArgRegs[Idx];
2948249423Sdim    unsigned DstReg = FuncInfo.MF->addLiveIn(SrcReg, RC);
2949249423Sdim    // FIXME: Unfortunately it's necessary to emit a copy from the livein copy.
2950249423Sdim    // Without this, EmitLiveInCopies may eliminate the livein if its only
2951249423Sdim    // use is a bitcast (which isn't turned into an instruction).
2952249423Sdim    unsigned ResultReg = createResultReg(RC);
2953249423Sdim    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(TargetOpcode::COPY),
2954249423Sdim            ResultReg).addReg(DstReg, getKillRegState(true));
2955249423Sdim    UpdateValueMap(I, ResultReg);
2956249423Sdim  }
2957249423Sdim
2958249423Sdim  return true;
2959249423Sdim}
2960249423Sdim
2961212793Sdimnamespace llvm {
2962239462Sdim  FastISel *ARM::createFastISel(FunctionLoweringInfo &funcInfo,
2963239462Sdim                                const TargetLibraryInfo *libInfo) {
2964234353Sdim    // Completely untested on non-iOS.
2965218893Sdim    const TargetMachine &TM = funcInfo.MF->getTarget();
2966218893Sdim
2967218893Sdim    // Darwin and thumb1 only for now.
2968218893Sdim    const ARMSubtarget *Subtarget = &TM.getSubtarget<ARMSubtarget>();
2969239462Sdim    if (Subtarget->isTargetIOS() && !Subtarget->isThumb1Only())
2970239462Sdim      return new ARMFastISel(funcInfo, libInfo);
2971212793Sdim    return 0;
2972212793Sdim  }
2973212793Sdim}
2974