1ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopher//===-- ARMFastISel.cpp - ARM FastISel implementation ---------------------===//
2ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopher//
3ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopher//                     The LLVM Compiler Infrastructure
4ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopher//
5ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopher// This file is distributed under the University of Illinois Open Source
6ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopher// License. See LICENSE.TXT for details.
7ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopher//
8ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopher//===----------------------------------------------------------------------===//
9ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopher//
10ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopher// This file defines the ARM-specific support for the FastISel class. Some
11ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopher// of the target-specific code is generated by tablegen in the file
12ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopher// ARMGenFastISel.inc, which is #included here.
13ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopher//
14ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopher//===----------------------------------------------------------------------===//
15ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopher
16ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopher#include "ARM.h"
17456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopher#include "ARMBaseInstrInfo.h"
18d10cd7b31464a73e3a19b9fada80b9567b04d314Eric Christopher#include "ARMCallingConv.h"
19c9932f6f60827e31395d5254fda73f03257963aeEric Christopher#include "ARMConstantPoolValue.h"
20d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "ARMSubtarget.h"
21d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "ARMTargetMachine.h"
22ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMAddressingModes.h"
23ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopher#include "llvm/CodeGen/Analysis.h"
24ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopher#include "llvm/CodeGen/FastISel.h"
25ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopher#include "llvm/CodeGen/FunctionLoweringInfo.h"
26ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopher#include "llvm/CodeGen/MachineConstantPool.h"
27ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopher#include "llvm/CodeGen/MachineFrameInfo.h"
28d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/CodeGen/MachineInstrBuilder.h"
29d56d61af0190ee8024eb71dd4138ed7861f20adcEric Christopher#include "llvm/CodeGen/MachineMemOperand.h"
30d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/CodeGen/MachineModuleInfo.h"
31ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopher#include "llvm/CodeGen/MachineRegisterInfo.h"
320b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/CallingConv.h"
330b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DataLayout.h"
340b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DerivedTypes.h"
350b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/GlobalVariable.h"
360b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Instructions.h"
370b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/IntrinsicInst.h"
380b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Module.h"
390b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Operator.h"
40ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopher#include "llvm/Support/CallSite.h"
41038fea5e30faaf37e597f8a4627e1e3141fb59baEric Christopher#include "llvm/Support/CommandLine.h"
42ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopher#include "llvm/Support/ErrorHandling.h"
43ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopher#include "llvm/Support/GetElementPtrTypeIterator.h"
440fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher#include "llvm/Target/TargetInstrInfo.h"
450fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher#include "llvm/Target/TargetLowering.h"
460fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher#include "llvm/Target/TargetMachine.h"
47ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopher#include "llvm/Target/TargetOptions.h"
48ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopherusing namespace llvm;
49ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopher
50836c6245ad7e8f2b9f72c2a9e4cb1df101eaf2c7Eric Christopherextern cl::opt<bool> EnableARMLongCalls;
51836c6245ad7e8f2b9f72c2a9e4cb1df101eaf2c7Eric Christopher
52ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christophernamespace {
53827656dab4931a512d6d994d9c61d280a2651dd4Eric Christopher
540d58122e1221665d421a53741ef638505ecbe745Eric Christopher  // All possible address modes, plus some.
550d58122e1221665d421a53741ef638505ecbe745Eric Christopher  typedef struct Address {
560d58122e1221665d421a53741ef638505ecbe745Eric Christopher    enum {
570d58122e1221665d421a53741ef638505ecbe745Eric Christopher      RegBase,
580d58122e1221665d421a53741ef638505ecbe745Eric Christopher      FrameIndexBase
590d58122e1221665d421a53741ef638505ecbe745Eric Christopher    } BaseType;
60827656dab4931a512d6d994d9c61d280a2651dd4Eric Christopher
610d58122e1221665d421a53741ef638505ecbe745Eric Christopher    union {
620d58122e1221665d421a53741ef638505ecbe745Eric Christopher      unsigned Reg;
630d58122e1221665d421a53741ef638505ecbe745Eric Christopher      int FI;
640d58122e1221665d421a53741ef638505ecbe745Eric Christopher    } Base;
65827656dab4931a512d6d994d9c61d280a2651dd4Eric Christopher
660d58122e1221665d421a53741ef638505ecbe745Eric Christopher    int Offset;
67827656dab4931a512d6d994d9c61d280a2651dd4Eric Christopher
680d58122e1221665d421a53741ef638505ecbe745Eric Christopher    // Innocuous defaults for our address.
690d58122e1221665d421a53741ef638505ecbe745Eric Christopher    Address()
700c720761903394c4dd232b9fe49da7d5fb40172bJim Grosbach     : BaseType(RegBase), Offset(0) {
710d58122e1221665d421a53741ef638505ecbe745Eric Christopher       Base.Reg = 0;
720d58122e1221665d421a53741ef638505ecbe745Eric Christopher     }
730d58122e1221665d421a53741ef638505ecbe745Eric Christopher  } Address;
74ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopher
75ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopherclass ARMFastISel : public FastISel {
76ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopher
77ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopher  /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can
78ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopher  /// make the right decision when generating code for different targets.
79ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopher  const ARMSubtarget *Subtarget;
800fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher  const TargetMachine &TM;
810fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher  const TargetInstrInfo &TII;
820fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher  const TargetLowering &TLI;
83c9932f6f60827e31395d5254fda73f03257963aeEric Christopher  ARMFunctionInfo *AFI;
84ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopher
858cf6c60710c7924bcd0235f37e4d613f9abf7dc6Eric Christopher  // Convenience variables to avoid some queries.
8666dc8ca04b719f3ab4aa650609dbd56b055ecb34Chad Rosier  bool isThumb2;
878cf6c60710c7924bcd0235f37e4d613f9abf7dc6Eric Christopher  LLVMContext *Context;
88eaa204b2f8414a2ac5764a753c119c8cd40bade3Eric Christopher
89ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopher  public:
90d49edb7ab098fa0c82f59efbcf1b4eb2958f8dc3Bob Wilson    explicit ARMFastISel(FunctionLoweringInfo &funcInfo,
91d49edb7ab098fa0c82f59efbcf1b4eb2958f8dc3Bob Wilson                         const TargetLibraryInfo *libInfo)
92d49edb7ab098fa0c82f59efbcf1b4eb2958f8dc3Bob Wilson    : FastISel(funcInfo, libInfo),
930fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher      TM(funcInfo.MF->getTarget()),
940fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher      TII(*TM.getInstrInfo()),
950fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher      TLI(*TM.getTargetLowering()) {
96ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopher      Subtarget = &TM.getSubtarget<ARMSubtarget>();
977fe55b739c1bc319da9c81bcfd9d3e5d5030721bEric Christopher      AFI = funcInfo.MF->getInfo<ARMFunctionInfo>();
9866dc8ca04b719f3ab4aa650609dbd56b055ecb34Chad Rosier      isThumb2 = AFI->isThumbFunction();
998cf6c60710c7924bcd0235f37e4d613f9abf7dc6Eric Christopher      Context = &funcInfo.Fn->getContext();
100ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopher    }
101ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopher
102cb59229a4a60abaee9ef060c515dbd3513865afdEric Christopher    // Code from FastISel.cpp.
10335fc62bf70074349d74357900dd65f08384970c5Craig Topper  private:
10435fc62bf70074349d74357900dd65f08384970c5Craig Topper    unsigned FastEmitInst_(unsigned MachineInstOpcode,
10535fc62bf70074349d74357900dd65f08384970c5Craig Topper                           const TargetRegisterClass *RC);
10635fc62bf70074349d74357900dd65f08384970c5Craig Topper    unsigned FastEmitInst_r(unsigned MachineInstOpcode,
10735fc62bf70074349d74357900dd65f08384970c5Craig Topper                            const TargetRegisterClass *RC,
10835fc62bf70074349d74357900dd65f08384970c5Craig Topper                            unsigned Op0, bool Op0IsKill);
10935fc62bf70074349d74357900dd65f08384970c5Craig Topper    unsigned FastEmitInst_rr(unsigned MachineInstOpcode,
11035fc62bf70074349d74357900dd65f08384970c5Craig Topper                             const TargetRegisterClass *RC,
11135fc62bf70074349d74357900dd65f08384970c5Craig Topper                             unsigned Op0, bool Op0IsKill,
11235fc62bf70074349d74357900dd65f08384970c5Craig Topper                             unsigned Op1, bool Op1IsKill);
11335fc62bf70074349d74357900dd65f08384970c5Craig Topper    unsigned FastEmitInst_rrr(unsigned MachineInstOpcode,
11435fc62bf70074349d74357900dd65f08384970c5Craig Topper                              const TargetRegisterClass *RC,
11535fc62bf70074349d74357900dd65f08384970c5Craig Topper                              unsigned Op0, bool Op0IsKill,
11635fc62bf70074349d74357900dd65f08384970c5Craig Topper                              unsigned Op1, bool Op1IsKill,
11735fc62bf70074349d74357900dd65f08384970c5Craig Topper                              unsigned Op2, bool Op2IsKill);
11835fc62bf70074349d74357900dd65f08384970c5Craig Topper    unsigned FastEmitInst_ri(unsigned MachineInstOpcode,
11935fc62bf70074349d74357900dd65f08384970c5Craig Topper                             const TargetRegisterClass *RC,
12035fc62bf70074349d74357900dd65f08384970c5Craig Topper                             unsigned Op0, bool Op0IsKill,
12135fc62bf70074349d74357900dd65f08384970c5Craig Topper                             uint64_t Imm);
12235fc62bf70074349d74357900dd65f08384970c5Craig Topper    unsigned FastEmitInst_rf(unsigned MachineInstOpcode,
12335fc62bf70074349d74357900dd65f08384970c5Craig Topper                             const TargetRegisterClass *RC,
12435fc62bf70074349d74357900dd65f08384970c5Craig Topper                             unsigned Op0, bool Op0IsKill,
12535fc62bf70074349d74357900dd65f08384970c5Craig Topper                             const ConstantFP *FPImm);
12635fc62bf70074349d74357900dd65f08384970c5Craig Topper    unsigned FastEmitInst_rri(unsigned MachineInstOpcode,
12735fc62bf70074349d74357900dd65f08384970c5Craig Topper                              const TargetRegisterClass *RC,
12835fc62bf70074349d74357900dd65f08384970c5Craig Topper                              unsigned Op0, bool Op0IsKill,
12935fc62bf70074349d74357900dd65f08384970c5Craig Topper                              unsigned Op1, bool Op1IsKill,
13035fc62bf70074349d74357900dd65f08384970c5Craig Topper                              uint64_t Imm);
13135fc62bf70074349d74357900dd65f08384970c5Craig Topper    unsigned FastEmitInst_i(unsigned MachineInstOpcode,
13235fc62bf70074349d74357900dd65f08384970c5Craig Topper                            const TargetRegisterClass *RC,
13335fc62bf70074349d74357900dd65f08384970c5Craig Topper                            uint64_t Imm);
13435fc62bf70074349d74357900dd65f08384970c5Craig Topper    unsigned FastEmitInst_ii(unsigned MachineInstOpcode,
13535fc62bf70074349d74357900dd65f08384970c5Craig Topper                             const TargetRegisterClass *RC,
13635fc62bf70074349d74357900dd65f08384970c5Craig Topper                             uint64_t Imm1, uint64_t Imm2);
13735fc62bf70074349d74357900dd65f08384970c5Craig Topper
13835fc62bf70074349d74357900dd65f08384970c5Craig Topper    unsigned FastEmitInst_extractsubreg(MVT RetVT,
13935fc62bf70074349d74357900dd65f08384970c5Craig Topper                                        unsigned Op0, bool Op0IsKill,
14035fc62bf70074349d74357900dd65f08384970c5Craig Topper                                        uint32_t Idx);
141ac1a19e18ad73198ae54cc4bc08000523031f84aEric Christopher
142cb59229a4a60abaee9ef060c515dbd3513865afdEric Christopher    // Backend specific FastISel code.
14335fc62bf70074349d74357900dd65f08384970c5Craig Topper  private:
144ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopher    virtual bool TargetSelectInstruction(const Instruction *I);
1451b61ef4b22c8ae0ef82685637142246a245f9ecbEric Christopher    virtual unsigned TargetMaterializeConstant(const Constant *C);
146f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher    virtual unsigned TargetMaterializeAlloca(const AllocaInst *AI);
147b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier    virtual bool TryToFoldLoad(MachineInstr *MI, unsigned OpNo,
148b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier                               const LoadInst *LI);
149092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng    virtual bool FastLowerArguments();
15035fc62bf70074349d74357900dd65f08384970c5Craig Topper  private:
151ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopher  #include "ARMGenFastISel.inc"
152ac1a19e18ad73198ae54cc4bc08000523031f84aEric Christopher
1538300712c1e73dc106242f0007e0e0e4dd9ea38ceEric Christopher    // Instruction selection routines.
15444bff903e20574e7ae6b23c7c3f244db39e0a035Eric Christopher  private:
1551778772d1ba9a434dc98a96cbb1b97028d6cd49cEric Christopher    bool SelectLoad(const Instruction *I);
1561778772d1ba9a434dc98a96cbb1b97028d6cd49cEric Christopher    bool SelectStore(const Instruction *I);
1571778772d1ba9a434dc98a96cbb1b97028d6cd49cEric Christopher    bool SelectBranch(const Instruction *I);
15860c8fa6bb9db791acf6846fe250c184e3f1df168Chad Rosier    bool SelectIndirectBr(const Instruction *I);
1591778772d1ba9a434dc98a96cbb1b97028d6cd49cEric Christopher    bool SelectCmp(const Instruction *I);
1601778772d1ba9a434dc98a96cbb1b97028d6cd49cEric Christopher    bool SelectFPExt(const Instruction *I);
1611778772d1ba9a434dc98a96cbb1b97028d6cd49cEric Christopher    bool SelectFPTrunc(const Instruction *I);
1623901c3e75009f2ec7b4e67c354170dadab9e5a02Chad Rosier    bool SelectBinaryIntOp(const Instruction *I, unsigned ISDOpcode);
1633901c3e75009f2ec7b4e67c354170dadab9e5a02Chad Rosier    bool SelectBinaryFPOp(const Instruction *I, unsigned ISDOpcode);
164ae46a3362d6c7fd2d4b1bf3b40982d289d7418fbChad Rosier    bool SelectIToFP(const Instruction *I, bool isSigned);
165ae46a3362d6c7fd2d4b1bf3b40982d289d7418fbChad Rosier    bool SelectFPToI(const Instruction *I, bool isSigned);
1667ccb30b5964675a70559ec25a6bff32f7dea1025Chad Rosier    bool SelectDiv(const Instruction *I, bool isSigned);
167769422f0fce4def419c8cdb72ee967437ffd2f4fChad Rosier    bool SelectRem(const Instruction *I, bool isSigned);
16811add26ec2bdf5109f0ff2ee19d237664687b914Chad Rosier    bool SelectCall(const Instruction *I, const char *IntrMemName);
16911add26ec2bdf5109f0ff2ee19d237664687b914Chad Rosier    bool SelectIntrinsicCall(const IntrinsicInst &I);
1701778772d1ba9a434dc98a96cbb1b97028d6cd49cEric Christopher    bool SelectSelect(const Instruction *I);
1714f512efee9198eb38bf190b0c3fe50429a065d15Eric Christopher    bool SelectRet(const Instruction *I);
1720d7b231c9b0acf2ea6bb99f75672751f64c6c6dbChad Rosier    bool SelectTrunc(const Instruction *I);
1730d7b231c9b0acf2ea6bb99f75672751f64c6c6dbChad Rosier    bool SelectIntExt(const Instruction *I);
1742946549a2817681f9117662139cc0f2241939965Jush Lu    bool SelectShift(const Instruction *I, ARM_AM::ShiftOpc ShiftTy);
175ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopher
1768300712c1e73dc106242f0007e0e0e4dd9ea38ceEric Christopher    // Utility routines.
177456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopher  private:
178db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner    bool isTypeLegal(Type *Ty, MVT &VT);
179db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner    bool isLoadTypeLegal(Type *Ty, MVT &VT);
180e07cd5e40ac06fabfb9d33ea7c79542f138f45ceChad Rosier    bool ARMEmitCmp(const Value *Src1Value, const Value *Src2Value,
181e07cd5e40ac06fabfb9d33ea7c79542f138f45ceChad Rosier                    bool isZExt);
182a61b17c18a67f1b3faef2f2108379c4337ce9bb7Patrik Hagglund    bool ARMEmitLoad(MVT VT, unsigned &ResultReg, Address &Addr,
183404ed3c2239ff394270053bdcb76a5a4908af7ceChad Rosier                     unsigned Alignment = 0, bool isZExt = true,
184404ed3c2239ff394270053bdcb76a5a4908af7ceChad Rosier                     bool allocReg = true);
185a61b17c18a67f1b3faef2f2108379c4337ce9bb7Patrik Hagglund    bool ARMEmitStore(MVT VT, unsigned SrcReg, Address &Addr,
1866ce2deacefa5fd2565983d513d07a06d6a8af602Bob Wilson                      unsigned Alignment = 0);
1870d58122e1221665d421a53741ef638505ecbe745Eric Christopher    bool ARMComputeAddress(const Value *Obj, Address &Addr);
1886290b936bf71fded40b8b765f8f7aef577fada24Chad Rosier    void ARMSimplifyAddress(Address &Addr, MVT VT, bool useAM3);
1892c42b8c912b62071c27454182cdef60e3b584083Chad Rosier    bool ARMIsMemCpySmall(uint64_t Len);
190c9758b13668013dea491a08b4f0c9256263927c2Chad Rosier    bool ARMTryEmitSmallMemCpy(Address Dest, Address Src, uint64_t Len,
191c9758b13668013dea491a08b4f0c9256263927c2Chad Rosier                               unsigned Alignment);
192316a5aa0a510e6183dd1981dd8bf328ffe7361f5Chad Rosier    unsigned ARMEmitIntExt(MVT SrcVT, unsigned SrcReg, MVT DestVT, bool isZExt);
193a61b17c18a67f1b3faef2f2108379c4337ce9bb7Patrik Hagglund    unsigned ARMMaterializeFP(const ConstantFP *CFP, MVT VT);
194a61b17c18a67f1b3faef2f2108379c4337ce9bb7Patrik Hagglund    unsigned ARMMaterializeInt(const Constant *C, MVT VT);
195a61b17c18a67f1b3faef2f2108379c4337ce9bb7Patrik Hagglund    unsigned ARMMaterializeGV(const GlobalValue *GV, MVT VT);
196a61b17c18a67f1b3faef2f2108379c4337ce9bb7Patrik Hagglund    unsigned ARMMoveToFPReg(MVT VT, unsigned SrcReg);
197a61b17c18a67f1b3faef2f2108379c4337ce9bb7Patrik Hagglund    unsigned ARMMoveToIntReg(MVT VT, unsigned SrcReg);
19849d6fc02efc45932e4d889fa56bbbfeefafbdc85Chad Rosier    unsigned ARMSelectCallOp(bool UseReg);
199a61b17c18a67f1b3faef2f2108379c4337ce9bb7Patrik Hagglund    unsigned ARMLowerPICELF(const GlobalValue *GV, unsigned Align, MVT VT);
200ac1a19e18ad73198ae54cc4bc08000523031f84aEric Christopher
201d10cd7b31464a73e3a19b9fada80b9567b04d314Eric Christopher    // Call handling routines.
202d10cd7b31464a73e3a19b9fada80b9567b04d314Eric Christopher  private:
203ee649839a243bb29b59b322203b982b2f132e7c5Jush Lu    CCAssignFn *CCAssignFnForCall(CallingConv::ID CC,
204ee649839a243bb29b59b322203b982b2f132e7c5Jush Lu                                  bool Return,
205ee649839a243bb29b59b322203b982b2f132e7c5Jush Lu                                  bool isVarArg);
206dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher    bool ProcessCallArgs(SmallVectorImpl<Value*> &Args,
207a9a7a1a9a557cc03d1fed6cba3f27520be5274c0Eric Christopher                         SmallVectorImpl<unsigned> &ArgRegs,
2081440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands                         SmallVectorImpl<MVT> &ArgVTs,
209a9a7a1a9a557cc03d1fed6cba3f27520be5274c0Eric Christopher                         SmallVectorImpl<ISD::ArgFlagsTy> &ArgFlags,
210a9a7a1a9a557cc03d1fed6cba3f27520be5274c0Eric Christopher                         SmallVectorImpl<unsigned> &RegArgs,
211a9a7a1a9a557cc03d1fed6cba3f27520be5274c0Eric Christopher                         CallingConv::ID CC,
212ee649839a243bb29b59b322203b982b2f132e7c5Jush Lu                         unsigned &NumBytes,
213ee649839a243bb29b59b322203b982b2f132e7c5Jush Lu                         bool isVarArg);
21449d6fc02efc45932e4d889fa56bbbfeefafbdc85Chad Rosier    unsigned getLibcallReg(const Twine &Name);
2151440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands    bool FinishCall(MVT RetVT, SmallVectorImpl<unsigned> &UsedRegs,
216a9a7a1a9a557cc03d1fed6cba3f27520be5274c0Eric Christopher                    const Instruction *I, CallingConv::ID CC,
217ee649839a243bb29b59b322203b982b2f132e7c5Jush Lu                    unsigned &NumBytes, bool isVarArg);
2187ed8ec94d96cc87e768fd5ebe4ddeb04dd56e8abEric Christopher    bool ARMEmitLibcall(const Instruction *I, RTLIB::Libcall Call);
219d10cd7b31464a73e3a19b9fada80b9567b04d314Eric Christopher
220d10cd7b31464a73e3a19b9fada80b9567b04d314Eric Christopher    // OptionalDef handling routines.
221d10cd7b31464a73e3a19b9fada80b9567b04d314Eric Christopher  private:
222af3dce51494b366024958b6dc9a15b95cb03011fEric Christopher    bool isARMNEONPred(const MachineInstr *MI);
223456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopher    bool DefinesOptionalPredicate(MachineInstr *MI, bool *CPSR);
224456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopher    const MachineInstrBuilder &AddOptionalDefs(const MachineInstrBuilder &MIB);
2256290b936bf71fded40b8b765f8f7aef577fada24Chad Rosier    void AddLoadStoreOperands(MVT VT, Address &Addr,
226c152aa6c86f87be6f3ca9b6e2d57ee31b9258385Cameron Zwarich                              const MachineInstrBuilder &MIB,
227b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier                              unsigned Flags, bool useAM3);
228456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopher};
229ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopher
230ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopher} // end anonymous namespace
231ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopher
232d10cd7b31464a73e3a19b9fada80b9567b04d314Eric Christopher#include "ARMGenCallingConv.inc"
233ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopher
234456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopher// DefinesOptionalPredicate - This is different from DefinesPredicate in that
235456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopher// we don't care about implicit defs here, just places we'll need to add a
236456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopher// default CCReg argument. Sets CPSR if we're setting CPSR instead of CCR.
237456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopherbool ARMFastISel::DefinesOptionalPredicate(MachineInstr *MI, bool *CPSR) {
2385a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng  if (!MI->hasOptionalDef())
239456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopher    return false;
240456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopher
241456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopher  // Look to see if our OptionalDef is defining CPSR or CCR.
242456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopher  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
243456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopher    const MachineOperand &MO = MI->getOperand(i);
244f762fbe4fa421c91e20044ee009ddb57e25dd135Eric Christopher    if (!MO.isReg() || !MO.isDef()) continue;
245f762fbe4fa421c91e20044ee009ddb57e25dd135Eric Christopher    if (MO.getReg() == ARM::CPSR)
246456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopher      *CPSR = true;
247456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopher  }
248456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopher  return true;
249456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopher}
250456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopher
251af3dce51494b366024958b6dc9a15b95cb03011fEric Christopherbool ARMFastISel::isARMNEONPred(const MachineInstr *MI) {
252e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  const MCInstrDesc &MCID = MI->getDesc();
253299bbb23a421fce79c63e9f879ff3baef18c2f90Eric Christopher
254af3dce51494b366024958b6dc9a15b95cb03011fEric Christopher  // If we're a thumb2 or not NEON function we were handled via isPredicable.
255e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if ((MCID.TSFlags & ARMII::DomainMask) != ARMII::DomainNEON ||
256af3dce51494b366024958b6dc9a15b95cb03011fEric Christopher       AFI->isThumb2Function())
257af3dce51494b366024958b6dc9a15b95cb03011fEric Christopher    return false;
258299bbb23a421fce79c63e9f879ff3baef18c2f90Eric Christopher
259e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  for (unsigned i = 0, e = MCID.getNumOperands(); i != e; ++i)
260e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng    if (MCID.OpInfo[i].isPredicate())
261af3dce51494b366024958b6dc9a15b95cb03011fEric Christopher      return true;
262299bbb23a421fce79c63e9f879ff3baef18c2f90Eric Christopher
263af3dce51494b366024958b6dc9a15b95cb03011fEric Christopher  return false;
264af3dce51494b366024958b6dc9a15b95cb03011fEric Christopher}
265af3dce51494b366024958b6dc9a15b95cb03011fEric Christopher
266456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopher// If the machine is predicable go ahead and add the predicate operands, if
267456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopher// it needs default CC operands add those.
268aaa8df4cad59e41bebba47ce2b4c74c1f0a23c77Eric Christopher// TODO: If we want to support thumb1 then we'll need to deal with optional
269aaa8df4cad59e41bebba47ce2b4c74c1f0a23c77Eric Christopher// CPSR defs that need to be added before the remaining operands. See s_cc_out
270aaa8df4cad59e41bebba47ce2b4c74c1f0a23c77Eric Christopher// for descriptions why.
271456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopherconst MachineInstrBuilder &
272456144eb14b377166af1d9439cee6fad86fcdb1bEric ChristopherARMFastISel::AddOptionalDefs(const MachineInstrBuilder &MIB) {
273456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopher  MachineInstr *MI = &*MIB;
274456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopher
275af3dce51494b366024958b6dc9a15b95cb03011fEric Christopher  // Do we use a predicate? or...
276af3dce51494b366024958b6dc9a15b95cb03011fEric Christopher  // Are we NEON in ARM mode and have a predicate operand? If so, I know
277af3dce51494b366024958b6dc9a15b95cb03011fEric Christopher  // we're not predicable but add it anyways.
278af3dce51494b366024958b6dc9a15b95cb03011fEric Christopher  if (TII.isPredicable(MI) || isARMNEONPred(MI))
279456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopher    AddDefaultPred(MIB);
280299bbb23a421fce79c63e9f879ff3baef18c2f90Eric Christopher
28194c22716d60ff5edf6a98a3c67e0faa001be1142Sylvestre Ledru  // Do we optionally set a predicate?  Preds is size > 0 iff the predicate
282456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopher  // defines CPSR. All other OptionalDefines in ARM are the CCR register.
283979e0a141487a4cd8538dffbe09eca544acf14c7Eric Christopher  bool CPSR = false;
284456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopher  if (DefinesOptionalPredicate(MI, &CPSR)) {
285456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopher    if (CPSR)
286456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopher      AddDefaultT1CC(MIB);
287456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopher    else
288456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopher      AddDefaultCC(MIB);
289456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopher  }
290456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopher  return MIB;
291456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopher}
292456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopher
2930fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopherunsigned ARMFastISel::FastEmitInst_(unsigned MachineInstOpcode,
2940fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher                                    const TargetRegisterClass* RC) {
2950fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher  unsigned ResultReg = createResultReg(RC);
296e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  const MCInstrDesc &II = TII.get(MachineInstOpcode);
2970fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher
298456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopher  AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg));
2990fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher  return ResultReg;
3000fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher}
3010fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher
3020fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopherunsigned ARMFastISel::FastEmitInst_r(unsigned MachineInstOpcode,
3030fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher                                     const TargetRegisterClass *RC,
3040fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher                                     unsigned Op0, bool Op0IsKill) {
3050fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher  unsigned ResultReg = createResultReg(RC);
306e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  const MCInstrDesc &II = TII.get(MachineInstOpcode);
3070fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher
30840d552e0be0ba66a3d8e31bf797f1acba4c91b17Chad Rosier  if (II.getNumDefs() >= 1) {
309456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopher    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
3100fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher                   .addReg(Op0, Op0IsKill * RegState::Kill));
31140d552e0be0ba66a3d8e31bf797f1acba4c91b17Chad Rosier  } else {
312456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopher    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
3130fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher                   .addReg(Op0, Op0IsKill * RegState::Kill));
314456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopher    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
3150fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher                   TII.get(TargetOpcode::COPY), ResultReg)
3160fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher                   .addReg(II.ImplicitDefs[0]));
3170fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher  }
3180fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher  return ResultReg;
3190fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher}
3200fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher
3210fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopherunsigned ARMFastISel::FastEmitInst_rr(unsigned MachineInstOpcode,
3220fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher                                      const TargetRegisterClass *RC,
3230fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher                                      unsigned Op0, bool Op0IsKill,
3240fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher                                      unsigned Op1, bool Op1IsKill) {
3250fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher  unsigned ResultReg = createResultReg(RC);
326e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  const MCInstrDesc &II = TII.get(MachineInstOpcode);
3270fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher
32840d552e0be0ba66a3d8e31bf797f1acba4c91b17Chad Rosier  if (II.getNumDefs() >= 1) {
329456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopher    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
3300fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher                   .addReg(Op0, Op0IsKill * RegState::Kill)
3310fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher                   .addReg(Op1, Op1IsKill * RegState::Kill));
33240d552e0be0ba66a3d8e31bf797f1acba4c91b17Chad Rosier  } else {
333456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopher    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
3340fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher                   .addReg(Op0, Op0IsKill * RegState::Kill)
3350fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher                   .addReg(Op1, Op1IsKill * RegState::Kill));
336456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopher    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
3370fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher                           TII.get(TargetOpcode::COPY), ResultReg)
3380fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher                   .addReg(II.ImplicitDefs[0]));
3390fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher  }
3400fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher  return ResultReg;
3410fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher}
3420fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher
343c0e6d780cd7a0935f545a0ec0a9ad4a6ae8db2a9Cameron Zwarichunsigned ARMFastISel::FastEmitInst_rrr(unsigned MachineInstOpcode,
344c0e6d780cd7a0935f545a0ec0a9ad4a6ae8db2a9Cameron Zwarich                                       const TargetRegisterClass *RC,
345c0e6d780cd7a0935f545a0ec0a9ad4a6ae8db2a9Cameron Zwarich                                       unsigned Op0, bool Op0IsKill,
346c0e6d780cd7a0935f545a0ec0a9ad4a6ae8db2a9Cameron Zwarich                                       unsigned Op1, bool Op1IsKill,
347c0e6d780cd7a0935f545a0ec0a9ad4a6ae8db2a9Cameron Zwarich                                       unsigned Op2, bool Op2IsKill) {
348c0e6d780cd7a0935f545a0ec0a9ad4a6ae8db2a9Cameron Zwarich  unsigned ResultReg = createResultReg(RC);
349e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  const MCInstrDesc &II = TII.get(MachineInstOpcode);
350c0e6d780cd7a0935f545a0ec0a9ad4a6ae8db2a9Cameron Zwarich
35140d552e0be0ba66a3d8e31bf797f1acba4c91b17Chad Rosier  if (II.getNumDefs() >= 1) {
352c0e6d780cd7a0935f545a0ec0a9ad4a6ae8db2a9Cameron Zwarich    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
353c0e6d780cd7a0935f545a0ec0a9ad4a6ae8db2a9Cameron Zwarich                   .addReg(Op0, Op0IsKill * RegState::Kill)
354c0e6d780cd7a0935f545a0ec0a9ad4a6ae8db2a9Cameron Zwarich                   .addReg(Op1, Op1IsKill * RegState::Kill)
355c0e6d780cd7a0935f545a0ec0a9ad4a6ae8db2a9Cameron Zwarich                   .addReg(Op2, Op2IsKill * RegState::Kill));
35640d552e0be0ba66a3d8e31bf797f1acba4c91b17Chad Rosier  } else {
357c0e6d780cd7a0935f545a0ec0a9ad4a6ae8db2a9Cameron Zwarich    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
358c0e6d780cd7a0935f545a0ec0a9ad4a6ae8db2a9Cameron Zwarich                   .addReg(Op0, Op0IsKill * RegState::Kill)
359c0e6d780cd7a0935f545a0ec0a9ad4a6ae8db2a9Cameron Zwarich                   .addReg(Op1, Op1IsKill * RegState::Kill)
360c0e6d780cd7a0935f545a0ec0a9ad4a6ae8db2a9Cameron Zwarich                   .addReg(Op2, Op2IsKill * RegState::Kill));
361c0e6d780cd7a0935f545a0ec0a9ad4a6ae8db2a9Cameron Zwarich    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
362c0e6d780cd7a0935f545a0ec0a9ad4a6ae8db2a9Cameron Zwarich                           TII.get(TargetOpcode::COPY), ResultReg)
363c0e6d780cd7a0935f545a0ec0a9ad4a6ae8db2a9Cameron Zwarich                   .addReg(II.ImplicitDefs[0]));
364c0e6d780cd7a0935f545a0ec0a9ad4a6ae8db2a9Cameron Zwarich  }
365c0e6d780cd7a0935f545a0ec0a9ad4a6ae8db2a9Cameron Zwarich  return ResultReg;
366c0e6d780cd7a0935f545a0ec0a9ad4a6ae8db2a9Cameron Zwarich}
367c0e6d780cd7a0935f545a0ec0a9ad4a6ae8db2a9Cameron Zwarich
3680fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopherunsigned ARMFastISel::FastEmitInst_ri(unsigned MachineInstOpcode,
3690fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher                                      const TargetRegisterClass *RC,
3700fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher                                      unsigned Op0, bool Op0IsKill,
3710fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher                                      uint64_t Imm) {
3720fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher  unsigned ResultReg = createResultReg(RC);
373e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  const MCInstrDesc &II = TII.get(MachineInstOpcode);
3740fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher
37540d552e0be0ba66a3d8e31bf797f1acba4c91b17Chad Rosier  if (II.getNumDefs() >= 1) {
376456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopher    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
3770fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher                   .addReg(Op0, Op0IsKill * RegState::Kill)
3780fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher                   .addImm(Imm));
37940d552e0be0ba66a3d8e31bf797f1acba4c91b17Chad Rosier  } else {
380456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopher    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
3810fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher                   .addReg(Op0, Op0IsKill * RegState::Kill)
3820fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher                   .addImm(Imm));
383456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopher    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
3840fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher                           TII.get(TargetOpcode::COPY), ResultReg)
3850fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher                   .addReg(II.ImplicitDefs[0]));
3860fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher  }
3870fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher  return ResultReg;
3880fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher}
3890fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher
3900fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopherunsigned ARMFastISel::FastEmitInst_rf(unsigned MachineInstOpcode,
3910fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher                                      const TargetRegisterClass *RC,
3920fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher                                      unsigned Op0, bool Op0IsKill,
3930fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher                                      const ConstantFP *FPImm) {
3940fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher  unsigned ResultReg = createResultReg(RC);
395e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  const MCInstrDesc &II = TII.get(MachineInstOpcode);
3960fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher
39740d552e0be0ba66a3d8e31bf797f1acba4c91b17Chad Rosier  if (II.getNumDefs() >= 1) {
398456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopher    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
3990fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher                   .addReg(Op0, Op0IsKill * RegState::Kill)
4000fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher                   .addFPImm(FPImm));
40140d552e0be0ba66a3d8e31bf797f1acba4c91b17Chad Rosier  } else {
402456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopher    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
4030fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher                   .addReg(Op0, Op0IsKill * RegState::Kill)
4040fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher                   .addFPImm(FPImm));
405456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopher    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
4060fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher                           TII.get(TargetOpcode::COPY), ResultReg)
4070fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher                   .addReg(II.ImplicitDefs[0]));
4080fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher  }
4090fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher  return ResultReg;
4100fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher}
4110fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher
4120fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopherunsigned ARMFastISel::FastEmitInst_rri(unsigned MachineInstOpcode,
4130fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher                                       const TargetRegisterClass *RC,
4140fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher                                       unsigned Op0, bool Op0IsKill,
4150fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher                                       unsigned Op1, bool Op1IsKill,
4160fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher                                       uint64_t Imm) {
4170fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher  unsigned ResultReg = createResultReg(RC);
418e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  const MCInstrDesc &II = TII.get(MachineInstOpcode);
4190fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher
42040d552e0be0ba66a3d8e31bf797f1acba4c91b17Chad Rosier  if (II.getNumDefs() >= 1) {
421456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopher    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
4220fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher                   .addReg(Op0, Op0IsKill * RegState::Kill)
4230fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher                   .addReg(Op1, Op1IsKill * RegState::Kill)
4240fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher                   .addImm(Imm));
42540d552e0be0ba66a3d8e31bf797f1acba4c91b17Chad Rosier  } else {
426456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopher    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
4270fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher                   .addReg(Op0, Op0IsKill * RegState::Kill)
4280fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher                   .addReg(Op1, Op1IsKill * RegState::Kill)
4290fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher                   .addImm(Imm));
430456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopher    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
4310fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher                           TII.get(TargetOpcode::COPY), ResultReg)
4320fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher                   .addReg(II.ImplicitDefs[0]));
4330fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher  }
4340fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher  return ResultReg;
4350fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher}
4360fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher
4370fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopherunsigned ARMFastISel::FastEmitInst_i(unsigned MachineInstOpcode,
4380fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher                                     const TargetRegisterClass *RC,
4390fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher                                     uint64_t Imm) {
4400fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher  unsigned ResultReg = createResultReg(RC);
441e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  const MCInstrDesc &II = TII.get(MachineInstOpcode);
442ac1a19e18ad73198ae54cc4bc08000523031f84aEric Christopher
44340d552e0be0ba66a3d8e31bf797f1acba4c91b17Chad Rosier  if (II.getNumDefs() >= 1) {
444456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopher    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
4450fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher                   .addImm(Imm));
44640d552e0be0ba66a3d8e31bf797f1acba4c91b17Chad Rosier  } else {
447456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopher    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
4480fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher                   .addImm(Imm));
449456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopher    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
4500fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher                           TII.get(TargetOpcode::COPY), ResultReg)
4510fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher                   .addReg(II.ImplicitDefs[0]));
4520fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher  }
4530fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher  return ResultReg;
4540fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher}
4550fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher
456d94bc549fcc34f1d97d27221ce5bbf46df207557Eric Christopherunsigned ARMFastISel::FastEmitInst_ii(unsigned MachineInstOpcode,
457d94bc549fcc34f1d97d27221ce5bbf46df207557Eric Christopher                                      const TargetRegisterClass *RC,
458d94bc549fcc34f1d97d27221ce5bbf46df207557Eric Christopher                                      uint64_t Imm1, uint64_t Imm2) {
459d94bc549fcc34f1d97d27221ce5bbf46df207557Eric Christopher  unsigned ResultReg = createResultReg(RC);
460e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  const MCInstrDesc &II = TII.get(MachineInstOpcode);
461471e4224809f51652c71f319532697a879a75a0dEric Christopher
46240d552e0be0ba66a3d8e31bf797f1acba4c91b17Chad Rosier  if (II.getNumDefs() >= 1) {
463d94bc549fcc34f1d97d27221ce5bbf46df207557Eric Christopher    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)
464d94bc549fcc34f1d97d27221ce5bbf46df207557Eric Christopher                    .addImm(Imm1).addImm(Imm2));
46540d552e0be0ba66a3d8e31bf797f1acba4c91b17Chad Rosier  } else {
466d94bc549fcc34f1d97d27221ce5bbf46df207557Eric Christopher    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
467d94bc549fcc34f1d97d27221ce5bbf46df207557Eric Christopher                    .addImm(Imm1).addImm(Imm2));
468471e4224809f51652c71f319532697a879a75a0dEric Christopher    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
469d94bc549fcc34f1d97d27221ce5bbf46df207557Eric Christopher                            TII.get(TargetOpcode::COPY),
470d94bc549fcc34f1d97d27221ce5bbf46df207557Eric Christopher                            ResultReg)
471d94bc549fcc34f1d97d27221ce5bbf46df207557Eric Christopher                    .addReg(II.ImplicitDefs[0]));
472d94bc549fcc34f1d97d27221ce5bbf46df207557Eric Christopher  }
473d94bc549fcc34f1d97d27221ce5bbf46df207557Eric Christopher  return ResultReg;
474d94bc549fcc34f1d97d27221ce5bbf46df207557Eric Christopher}
475d94bc549fcc34f1d97d27221ce5bbf46df207557Eric Christopher
4760fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopherunsigned ARMFastISel::FastEmitInst_extractsubreg(MVT RetVT,
4770fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher                                                 unsigned Op0, bool Op0IsKill,
4780fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher                                                 uint32_t Idx) {
4790fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher  unsigned ResultReg = createResultReg(TLI.getRegClassFor(RetVT));
4800fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher  assert(TargetRegisterInfo::isVirtualRegister(Op0) &&
4810fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher         "Cannot yet extract from physregs");
48240d552e0be0ba66a3d8e31bf797f1acba4c91b17Chad Rosier
483456144eb14b377166af1d9439cee6fad86fcdb1bEric Christopher  AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt,
48440d552e0be0ba66a3d8e31bf797f1acba4c91b17Chad Rosier                          DL, TII.get(TargetOpcode::COPY), ResultReg)
48540d552e0be0ba66a3d8e31bf797f1acba4c91b17Chad Rosier                  .addReg(Op0, getKillRegState(Op0IsKill), Idx));
4860fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher  return ResultReg;
4870fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher}
4880fe7d54732491126c26e7e1ec60274ff2b02b849Eric Christopher
489db12b2ba9c602fc9bedcf0a9b2e72e23e29005d8Eric Christopher// TODO: Don't worry about 64-bit now, but when this is fixed remove the
490db12b2ba9c602fc9bedcf0a9b2e72e23e29005d8Eric Christopher// checks from the various callers.
491a61b17c18a67f1b3faef2f2108379c4337ce9bb7Patrik Hagglundunsigned ARMFastISel::ARMMoveToFPReg(MVT VT, unsigned SrcReg) {
492cdfad36b401be6fc709ea4051f9de58e1a30bcc9Duncan Sands  if (VT == MVT::f64) return 0;
493dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher
4949ee4ce2f91250ef44fea427392c8dad369df8972Eric Christopher  unsigned MoveReg = createResultReg(TLI.getRegClassFor(VT));
4959ee4ce2f91250ef44fea427392c8dad369df8972Eric Christopher  AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
496e751c0069aee16e85156d6539f4b724f71c341c6Jim Grosbach                          TII.get(ARM::VMOVSR), MoveReg)
4979ee4ce2f91250ef44fea427392c8dad369df8972Eric Christopher                  .addReg(SrcReg));
4989ee4ce2f91250ef44fea427392c8dad369df8972Eric Christopher  return MoveReg;
4999ee4ce2f91250ef44fea427392c8dad369df8972Eric Christopher}
5009ee4ce2f91250ef44fea427392c8dad369df8972Eric Christopher
501a61b17c18a67f1b3faef2f2108379c4337ce9bb7Patrik Hagglundunsigned ARMFastISel::ARMMoveToIntReg(MVT VT, unsigned SrcReg) {
502cdfad36b401be6fc709ea4051f9de58e1a30bcc9Duncan Sands  if (VT == MVT::i64) return 0;
503dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher
504aa3ace10c1b90e07114e60700c8c1f8e6b4f3e84Eric Christopher  unsigned MoveReg = createResultReg(TLI.getRegClassFor(VT));
505aa3ace10c1b90e07114e60700c8c1f8e6b4f3e84Eric Christopher  AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
506e751c0069aee16e85156d6539f4b724f71c341c6Jim Grosbach                          TII.get(ARM::VMOVRS), MoveReg)
507aa3ace10c1b90e07114e60700c8c1f8e6b4f3e84Eric Christopher                  .addReg(SrcReg));
508aa3ace10c1b90e07114e60700c8c1f8e6b4f3e84Eric Christopher  return MoveReg;
509aa3ace10c1b90e07114e60700c8c1f8e6b4f3e84Eric Christopher}
510aa3ace10c1b90e07114e60700c8c1f8e6b4f3e84Eric Christopher
5119ed58dff86f09699946641ba87f6c4f04a3773c8Eric Christopher// For double width floating point we need to materialize two constants
5129ed58dff86f09699946641ba87f6c4f04a3773c8Eric Christopher// (the high and the low) into integer registers then use a move to get
5139ed58dff86f09699946641ba87f6c4f04a3773c8Eric Christopher// the combined constant into an FP reg.
514a61b17c18a67f1b3faef2f2108379c4337ce9bb7Patrik Hagglundunsigned ARMFastISel::ARMMaterializeFP(const ConstantFP *CFP, MVT VT) {
5159ed58dff86f09699946641ba87f6c4f04a3773c8Eric Christopher  const APFloat Val = CFP->getValueAPF();
516cdfad36b401be6fc709ea4051f9de58e1a30bcc9Duncan Sands  bool is64bit = VT == MVT::f64;
517ac1a19e18ad73198ae54cc4bc08000523031f84aEric Christopher
5189ed58dff86f09699946641ba87f6c4f04a3773c8Eric Christopher  // This checks to see if we can use VFP3 instructions to materialize
5199ed58dff86f09699946641ba87f6c4f04a3773c8Eric Christopher  // a constant, otherwise we have to go through the constant pool.
5209ed58dff86f09699946641ba87f6c4f04a3773c8Eric Christopher  if (TLI.isFPImmLegal(Val, VT)) {
5214ebbf7b8a8e80532bd2ddf7209e62689c1698a96Jim Grosbach    int Imm;
5224ebbf7b8a8e80532bd2ddf7209e62689c1698a96Jim Grosbach    unsigned Opc;
5234ebbf7b8a8e80532bd2ddf7209e62689c1698a96Jim Grosbach    if (is64bit) {
5244ebbf7b8a8e80532bd2ddf7209e62689c1698a96Jim Grosbach      Imm = ARM_AM::getFP64Imm(Val);
5254ebbf7b8a8e80532bd2ddf7209e62689c1698a96Jim Grosbach      Opc = ARM::FCONSTD;
5264ebbf7b8a8e80532bd2ddf7209e62689c1698a96Jim Grosbach    } else {
5274ebbf7b8a8e80532bd2ddf7209e62689c1698a96Jim Grosbach      Imm = ARM_AM::getFP32Imm(Val);
5284ebbf7b8a8e80532bd2ddf7209e62689c1698a96Jim Grosbach      Opc = ARM::FCONSTS;
5294ebbf7b8a8e80532bd2ddf7209e62689c1698a96Jim Grosbach    }
5309ed58dff86f09699946641ba87f6c4f04a3773c8Eric Christopher    unsigned DestReg = createResultReg(TLI.getRegClassFor(VT));
5319ed58dff86f09699946641ba87f6c4f04a3773c8Eric Christopher    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc),
5329ed58dff86f09699946641ba87f6c4f04a3773c8Eric Christopher                            DestReg)
5334ebbf7b8a8e80532bd2ddf7209e62689c1698a96Jim Grosbach                    .addImm(Imm));
5349ed58dff86f09699946641ba87f6c4f04a3773c8Eric Christopher    return DestReg;
5359ed58dff86f09699946641ba87f6c4f04a3773c8Eric Christopher  }
536dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher
537db12b2ba9c602fc9bedcf0a9b2e72e23e29005d8Eric Christopher  // Require VFP2 for loading fp constants.
538238bb162514afac2cfb7221a0f102456de09f581Eric Christopher  if (!Subtarget->hasVFP2()) return false;
539dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher
540238bb162514afac2cfb7221a0f102456de09f581Eric Christopher  // MachineConstantPool wants an explicit alignment.
541238bb162514afac2cfb7221a0f102456de09f581Eric Christopher  unsigned Align = TD.getPrefTypeAlignment(CFP->getType());
542238bb162514afac2cfb7221a0f102456de09f581Eric Christopher  if (Align == 0) {
543238bb162514afac2cfb7221a0f102456de09f581Eric Christopher    // TODO: Figure out if this is correct.
544238bb162514afac2cfb7221a0f102456de09f581Eric Christopher    Align = TD.getTypeAllocSize(CFP->getType());
545238bb162514afac2cfb7221a0f102456de09f581Eric Christopher  }
546238bb162514afac2cfb7221a0f102456de09f581Eric Christopher  unsigned Idx = MCP.getConstantPoolIndex(cast<Constant>(CFP), Align);
547238bb162514afac2cfb7221a0f102456de09f581Eric Christopher  unsigned DestReg = createResultReg(TLI.getRegClassFor(VT));
548238bb162514afac2cfb7221a0f102456de09f581Eric Christopher  unsigned Opc = is64bit ? ARM::VLDRD : ARM::VLDRS;
549dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher
550db12b2ba9c602fc9bedcf0a9b2e72e23e29005d8Eric Christopher  // The extra reg is for addrmode5.
551f5732c4ee5af93bddeb8f4612441bfdf19237ea3Eric Christopher  AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc),
552f5732c4ee5af93bddeb8f4612441bfdf19237ea3Eric Christopher                          DestReg)
553f5732c4ee5af93bddeb8f4612441bfdf19237ea3Eric Christopher                  .addConstantPoolIndex(Idx)
554238bb162514afac2cfb7221a0f102456de09f581Eric Christopher                  .addReg(0));
555238bb162514afac2cfb7221a0f102456de09f581Eric Christopher  return DestReg;
5569ed58dff86f09699946641ba87f6c4f04a3773c8Eric Christopher}
55756d2b72884f98001cefdf8de61d6d7fc00d3df90Eric Christopher
558a61b17c18a67f1b3faef2f2108379c4337ce9bb7Patrik Hagglundunsigned ARMFastISel::ARMMaterializeInt(const Constant *C, MVT VT) {
559dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher
56044e895761f289029657a8d066f67f0c9d18693b3Chad Rosier  if (VT != MVT::i32 && VT != MVT::i16 && VT != MVT::i8 && VT != MVT::i1)
56144e895761f289029657a8d066f67f0c9d18693b3Chad Rosier    return false;
562e5b13cfdd0fc6529f8e2b3704ccaf20369aec486Eric Christopher
563e5b13cfdd0fc6529f8e2b3704ccaf20369aec486Eric Christopher  // If we can do this in a single instruction without a constant pool entry
564e5b13cfdd0fc6529f8e2b3704ccaf20369aec486Eric Christopher  // do so now.
565e5b13cfdd0fc6529f8e2b3704ccaf20369aec486Eric Christopher  const ConstantInt *CI = cast<ConstantInt>(C);
566a4e07270bccb3cb6774af975300628e072bf03f1Chad Rosier  if (Subtarget->hasV6T2Ops() && isUInt<16>(CI->getZExtValue())) {
56766dc8ca04b719f3ab4aa650609dbd56b055ecb34Chad Rosier    unsigned Opc = isThumb2 ? ARM::t2MOVi16 : ARM::MOVi16;
568fc17ddd889e3dcb608e8e97c4c791755c21d7b14Chad Rosier    const TargetRegisterClass *RC = isThumb2 ? &ARM::rGPRRegClass :
569fc17ddd889e3dcb608e8e97c4c791755c21d7b14Chad Rosier      &ARM::GPRRegClass;
570fc17ddd889e3dcb608e8e97c4c791755c21d7b14Chad Rosier    unsigned ImmReg = createResultReg(RC);
571e5b13cfdd0fc6529f8e2b3704ccaf20369aec486Eric Christopher    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
57244e895761f289029657a8d066f67f0c9d18693b3Chad Rosier                            TII.get(Opc), ImmReg)
57342536af5ce152593f489ca88bd0732218594d536Chad Rosier                    .addImm(CI->getZExtValue()));
57444e895761f289029657a8d066f67f0c9d18693b3Chad Rosier    return ImmReg;
575e5b13cfdd0fc6529f8e2b3704ccaf20369aec486Eric Christopher  }
576e5b13cfdd0fc6529f8e2b3704ccaf20369aec486Eric Christopher
5774e89d97e3a40dcbbf07648512f0e95133867a74fChad Rosier  // Use MVN to emit negative constants.
5784e89d97e3a40dcbbf07648512f0e95133867a74fChad Rosier  if (VT == MVT::i32 && Subtarget->hasV6T2Ops() && CI->isNegative()) {
5794e89d97e3a40dcbbf07648512f0e95133867a74fChad Rosier    unsigned Imm = (unsigned)~(CI->getSExtValue());
5801c47de87c74c3834c5cfab8a7e0fa67b1805f927Chad Rosier    bool UseImm = isThumb2 ? (ARM_AM::getT2SOImmVal(Imm) != -1) :
5814e89d97e3a40dcbbf07648512f0e95133867a74fChad Rosier      (ARM_AM::getSOImmVal(Imm) != -1);
5821c47de87c74c3834c5cfab8a7e0fa67b1805f927Chad Rosier    if (UseImm) {
5834e89d97e3a40dcbbf07648512f0e95133867a74fChad Rosier      unsigned Opc = isThumb2 ? ARM::t2MVNi : ARM::MVNi;
5844e89d97e3a40dcbbf07648512f0e95133867a74fChad Rosier      unsigned ImmReg = createResultReg(TLI.getRegClassFor(MVT::i32));
5854e89d97e3a40dcbbf07648512f0e95133867a74fChad Rosier      AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
5864e89d97e3a40dcbbf07648512f0e95133867a74fChad Rosier                              TII.get(Opc), ImmReg)
5874e89d97e3a40dcbbf07648512f0e95133867a74fChad Rosier                      .addImm(Imm));
5884e89d97e3a40dcbbf07648512f0e95133867a74fChad Rosier      return ImmReg;
5894e89d97e3a40dcbbf07648512f0e95133867a74fChad Rosier    }
5904e89d97e3a40dcbbf07648512f0e95133867a74fChad Rosier  }
5914e89d97e3a40dcbbf07648512f0e95133867a74fChad Rosier
5924e89d97e3a40dcbbf07648512f0e95133867a74fChad Rosier  // Load from constant pool.  For now 32-bit only.
59344e895761f289029657a8d066f67f0c9d18693b3Chad Rosier  if (VT != MVT::i32)
59444e895761f289029657a8d066f67f0c9d18693b3Chad Rosier    return false;
59544e895761f289029657a8d066f67f0c9d18693b3Chad Rosier
59644e895761f289029657a8d066f67f0c9d18693b3Chad Rosier  unsigned DestReg = createResultReg(TLI.getRegClassFor(VT));
59744e895761f289029657a8d066f67f0c9d18693b3Chad Rosier
59856d2b72884f98001cefdf8de61d6d7fc00d3df90Eric Christopher  // MachineConstantPool wants an explicit alignment.
59956d2b72884f98001cefdf8de61d6d7fc00d3df90Eric Christopher  unsigned Align = TD.getPrefTypeAlignment(C->getType());
60056d2b72884f98001cefdf8de61d6d7fc00d3df90Eric Christopher  if (Align == 0) {
60156d2b72884f98001cefdf8de61d6d7fc00d3df90Eric Christopher    // TODO: Figure out if this is correct.
60256d2b72884f98001cefdf8de61d6d7fc00d3df90Eric Christopher    Align = TD.getTypeAllocSize(C->getType());
60356d2b72884f98001cefdf8de61d6d7fc00d3df90Eric Christopher  }
60456d2b72884f98001cefdf8de61d6d7fc00d3df90Eric Christopher  unsigned Idx = MCP.getConstantPoolIndex(C, Align);
605dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher
60666dc8ca04b719f3ab4aa650609dbd56b055ecb34Chad Rosier  if (isThumb2)
60756d2b72884f98001cefdf8de61d6d7fc00d3df90Eric Christopher    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
608fd60980eb248f44927ea55c1f8d11fa019d318a6Eric Christopher                            TII.get(ARM::t2LDRpci), DestReg)
609fd60980eb248f44927ea55c1f8d11fa019d318a6Eric Christopher                    .addConstantPoolIndex(Idx));
61056d2b72884f98001cefdf8de61d6d7fc00d3df90Eric Christopher  else
611d0c82a683e965f326e36a2bcaa85c00e917f8282Eric Christopher    // The extra immediate is for addrmode2.
61256d2b72884f98001cefdf8de61d6d7fc00d3df90Eric Christopher    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
613fd60980eb248f44927ea55c1f8d11fa019d318a6Eric Christopher                            TII.get(ARM::LDRcp), DestReg)
614fd60980eb248f44927ea55c1f8d11fa019d318a6Eric Christopher                    .addConstantPoolIndex(Idx)
6153e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach                    .addImm(0));
616ac1a19e18ad73198ae54cc4bc08000523031f84aEric Christopher
61756d2b72884f98001cefdf8de61d6d7fc00d3df90Eric Christopher  return DestReg;
6181b61ef4b22c8ae0ef82685637142246a245f9ecbEric Christopher}
6191b61ef4b22c8ae0ef82685637142246a245f9ecbEric Christopher
620a61b17c18a67f1b3faef2f2108379c4337ce9bb7Patrik Hagglundunsigned ARMFastISel::ARMMaterializeGV(const GlobalValue *GV, MVT VT) {
621890dbbec5773fb4d3823e3102d403d79900b08bcEric Christopher  // For now 32-bit only.
622cdfad36b401be6fc709ea4051f9de58e1a30bcc9Duncan Sands  if (VT != MVT::i32) return 0;
623dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher
624890dbbec5773fb4d3823e3102d403d79900b08bcEric Christopher  Reloc::Model RelocM = TM.getRelocationModel();
625c4dc2490c4ea2c75e451eec5950179f06d2610a2Jush Lu  bool IsIndirect = Subtarget->GVIsIndirectSymbol(GV, RelocM);
6266aa6e5a2852ad5c83cef5eb52f62f9267e3511eaChad Rosier  const TargetRegisterClass *RC = isThumb2 ?
6276aa6e5a2852ad5c83cef5eb52f62f9267e3511eaChad Rosier    (const TargetRegisterClass*)&ARM::rGPRRegClass :
6286aa6e5a2852ad5c83cef5eb52f62f9267e3511eaChad Rosier    (const TargetRegisterClass*)&ARM::GPRRegClass;
6296aa6e5a2852ad5c83cef5eb52f62f9267e3511eaChad Rosier  unsigned DestReg = createResultReg(RC);
63045ca7c6336f174fae3a9521d5161a498ca27fd13Jakob Stoklund Olesen
63145ca7c6336f174fae3a9521d5161a498ca27fd13Jakob Stoklund Olesen  // Use movw+movt when possible, it avoids constant pool entries.
6328f37a2422ea948b71d0992ab3f82dab07a54ce52Jakob Stoklund Olesen  // Darwin targets don't support movt with Reloc::Static, see
6338f37a2422ea948b71d0992ab3f82dab07a54ce52Jakob Stoklund Olesen  // ARMTargetLowering::LowerGlobalAddressDarwin.  Other targets only support
6348f37a2422ea948b71d0992ab3f82dab07a54ce52Jakob Stoklund Olesen  // static movt relocations.
6358f37a2422ea948b71d0992ab3f82dab07a54ce52Jakob Stoklund Olesen  if (Subtarget->useMovt() &&
6368f37a2422ea948b71d0992ab3f82dab07a54ce52Jakob Stoklund Olesen      Subtarget->isTargetDarwin() == (RelocM != Reloc::Static)) {
63745ca7c6336f174fae3a9521d5161a498ca27fd13Jakob Stoklund Olesen    unsigned Opc;
63845ca7c6336f174fae3a9521d5161a498ca27fd13Jakob Stoklund Olesen    switch (RelocM) {
63945ca7c6336f174fae3a9521d5161a498ca27fd13Jakob Stoklund Olesen    case Reloc::PIC_:
64045ca7c6336f174fae3a9521d5161a498ca27fd13Jakob Stoklund Olesen      Opc = isThumb2 ? ARM::t2MOV_ga_pcrel : ARM::MOV_ga_pcrel;
64145ca7c6336f174fae3a9521d5161a498ca27fd13Jakob Stoklund Olesen      break;
64245ca7c6336f174fae3a9521d5161a498ca27fd13Jakob Stoklund Olesen    case Reloc::DynamicNoPIC:
64345ca7c6336f174fae3a9521d5161a498ca27fd13Jakob Stoklund Olesen      Opc = isThumb2 ? ARM::t2MOV_ga_dyn : ARM::MOV_ga_dyn;
64445ca7c6336f174fae3a9521d5161a498ca27fd13Jakob Stoklund Olesen      break;
64545ca7c6336f174fae3a9521d5161a498ca27fd13Jakob Stoklund Olesen    default:
64645ca7c6336f174fae3a9521d5161a498ca27fd13Jakob Stoklund Olesen      Opc = isThumb2 ? ARM::t2MOVi32imm : ARM::MOVi32imm;
64745ca7c6336f174fae3a9521d5161a498ca27fd13Jakob Stoklund Olesen      break;
64845ca7c6336f174fae3a9521d5161a498ca27fd13Jakob Stoklund Olesen    }
64945ca7c6336f174fae3a9521d5161a498ca27fd13Jakob Stoklund Olesen    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc),
65045ca7c6336f174fae3a9521d5161a498ca27fd13Jakob Stoklund Olesen                            DestReg).addGlobalAddress(GV));
651890dbbec5773fb4d3823e3102d403d79900b08bcEric Christopher  } else {
65245ca7c6336f174fae3a9521d5161a498ca27fd13Jakob Stoklund Olesen    // MachineConstantPool wants an explicit alignment.
65345ca7c6336f174fae3a9521d5161a498ca27fd13Jakob Stoklund Olesen    unsigned Align = TD.getPrefTypeAlignment(GV->getType());
65445ca7c6336f174fae3a9521d5161a498ca27fd13Jakob Stoklund Olesen    if (Align == 0) {
65545ca7c6336f174fae3a9521d5161a498ca27fd13Jakob Stoklund Olesen      // TODO: Figure out if this is correct.
65645ca7c6336f174fae3a9521d5161a498ca27fd13Jakob Stoklund Olesen      Align = TD.getTypeAllocSize(GV->getType());
65745ca7c6336f174fae3a9521d5161a498ca27fd13Jakob Stoklund Olesen    }
65845ca7c6336f174fae3a9521d5161a498ca27fd13Jakob Stoklund Olesen
6598f50647662560167b88851f92c3c891d2e7c1696Jush Lu    if (Subtarget->isTargetELF() && RelocM == Reloc::PIC_)
6608f50647662560167b88851f92c3c891d2e7c1696Jush Lu      return ARMLowerPICELF(GV, Align, VT);
6618f50647662560167b88851f92c3c891d2e7c1696Jush Lu
66245ca7c6336f174fae3a9521d5161a498ca27fd13Jakob Stoklund Olesen    // Grab index.
66345ca7c6336f174fae3a9521d5161a498ca27fd13Jakob Stoklund Olesen    unsigned PCAdj = (RelocM != Reloc::PIC_) ? 0 :
66445ca7c6336f174fae3a9521d5161a498ca27fd13Jakob Stoklund Olesen      (Subtarget->isThumb() ? 4 : 8);
66545ca7c6336f174fae3a9521d5161a498ca27fd13Jakob Stoklund Olesen    unsigned Id = AFI->createPICLabelUId();
66645ca7c6336f174fae3a9521d5161a498ca27fd13Jakob Stoklund Olesen    ARMConstantPoolValue *CPV = ARMConstantPoolConstant::Create(GV, Id,
66745ca7c6336f174fae3a9521d5161a498ca27fd13Jakob Stoklund Olesen                                                                ARMCP::CPValue,
66845ca7c6336f174fae3a9521d5161a498ca27fd13Jakob Stoklund Olesen                                                                PCAdj);
66945ca7c6336f174fae3a9521d5161a498ca27fd13Jakob Stoklund Olesen    unsigned Idx = MCP.getConstantPoolIndex(CPV, Align);
67045ca7c6336f174fae3a9521d5161a498ca27fd13Jakob Stoklund Olesen
67145ca7c6336f174fae3a9521d5161a498ca27fd13Jakob Stoklund Olesen    // Load value.
67245ca7c6336f174fae3a9521d5161a498ca27fd13Jakob Stoklund Olesen    MachineInstrBuilder MIB;
67345ca7c6336f174fae3a9521d5161a498ca27fd13Jakob Stoklund Olesen    if (isThumb2) {
67445ca7c6336f174fae3a9521d5161a498ca27fd13Jakob Stoklund Olesen      unsigned Opc = (RelocM!=Reloc::PIC_) ? ARM::t2LDRpci : ARM::t2LDRpci_pic;
67545ca7c6336f174fae3a9521d5161a498ca27fd13Jakob Stoklund Olesen      MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc), DestReg)
67645ca7c6336f174fae3a9521d5161a498ca27fd13Jakob Stoklund Olesen        .addConstantPoolIndex(Idx);
67745ca7c6336f174fae3a9521d5161a498ca27fd13Jakob Stoklund Olesen      if (RelocM == Reloc::PIC_)
67845ca7c6336f174fae3a9521d5161a498ca27fd13Jakob Stoklund Olesen        MIB.addImm(Id);
679c4dc2490c4ea2c75e451eec5950179f06d2610a2Jush Lu      AddOptionalDefs(MIB);
68045ca7c6336f174fae3a9521d5161a498ca27fd13Jakob Stoklund Olesen    } else {
68145ca7c6336f174fae3a9521d5161a498ca27fd13Jakob Stoklund Olesen      // The extra immediate is for addrmode2.
68245ca7c6336f174fae3a9521d5161a498ca27fd13Jakob Stoklund Olesen      MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(ARM::LDRcp),
68345ca7c6336f174fae3a9521d5161a498ca27fd13Jakob Stoklund Olesen                    DestReg)
68445ca7c6336f174fae3a9521d5161a498ca27fd13Jakob Stoklund Olesen        .addConstantPoolIndex(Idx)
68545ca7c6336f174fae3a9521d5161a498ca27fd13Jakob Stoklund Olesen        .addImm(0);
686c4dc2490c4ea2c75e451eec5950179f06d2610a2Jush Lu      AddOptionalDefs(MIB);
687c4dc2490c4ea2c75e451eec5950179f06d2610a2Jush Lu
688c4dc2490c4ea2c75e451eec5950179f06d2610a2Jush Lu      if (RelocM == Reloc::PIC_) {
689c4dc2490c4ea2c75e451eec5950179f06d2610a2Jush Lu        unsigned Opc = IsIndirect ? ARM::PICLDR : ARM::PICADD;
690c4dc2490c4ea2c75e451eec5950179f06d2610a2Jush Lu        unsigned NewDestReg = createResultReg(TLI.getRegClassFor(VT));
691c4dc2490c4ea2c75e451eec5950179f06d2610a2Jush Lu
692c4dc2490c4ea2c75e451eec5950179f06d2610a2Jush Lu        MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt,
693c4dc2490c4ea2c75e451eec5950179f06d2610a2Jush Lu                                          DL, TII.get(Opc), NewDestReg)
694c4dc2490c4ea2c75e451eec5950179f06d2610a2Jush Lu                                  .addReg(DestReg)
695c4dc2490c4ea2c75e451eec5950179f06d2610a2Jush Lu                                  .addImm(Id);
696c4dc2490c4ea2c75e451eec5950179f06d2610a2Jush Lu        AddOptionalDefs(MIB);
697c4dc2490c4ea2c75e451eec5950179f06d2610a2Jush Lu        return NewDestReg;
698c4dc2490c4ea2c75e451eec5950179f06d2610a2Jush Lu      }
69945ca7c6336f174fae3a9521d5161a498ca27fd13Jakob Stoklund Olesen    }
700890dbbec5773fb4d3823e3102d403d79900b08bcEric Christopher  }
701d6412c940ef863d02595f7be094d8cd3afc908a1Eli Friedman
702c4dc2490c4ea2c75e451eec5950179f06d2610a2Jush Lu  if (IsIndirect) {
70345ca7c6336f174fae3a9521d5161a498ca27fd13Jakob Stoklund Olesen    MachineInstrBuilder MIB;
704d6412c940ef863d02595f7be094d8cd3afc908a1Eli Friedman    unsigned NewDestReg = createResultReg(TLI.getRegClassFor(VT));
70566dc8ca04b719f3ab4aa650609dbd56b055ecb34Chad Rosier    if (isThumb2)
706b04546ff5b1a7a03eec1076900c945223bf494ccJim Grosbach      MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
707b04546ff5b1a7a03eec1076900c945223bf494ccJim Grosbach                    TII.get(ARM::t2LDRi12), NewDestReg)
708d6412c940ef863d02595f7be094d8cd3afc908a1Eli Friedman            .addReg(DestReg)
709d6412c940ef863d02595f7be094d8cd3afc908a1Eli Friedman            .addImm(0);
710d6412c940ef863d02595f7be094d8cd3afc908a1Eli Friedman    else
711d6412c940ef863d02595f7be094d8cd3afc908a1Eli Friedman      MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(ARM::LDRi12),
712d6412c940ef863d02595f7be094d8cd3afc908a1Eli Friedman                    NewDestReg)
713d6412c940ef863d02595f7be094d8cd3afc908a1Eli Friedman            .addReg(DestReg)
714d6412c940ef863d02595f7be094d8cd3afc908a1Eli Friedman            .addImm(0);
715d6412c940ef863d02595f7be094d8cd3afc908a1Eli Friedman    DestReg = NewDestReg;
716d6412c940ef863d02595f7be094d8cd3afc908a1Eli Friedman    AddOptionalDefs(MIB);
717d6412c940ef863d02595f7be094d8cd3afc908a1Eli Friedman  }
718d6412c940ef863d02595f7be094d8cd3afc908a1Eli Friedman
719890dbbec5773fb4d3823e3102d403d79900b08bcEric Christopher  return DestReg;
720c9932f6f60827e31395d5254fda73f03257963aeEric Christopher}
721c9932f6f60827e31395d5254fda73f03257963aeEric Christopher
7229ed58dff86f09699946641ba87f6c4f04a3773c8Eric Christopherunsigned ARMFastISel::TargetMaterializeConstant(const Constant *C) {
7233d170e64ca1af491e2aa58f882f93b8e8111eef8Patrik Hagglund  EVT CEVT = TLI.getValueType(C->getType(), true);
7243d170e64ca1af491e2aa58f882f93b8e8111eef8Patrik Hagglund
7253d170e64ca1af491e2aa58f882f93b8e8111eef8Patrik Hagglund  // Only handle simple types.
7263d170e64ca1af491e2aa58f882f93b8e8111eef8Patrik Hagglund  if (!CEVT.isSimple()) return 0;
7273d170e64ca1af491e2aa58f882f93b8e8111eef8Patrik Hagglund  MVT VT = CEVT.getSimpleVT();
7289ed58dff86f09699946641ba87f6c4f04a3773c8Eric Christopher
7299ed58dff86f09699946641ba87f6c4f04a3773c8Eric Christopher  if (const ConstantFP *CFP = dyn_cast<ConstantFP>(C))
7309ed58dff86f09699946641ba87f6c4f04a3773c8Eric Christopher    return ARMMaterializeFP(CFP, VT);
731c9932f6f60827e31395d5254fda73f03257963aeEric Christopher  else if (const GlobalValue *GV = dyn_cast<GlobalValue>(C))
732c9932f6f60827e31395d5254fda73f03257963aeEric Christopher    return ARMMaterializeGV(GV, VT);
733c9932f6f60827e31395d5254fda73f03257963aeEric Christopher  else if (isa<ConstantInt>(C))
734c9932f6f60827e31395d5254fda73f03257963aeEric Christopher    return ARMMaterializeInt(C, VT);
735dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher
736c9932f6f60827e31395d5254fda73f03257963aeEric Christopher  return 0;
7379ed58dff86f09699946641ba87f6c4f04a3773c8Eric Christopher}
7389ed58dff86f09699946641ba87f6c4f04a3773c8Eric Christopher
739944d82ba06bcb6bf92ca1fbcbdf1a882cd009363Chad Rosier// TODO: unsigned ARMFastISel::TargetMaterializeFloatZero(const ConstantFP *CF);
740944d82ba06bcb6bf92ca1fbcbdf1a882cd009363Chad Rosier
741f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopherunsigned ARMFastISel::TargetMaterializeAlloca(const AllocaInst *AI) {
742f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher  // Don't handle dynamic allocas.
743f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher  if (!FuncInfo.StaticAllocaMap.count(AI)) return 0;
744dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher
7451440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands  MVT VT;
746f4bd21c256f6aabdc13f54ff7bf5d69e8305302cChad Rosier  if (!isLoadTypeLegal(AI->getType(), VT)) return 0;
747dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher
748f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher  DenseMap<const AllocaInst*, int>::iterator SI =
749f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher    FuncInfo.StaticAllocaMap.find(AI);
750f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher
751f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher  // This will get lowered later into the correct offsets and registers
752f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher  // via rewriteXFrameIndex.
753f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher  if (SI != FuncInfo.StaticAllocaMap.end()) {
75444d23825d61d530b8d562329ec8fc2d4f843bb8dCraig Topper    const TargetRegisterClass* RC = TLI.getRegClassFor(VT);
755f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher    unsigned ResultReg = createResultReg(RC);
75666dc8ca04b719f3ab4aa650609dbd56b055ecb34Chad Rosier    unsigned Opc = isThumb2 ? ARM::t2ADDri : ARM::ADDri;
757ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
758f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher                            TII.get(Opc), ResultReg)
759f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher                            .addFrameIndex(SI->second)
760f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher                            .addImm(0));
761f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher    return ResultReg;
762f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher  }
763dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher
764f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher  return 0;
765f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher}
766f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher
767db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattnerbool ARMFastISel::isTypeLegal(Type *Ty, MVT &VT) {
7681440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands  EVT evt = TLI.getValueType(Ty, true);
769ac1a19e18ad73198ae54cc4bc08000523031f84aEric Christopher
770b1cc848d1a9a831e8058fad546e41b21d955fd88Eric Christopher  // Only handle simple types.
7711440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands  if (evt == MVT::Other || !evt.isSimple()) return false;
7721440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands  VT = evt.getSimpleVT();
773ac1a19e18ad73198ae54cc4bc08000523031f84aEric Christopher
774dc90804a402b9d617c154625e04a74ebd7fe3599Eric Christopher  // Handle all legal types, i.e. a register that will directly hold this
775dc90804a402b9d617c154625e04a74ebd7fe3599Eric Christopher  // value.
776dc90804a402b9d617c154625e04a74ebd7fe3599Eric Christopher  return TLI.isTypeLegal(VT);
777b1cc848d1a9a831e8058fad546e41b21d955fd88Eric Christopher}
778b1cc848d1a9a831e8058fad546e41b21d955fd88Eric Christopher
779db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattnerbool ARMFastISel::isLoadTypeLegal(Type *Ty, MVT &VT) {
7804e68c7cca44d33771d376f1668d687ce9d8f11d3Eric Christopher  if (isTypeLegal(Ty, VT)) return true;
781ac1a19e18ad73198ae54cc4bc08000523031f84aEric Christopher
7824e68c7cca44d33771d376f1668d687ce9d8f11d3Eric Christopher  // If this is a type than can be sign or zero-extended to a basic operation
7834e68c7cca44d33771d376f1668d687ce9d8f11d3Eric Christopher  // go ahead and accept it now.
784b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier  if (VT == MVT::i1 || VT == MVT::i8 || VT == MVT::i16)
7854e68c7cca44d33771d376f1668d687ce9d8f11d3Eric Christopher    return true;
786ac1a19e18ad73198ae54cc4bc08000523031f84aEric Christopher
7874e68c7cca44d33771d376f1668d687ce9d8f11d3Eric Christopher  return false;
7884e68c7cca44d33771d376f1668d687ce9d8f11d3Eric Christopher}
7894e68c7cca44d33771d376f1668d687ce9d8f11d3Eric Christopher
79088de86b550a1fd19dd968cafac48e810f1da5254Eric Christopher// Computes the address to get to an object.
7910d58122e1221665d421a53741ef638505ecbe745Eric Christopherbool ARMFastISel::ARMComputeAddress(const Value *Obj, Address &Addr) {
7928300712c1e73dc106242f0007e0e0e4dd9ea38ceEric Christopher  // Some boilerplate from the X86 FastISel.
7938300712c1e73dc106242f0007e0e0e4dd9ea38ceEric Christopher  const User *U = NULL;
7948300712c1e73dc106242f0007e0e0e4dd9ea38ceEric Christopher  unsigned Opcode = Instruction::UserOp1;
795cb0b04ba6fc847574f592d1a80ff3b60c0d4228cEric Christopher  if (const Instruction *I = dyn_cast<Instruction>(Obj)) {
7962d630d7bc9ae746d353211c3532dfa8e4f0ce9d5Eric Christopher    // Don't walk into other basic blocks unless the object is an alloca from
7972d630d7bc9ae746d353211c3532dfa8e4f0ce9d5Eric Christopher    // another block, otherwise it may not have a virtual register assigned.
79876dda7ec1d8d0ee65a103b6710ab75c2a9e012d1Eric Christopher    if (FuncInfo.StaticAllocaMap.count(static_cast<const AllocaInst *>(Obj)) ||
79976dda7ec1d8d0ee65a103b6710ab75c2a9e012d1Eric Christopher        FuncInfo.MBBMap[I->getParent()] == FuncInfo.MBB) {
80076dda7ec1d8d0ee65a103b6710ab75c2a9e012d1Eric Christopher      Opcode = I->getOpcode();
80176dda7ec1d8d0ee65a103b6710ab75c2a9e012d1Eric Christopher      U = I;
80276dda7ec1d8d0ee65a103b6710ab75c2a9e012d1Eric Christopher    }
803cb0b04ba6fc847574f592d1a80ff3b60c0d4228cEric Christopher  } else if (const ConstantExpr *C = dyn_cast<ConstantExpr>(Obj)) {
8048300712c1e73dc106242f0007e0e0e4dd9ea38ceEric Christopher    Opcode = C->getOpcode();
8058300712c1e73dc106242f0007e0e0e4dd9ea38ceEric Christopher    U = C;
8068300712c1e73dc106242f0007e0e0e4dd9ea38ceEric Christopher  }
8078300712c1e73dc106242f0007e0e0e4dd9ea38ceEric Christopher
808db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  if (PointerType *Ty = dyn_cast<PointerType>(Obj->getType()))
8098300712c1e73dc106242f0007e0e0e4dd9ea38ceEric Christopher    if (Ty->getAddressSpace() > 255)
8108300712c1e73dc106242f0007e0e0e4dd9ea38ceEric Christopher      // Fast instruction selection doesn't support the special
8118300712c1e73dc106242f0007e0e0e4dd9ea38ceEric Christopher      // address spaces.
8128300712c1e73dc106242f0007e0e0e4dd9ea38ceEric Christopher      return false;
813ac1a19e18ad73198ae54cc4bc08000523031f84aEric Christopher
8148300712c1e73dc106242f0007e0e0e4dd9ea38ceEric Christopher  switch (Opcode) {
815ac1a19e18ad73198ae54cc4bc08000523031f84aEric Christopher    default:
8168300712c1e73dc106242f0007e0e0e4dd9ea38ceEric Christopher    break;
8175532433a574043b516aec26a4dd4b6c8d7fc551eEric Christopher    case Instruction::BitCast: {
8185532433a574043b516aec26a4dd4b6c8d7fc551eEric Christopher      // Look through bitcasts.
8190d58122e1221665d421a53741ef638505ecbe745Eric Christopher      return ARMComputeAddress(U->getOperand(0), Addr);
8205532433a574043b516aec26a4dd4b6c8d7fc551eEric Christopher    }
8215532433a574043b516aec26a4dd4b6c8d7fc551eEric Christopher    case Instruction::IntToPtr: {
8225532433a574043b516aec26a4dd4b6c8d7fc551eEric Christopher      // Look past no-op inttoptrs.
8235532433a574043b516aec26a4dd4b6c8d7fc551eEric Christopher      if (TLI.getValueType(U->getOperand(0)->getType()) == TLI.getPointerTy())
8240d58122e1221665d421a53741ef638505ecbe745Eric Christopher        return ARMComputeAddress(U->getOperand(0), Addr);
8255532433a574043b516aec26a4dd4b6c8d7fc551eEric Christopher      break;
8265532433a574043b516aec26a4dd4b6c8d7fc551eEric Christopher    }
8275532433a574043b516aec26a4dd4b6c8d7fc551eEric Christopher    case Instruction::PtrToInt: {
8285532433a574043b516aec26a4dd4b6c8d7fc551eEric Christopher      // Look past no-op ptrtoints.
8295532433a574043b516aec26a4dd4b6c8d7fc551eEric Christopher      if (TLI.getValueType(U->getType()) == TLI.getPointerTy())
8300d58122e1221665d421a53741ef638505ecbe745Eric Christopher        return ARMComputeAddress(U->getOperand(0), Addr);
8315532433a574043b516aec26a4dd4b6c8d7fc551eEric Christopher      break;
8325532433a574043b516aec26a4dd4b6c8d7fc551eEric Christopher    }
833eae8439771a9dafd09e32026ca42bb81cceb2af1Eric Christopher    case Instruction::GetElementPtr: {
834b37165808359c71b20291de51368f9efb65e7108Eric Christopher      Address SavedAddr = Addr;
8350d58122e1221665d421a53741ef638505ecbe745Eric Christopher      int TmpOffset = Addr.Offset;
8362896df897cc7d1bd3d211f6a8f47081a1a929bb2Eric Christopher
837eae8439771a9dafd09e32026ca42bb81cceb2af1Eric Christopher      // Iterate through the GEP folding the constants into offsets where
838eae8439771a9dafd09e32026ca42bb81cceb2af1Eric Christopher      // we can.
839eae8439771a9dafd09e32026ca42bb81cceb2af1Eric Christopher      gep_type_iterator GTI = gep_type_begin(U);
840eae8439771a9dafd09e32026ca42bb81cceb2af1Eric Christopher      for (User::const_op_iterator i = U->op_begin() + 1, e = U->op_end();
841eae8439771a9dafd09e32026ca42bb81cceb2af1Eric Christopher           i != e; ++i, ++GTI) {
842eae8439771a9dafd09e32026ca42bb81cceb2af1Eric Christopher        const Value *Op = *i;
843db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner        if (StructType *STy = dyn_cast<StructType>(*GTI)) {
844eae8439771a9dafd09e32026ca42bb81cceb2af1Eric Christopher          const StructLayout *SL = TD.getStructLayout(STy);
845eae8439771a9dafd09e32026ca42bb81cceb2af1Eric Christopher          unsigned Idx = cast<ConstantInt>(Op)->getZExtValue();
846eae8439771a9dafd09e32026ca42bb81cceb2af1Eric Christopher          TmpOffset += SL->getElementOffset(Idx);
847eae8439771a9dafd09e32026ca42bb81cceb2af1Eric Christopher        } else {
8482896df897cc7d1bd3d211f6a8f47081a1a929bb2Eric Christopher          uint64_t S = TD.getTypeAllocSize(GTI.getIndexedType());
8497244d7cbcea232049f2676e4d204dddf6520821fEric Christopher          for (;;) {
8502896df897cc7d1bd3d211f6a8f47081a1a929bb2Eric Christopher            if (const ConstantInt *CI = dyn_cast<ConstantInt>(Op)) {
8512896df897cc7d1bd3d211f6a8f47081a1a929bb2Eric Christopher              // Constant-offset addressing.
8522896df897cc7d1bd3d211f6a8f47081a1a929bb2Eric Christopher              TmpOffset += CI->getSExtValue() * S;
8537244d7cbcea232049f2676e4d204dddf6520821fEric Christopher              break;
8547244d7cbcea232049f2676e4d204dddf6520821fEric Christopher            }
8557244d7cbcea232049f2676e4d204dddf6520821fEric Christopher            if (isa<AddOperator>(Op) &&
8567244d7cbcea232049f2676e4d204dddf6520821fEric Christopher                (!isa<Instruction>(Op) ||
8577244d7cbcea232049f2676e4d204dddf6520821fEric Christopher                 FuncInfo.MBBMap[cast<Instruction>(Op)->getParent()]
8587244d7cbcea232049f2676e4d204dddf6520821fEric Christopher                 == FuncInfo.MBB) &&
8597244d7cbcea232049f2676e4d204dddf6520821fEric Christopher                isa<ConstantInt>(cast<AddOperator>(Op)->getOperand(1))) {
860299bbb23a421fce79c63e9f879ff3baef18c2f90Eric Christopher              // An add (in the same block) with a constant operand. Fold the
8617244d7cbcea232049f2676e4d204dddf6520821fEric Christopher              // constant.
8622896df897cc7d1bd3d211f6a8f47081a1a929bb2Eric Christopher              ConstantInt *CI =
8637244d7cbcea232049f2676e4d204dddf6520821fEric Christopher              cast<ConstantInt>(cast<AddOperator>(Op)->getOperand(1));
8642896df897cc7d1bd3d211f6a8f47081a1a929bb2Eric Christopher              TmpOffset += CI->getSExtValue() * S;
8657244d7cbcea232049f2676e4d204dddf6520821fEric Christopher              // Iterate on the other operand.
8667244d7cbcea232049f2676e4d204dddf6520821fEric Christopher              Op = cast<AddOperator>(Op)->getOperand(0);
8677244d7cbcea232049f2676e4d204dddf6520821fEric Christopher              continue;
868299bbb23a421fce79c63e9f879ff3baef18c2f90Eric Christopher            }
8697244d7cbcea232049f2676e4d204dddf6520821fEric Christopher            // Unsupported
8707244d7cbcea232049f2676e4d204dddf6520821fEric Christopher            goto unsupported_gep;
8717244d7cbcea232049f2676e4d204dddf6520821fEric Christopher          }
872eae8439771a9dafd09e32026ca42bb81cceb2af1Eric Christopher        }
873eae8439771a9dafd09e32026ca42bb81cceb2af1Eric Christopher      }
8742896df897cc7d1bd3d211f6a8f47081a1a929bb2Eric Christopher
8752896df897cc7d1bd3d211f6a8f47081a1a929bb2Eric Christopher      // Try to grab the base operand now.
8760d58122e1221665d421a53741ef638505ecbe745Eric Christopher      Addr.Offset = TmpOffset;
8770d58122e1221665d421a53741ef638505ecbe745Eric Christopher      if (ARMComputeAddress(U->getOperand(0), Addr)) return true;
8782896df897cc7d1bd3d211f6a8f47081a1a929bb2Eric Christopher
8792896df897cc7d1bd3d211f6a8f47081a1a929bb2Eric Christopher      // We failed, restore everything and try the other options.
880b37165808359c71b20291de51368f9efb65e7108Eric Christopher      Addr = SavedAddr;
8812896df897cc7d1bd3d211f6a8f47081a1a929bb2Eric Christopher
882eae8439771a9dafd09e32026ca42bb81cceb2af1Eric Christopher      unsupported_gep:
883eae8439771a9dafd09e32026ca42bb81cceb2af1Eric Christopher      break;
884eae8439771a9dafd09e32026ca42bb81cceb2af1Eric Christopher    }
8858300712c1e73dc106242f0007e0e0e4dd9ea38ceEric Christopher    case Instruction::Alloca: {
88615418779419923dc9222cd804d409c1878b5e3b1Eric Christopher      const AllocaInst *AI = cast<AllocaInst>(Obj);
887827656dab4931a512d6d994d9c61d280a2651dd4Eric Christopher      DenseMap<const AllocaInst*, int>::iterator SI =
888827656dab4931a512d6d994d9c61d280a2651dd4Eric Christopher        FuncInfo.StaticAllocaMap.find(AI);
889827656dab4931a512d6d994d9c61d280a2651dd4Eric Christopher      if (SI != FuncInfo.StaticAllocaMap.end()) {
890827656dab4931a512d6d994d9c61d280a2651dd4Eric Christopher        Addr.BaseType = Address::FrameIndexBase;
891827656dab4931a512d6d994d9c61d280a2651dd4Eric Christopher        Addr.Base.FI = SI->second;
892827656dab4931a512d6d994d9c61d280a2651dd4Eric Christopher        return true;
893827656dab4931a512d6d994d9c61d280a2651dd4Eric Christopher      }
894827656dab4931a512d6d994d9c61d280a2651dd4Eric Christopher      break;
8958300712c1e73dc106242f0007e0e0e4dd9ea38ceEric Christopher    }
8968300712c1e73dc106242f0007e0e0e4dd9ea38ceEric Christopher  }
897ac1a19e18ad73198ae54cc4bc08000523031f84aEric Christopher
898cb0b04ba6fc847574f592d1a80ff3b60c0d4228cEric Christopher  // Try to get this in a register if nothing else has worked.
8990d58122e1221665d421a53741ef638505ecbe745Eric Christopher  if (Addr.Base.Reg == 0) Addr.Base.Reg = getRegForValue(Obj);
9000d58122e1221665d421a53741ef638505ecbe745Eric Christopher  return Addr.Base.Reg != 0;
901eae8439771a9dafd09e32026ca42bb81cceb2af1Eric Christopher}
902eae8439771a9dafd09e32026ca42bb81cceb2af1Eric Christopher
9036290b936bf71fded40b8b765f8f7aef577fada24Chad Rosiervoid ARMFastISel::ARMSimplifyAddress(Address &Addr, MVT VT, bool useAM3) {
904212ae937bb9b52bb1f27f02cb0c28496c4d1e2b9Eric Christopher  bool needsLowering = false;
9056290b936bf71fded40b8b765f8f7aef577fada24Chad Rosier  switch (VT.SimpleTy) {
906bc2198133a1836598b54b943420748e75d5dea94Craig Topper    default: llvm_unreachable("Unhandled load/store type!");
907b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier    case MVT::i1:
908b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier    case MVT::i8:
9097346347674f03868e8c076c8c27a7f09f0a086c2Chad Rosier    case MVT::i16:
910b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier    case MVT::i32:
91157b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier      if (!useAM3) {
9127346347674f03868e8c076c8c27a7f09f0a086c2Chad Rosier        // Integer loads/stores handle 12-bit offsets.
9137346347674f03868e8c076c8c27a7f09f0a086c2Chad Rosier        needsLowering = ((Addr.Offset & 0xfff) != Addr.Offset);
91457b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier        // Handle negative offsets.
915e489af8dce12249be26ac0c8e371557378886bc2Chad Rosier        if (needsLowering && isThumb2)
916e489af8dce12249be26ac0c8e371557378886bc2Chad Rosier          needsLowering = !(Subtarget->hasV6T2Ops() && Addr.Offset < 0 &&
917e489af8dce12249be26ac0c8e371557378886bc2Chad Rosier                            Addr.Offset > -256);
91857b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier      } else {
9195be833de769608254fdfc56e8173000e874a8154Chad Rosier        // ARM halfword load/stores and signed byte loads use +/-imm8 offsets.
920dc9205d9c29171f1ddcf2de7eb172a583cadbe63Chad Rosier        needsLowering = (Addr.Offset > 255 || Addr.Offset < -255);
92157b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier      }
922212ae937bb9b52bb1f27f02cb0c28496c4d1e2b9Eric Christopher      break;
923212ae937bb9b52bb1f27f02cb0c28496c4d1e2b9Eric Christopher    case MVT::f32:
924212ae937bb9b52bb1f27f02cb0c28496c4d1e2b9Eric Christopher    case MVT::f64:
925212ae937bb9b52bb1f27f02cb0c28496c4d1e2b9Eric Christopher      // Floating point operands handle 8-bit offsets.
9260d58122e1221665d421a53741ef638505ecbe745Eric Christopher      needsLowering = ((Addr.Offset & 0xff) != Addr.Offset);
927212ae937bb9b52bb1f27f02cb0c28496c4d1e2b9Eric Christopher      break;
928212ae937bb9b52bb1f27f02cb0c28496c4d1e2b9Eric Christopher  }
9296b15639e267575a2c95f89d6b266e0fcd9231d91Jim Grosbach
930827656dab4931a512d6d994d9c61d280a2651dd4Eric Christopher  // If this is a stack pointer and the offset needs to be simplified then
931827656dab4931a512d6d994d9c61d280a2651dd4Eric Christopher  // put the alloca address into a register, set the base type back to
932827656dab4931a512d6d994d9c61d280a2651dd4Eric Christopher  // register and continue. This should almost never happen.
933827656dab4931a512d6d994d9c61d280a2651dd4Eric Christopher  if (needsLowering && Addr.BaseType == Address::FrameIndexBase) {
934420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper    const TargetRegisterClass *RC = isThumb2 ?
935420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper      (const TargetRegisterClass*)&ARM::tGPRRegClass :
936420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper      (const TargetRegisterClass*)&ARM::GPRRegClass;
937827656dab4931a512d6d994d9c61d280a2651dd4Eric Christopher    unsigned ResultReg = createResultReg(RC);
93866dc8ca04b719f3ab4aa650609dbd56b055ecb34Chad Rosier    unsigned Opc = isThumb2 ? ARM::t2ADDri : ARM::ADDri;
939ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
940827656dab4931a512d6d994d9c61d280a2651dd4Eric Christopher                            TII.get(Opc), ResultReg)
941827656dab4931a512d6d994d9c61d280a2651dd4Eric Christopher                            .addFrameIndex(Addr.Base.FI)
942827656dab4931a512d6d994d9c61d280a2651dd4Eric Christopher                            .addImm(0));
943827656dab4931a512d6d994d9c61d280a2651dd4Eric Christopher    Addr.Base.Reg = ResultReg;
944827656dab4931a512d6d994d9c61d280a2651dd4Eric Christopher    Addr.BaseType = Address::RegBase;
945827656dab4931a512d6d994d9c61d280a2651dd4Eric Christopher  }
946827656dab4931a512d6d994d9c61d280a2651dd4Eric Christopher
947212ae937bb9b52bb1f27f02cb0c28496c4d1e2b9Eric Christopher  // Since the offset is too large for the load/store instruction
948318b6eec8d72ad6dad887abde3fed484bd8d86efEric Christopher  // get the reg+offset into a register.
949212ae937bb9b52bb1f27f02cb0c28496c4d1e2b9Eric Christopher  if (needsLowering) {
9509ebf57ae132369248c885a90bc3dd5e3cf589247Eli Friedman    Addr.Base.Reg = FastEmit_ri_(MVT::i32, ISD::ADD, Addr.Base.Reg,
9519ebf57ae132369248c885a90bc3dd5e3cf589247Eli Friedman                                 /*Op0IsKill*/false, Addr.Offset, MVT::i32);
9520d58122e1221665d421a53741ef638505ecbe745Eric Christopher    Addr.Offset = 0;
953318b6eec8d72ad6dad887abde3fed484bd8d86efEric Christopher  }
9548300712c1e73dc106242f0007e0e0e4dd9ea38ceEric Christopher}
9558300712c1e73dc106242f0007e0e0e4dd9ea38ceEric Christopher
9566290b936bf71fded40b8b765f8f7aef577fada24Chad Rosiervoid ARMFastISel::AddLoadStoreOperands(MVT VT, Address &Addr,
957c152aa6c86f87be6f3ca9b6e2d57ee31b9258385Cameron Zwarich                                       const MachineInstrBuilder &MIB,
958b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier                                       unsigned Flags, bool useAM3) {
959564857f776084a85b6b4bf0c896fd60c69d0c521Eric Christopher  // addrmode5 output depends on the selection dag addressing dividing the
960564857f776084a85b6b4bf0c896fd60c69d0c521Eric Christopher  // offset by 4 that it then later multiplies. Do this here as well.
9616290b936bf71fded40b8b765f8f7aef577fada24Chad Rosier  if (VT.SimpleTy == MVT::f32 || VT.SimpleTy == MVT::f64)
962564857f776084a85b6b4bf0c896fd60c69d0c521Eric Christopher    Addr.Offset /= 4;
963299bbb23a421fce79c63e9f879ff3baef18c2f90Eric Christopher
964564857f776084a85b6b4bf0c896fd60c69d0c521Eric Christopher  // Frame base works a bit differently. Handle it separately.
965564857f776084a85b6b4bf0c896fd60c69d0c521Eric Christopher  if (Addr.BaseType == Address::FrameIndexBase) {
966564857f776084a85b6b4bf0c896fd60c69d0c521Eric Christopher    int FI = Addr.Base.FI;
967564857f776084a85b6b4bf0c896fd60c69d0c521Eric Christopher    int Offset = Addr.Offset;
968564857f776084a85b6b4bf0c896fd60c69d0c521Eric Christopher    MachineMemOperand *MMO =
969564857f776084a85b6b4bf0c896fd60c69d0c521Eric Christopher          FuncInfo.MF->getMachineMemOperand(
970564857f776084a85b6b4bf0c896fd60c69d0c521Eric Christopher                                  MachinePointerInfo::getFixedStack(FI, Offset),
971c152aa6c86f87be6f3ca9b6e2d57ee31b9258385Cameron Zwarich                                  Flags,
972564857f776084a85b6b4bf0c896fd60c69d0c521Eric Christopher                                  MFI.getObjectSize(FI),
973564857f776084a85b6b4bf0c896fd60c69d0c521Eric Christopher                                  MFI.getObjectAlignment(FI));
974564857f776084a85b6b4bf0c896fd60c69d0c521Eric Christopher    // Now add the rest of the operands.
975564857f776084a85b6b4bf0c896fd60c69d0c521Eric Christopher    MIB.addFrameIndex(FI);
976564857f776084a85b6b4bf0c896fd60c69d0c521Eric Christopher
9776ce2deacefa5fd2565983d513d07a06d6a8af602Bob Wilson    // ARM halfword load/stores and signed byte loads need an additional
9786ce2deacefa5fd2565983d513d07a06d6a8af602Bob Wilson    // operand.
979dc9205d9c29171f1ddcf2de7eb172a583cadbe63Chad Rosier    if (useAM3) {
980dc9205d9c29171f1ddcf2de7eb172a583cadbe63Chad Rosier      signed Imm = (Addr.Offset < 0) ? (0x100 | -Addr.Offset) : Addr.Offset;
981dc9205d9c29171f1ddcf2de7eb172a583cadbe63Chad Rosier      MIB.addReg(0);
982dc9205d9c29171f1ddcf2de7eb172a583cadbe63Chad Rosier      MIB.addImm(Imm);
983dc9205d9c29171f1ddcf2de7eb172a583cadbe63Chad Rosier    } else {
984dc9205d9c29171f1ddcf2de7eb172a583cadbe63Chad Rosier      MIB.addImm(Addr.Offset);
985dc9205d9c29171f1ddcf2de7eb172a583cadbe63Chad Rosier    }
986564857f776084a85b6b4bf0c896fd60c69d0c521Eric Christopher    MIB.addMemOperand(MMO);
987564857f776084a85b6b4bf0c896fd60c69d0c521Eric Christopher  } else {
988564857f776084a85b6b4bf0c896fd60c69d0c521Eric Christopher    // Now add the rest of the operands.
989564857f776084a85b6b4bf0c896fd60c69d0c521Eric Christopher    MIB.addReg(Addr.Base.Reg);
990299bbb23a421fce79c63e9f879ff3baef18c2f90Eric Christopher
9916ce2deacefa5fd2565983d513d07a06d6a8af602Bob Wilson    // ARM halfword load/stores and signed byte loads need an additional
9926ce2deacefa5fd2565983d513d07a06d6a8af602Bob Wilson    // operand.
993dc9205d9c29171f1ddcf2de7eb172a583cadbe63Chad Rosier    if (useAM3) {
994dc9205d9c29171f1ddcf2de7eb172a583cadbe63Chad Rosier      signed Imm = (Addr.Offset < 0) ? (0x100 | -Addr.Offset) : Addr.Offset;
995dc9205d9c29171f1ddcf2de7eb172a583cadbe63Chad Rosier      MIB.addReg(0);
996dc9205d9c29171f1ddcf2de7eb172a583cadbe63Chad Rosier      MIB.addImm(Imm);
997dc9205d9c29171f1ddcf2de7eb172a583cadbe63Chad Rosier    } else {
998dc9205d9c29171f1ddcf2de7eb172a583cadbe63Chad Rosier      MIB.addImm(Addr.Offset);
999dc9205d9c29171f1ddcf2de7eb172a583cadbe63Chad Rosier    }
1000564857f776084a85b6b4bf0c896fd60c69d0c521Eric Christopher  }
1001564857f776084a85b6b4bf0c896fd60c69d0c521Eric Christopher  AddOptionalDefs(MIB);
1002564857f776084a85b6b4bf0c896fd60c69d0c521Eric Christopher}
1003564857f776084a85b6b4bf0c896fd60c69d0c521Eric Christopher
1004a61b17c18a67f1b3faef2f2108379c4337ce9bb7Patrik Hagglundbool ARMFastISel::ARMEmitLoad(MVT VT, unsigned &ResultReg, Address &Addr,
10058a9bce978fa4ca60d3a0ba42a1d44c41463a3c33Chad Rosier                              unsigned Alignment, bool isZExt, bool allocReg) {
1006dc90804a402b9d617c154625e04a74ebd7fe3599Eric Christopher  unsigned Opc;
1007b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier  bool useAM3 = false;
10088a9bce978fa4ca60d3a0ba42a1d44c41463a3c33Chad Rosier  bool needVMOV = false;
100944d23825d61d530b8d562329ec8fc2d4f843bb8dCraig Topper  const TargetRegisterClass *RC;
1010a61b17c18a67f1b3faef2f2108379c4337ce9bb7Patrik Hagglund  switch (VT.SimpleTy) {
1011564857f776084a85b6b4bf0c896fd60c69d0c521Eric Christopher    // This is mostly going to be Neon/vector support.
1012564857f776084a85b6b4bf0c896fd60c69d0c521Eric Christopher    default: return false;
1013646abbfa30f881b5183b62e77a185fc48d9d82bdChad Rosier    case MVT::i1:
10144e68c7cca44d33771d376f1668d687ce9d8f11d3Eric Christopher    case MVT::i8:
101557b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier      if (isThumb2) {
101657b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier        if (Addr.Offset < 0 && Addr.Offset > -256 && Subtarget->hasV6T2Ops())
101757b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier          Opc = isZExt ? ARM::t2LDRBi8 : ARM::t2LDRSBi8;
101857b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier        else
101957b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier          Opc = isZExt ? ARM::t2LDRBi12 : ARM::t2LDRSBi12;
1020b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier      } else {
102157b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier        if (isZExt) {
102257b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier          Opc = ARM::LDRBi12;
102357b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier        } else {
102457b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier          Opc = ARM::LDRSB;
102557b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier          useAM3 = true;
102657b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier        }
1027b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier      }
1028420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper      RC = &ARM::GPRRegClass;
10294e68c7cca44d33771d376f1668d687ce9d8f11d3Eric Christopher      break;
10307346347674f03868e8c076c8c27a7f09f0a086c2Chad Rosier    case MVT::i16:
1031b3235b128f383559a7a9b9119896e406b347879cChad Rosier      if (Alignment && Alignment < 2 && !Subtarget->allowsUnalignedMem())
1032d70c98e884d19c4d94b5e83efd32888b8ee47869Chad Rosier        return false;
1033d70c98e884d19c4d94b5e83efd32888b8ee47869Chad Rosier
103457b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier      if (isThumb2) {
103557b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier        if (Addr.Offset < 0 && Addr.Offset > -256 && Subtarget->hasV6T2Ops())
103657b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier          Opc = isZExt ? ARM::t2LDRHi8 : ARM::t2LDRSHi8;
103757b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier        else
103857b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier          Opc = isZExt ? ARM::t2LDRHi12 : ARM::t2LDRSHi12;
103957b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier      } else {
104057b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier        Opc = isZExt ? ARM::LDRH : ARM::LDRSH;
104157b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier        useAM3 = true;
104257b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier      }
1043420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper      RC = &ARM::GPRRegClass;
10447346347674f03868e8c076c8c27a7f09f0a086c2Chad Rosier      break;
1045dc90804a402b9d617c154625e04a74ebd7fe3599Eric Christopher    case MVT::i32:
1046b3235b128f383559a7a9b9119896e406b347879cChad Rosier      if (Alignment && Alignment < 4 && !Subtarget->allowsUnalignedMem())
1047e5e674ba1191d9e9c528eb363babdcbea1359e10Chad Rosier        return false;
1048e5e674ba1191d9e9c528eb363babdcbea1359e10Chad Rosier
104957b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier      if (isThumb2) {
105057b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier        if (Addr.Offset < 0 && Addr.Offset > -256 && Subtarget->hasV6T2Ops())
105157b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier          Opc = ARM::t2LDRi8;
105257b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier        else
105357b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier          Opc = ARM::t2LDRi12;
105457b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier      } else {
105557b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier        Opc = ARM::LDRi12;
105657b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier      }
1057420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper      RC = &ARM::GPRRegClass;
1058dc90804a402b9d617c154625e04a74ebd7fe3599Eric Christopher      break;
10596dab137b889d1fafdeee9c70c2b59d549d59163aEric Christopher    case MVT::f32:
10606762f8f302f5c01a26e848cdcac20bddde0dd22cChad Rosier      if (!Subtarget->hasVFP2()) return false;
10618a9bce978fa4ca60d3a0ba42a1d44c41463a3c33Chad Rosier      // Unaligned loads need special handling. Floats require word-alignment.
10628a9bce978fa4ca60d3a0ba42a1d44c41463a3c33Chad Rosier      if (Alignment && Alignment < 4) {
10638a9bce978fa4ca60d3a0ba42a1d44c41463a3c33Chad Rosier        needVMOV = true;
10648a9bce978fa4ca60d3a0ba42a1d44c41463a3c33Chad Rosier        VT = MVT::i32;
10658a9bce978fa4ca60d3a0ba42a1d44c41463a3c33Chad Rosier        Opc = isThumb2 ? ARM::t2LDRi12 : ARM::LDRi12;
1066420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper        RC = &ARM::GPRRegClass;
10678a9bce978fa4ca60d3a0ba42a1d44c41463a3c33Chad Rosier      } else {
10688a9bce978fa4ca60d3a0ba42a1d44c41463a3c33Chad Rosier        Opc = ARM::VLDRS;
10698a9bce978fa4ca60d3a0ba42a1d44c41463a3c33Chad Rosier        RC = TLI.getRegClassFor(VT);
10708a9bce978fa4ca60d3a0ba42a1d44c41463a3c33Chad Rosier      }
10716dab137b889d1fafdeee9c70c2b59d549d59163aEric Christopher      break;
10726dab137b889d1fafdeee9c70c2b59d549d59163aEric Christopher    case MVT::f64:
10736762f8f302f5c01a26e848cdcac20bddde0dd22cChad Rosier      if (!Subtarget->hasVFP2()) return false;
1074404ed3c2239ff394270053bdcb76a5a4908af7ceChad Rosier      // FIXME: Unaligned loads need special handling.  Doublewords require
1075404ed3c2239ff394270053bdcb76a5a4908af7ceChad Rosier      // word-alignment.
1076404ed3c2239ff394270053bdcb76a5a4908af7ceChad Rosier      if (Alignment && Alignment < 4)
10778a9bce978fa4ca60d3a0ba42a1d44c41463a3c33Chad Rosier        return false;
1078404ed3c2239ff394270053bdcb76a5a4908af7ceChad Rosier
10796dab137b889d1fafdeee9c70c2b59d549d59163aEric Christopher      Opc = ARM::VLDRD;
1080ee56ea62431081a2333eb47df3fa4dfcd425cb54Eric Christopher      RC = TLI.getRegClassFor(VT);
10816dab137b889d1fafdeee9c70c2b59d549d59163aEric Christopher      break;
1082b1cc848d1a9a831e8058fad546e41b21d955fd88Eric Christopher  }
1083564857f776084a85b6b4bf0c896fd60c69d0c521Eric Christopher  // Simplify this down to something we can handle.
1084b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier  ARMSimplifyAddress(Addr, VT, useAM3);
10856b15639e267575a2c95f89d6b266e0fcd9231d91Jim Grosbach
1086564857f776084a85b6b4bf0c896fd60c69d0c521Eric Christopher  // Create the base instruction, then add the operands.
1087b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier  if (allocReg)
1088b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier    ResultReg = createResultReg(RC);
1089b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier  assert (ResultReg > 255 && "Expected an allocated virtual register.");
1090564857f776084a85b6b4bf0c896fd60c69d0c521Eric Christopher  MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
1091564857f776084a85b6b4bf0c896fd60c69d0c521Eric Christopher                                    TII.get(Opc), ResultReg);
1092b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier  AddLoadStoreOperands(VT, Addr, MIB, MachineMemOperand::MOLoad, useAM3);
10938a9bce978fa4ca60d3a0ba42a1d44c41463a3c33Chad Rosier
10948a9bce978fa4ca60d3a0ba42a1d44c41463a3c33Chad Rosier  // If we had an unaligned load of a float we've converted it to an regular
10958a9bce978fa4ca60d3a0ba42a1d44c41463a3c33Chad Rosier  // load.  Now we must move from the GRP to the FP register.
10968a9bce978fa4ca60d3a0ba42a1d44c41463a3c33Chad Rosier  if (needVMOV) {
10978a9bce978fa4ca60d3a0ba42a1d44c41463a3c33Chad Rosier    unsigned MoveReg = createResultReg(TLI.getRegClassFor(MVT::f32));
10988a9bce978fa4ca60d3a0ba42a1d44c41463a3c33Chad Rosier    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
10998a9bce978fa4ca60d3a0ba42a1d44c41463a3c33Chad Rosier                            TII.get(ARM::VMOVSR), MoveReg)
11008a9bce978fa4ca60d3a0ba42a1d44c41463a3c33Chad Rosier                    .addReg(ResultReg));
11018a9bce978fa4ca60d3a0ba42a1d44c41463a3c33Chad Rosier    ResultReg = MoveReg;
11028a9bce978fa4ca60d3a0ba42a1d44c41463a3c33Chad Rosier  }
1103dc90804a402b9d617c154625e04a74ebd7fe3599Eric Christopher  return true;
1104b1cc848d1a9a831e8058fad546e41b21d955fd88Eric Christopher}
1105b1cc848d1a9a831e8058fad546e41b21d955fd88Eric Christopher
110643b62beb4cac4337a080c2d3fb8f218a7ffb59c3Eric Christopherbool ARMFastISel::SelectLoad(const Instruction *I) {
11074136d23c4805c5403a3521bf03fbfeee75b9216bEli Friedman  // Atomic loads need special handling.
11084136d23c4805c5403a3521bf03fbfeee75b9216bEli Friedman  if (cast<LoadInst>(I)->isAtomic())
11094136d23c4805c5403a3521bf03fbfeee75b9216bEli Friedman    return false;
11104136d23c4805c5403a3521bf03fbfeee75b9216bEli Friedman
1111db12b2ba9c602fc9bedcf0a9b2e72e23e29005d8Eric Christopher  // Verify we have a legal type before going any further.
11121440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands  MVT VT;
1113db12b2ba9c602fc9bedcf0a9b2e72e23e29005d8Eric Christopher  if (!isLoadTypeLegal(I->getType(), VT))
1114db12b2ba9c602fc9bedcf0a9b2e72e23e29005d8Eric Christopher    return false;
1115db12b2ba9c602fc9bedcf0a9b2e72e23e29005d8Eric Christopher
1116564857f776084a85b6b4bf0c896fd60c69d0c521Eric Christopher  // See if we can handle this address.
11170d58122e1221665d421a53741ef638505ecbe745Eric Christopher  Address Addr;
1118564857f776084a85b6b4bf0c896fd60c69d0c521Eric Christopher  if (!ARMComputeAddress(I->getOperand(0), Addr)) return false;
1119db12b2ba9c602fc9bedcf0a9b2e72e23e29005d8Eric Christopher
1120db12b2ba9c602fc9bedcf0a9b2e72e23e29005d8Eric Christopher  unsigned ResultReg;
11218a9bce978fa4ca60d3a0ba42a1d44c41463a3c33Chad Rosier  if (!ARMEmitLoad(VT, ResultReg, Addr, cast<LoadInst>(I)->getAlignment()))
11228a9bce978fa4ca60d3a0ba42a1d44c41463a3c33Chad Rosier    return false;
1123db12b2ba9c602fc9bedcf0a9b2e72e23e29005d8Eric Christopher  UpdateValueMap(I, ResultReg);
1124db12b2ba9c602fc9bedcf0a9b2e72e23e29005d8Eric Christopher  return true;
1125db12b2ba9c602fc9bedcf0a9b2e72e23e29005d8Eric Christopher}
1126db12b2ba9c602fc9bedcf0a9b2e72e23e29005d8Eric Christopher
1127a61b17c18a67f1b3faef2f2108379c4337ce9bb7Patrik Hagglundbool ARMFastISel::ARMEmitStore(MVT VT, unsigned SrcReg, Address &Addr,
11286ce2deacefa5fd2565983d513d07a06d6a8af602Bob Wilson                               unsigned Alignment) {
1129318b6eec8d72ad6dad887abde3fed484bd8d86efEric Christopher  unsigned StrOpc;
1130b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier  bool useAM3 = false;
1131a61b17c18a67f1b3faef2f2108379c4337ce9bb7Patrik Hagglund  switch (VT.SimpleTy) {
1132564857f776084a85b6b4bf0c896fd60c69d0c521Eric Christopher    // This is mostly going to be Neon/vector support.
1133318b6eec8d72ad6dad887abde3fed484bd8d86efEric Christopher    default: return false;
11344c914125c4d1746dd2436cb5b1620efd6182f1dbEric Christopher    case MVT::i1: {
1135420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper      unsigned Res = createResultReg(isThumb2 ?
1136420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper        (const TargetRegisterClass*)&ARM::tGPRRegClass :
1137420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper        (const TargetRegisterClass*)&ARM::GPRRegClass);
113866dc8ca04b719f3ab4aa650609dbd56b055ecb34Chad Rosier      unsigned Opc = isThumb2 ? ARM::t2ANDri : ARM::ANDri;
11394c914125c4d1746dd2436cb5b1620efd6182f1dbEric Christopher      AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
11404c914125c4d1746dd2436cb5b1620efd6182f1dbEric Christopher                              TII.get(Opc), Res)
11414c914125c4d1746dd2436cb5b1620efd6182f1dbEric Christopher                      .addReg(SrcReg).addImm(1));
11424c914125c4d1746dd2436cb5b1620efd6182f1dbEric Christopher      SrcReg = Res;
11434c914125c4d1746dd2436cb5b1620efd6182f1dbEric Christopher    } // Fallthrough here.
11442896df897cc7d1bd3d211f6a8f47081a1a929bb2Eric Christopher    case MVT::i8:
114557b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier      if (isThumb2) {
114657b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier        if (Addr.Offset < 0 && Addr.Offset > -256 && Subtarget->hasV6T2Ops())
114757b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier          StrOpc = ARM::t2STRBi8;
114857b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier        else
114957b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier          StrOpc = ARM::t2STRBi12;
115057b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier      } else {
115157b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier        StrOpc = ARM::STRBi12;
115257b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier      }
115315418779419923dc9222cd804d409c1878b5e3b1Eric Christopher      break;
115415418779419923dc9222cd804d409c1878b5e3b1Eric Christopher    case MVT::i16:
1155b3235b128f383559a7a9b9119896e406b347879cChad Rosier      if (Alignment && Alignment < 2 && !Subtarget->allowsUnalignedMem())
1156d70c98e884d19c4d94b5e83efd32888b8ee47869Chad Rosier        return false;
1157d70c98e884d19c4d94b5e83efd32888b8ee47869Chad Rosier
115857b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier      if (isThumb2) {
115957b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier        if (Addr.Offset < 0 && Addr.Offset > -256 && Subtarget->hasV6T2Ops())
116057b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier          StrOpc = ARM::t2STRHi8;
116157b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier        else
116257b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier          StrOpc = ARM::t2STRHi12;
116357b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier      } else {
116457b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier        StrOpc = ARM::STRH;
116557b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier        useAM3 = true;
116657b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier      }
116715418779419923dc9222cd804d409c1878b5e3b1Eric Christopher      break;
116847650ece374315ce4ff5e483f6165ae37752f230Eric Christopher    case MVT::i32:
1169b3235b128f383559a7a9b9119896e406b347879cChad Rosier      if (Alignment && Alignment < 4 && !Subtarget->allowsUnalignedMem())
1170e5e674ba1191d9e9c528eb363babdcbea1359e10Chad Rosier        return false;
1171e5e674ba1191d9e9c528eb363babdcbea1359e10Chad Rosier
117257b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier      if (isThumb2) {
117357b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier        if (Addr.Offset < 0 && Addr.Offset > -256 && Subtarget->hasV6T2Ops())
117457b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier          StrOpc = ARM::t2STRi8;
117557b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier        else
117657b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier          StrOpc = ARM::t2STRi12;
117757b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier      } else {
117857b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier        StrOpc = ARM::STRi12;
117957b299796685033c87a5414e179b95b5ae7dc8d4Chad Rosier      }
118047650ece374315ce4ff5e483f6165ae37752f230Eric Christopher      break;
118156d2b72884f98001cefdf8de61d6d7fc00d3df90Eric Christopher    case MVT::f32:
118256d2b72884f98001cefdf8de61d6d7fc00d3df90Eric Christopher      if (!Subtarget->hasVFP2()) return false;
1183ed42c5f778dd0128429e4feffe2c028b2352b534Chad Rosier      // Unaligned stores need special handling. Floats require word-alignment.
11849eff1e33f616ad2d0134740ac4595ed2e79e3d74Chad Rosier      if (Alignment && Alignment < 4) {
11859eff1e33f616ad2d0134740ac4595ed2e79e3d74Chad Rosier        unsigned MoveReg = createResultReg(TLI.getRegClassFor(MVT::i32));
11869eff1e33f616ad2d0134740ac4595ed2e79e3d74Chad Rosier        AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
11879eff1e33f616ad2d0134740ac4595ed2e79e3d74Chad Rosier                                TII.get(ARM::VMOVRS), MoveReg)
11889eff1e33f616ad2d0134740ac4595ed2e79e3d74Chad Rosier                        .addReg(SrcReg));
11899eff1e33f616ad2d0134740ac4595ed2e79e3d74Chad Rosier        SrcReg = MoveReg;
11909eff1e33f616ad2d0134740ac4595ed2e79e3d74Chad Rosier        VT = MVT::i32;
11919eff1e33f616ad2d0134740ac4595ed2e79e3d74Chad Rosier        StrOpc = isThumb2 ? ARM::t2STRi12 : ARM::STRi12;
119264ac91b4b6e62f82d608fe9602b28c00171f88a0Chad Rosier      } else {
119364ac91b4b6e62f82d608fe9602b28c00171f88a0Chad Rosier        StrOpc = ARM::VSTRS;
11949eff1e33f616ad2d0134740ac4595ed2e79e3d74Chad Rosier      }
119556d2b72884f98001cefdf8de61d6d7fc00d3df90Eric Christopher      break;
119656d2b72884f98001cefdf8de61d6d7fc00d3df90Eric Christopher    case MVT::f64:
119756d2b72884f98001cefdf8de61d6d7fc00d3df90Eric Christopher      if (!Subtarget->hasVFP2()) return false;
1198ed42c5f778dd0128429e4feffe2c028b2352b534Chad Rosier      // FIXME: Unaligned stores need special handling.  Doublewords require
1199ed42c5f778dd0128429e4feffe2c028b2352b534Chad Rosier      // word-alignment.
1200404ed3c2239ff394270053bdcb76a5a4908af7ceChad Rosier      if (Alignment && Alignment < 4)
12019eff1e33f616ad2d0134740ac4595ed2e79e3d74Chad Rosier          return false;
1202404ed3c2239ff394270053bdcb76a5a4908af7ceChad Rosier
120356d2b72884f98001cefdf8de61d6d7fc00d3df90Eric Christopher      StrOpc = ARM::VSTRD;
120456d2b72884f98001cefdf8de61d6d7fc00d3df90Eric Christopher      break;
1205318b6eec8d72ad6dad887abde3fed484bd8d86efEric Christopher  }
1206564857f776084a85b6b4bf0c896fd60c69d0c521Eric Christopher  // Simplify this down to something we can handle.
1207b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier  ARMSimplifyAddress(Addr, VT, useAM3);
12086b15639e267575a2c95f89d6b266e0fcd9231d91Jim Grosbach
1209564857f776084a85b6b4bf0c896fd60c69d0c521Eric Christopher  // Create the base instruction, then add the operands.
1210564857f776084a85b6b4bf0c896fd60c69d0c521Eric Christopher  MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
1211564857f776084a85b6b4bf0c896fd60c69d0c521Eric Christopher                                    TII.get(StrOpc))
12123bdb3c9b511b89d38696587d61b82949e06a7729Chad Rosier                            .addReg(SrcReg);
1213b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier  AddLoadStoreOperands(VT, Addr, MIB, MachineMemOperand::MOStore, useAM3);
1214318b6eec8d72ad6dad887abde3fed484bd8d86efEric Christopher  return true;
1215318b6eec8d72ad6dad887abde3fed484bd8d86efEric Christopher}
1216318b6eec8d72ad6dad887abde3fed484bd8d86efEric Christopher
121743b62beb4cac4337a080c2d3fb8f218a7ffb59c3Eric Christopherbool ARMFastISel::SelectStore(const Instruction *I) {
1218318b6eec8d72ad6dad887abde3fed484bd8d86efEric Christopher  Value *Op0 = I->getOperand(0);
1219318b6eec8d72ad6dad887abde3fed484bd8d86efEric Christopher  unsigned SrcReg = 0;
1220318b6eec8d72ad6dad887abde3fed484bd8d86efEric Christopher
12214136d23c4805c5403a3521bf03fbfeee75b9216bEli Friedman  // Atomic stores need special handling.
12224136d23c4805c5403a3521bf03fbfeee75b9216bEli Friedman  if (cast<StoreInst>(I)->isAtomic())
12234136d23c4805c5403a3521bf03fbfeee75b9216bEli Friedman    return false;
12244136d23c4805c5403a3521bf03fbfeee75b9216bEli Friedman
1225564857f776084a85b6b4bf0c896fd60c69d0c521Eric Christopher  // Verify we have a legal type before going any further.
12261440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands  MVT VT;
1227318b6eec8d72ad6dad887abde3fed484bd8d86efEric Christopher  if (!isLoadTypeLegal(I->getOperand(0)->getType(), VT))
1228318b6eec8d72ad6dad887abde3fed484bd8d86efEric Christopher    return false;
1229318b6eec8d72ad6dad887abde3fed484bd8d86efEric Christopher
12301b61ef4b22c8ae0ef82685637142246a245f9ecbEric Christopher  // Get the value to be stored into a register.
12311b61ef4b22c8ae0ef82685637142246a245f9ecbEric Christopher  SrcReg = getRegForValue(Op0);
1232564857f776084a85b6b4bf0c896fd60c69d0c521Eric Christopher  if (SrcReg == 0) return false;
1233ac1a19e18ad73198ae54cc4bc08000523031f84aEric Christopher
1234564857f776084a85b6b4bf0c896fd60c69d0c521Eric Christopher  // See if we can handle this address.
12350d58122e1221665d421a53741ef638505ecbe745Eric Christopher  Address Addr;
12360d58122e1221665d421a53741ef638505ecbe745Eric Christopher  if (!ARMComputeAddress(I->getOperand(1), Addr))
1237543cf05b9cb98f50a22cf05137d97bb3bb61f94aEric Christopher    return false;
1238ac1a19e18ad73198ae54cc4bc08000523031f84aEric Christopher
12399eff1e33f616ad2d0134740ac4595ed2e79e3d74Chad Rosier  if (!ARMEmitStore(VT, SrcReg, Addr, cast<StoreInst>(I)->getAlignment()))
12409eff1e33f616ad2d0134740ac4595ed2e79e3d74Chad Rosier    return false;
1241a5b1e6810769bef9a1fd98c69877bdfd75d7b106Eric Christopher  return true;
1242a5b1e6810769bef9a1fd98c69877bdfd75d7b106Eric Christopher}
1243a5b1e6810769bef9a1fd98c69877bdfd75d7b106Eric Christopher
1244a5b1e6810769bef9a1fd98c69877bdfd75d7b106Eric Christopherstatic ARMCC::CondCodes getComparePred(CmpInst::Predicate Pred) {
1245a5b1e6810769bef9a1fd98c69877bdfd75d7b106Eric Christopher  switch (Pred) {
1246a5b1e6810769bef9a1fd98c69877bdfd75d7b106Eric Christopher    // Needs two compares...
1247a5b1e6810769bef9a1fd98c69877bdfd75d7b106Eric Christopher    case CmpInst::FCMP_ONE:
1248dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher    case CmpInst::FCMP_UEQ:
1249a5b1e6810769bef9a1fd98c69877bdfd75d7b106Eric Christopher    default:
12504053e63a4b2f54446e29ef5bdad64e43b3bf52d6Eric Christopher      // AL is our "false" for now. The other two need more compares.
1251a5b1e6810769bef9a1fd98c69877bdfd75d7b106Eric Christopher      return ARMCC::AL;
1252a5b1e6810769bef9a1fd98c69877bdfd75d7b106Eric Christopher    case CmpInst::ICMP_EQ:
1253a5b1e6810769bef9a1fd98c69877bdfd75d7b106Eric Christopher    case CmpInst::FCMP_OEQ:
1254a5b1e6810769bef9a1fd98c69877bdfd75d7b106Eric Christopher      return ARMCC::EQ;
1255a5b1e6810769bef9a1fd98c69877bdfd75d7b106Eric Christopher    case CmpInst::ICMP_SGT:
1256a5b1e6810769bef9a1fd98c69877bdfd75d7b106Eric Christopher    case CmpInst::FCMP_OGT:
1257a5b1e6810769bef9a1fd98c69877bdfd75d7b106Eric Christopher      return ARMCC::GT;
1258a5b1e6810769bef9a1fd98c69877bdfd75d7b106Eric Christopher    case CmpInst::ICMP_SGE:
1259a5b1e6810769bef9a1fd98c69877bdfd75d7b106Eric Christopher    case CmpInst::FCMP_OGE:
1260a5b1e6810769bef9a1fd98c69877bdfd75d7b106Eric Christopher      return ARMCC::GE;
1261a5b1e6810769bef9a1fd98c69877bdfd75d7b106Eric Christopher    case CmpInst::ICMP_UGT:
1262a5b1e6810769bef9a1fd98c69877bdfd75d7b106Eric Christopher    case CmpInst::FCMP_UGT:
1263a5b1e6810769bef9a1fd98c69877bdfd75d7b106Eric Christopher      return ARMCC::HI;
1264a5b1e6810769bef9a1fd98c69877bdfd75d7b106Eric Christopher    case CmpInst::FCMP_OLT:
1265a5b1e6810769bef9a1fd98c69877bdfd75d7b106Eric Christopher      return ARMCC::MI;
1266a5b1e6810769bef9a1fd98c69877bdfd75d7b106Eric Christopher    case CmpInst::ICMP_ULE:
1267a5b1e6810769bef9a1fd98c69877bdfd75d7b106Eric Christopher    case CmpInst::FCMP_OLE:
1268a5b1e6810769bef9a1fd98c69877bdfd75d7b106Eric Christopher      return ARMCC::LS;
1269a5b1e6810769bef9a1fd98c69877bdfd75d7b106Eric Christopher    case CmpInst::FCMP_ORD:
1270a5b1e6810769bef9a1fd98c69877bdfd75d7b106Eric Christopher      return ARMCC::VC;
1271a5b1e6810769bef9a1fd98c69877bdfd75d7b106Eric Christopher    case CmpInst::FCMP_UNO:
1272a5b1e6810769bef9a1fd98c69877bdfd75d7b106Eric Christopher      return ARMCC::VS;
1273a5b1e6810769bef9a1fd98c69877bdfd75d7b106Eric Christopher    case CmpInst::FCMP_UGE:
1274a5b1e6810769bef9a1fd98c69877bdfd75d7b106Eric Christopher      return ARMCC::PL;
1275a5b1e6810769bef9a1fd98c69877bdfd75d7b106Eric Christopher    case CmpInst::ICMP_SLT:
1276a5b1e6810769bef9a1fd98c69877bdfd75d7b106Eric Christopher    case CmpInst::FCMP_ULT:
1277dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher      return ARMCC::LT;
1278a5b1e6810769bef9a1fd98c69877bdfd75d7b106Eric Christopher    case CmpInst::ICMP_SLE:
1279a5b1e6810769bef9a1fd98c69877bdfd75d7b106Eric Christopher    case CmpInst::FCMP_ULE:
1280a5b1e6810769bef9a1fd98c69877bdfd75d7b106Eric Christopher      return ARMCC::LE;
1281a5b1e6810769bef9a1fd98c69877bdfd75d7b106Eric Christopher    case CmpInst::FCMP_UNE:
1282a5b1e6810769bef9a1fd98c69877bdfd75d7b106Eric Christopher    case CmpInst::ICMP_NE:
1283a5b1e6810769bef9a1fd98c69877bdfd75d7b106Eric Christopher      return ARMCC::NE;
1284a5b1e6810769bef9a1fd98c69877bdfd75d7b106Eric Christopher    case CmpInst::ICMP_UGE:
1285a5b1e6810769bef9a1fd98c69877bdfd75d7b106Eric Christopher      return ARMCC::HS;
1286a5b1e6810769bef9a1fd98c69877bdfd75d7b106Eric Christopher    case CmpInst::ICMP_ULT:
1287a5b1e6810769bef9a1fd98c69877bdfd75d7b106Eric Christopher      return ARMCC::LO;
1288a5b1e6810769bef9a1fd98c69877bdfd75d7b106Eric Christopher  }
1289543cf05b9cb98f50a22cf05137d97bb3bb61f94aEric Christopher}
1290543cf05b9cb98f50a22cf05137d97bb3bb61f94aEric Christopher
129143b62beb4cac4337a080c2d3fb8f218a7ffb59c3Eric Christopherbool ARMFastISel::SelectBranch(const Instruction *I) {
1292e5734105daf799dea671666059f7ecab6abb389fEric Christopher  const BranchInst *BI = cast<BranchInst>(I);
1293e5734105daf799dea671666059f7ecab6abb389fEric Christopher  MachineBasicBlock *TBB = FuncInfo.MBBMap[BI->getSuccessor(0)];
1294e5734105daf799dea671666059f7ecab6abb389fEric Christopher  MachineBasicBlock *FBB = FuncInfo.MBBMap[BI->getSuccessor(1)];
1295ac1a19e18ad73198ae54cc4bc08000523031f84aEric Christopher
1296e5734105daf799dea671666059f7ecab6abb389fEric Christopher  // Simple branch support.
129716cb3763c5a1dad7d6bcbf0fffdfc58c84b46f89Jim Grosbach
12980e6233bfd75a12b9e56507086a37816240ca877aEric Christopher  // If we can, avoid recomputing the compare - redoing it could lead to wonky
12990e6233bfd75a12b9e56507086a37816240ca877aEric Christopher  // behavior.
13000e6233bfd75a12b9e56507086a37816240ca877aEric Christopher  if (const CmpInst *CI = dyn_cast<CmpInst>(BI->getCondition())) {
130175698f346fc44bdd8803b5dda4071d4b5872d82bChad Rosier    if (CI->hasOneUse() && (CI->getParent() == I->getParent())) {
13020e6233bfd75a12b9e56507086a37816240ca877aEric Christopher
13030e6233bfd75a12b9e56507086a37816240ca877aEric Christopher      // Get the compare predicate.
1304632ae892e6517e27791ac9e51188ca697ccc6515Eric Christopher      // Try to take advantage of fallthrough opportunities.
1305632ae892e6517e27791ac9e51188ca697ccc6515Eric Christopher      CmpInst::Predicate Predicate = CI->getPredicate();
1306632ae892e6517e27791ac9e51188ca697ccc6515Eric Christopher      if (FuncInfo.MBB->isLayoutSuccessor(TBB)) {
1307632ae892e6517e27791ac9e51188ca697ccc6515Eric Christopher        std::swap(TBB, FBB);
1308632ae892e6517e27791ac9e51188ca697ccc6515Eric Christopher        Predicate = CmpInst::getInversePredicate(Predicate);
1309632ae892e6517e27791ac9e51188ca697ccc6515Eric Christopher      }
1310632ae892e6517e27791ac9e51188ca697ccc6515Eric Christopher
1311632ae892e6517e27791ac9e51188ca697ccc6515Eric Christopher      ARMCC::CondCodes ARMPred = getComparePred(Predicate);
13120e6233bfd75a12b9e56507086a37816240ca877aEric Christopher
13130e6233bfd75a12b9e56507086a37816240ca877aEric Christopher      // We may not handle every CC for now.
13140e6233bfd75a12b9e56507086a37816240ca877aEric Christopher      if (ARMPred == ARMCC::AL) return false;
13150e6233bfd75a12b9e56507086a37816240ca877aEric Christopher
131675698f346fc44bdd8803b5dda4071d4b5872d82bChad Rosier      // Emit the compare.
1317e07cd5e40ac06fabfb9d33ea7c79542f138f45ceChad Rosier      if (!ARMEmitCmp(CI->getOperand(0), CI->getOperand(1), CI->isUnsigned()))
131875698f346fc44bdd8803b5dda4071d4b5872d82bChad Rosier        return false;
131916cb3763c5a1dad7d6bcbf0fffdfc58c84b46f89Jim Grosbach
132066dc8ca04b719f3ab4aa650609dbd56b055ecb34Chad Rosier      unsigned BrOpc = isThumb2 ? ARM::t2Bcc : ARM::Bcc;
13210e6233bfd75a12b9e56507086a37816240ca877aEric Christopher      BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(BrOpc))
13220e6233bfd75a12b9e56507086a37816240ca877aEric Christopher      .addMBB(TBB).addImm(ARMPred).addReg(ARM::CPSR);
13230e6233bfd75a12b9e56507086a37816240ca877aEric Christopher      FastEmitBranch(FBB, DL);
13240e6233bfd75a12b9e56507086a37816240ca877aEric Christopher      FuncInfo.MBB->addSuccessor(TBB);
13250e6233bfd75a12b9e56507086a37816240ca877aEric Christopher      return true;
13260e6233bfd75a12b9e56507086a37816240ca877aEric Christopher    }
1327bcf26aee86b1ab15b3e1442483eaa7be9fa00a82Eric Christopher  } else if (TruncInst *TI = dyn_cast<TruncInst>(BI->getCondition())) {
1328bcf26aee86b1ab15b3e1442483eaa7be9fa00a82Eric Christopher    MVT SourceVT;
1329bcf26aee86b1ab15b3e1442483eaa7be9fa00a82Eric Christopher    if (TI->hasOneUse() && TI->getParent() == I->getParent() &&
133076927d7303046058c627691bd45d6bff608f49f4Eli Friedman        (isLoadTypeLegal(TI->getOperand(0)->getType(), SourceVT))) {
133166dc8ca04b719f3ab4aa650609dbd56b055ecb34Chad Rosier      unsigned TstOpc = isThumb2 ? ARM::t2TSTri : ARM::TSTri;
1332bcf26aee86b1ab15b3e1442483eaa7be9fa00a82Eric Christopher      unsigned OpReg = getRegForValue(TI->getOperand(0));
1333bcf26aee86b1ab15b3e1442483eaa7be9fa00a82Eric Christopher      AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
1334bcf26aee86b1ab15b3e1442483eaa7be9fa00a82Eric Christopher                              TII.get(TstOpc))
1335bcf26aee86b1ab15b3e1442483eaa7be9fa00a82Eric Christopher                      .addReg(OpReg).addImm(1));
1336bcf26aee86b1ab15b3e1442483eaa7be9fa00a82Eric Christopher
1337bcf26aee86b1ab15b3e1442483eaa7be9fa00a82Eric Christopher      unsigned CCMode = ARMCC::NE;
1338bcf26aee86b1ab15b3e1442483eaa7be9fa00a82Eric Christopher      if (FuncInfo.MBB->isLayoutSuccessor(TBB)) {
1339bcf26aee86b1ab15b3e1442483eaa7be9fa00a82Eric Christopher        std::swap(TBB, FBB);
1340bcf26aee86b1ab15b3e1442483eaa7be9fa00a82Eric Christopher        CCMode = ARMCC::EQ;
1341bcf26aee86b1ab15b3e1442483eaa7be9fa00a82Eric Christopher      }
1342bcf26aee86b1ab15b3e1442483eaa7be9fa00a82Eric Christopher
134366dc8ca04b719f3ab4aa650609dbd56b055ecb34Chad Rosier      unsigned BrOpc = isThumb2 ? ARM::t2Bcc : ARM::Bcc;
1344bcf26aee86b1ab15b3e1442483eaa7be9fa00a82Eric Christopher      BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(BrOpc))
1345bcf26aee86b1ab15b3e1442483eaa7be9fa00a82Eric Christopher      .addMBB(TBB).addImm(CCMode).addReg(ARM::CPSR);
1346bcf26aee86b1ab15b3e1442483eaa7be9fa00a82Eric Christopher
1347bcf26aee86b1ab15b3e1442483eaa7be9fa00a82Eric Christopher      FastEmitBranch(FBB, DL);
1348bcf26aee86b1ab15b3e1442483eaa7be9fa00a82Eric Christopher      FuncInfo.MBB->addSuccessor(TBB);
1349bcf26aee86b1ab15b3e1442483eaa7be9fa00a82Eric Christopher      return true;
1350bcf26aee86b1ab15b3e1442483eaa7be9fa00a82Eric Christopher    }
13516d64b3adab682aea9c0b4dd665acc5e863ac6d21Chad Rosier  } else if (const ConstantInt *CI =
13526d64b3adab682aea9c0b4dd665acc5e863ac6d21Chad Rosier             dyn_cast<ConstantInt>(BI->getCondition())) {
13536d64b3adab682aea9c0b4dd665acc5e863ac6d21Chad Rosier    uint64_t Imm = CI->getZExtValue();
13546d64b3adab682aea9c0b4dd665acc5e863ac6d21Chad Rosier    MachineBasicBlock *Target = (Imm == 0) ? FBB : TBB;
13556d64b3adab682aea9c0b4dd665acc5e863ac6d21Chad Rosier    FastEmitBranch(Target, DL);
13566d64b3adab682aea9c0b4dd665acc5e863ac6d21Chad Rosier    return true;
13570e6233bfd75a12b9e56507086a37816240ca877aEric Christopher  }
135816cb3763c5a1dad7d6bcbf0fffdfc58c84b46f89Jim Grosbach
13590e6233bfd75a12b9e56507086a37816240ca877aEric Christopher  unsigned CmpReg = getRegForValue(BI->getCondition());
13600e6233bfd75a12b9e56507086a37816240ca877aEric Christopher  if (CmpReg == 0) return false;
1361ac1a19e18ad73198ae54cc4bc08000523031f84aEric Christopher
1362c5eecbc4ec3e8b6934b2c932735c8ebc1b78f537Stuart Hastings  // We've been divorced from our compare!  Our block was split, and
1363c5eecbc4ec3e8b6934b2c932735c8ebc1b78f537Stuart Hastings  // now our compare lives in a predecessor block.  We musn't
1364c5eecbc4ec3e8b6934b2c932735c8ebc1b78f537Stuart Hastings  // re-compare here, as the children of the compare aren't guaranteed
1365c5eecbc4ec3e8b6934b2c932735c8ebc1b78f537Stuart Hastings  // live across the block boundary (we *could* check for this).
1366c5eecbc4ec3e8b6934b2c932735c8ebc1b78f537Stuart Hastings  // Regardless, the compare has been done in the predecessor block,
1367c5eecbc4ec3e8b6934b2c932735c8ebc1b78f537Stuart Hastings  // and it left a value for us in a virtual register.  Ergo, we test
1368c5eecbc4ec3e8b6934b2c932735c8ebc1b78f537Stuart Hastings  // the one-bit value left in the virtual register.
136966dc8ca04b719f3ab4aa650609dbd56b055ecb34Chad Rosier  unsigned TstOpc = isThumb2 ? ARM::t2TSTri : ARM::TSTri;
1370c5eecbc4ec3e8b6934b2c932735c8ebc1b78f537Stuart Hastings  AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(TstOpc))
1371c5eecbc4ec3e8b6934b2c932735c8ebc1b78f537Stuart Hastings                  .addReg(CmpReg).addImm(1));
1372dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher
13737a20a37bacfb2abc0622768fb9d25797518b1f0eEric Christopher  unsigned CCMode = ARMCC::NE;
13747a20a37bacfb2abc0622768fb9d25797518b1f0eEric Christopher  if (FuncInfo.MBB->isLayoutSuccessor(TBB)) {
13757a20a37bacfb2abc0622768fb9d25797518b1f0eEric Christopher    std::swap(TBB, FBB);
13767a20a37bacfb2abc0622768fb9d25797518b1f0eEric Christopher    CCMode = ARMCC::EQ;
13777a20a37bacfb2abc0622768fb9d25797518b1f0eEric Christopher  }
13787a20a37bacfb2abc0622768fb9d25797518b1f0eEric Christopher
137966dc8ca04b719f3ab4aa650609dbd56b055ecb34Chad Rosier  unsigned BrOpc = isThumb2 ? ARM::t2Bcc : ARM::Bcc;
1380e5734105daf799dea671666059f7ecab6abb389fEric Christopher  BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(BrOpc))
13817a20a37bacfb2abc0622768fb9d25797518b1f0eEric Christopher                  .addMBB(TBB).addImm(CCMode).addReg(ARM::CPSR);
1382e5734105daf799dea671666059f7ecab6abb389fEric Christopher  FastEmitBranch(FBB, DL);
1383e5734105daf799dea671666059f7ecab6abb389fEric Christopher  FuncInfo.MBB->addSuccessor(TBB);
1384dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher  return true;
1385e5734105daf799dea671666059f7ecab6abb389fEric Christopher}
1386e5734105daf799dea671666059f7ecab6abb389fEric Christopher
138760c8fa6bb9db791acf6846fe250c184e3f1df168Chad Rosierbool ARMFastISel::SelectIndirectBr(const Instruction *I) {
138860c8fa6bb9db791acf6846fe250c184e3f1df168Chad Rosier  unsigned AddrReg = getRegForValue(I->getOperand(0));
138960c8fa6bb9db791acf6846fe250c184e3f1df168Chad Rosier  if (AddrReg == 0) return false;
139060c8fa6bb9db791acf6846fe250c184e3f1df168Chad Rosier
139160c8fa6bb9db791acf6846fe250c184e3f1df168Chad Rosier  unsigned Opc = isThumb2 ? ARM::tBRIND : ARM::BX;
139260c8fa6bb9db791acf6846fe250c184e3f1df168Chad Rosier  AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc))
139360c8fa6bb9db791acf6846fe250c184e3f1df168Chad Rosier                  .addReg(AddrReg));
13948f47fc8f00fbb1cc2215fc90942b0948e3ca121bBill Wendling
13958f47fc8f00fbb1cc2215fc90942b0948e3ca121bBill Wendling  const IndirectBrInst *IB = cast<IndirectBrInst>(I);
13968f47fc8f00fbb1cc2215fc90942b0948e3ca121bBill Wendling  for (unsigned i = 0, e = IB->getNumSuccessors(); i != e; ++i)
13978f47fc8f00fbb1cc2215fc90942b0948e3ca121bBill Wendling    FuncInfo.MBB->addSuccessor(FuncInfo.MBBMap[IB->getSuccessor(i)]);
13988f47fc8f00fbb1cc2215fc90942b0948e3ca121bBill Wendling
1399efc967e04459753a588ebf5820e526d790fe1cfaJush Lu  return true;
140060c8fa6bb9db791acf6846fe250c184e3f1df168Chad Rosier}
140160c8fa6bb9db791acf6846fe250c184e3f1df168Chad Rosier
1402e07cd5e40ac06fabfb9d33ea7c79542f138f45ceChad Rosierbool ARMFastISel::ARMEmitCmp(const Value *Src1Value, const Value *Src2Value,
1403e07cd5e40ac06fabfb9d33ea7c79542f138f45ceChad Rosier                             bool isZExt) {
1404ade620065d1ad591e0f3d39d40cc241f49cf0a99Chad Rosier  Type *Ty = Src1Value->getType();
14053d170e64ca1af491e2aa58f882f93b8e8111eef8Patrik Hagglund  EVT SrcEVT = TLI.getValueType(Ty, true);
14063d170e64ca1af491e2aa58f882f93b8e8111eef8Patrik Hagglund  if (!SrcEVT.isSimple()) return false;
14073d170e64ca1af491e2aa58f882f93b8e8111eef8Patrik Hagglund  MVT SrcVT = SrcEVT.getSimpleVT();
1408ac1a19e18ad73198ae54cc4bc08000523031f84aEric Christopher
1409ade620065d1ad591e0f3d39d40cc241f49cf0a99Chad Rosier  bool isFloat = (Ty->isFloatTy() || Ty->isDoubleTy());
1410ade620065d1ad591e0f3d39d40cc241f49cf0a99Chad Rosier  if (isFloat && !Subtarget->hasVFP2())
1411d43393ae34ba7e39239d593742eb63086b68f29aEric Christopher    return false;
1412ac1a19e18ad73198ae54cc4bc08000523031f84aEric Christopher
14132f2fe417f98406140504ba3bbb65676d4a00ed87Chad Rosier  // Check to see if the 2nd operand is a constant that we can encode directly
14142f2fe417f98406140504ba3bbb65676d4a00ed87Chad Rosier  // in the compare.
14151c47de87c74c3834c5cfab8a7e0fa67b1805f927Chad Rosier  int Imm = 0;
14161c47de87c74c3834c5cfab8a7e0fa67b1805f927Chad Rosier  bool UseImm = false;
14172f2fe417f98406140504ba3bbb65676d4a00ed87Chad Rosier  bool isNegativeImm = false;
1418f56c60b5713c57a3f9223d4ed3d9c88088132fadChad Rosier  // FIXME: At -O0 we don't have anything that canonicalizes operand order.
1419f56c60b5713c57a3f9223d4ed3d9c88088132fadChad Rosier  // Thus, Src1Value may be a ConstantInt, but we're missing it.
14202f2fe417f98406140504ba3bbb65676d4a00ed87Chad Rosier  if (const ConstantInt *ConstInt = dyn_cast<ConstantInt>(Src2Value)) {
14212f2fe417f98406140504ba3bbb65676d4a00ed87Chad Rosier    if (SrcVT == MVT::i32 || SrcVT == MVT::i16 || SrcVT == MVT::i8 ||
14222f2fe417f98406140504ba3bbb65676d4a00ed87Chad Rosier        SrcVT == MVT::i1) {
14232f2fe417f98406140504ba3bbb65676d4a00ed87Chad Rosier      const APInt &CIVal = ConstInt->getValue();
14241c47de87c74c3834c5cfab8a7e0fa67b1805f927Chad Rosier      Imm = (isZExt) ? (int)CIVal.getZExtValue() : (int)CIVal.getSExtValue();
14250ac754f6f43a0e5a56f712aebb663581ae512e4cChad Rosier      // For INT_MIN/LONG_MIN (i.e., 0x80000000) we need to use a cmp, rather
14260ac754f6f43a0e5a56f712aebb663581ae512e4cChad Rosier      // then a cmn, because there is no way to represent 2147483648 as a
14270ac754f6f43a0e5a56f712aebb663581ae512e4cChad Rosier      // signed 32-bit int.
14280ac754f6f43a0e5a56f712aebb663581ae512e4cChad Rosier      if (Imm < 0 && Imm != (int)0x80000000) {
14290ac754f6f43a0e5a56f712aebb663581ae512e4cChad Rosier        isNegativeImm = true;
14300ac754f6f43a0e5a56f712aebb663581ae512e4cChad Rosier        Imm = -Imm;
14316cba97c5557ac51d8ae09b9f5cbad6891124db4dChad Rosier      }
14320ac754f6f43a0e5a56f712aebb663581ae512e4cChad Rosier      UseImm = isThumb2 ? (ARM_AM::getT2SOImmVal(Imm) != -1) :
14330ac754f6f43a0e5a56f712aebb663581ae512e4cChad Rosier        (ARM_AM::getSOImmVal(Imm) != -1);
14342f2fe417f98406140504ba3bbb65676d4a00ed87Chad Rosier    }
14352f2fe417f98406140504ba3bbb65676d4a00ed87Chad Rosier  } else if (const ConstantFP *ConstFP = dyn_cast<ConstantFP>(Src2Value)) {
14362f2fe417f98406140504ba3bbb65676d4a00ed87Chad Rosier    if (SrcVT == MVT::f32 || SrcVT == MVT::f64)
14372f2fe417f98406140504ba3bbb65676d4a00ed87Chad Rosier      if (ConstFP->isZero() && !ConstFP->isNegative())
14381c47de87c74c3834c5cfab8a7e0fa67b1805f927Chad Rosier        UseImm = true;
14392f2fe417f98406140504ba3bbb65676d4a00ed87Chad Rosier  }
14402f2fe417f98406140504ba3bbb65676d4a00ed87Chad Rosier
1441d43393ae34ba7e39239d593742eb63086b68f29aEric Christopher  unsigned CmpOpc;
14422f2fe417f98406140504ba3bbb65676d4a00ed87Chad Rosier  bool isICmp = true;
1443e07cd5e40ac06fabfb9d33ea7c79542f138f45ceChad Rosier  bool needsExt = false;
1444a61b17c18a67f1b3faef2f2108379c4337ce9bb7Patrik Hagglund  switch (SrcVT.SimpleTy) {
1445d43393ae34ba7e39239d593742eb63086b68f29aEric Christopher    default: return false;
1446d43393ae34ba7e39239d593742eb63086b68f29aEric Christopher    // TODO: Verify compares.
1447d43393ae34ba7e39239d593742eb63086b68f29aEric Christopher    case MVT::f32:
14482f2fe417f98406140504ba3bbb65676d4a00ed87Chad Rosier      isICmp = false;
14491c47de87c74c3834c5cfab8a7e0fa67b1805f927Chad Rosier      CmpOpc = UseImm ? ARM::VCMPEZS : ARM::VCMPES;
1450d43393ae34ba7e39239d593742eb63086b68f29aEric Christopher      break;
1451d43393ae34ba7e39239d593742eb63086b68f29aEric Christopher    case MVT::f64:
14522f2fe417f98406140504ba3bbb65676d4a00ed87Chad Rosier      isICmp = false;
14531c47de87c74c3834c5cfab8a7e0fa67b1805f927Chad Rosier      CmpOpc = UseImm ? ARM::VCMPEZD : ARM::VCMPED;
1454d43393ae34ba7e39239d593742eb63086b68f29aEric Christopher      break;
1455e07cd5e40ac06fabfb9d33ea7c79542f138f45ceChad Rosier    case MVT::i1:
1456e07cd5e40ac06fabfb9d33ea7c79542f138f45ceChad Rosier    case MVT::i8:
1457e07cd5e40ac06fabfb9d33ea7c79542f138f45ceChad Rosier    case MVT::i16:
1458e07cd5e40ac06fabfb9d33ea7c79542f138f45ceChad Rosier      needsExt = true;
1459e07cd5e40ac06fabfb9d33ea7c79542f138f45ceChad Rosier    // Intentional fall-through.
1460d43393ae34ba7e39239d593742eb63086b68f29aEric Christopher    case MVT::i32:
14612f2fe417f98406140504ba3bbb65676d4a00ed87Chad Rosier      if (isThumb2) {
14621c47de87c74c3834c5cfab8a7e0fa67b1805f927Chad Rosier        if (!UseImm)
14632f2fe417f98406140504ba3bbb65676d4a00ed87Chad Rosier          CmpOpc = ARM::t2CMPrr;
14642f2fe417f98406140504ba3bbb65676d4a00ed87Chad Rosier        else
1465ad5c8808923ed5b24b586cec544e45cee539e529Bill Wendling          CmpOpc = isNegativeImm ? ARM::t2CMNri : ARM::t2CMPri;
14662f2fe417f98406140504ba3bbb65676d4a00ed87Chad Rosier      } else {
14671c47de87c74c3834c5cfab8a7e0fa67b1805f927Chad Rosier        if (!UseImm)
14682f2fe417f98406140504ba3bbb65676d4a00ed87Chad Rosier          CmpOpc = ARM::CMPrr;
14692f2fe417f98406140504ba3bbb65676d4a00ed87Chad Rosier        else
1470ad5c8808923ed5b24b586cec544e45cee539e529Bill Wendling          CmpOpc = isNegativeImm ? ARM::CMNri : ARM::CMPri;
14712f2fe417f98406140504ba3bbb65676d4a00ed87Chad Rosier      }
1472d43393ae34ba7e39239d593742eb63086b68f29aEric Christopher      break;
1473d43393ae34ba7e39239d593742eb63086b68f29aEric Christopher  }
1474d43393ae34ba7e39239d593742eb63086b68f29aEric Christopher
1475e07cd5e40ac06fabfb9d33ea7c79542f138f45ceChad Rosier  unsigned SrcReg1 = getRegForValue(Src1Value);
1476e07cd5e40ac06fabfb9d33ea7c79542f138f45ceChad Rosier  if (SrcReg1 == 0) return false;
1477e07cd5e40ac06fabfb9d33ea7c79542f138f45ceChad Rosier
14784c0c5451c78423bcc08e23f230e912e35d11dc4dDuncan Sands  unsigned SrcReg2 = 0;
14791c47de87c74c3834c5cfab8a7e0fa67b1805f927Chad Rosier  if (!UseImm) {
14802f2fe417f98406140504ba3bbb65676d4a00ed87Chad Rosier    SrcReg2 = getRegForValue(Src2Value);
14812f2fe417f98406140504ba3bbb65676d4a00ed87Chad Rosier    if (SrcReg2 == 0) return false;
14822f2fe417f98406140504ba3bbb65676d4a00ed87Chad Rosier  }
1483e07cd5e40ac06fabfb9d33ea7c79542f138f45ceChad Rosier
1484e07cd5e40ac06fabfb9d33ea7c79542f138f45ceChad Rosier  // We have i1, i8, or i16, we need to either zero extend or sign extend.
1485e07cd5e40ac06fabfb9d33ea7c79542f138f45ceChad Rosier  if (needsExt) {
1486a69feb0f33788b13aa4c25736e50afc6f2b4ce44Chad Rosier    SrcReg1 = ARMEmitIntExt(SrcVT, SrcReg1, MVT::i32, isZExt);
1487a69feb0f33788b13aa4c25736e50afc6f2b4ce44Chad Rosier    if (SrcReg1 == 0) return false;
14881c47de87c74c3834c5cfab8a7e0fa67b1805f927Chad Rosier    if (!UseImm) {
1489a69feb0f33788b13aa4c25736e50afc6f2b4ce44Chad Rosier      SrcReg2 = ARMEmitIntExt(SrcVT, SrcReg2, MVT::i32, isZExt);
1490a69feb0f33788b13aa4c25736e50afc6f2b4ce44Chad Rosier      if (SrcReg2 == 0) return false;
14912f2fe417f98406140504ba3bbb65676d4a00ed87Chad Rosier    }
1492e07cd5e40ac06fabfb9d33ea7c79542f138f45ceChad Rosier  }
1493530f7cefd3082e8aaa74b7d65636f30d0312b6ecChad Rosier
14941c47de87c74c3834c5cfab8a7e0fa67b1805f927Chad Rosier  if (!UseImm) {
14952f2fe417f98406140504ba3bbb65676d4a00ed87Chad Rosier    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
14962f2fe417f98406140504ba3bbb65676d4a00ed87Chad Rosier                            TII.get(CmpOpc))
14972f2fe417f98406140504ba3bbb65676d4a00ed87Chad Rosier                    .addReg(SrcReg1).addReg(SrcReg2));
14982f2fe417f98406140504ba3bbb65676d4a00ed87Chad Rosier  } else {
14992f2fe417f98406140504ba3bbb65676d4a00ed87Chad Rosier    MachineInstrBuilder MIB;
15002f2fe417f98406140504ba3bbb65676d4a00ed87Chad Rosier    MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(CmpOpc))
15012f2fe417f98406140504ba3bbb65676d4a00ed87Chad Rosier      .addReg(SrcReg1);
15022f2fe417f98406140504ba3bbb65676d4a00ed87Chad Rosier
15032f2fe417f98406140504ba3bbb65676d4a00ed87Chad Rosier    // Only add immediate for icmp as the immediate for fcmp is an implicit 0.0.
15042f2fe417f98406140504ba3bbb65676d4a00ed87Chad Rosier    if (isICmp)
15051c47de87c74c3834c5cfab8a7e0fa67b1805f927Chad Rosier      MIB.addImm(Imm);
15062f2fe417f98406140504ba3bbb65676d4a00ed87Chad Rosier    AddOptionalDefs(MIB);
15072f2fe417f98406140504ba3bbb65676d4a00ed87Chad Rosier  }
1508ade620065d1ad591e0f3d39d40cc241f49cf0a99Chad Rosier
1509ade620065d1ad591e0f3d39d40cc241f49cf0a99Chad Rosier  // For floating point we need to move the result to a comparison register
1510ade620065d1ad591e0f3d39d40cc241f49cf0a99Chad Rosier  // that we can then use for branches.
1511ade620065d1ad591e0f3d39d40cc241f49cf0a99Chad Rosier  if (Ty->isFloatTy() || Ty->isDoubleTy())
1512ade620065d1ad591e0f3d39d40cc241f49cf0a99Chad Rosier    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
1513ade620065d1ad591e0f3d39d40cc241f49cf0a99Chad Rosier                            TII.get(ARM::FMSTAT)));
1514530f7cefd3082e8aaa74b7d65636f30d0312b6ecChad Rosier  return true;
1515530f7cefd3082e8aaa74b7d65636f30d0312b6ecChad Rosier}
1516530f7cefd3082e8aaa74b7d65636f30d0312b6ecChad Rosier
1517530f7cefd3082e8aaa74b7d65636f30d0312b6ecChad Rosierbool ARMFastISel::SelectCmp(const Instruction *I) {
1518530f7cefd3082e8aaa74b7d65636f30d0312b6ecChad Rosier  const CmpInst *CI = cast<CmpInst>(I);
1519530f7cefd3082e8aaa74b7d65636f30d0312b6ecChad Rosier
1520229207aa2edaeb872e9f987ad8df3a67455f240cEric Christopher  // Get the compare predicate.
1521229207aa2edaeb872e9f987ad8df3a67455f240cEric Christopher  ARMCC::CondCodes ARMPred = getComparePred(CI->getPredicate());
1522dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher
1523229207aa2edaeb872e9f987ad8df3a67455f240cEric Christopher  // We may not handle every CC for now.
1524229207aa2edaeb872e9f987ad8df3a67455f240cEric Christopher  if (ARMPred == ARMCC::AL) return false;
1525229207aa2edaeb872e9f987ad8df3a67455f240cEric Christopher
1526530f7cefd3082e8aaa74b7d65636f30d0312b6ecChad Rosier  // Emit the compare.
1527e07cd5e40ac06fabfb9d33ea7c79542f138f45ceChad Rosier  if (!ARMEmitCmp(CI->getOperand(0), CI->getOperand(1), CI->isUnsigned()))
1528530f7cefd3082e8aaa74b7d65636f30d0312b6ecChad Rosier    return false;
1529ac1a19e18ad73198ae54cc4bc08000523031f84aEric Christopher
1530229207aa2edaeb872e9f987ad8df3a67455f240cEric Christopher  // Now set a register based on the comparison. Explicitly set the predicates
1531229207aa2edaeb872e9f987ad8df3a67455f240cEric Christopher  // here.
153266dc8ca04b719f3ab4aa650609dbd56b055ecb34Chad Rosier  unsigned MovCCOpc = isThumb2 ? ARM::t2MOVCCi : ARM::MOVCCi;
1533420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper  const TargetRegisterClass *RC = isThumb2 ?
1534420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper    (const TargetRegisterClass*)&ARM::rGPRRegClass :
1535420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper    (const TargetRegisterClass*)&ARM::GPRRegClass;
15365d18d92aad587381b5d9ecf0aeb3c2eb1530ee61Eric Christopher  unsigned DestReg = createResultReg(RC);
1537ade620065d1ad591e0f3d39d40cc241f49cf0a99Chad Rosier  Constant *Zero = ConstantInt::get(Type::getInt32Ty(*Context), 0);
1538229207aa2edaeb872e9f987ad8df3a67455f240cEric Christopher  unsigned ZeroReg = TargetMaterializeConstant(Zero);
153944c98b71148d11368c18ffb9c14e8a28a76a8021Chad Rosier  // ARMEmitCmp emits a FMSTAT when necessary, so it's always safe to use CPSR.
1540229207aa2edaeb872e9f987ad8df3a67455f240cEric Christopher  BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(MovCCOpc), DestReg)
1541229207aa2edaeb872e9f987ad8df3a67455f240cEric Christopher          .addReg(ZeroReg).addImm(1)
154244c98b71148d11368c18ffb9c14e8a28a76a8021Chad Rosier          .addImm(ARMPred).addReg(ARM::CPSR);
1543229207aa2edaeb872e9f987ad8df3a67455f240cEric Christopher
1544a5b1e6810769bef9a1fd98c69877bdfd75d7b106Eric Christopher  UpdateValueMap(I, DestReg);
1545d43393ae34ba7e39239d593742eb63086b68f29aEric Christopher  return true;
1546d43393ae34ba7e39239d593742eb63086b68f29aEric Christopher}
1547d43393ae34ba7e39239d593742eb63086b68f29aEric Christopher
154843b62beb4cac4337a080c2d3fb8f218a7ffb59c3Eric Christopherbool ARMFastISel::SelectFPExt(const Instruction *I) {
15494620360842bd8cddc5b1bad7f2f04214c91ac9cbEric Christopher  // Make sure we have VFP and that we're extending float to double.
15504620360842bd8cddc5b1bad7f2f04214c91ac9cbEric Christopher  if (!Subtarget->hasVFP2()) return false;
1551ac1a19e18ad73198ae54cc4bc08000523031f84aEric Christopher
15524620360842bd8cddc5b1bad7f2f04214c91ac9cbEric Christopher  Value *V = I->getOperand(0);
15534620360842bd8cddc5b1bad7f2f04214c91ac9cbEric Christopher  if (!I->getType()->isDoubleTy() ||
15544620360842bd8cddc5b1bad7f2f04214c91ac9cbEric Christopher      !V->getType()->isFloatTy()) return false;
1555ac1a19e18ad73198ae54cc4bc08000523031f84aEric Christopher
15564620360842bd8cddc5b1bad7f2f04214c91ac9cbEric Christopher  unsigned Op = getRegForValue(V);
15574620360842bd8cddc5b1bad7f2f04214c91ac9cbEric Christopher  if (Op == 0) return false;
1558ac1a19e18ad73198ae54cc4bc08000523031f84aEric Christopher
1559420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper  unsigned Result = createResultReg(&ARM::DPRRegClass);
1560ac1a19e18ad73198ae54cc4bc08000523031f84aEric Christopher  AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
1561ef2fdd21418e0cdc5df963a063b0f940964fa208Eric Christopher                          TII.get(ARM::VCVTDS), Result)
1562ce07b5458d87d5f5ad306a1d86785537e9a3ce0cEric Christopher                  .addReg(Op));
1563ce07b5458d87d5f5ad306a1d86785537e9a3ce0cEric Christopher  UpdateValueMap(I, Result);
1564ce07b5458d87d5f5ad306a1d86785537e9a3ce0cEric Christopher  return true;
1565ce07b5458d87d5f5ad306a1d86785537e9a3ce0cEric Christopher}
1566ce07b5458d87d5f5ad306a1d86785537e9a3ce0cEric Christopher
156743b62beb4cac4337a080c2d3fb8f218a7ffb59c3Eric Christopherbool ARMFastISel::SelectFPTrunc(const Instruction *I) {
1568ce07b5458d87d5f5ad306a1d86785537e9a3ce0cEric Christopher  // Make sure we have VFP and that we're truncating double to float.
1569ce07b5458d87d5f5ad306a1d86785537e9a3ce0cEric Christopher  if (!Subtarget->hasVFP2()) return false;
1570ce07b5458d87d5f5ad306a1d86785537e9a3ce0cEric Christopher
1571ce07b5458d87d5f5ad306a1d86785537e9a3ce0cEric Christopher  Value *V = I->getOperand(0);
1572022b7fb045973531a1b05f4f0dae28fd836c9890Eric Christopher  if (!(I->getType()->isFloatTy() &&
1573022b7fb045973531a1b05f4f0dae28fd836c9890Eric Christopher        V->getType()->isDoubleTy())) return false;
1574ce07b5458d87d5f5ad306a1d86785537e9a3ce0cEric Christopher
1575ce07b5458d87d5f5ad306a1d86785537e9a3ce0cEric Christopher  unsigned Op = getRegForValue(V);
1576ce07b5458d87d5f5ad306a1d86785537e9a3ce0cEric Christopher  if (Op == 0) return false;
1577ce07b5458d87d5f5ad306a1d86785537e9a3ce0cEric Christopher
1578420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper  unsigned Result = createResultReg(&ARM::SPRRegClass);
1579ce07b5458d87d5f5ad306a1d86785537e9a3ce0cEric Christopher  AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
1580ef2fdd21418e0cdc5df963a063b0f940964fa208Eric Christopher                          TII.get(ARM::VCVTSD), Result)
15814620360842bd8cddc5b1bad7f2f04214c91ac9cbEric Christopher                  .addReg(Op));
15824620360842bd8cddc5b1bad7f2f04214c91ac9cbEric Christopher  UpdateValueMap(I, Result);
15834620360842bd8cddc5b1bad7f2f04214c91ac9cbEric Christopher  return true;
15844620360842bd8cddc5b1bad7f2f04214c91ac9cbEric Christopher}
15854620360842bd8cddc5b1bad7f2f04214c91ac9cbEric Christopher
1586ae46a3362d6c7fd2d4b1bf3b40982d289d7418fbChad Rosierbool ARMFastISel::SelectIToFP(const Instruction *I, bool isSigned) {
15879a040492f7ed084e12a19d56995855c9b5b1d3aaEric Christopher  // Make sure we have VFP.
15889a040492f7ed084e12a19d56995855c9b5b1d3aaEric Christopher  if (!Subtarget->hasVFP2()) return false;
1589dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher
15901440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands  MVT DstVT;
1591db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  Type *Ty = I->getType();
15929ee4ce2f91250ef44fea427392c8dad369df8972Eric Christopher  if (!isTypeLegal(Ty, DstVT))
15939a040492f7ed084e12a19d56995855c9b5b1d3aaEric Christopher    return false;
1594dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher
1595463fe24f1dd5132607abb3548a2acb1849e9aa99Chad Rosier  Value *Src = I->getOperand(0);
15963d170e64ca1af491e2aa58f882f93b8e8111eef8Patrik Hagglund  EVT SrcEVT = TLI.getValueType(Src->getType(), true);
15973d170e64ca1af491e2aa58f882f93b8e8111eef8Patrik Hagglund  if (!SrcEVT.isSimple())
15983d170e64ca1af491e2aa58f882f93b8e8111eef8Patrik Hagglund    return false;
15993d170e64ca1af491e2aa58f882f93b8e8111eef8Patrik Hagglund  MVT SrcVT = SrcEVT.getSimpleVT();
1600463fe24f1dd5132607abb3548a2acb1849e9aa99Chad Rosier  if (SrcVT != MVT::i32 && SrcVT != MVT::i16 && SrcVT != MVT::i8)
1601783c66414ae54ddc9879843b4bc878dc66a70478Eli Friedman    return false;
1602783c66414ae54ddc9879843b4bc878dc66a70478Eli Friedman
1603463fe24f1dd5132607abb3548a2acb1849e9aa99Chad Rosier  unsigned SrcReg = getRegForValue(Src);
1604463fe24f1dd5132607abb3548a2acb1849e9aa99Chad Rosier  if (SrcReg == 0) return false;
1605463fe24f1dd5132607abb3548a2acb1849e9aa99Chad Rosier
1606463fe24f1dd5132607abb3548a2acb1849e9aa99Chad Rosier  // Handle sign-extension.
1607463fe24f1dd5132607abb3548a2acb1849e9aa99Chad Rosier  if (SrcVT == MVT::i16 || SrcVT == MVT::i8) {
1608316a5aa0a510e6183dd1981dd8bf328ffe7361f5Chad Rosier    SrcReg = ARMEmitIntExt(SrcVT, SrcReg, MVT::i32,
1609ae46a3362d6c7fd2d4b1bf3b40982d289d7418fbChad Rosier                                       /*isZExt*/!isSigned);
1610a69feb0f33788b13aa4c25736e50afc6f2b4ce44Chad Rosier    if (SrcReg == 0) return false;
1611463fe24f1dd5132607abb3548a2acb1849e9aa99Chad Rosier  }
1612dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher
1613db12b2ba9c602fc9bedcf0a9b2e72e23e29005d8Eric Christopher  // The conversion routine works on fp-reg to fp-reg and the operand above
1614db12b2ba9c602fc9bedcf0a9b2e72e23e29005d8Eric Christopher  // was an integer, move it to the fp registers if possible.
1615463fe24f1dd5132607abb3548a2acb1849e9aa99Chad Rosier  unsigned FP = ARMMoveToFPReg(MVT::f32, SrcReg);
16169ee4ce2f91250ef44fea427392c8dad369df8972Eric Christopher  if (FP == 0) return false;
1617dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher
16189a040492f7ed084e12a19d56995855c9b5b1d3aaEric Christopher  unsigned Opc;
1619ae46a3362d6c7fd2d4b1bf3b40982d289d7418fbChad Rosier  if (Ty->isFloatTy()) Opc = isSigned ? ARM::VSITOS : ARM::VUITOS;
1620ae46a3362d6c7fd2d4b1bf3b40982d289d7418fbChad Rosier  else if (Ty->isDoubleTy()) Opc = isSigned ? ARM::VSITOD : ARM::VUITOD;
1621dd1e7517b5bdda245c907f7e36350ef862be2571Chad Rosier  else return false;
1622dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher
16239ee4ce2f91250ef44fea427392c8dad369df8972Eric Christopher  unsigned ResultReg = createResultReg(TLI.getRegClassFor(DstVT));
16249a040492f7ed084e12a19d56995855c9b5b1d3aaEric Christopher  AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc),
16259a040492f7ed084e12a19d56995855c9b5b1d3aaEric Christopher                          ResultReg)
16269ee4ce2f91250ef44fea427392c8dad369df8972Eric Christopher                  .addReg(FP));
1627ce07b5458d87d5f5ad306a1d86785537e9a3ce0cEric Christopher  UpdateValueMap(I, ResultReg);
16289a040492f7ed084e12a19d56995855c9b5b1d3aaEric Christopher  return true;
16299a040492f7ed084e12a19d56995855c9b5b1d3aaEric Christopher}
16309a040492f7ed084e12a19d56995855c9b5b1d3aaEric Christopher
1631ae46a3362d6c7fd2d4b1bf3b40982d289d7418fbChad Rosierbool ARMFastISel::SelectFPToI(const Instruction *I, bool isSigned) {
16329a040492f7ed084e12a19d56995855c9b5b1d3aaEric Christopher  // Make sure we have VFP.
16339a040492f7ed084e12a19d56995855c9b5b1d3aaEric Christopher  if (!Subtarget->hasVFP2()) return false;
1634dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher
16351440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands  MVT DstVT;
1636db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  Type *RetTy = I->getType();
1637920a2089d9b737820631bc6de4c4fb9fa9ad1e07Eric Christopher  if (!isTypeLegal(RetTy, DstVT))
16389a040492f7ed084e12a19d56995855c9b5b1d3aaEric Christopher    return false;
1639dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher
16409a040492f7ed084e12a19d56995855c9b5b1d3aaEric Christopher  unsigned Op = getRegForValue(I->getOperand(0));
16419a040492f7ed084e12a19d56995855c9b5b1d3aaEric Christopher  if (Op == 0) return false;
1642dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher
16439a040492f7ed084e12a19d56995855c9b5b1d3aaEric Christopher  unsigned Opc;
1644db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  Type *OpTy = I->getOperand(0)->getType();
1645ae46a3362d6c7fd2d4b1bf3b40982d289d7418fbChad Rosier  if (OpTy->isFloatTy()) Opc = isSigned ? ARM::VTOSIZS : ARM::VTOUIZS;
1646ae46a3362d6c7fd2d4b1bf3b40982d289d7418fbChad Rosier  else if (OpTy->isDoubleTy()) Opc = isSigned ? ARM::VTOSIZD : ARM::VTOUIZD;
1647dd1e7517b5bdda245c907f7e36350ef862be2571Chad Rosier  else return false;
1648dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher
1649ee8901c08fb27e98078326706a49dba70e1768a3Chad Rosier  // f64->s32/u32 or f32->s32/u32 both need an intermediate f32 reg.
1650022b7fb045973531a1b05f4f0dae28fd836c9890Eric Christopher  unsigned ResultReg = createResultReg(TLI.getRegClassFor(MVT::f32));
16519a040492f7ed084e12a19d56995855c9b5b1d3aaEric Christopher  AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc),
16529a040492f7ed084e12a19d56995855c9b5b1d3aaEric Christopher                          ResultReg)
16539a040492f7ed084e12a19d56995855c9b5b1d3aaEric Christopher                  .addReg(Op));
1654dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher
16559ee4ce2f91250ef44fea427392c8dad369df8972Eric Christopher  // This result needs to be in an integer register, but the conversion only
16569ee4ce2f91250ef44fea427392c8dad369df8972Eric Christopher  // takes place in fp-regs.
1657db12b2ba9c602fc9bedcf0a9b2e72e23e29005d8Eric Christopher  unsigned IntReg = ARMMoveToIntReg(DstVT, ResultReg);
16589ee4ce2f91250ef44fea427392c8dad369df8972Eric Christopher  if (IntReg == 0) return false;
1659dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher
16609ee4ce2f91250ef44fea427392c8dad369df8972Eric Christopher  UpdateValueMap(I, IntReg);
16619a040492f7ed084e12a19d56995855c9b5b1d3aaEric Christopher  return true;
16629a040492f7ed084e12a19d56995855c9b5b1d3aaEric Christopher}
16639a040492f7ed084e12a19d56995855c9b5b1d3aaEric Christopher
16643bbd396853c7645791417bc795bab4662235ec10Eric Christopherbool ARMFastISel::SelectSelect(const Instruction *I) {
16651440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands  MVT VT;
16661440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands  if (!isTypeLegal(I->getType(), VT))
16673bbd396853c7645791417bc795bab4662235ec10Eric Christopher    return false;
16683bbd396853c7645791417bc795bab4662235ec10Eric Christopher
16693bbd396853c7645791417bc795bab4662235ec10Eric Christopher  // Things need to be register sized for register moves.
16701440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands  if (VT != MVT::i32) return false;
16713bbd396853c7645791417bc795bab4662235ec10Eric Christopher
16723bbd396853c7645791417bc795bab4662235ec10Eric Christopher  unsigned CondReg = getRegForValue(I->getOperand(0));
16733bbd396853c7645791417bc795bab4662235ec10Eric Christopher  if (CondReg == 0) return false;
16743bbd396853c7645791417bc795bab4662235ec10Eric Christopher  unsigned Op1Reg = getRegForValue(I->getOperand(1));
16753bbd396853c7645791417bc795bab4662235ec10Eric Christopher  if (Op1Reg == 0) return false;
16763bbd396853c7645791417bc795bab4662235ec10Eric Christopher
1677a07d3fc693e2a3ac7c9ed2a59f62b21ab33d9fd4Chad Rosier  // Check to see if we can use an immediate in the conditional move.
1678a07d3fc693e2a3ac7c9ed2a59f62b21ab33d9fd4Chad Rosier  int Imm = 0;
1679a07d3fc693e2a3ac7c9ed2a59f62b21ab33d9fd4Chad Rosier  bool UseImm = false;
1680a07d3fc693e2a3ac7c9ed2a59f62b21ab33d9fd4Chad Rosier  bool isNegativeImm = false;
1681a07d3fc693e2a3ac7c9ed2a59f62b21ab33d9fd4Chad Rosier  if (const ConstantInt *ConstInt = dyn_cast<ConstantInt>(I->getOperand(2))) {
1682a07d3fc693e2a3ac7c9ed2a59f62b21ab33d9fd4Chad Rosier    assert (VT == MVT::i32 && "Expecting an i32.");
1683a07d3fc693e2a3ac7c9ed2a59f62b21ab33d9fd4Chad Rosier    Imm = (int)ConstInt->getValue().getZExtValue();
1684a07d3fc693e2a3ac7c9ed2a59f62b21ab33d9fd4Chad Rosier    if (Imm < 0) {
1685a07d3fc693e2a3ac7c9ed2a59f62b21ab33d9fd4Chad Rosier      isNegativeImm = true;
1686a07d3fc693e2a3ac7c9ed2a59f62b21ab33d9fd4Chad Rosier      Imm = ~Imm;
1687a07d3fc693e2a3ac7c9ed2a59f62b21ab33d9fd4Chad Rosier    }
1688a07d3fc693e2a3ac7c9ed2a59f62b21ab33d9fd4Chad Rosier    UseImm = isThumb2 ? (ARM_AM::getT2SOImmVal(Imm) != -1) :
1689a07d3fc693e2a3ac7c9ed2a59f62b21ab33d9fd4Chad Rosier      (ARM_AM::getSOImmVal(Imm) != -1);
1690a07d3fc693e2a3ac7c9ed2a59f62b21ab33d9fd4Chad Rosier  }
1691a07d3fc693e2a3ac7c9ed2a59f62b21ab33d9fd4Chad Rosier
16924c0c5451c78423bcc08e23f230e912e35d11dc4dDuncan Sands  unsigned Op2Reg = 0;
1693a07d3fc693e2a3ac7c9ed2a59f62b21ab33d9fd4Chad Rosier  if (!UseImm) {
1694a07d3fc693e2a3ac7c9ed2a59f62b21ab33d9fd4Chad Rosier    Op2Reg = getRegForValue(I->getOperand(2));
1695a07d3fc693e2a3ac7c9ed2a59f62b21ab33d9fd4Chad Rosier    if (Op2Reg == 0) return false;
1696a07d3fc693e2a3ac7c9ed2a59f62b21ab33d9fd4Chad Rosier  }
1697a07d3fc693e2a3ac7c9ed2a59f62b21ab33d9fd4Chad Rosier
1698a07d3fc693e2a3ac7c9ed2a59f62b21ab33d9fd4Chad Rosier  unsigned CmpOpc = isThumb2 ? ARM::t2CMPri : ARM::CMPri;
16993bbd396853c7645791417bc795bab4662235ec10Eric Christopher  AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(CmpOpc))
1700a07d3fc693e2a3ac7c9ed2a59f62b21ab33d9fd4Chad Rosier                  .addReg(CondReg).addImm(0));
1701a07d3fc693e2a3ac7c9ed2a59f62b21ab33d9fd4Chad Rosier
1702a07d3fc693e2a3ac7c9ed2a59f62b21ab33d9fd4Chad Rosier  unsigned MovCCOpc;
1703ac3158b5718ad724a02694c9f1c08bbfaf5fec11Chad Rosier  const TargetRegisterClass *RC;
1704a07d3fc693e2a3ac7c9ed2a59f62b21ab33d9fd4Chad Rosier  if (!UseImm) {
1705ac3158b5718ad724a02694c9f1c08bbfaf5fec11Chad Rosier    RC = isThumb2 ? &ARM::tGPRRegClass : &ARM::GPRRegClass;
1706a07d3fc693e2a3ac7c9ed2a59f62b21ab33d9fd4Chad Rosier    MovCCOpc = isThumb2 ? ARM::t2MOVCCr : ARM::MOVCCr;
1707a07d3fc693e2a3ac7c9ed2a59f62b21ab33d9fd4Chad Rosier  } else {
1708ac3158b5718ad724a02694c9f1c08bbfaf5fec11Chad Rosier    RC = isThumb2 ? &ARM::rGPRRegClass : &ARM::GPRRegClass;
1709ac3158b5718ad724a02694c9f1c08bbfaf5fec11Chad Rosier    if (!isNegativeImm)
1710a07d3fc693e2a3ac7c9ed2a59f62b21ab33d9fd4Chad Rosier      MovCCOpc = isThumb2 ? ARM::t2MOVCCi : ARM::MOVCCi;
1711ac3158b5718ad724a02694c9f1c08bbfaf5fec11Chad Rosier    else
1712a07d3fc693e2a3ac7c9ed2a59f62b21ab33d9fd4Chad Rosier      MovCCOpc = isThumb2 ? ARM::t2MVNCCi : ARM::MVNCCi;
1713a07d3fc693e2a3ac7c9ed2a59f62b21ab33d9fd4Chad Rosier  }
17143bbd396853c7645791417bc795bab4662235ec10Eric Christopher  unsigned ResultReg = createResultReg(RC);
1715a07d3fc693e2a3ac7c9ed2a59f62b21ab33d9fd4Chad Rosier  if (!UseImm)
1716a07d3fc693e2a3ac7c9ed2a59f62b21ab33d9fd4Chad Rosier    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(MovCCOpc), ResultReg)
1717a07d3fc693e2a3ac7c9ed2a59f62b21ab33d9fd4Chad Rosier    .addReg(Op2Reg).addReg(Op1Reg).addImm(ARMCC::NE).addReg(ARM::CPSR);
1718a07d3fc693e2a3ac7c9ed2a59f62b21ab33d9fd4Chad Rosier  else
1719a07d3fc693e2a3ac7c9ed2a59f62b21ab33d9fd4Chad Rosier    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(MovCCOpc), ResultReg)
1720a07d3fc693e2a3ac7c9ed2a59f62b21ab33d9fd4Chad Rosier    .addReg(Op1Reg).addImm(Imm).addImm(ARMCC::EQ).addReg(ARM::CPSR);
17213bbd396853c7645791417bc795bab4662235ec10Eric Christopher  UpdateValueMap(I, ResultReg);
17223bbd396853c7645791417bc795bab4662235ec10Eric Christopher  return true;
17233bbd396853c7645791417bc795bab4662235ec10Eric Christopher}
17243bbd396853c7645791417bc795bab4662235ec10Eric Christopher
17257ccb30b5964675a70559ec25a6bff32f7dea1025Chad Rosierbool ARMFastISel::SelectDiv(const Instruction *I, bool isSigned) {
17261440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands  MVT VT;
1727db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  Type *Ty = I->getType();
1728086378597df590e6401abf90d0b5edb09bbaa297Eric Christopher  if (!isTypeLegal(Ty, VT))
1729086378597df590e6401abf90d0b5edb09bbaa297Eric Christopher    return false;
1730086378597df590e6401abf90d0b5edb09bbaa297Eric Christopher
1731086378597df590e6401abf90d0b5edb09bbaa297Eric Christopher  // If we have integer div support we should have selected this automagically.
1732086378597df590e6401abf90d0b5edb09bbaa297Eric Christopher  // In case we have a real miss go ahead and return false and we'll pick
1733086378597df590e6401abf90d0b5edb09bbaa297Eric Christopher  // it up later.
1734dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher  if (Subtarget->hasDivide()) return false;
1735dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher
1736086378597df590e6401abf90d0b5edb09bbaa297Eric Christopher  // Otherwise emit a libcall.
1737086378597df590e6401abf90d0b5edb09bbaa297Eric Christopher  RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
17387bdc4de4e71e3c9c8d82504b99d03bbec3c06ec3Eric Christopher  if (VT == MVT::i8)
17397ccb30b5964675a70559ec25a6bff32f7dea1025Chad Rosier    LC = isSigned ? RTLIB::SDIV_I8 : RTLIB::UDIV_I8;
17407bdc4de4e71e3c9c8d82504b99d03bbec3c06ec3Eric Christopher  else if (VT == MVT::i16)
17417ccb30b5964675a70559ec25a6bff32f7dea1025Chad Rosier    LC = isSigned ? RTLIB::SDIV_I16 : RTLIB::UDIV_I16;
1742086378597df590e6401abf90d0b5edb09bbaa297Eric Christopher  else if (VT == MVT::i32)
17437ccb30b5964675a70559ec25a6bff32f7dea1025Chad Rosier    LC = isSigned ? RTLIB::SDIV_I32 : RTLIB::UDIV_I32;
1744086378597df590e6401abf90d0b5edb09bbaa297Eric Christopher  else if (VT == MVT::i64)
17457ccb30b5964675a70559ec25a6bff32f7dea1025Chad Rosier    LC = isSigned ? RTLIB::SDIV_I64 : RTLIB::UDIV_I64;
1746086378597df590e6401abf90d0b5edb09bbaa297Eric Christopher  else if (VT == MVT::i128)
17477ccb30b5964675a70559ec25a6bff32f7dea1025Chad Rosier    LC = isSigned ? RTLIB::SDIV_I128 : RTLIB::UDIV_I128;
1748086378597df590e6401abf90d0b5edb09bbaa297Eric Christopher  assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported SDIV!");
1749dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher
1750086378597df590e6401abf90d0b5edb09bbaa297Eric Christopher  return ARMEmitLibcall(I, LC);
1751086378597df590e6401abf90d0b5edb09bbaa297Eric Christopher}
1752086378597df590e6401abf90d0b5edb09bbaa297Eric Christopher
1753769422f0fce4def419c8cdb72ee967437ffd2f4fChad Rosierbool ARMFastISel::SelectRem(const Instruction *I, bool isSigned) {
17541440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands  MVT VT;
1755db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  Type *Ty = I->getType();
17566a880d6ba8e489fc85d18cfbc5f8f6187d438630Eric Christopher  if (!isTypeLegal(Ty, VT))
17576a880d6ba8e489fc85d18cfbc5f8f6187d438630Eric Christopher    return false;
17586a880d6ba8e489fc85d18cfbc5f8f6187d438630Eric Christopher
17596a880d6ba8e489fc85d18cfbc5f8f6187d438630Eric Christopher  RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
17606a880d6ba8e489fc85d18cfbc5f8f6187d438630Eric Christopher  if (VT == MVT::i8)
1761769422f0fce4def419c8cdb72ee967437ffd2f4fChad Rosier    LC = isSigned ? RTLIB::SREM_I8 : RTLIB::UREM_I8;
17626a880d6ba8e489fc85d18cfbc5f8f6187d438630Eric Christopher  else if (VT == MVT::i16)
1763769422f0fce4def419c8cdb72ee967437ffd2f4fChad Rosier    LC = isSigned ? RTLIB::SREM_I16 : RTLIB::UREM_I16;
17646a880d6ba8e489fc85d18cfbc5f8f6187d438630Eric Christopher  else if (VT == MVT::i32)
1765769422f0fce4def419c8cdb72ee967437ffd2f4fChad Rosier    LC = isSigned ? RTLIB::SREM_I32 : RTLIB::UREM_I32;
17666a880d6ba8e489fc85d18cfbc5f8f6187d438630Eric Christopher  else if (VT == MVT::i64)
1767769422f0fce4def419c8cdb72ee967437ffd2f4fChad Rosier    LC = isSigned ? RTLIB::SREM_I64 : RTLIB::UREM_I64;
17686a880d6ba8e489fc85d18cfbc5f8f6187d438630Eric Christopher  else if (VT == MVT::i128)
1769769422f0fce4def419c8cdb72ee967437ffd2f4fChad Rosier    LC = isSigned ? RTLIB::SREM_I128 : RTLIB::UREM_I128;
1770a1640d9ed9e0e9860614944f79a40ae66ecf56fcEric Christopher  assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported SREM!");
17712896df897cc7d1bd3d211f6a8f47081a1a929bb2Eric Christopher
17726a880d6ba8e489fc85d18cfbc5f8f6187d438630Eric Christopher  return ARMEmitLibcall(I, LC);
17736a880d6ba8e489fc85d18cfbc5f8f6187d438630Eric Christopher}
17746a880d6ba8e489fc85d18cfbc5f8f6187d438630Eric Christopher
17753901c3e75009f2ec7b4e67c354170dadab9e5a02Chad Rosierbool ARMFastISel::SelectBinaryIntOp(const Instruction *I, unsigned ISDOpcode) {
17763901c3e75009f2ec7b4e67c354170dadab9e5a02Chad Rosier  EVT DestVT  = TLI.getValueType(I->getType(), true);
17773901c3e75009f2ec7b4e67c354170dadab9e5a02Chad Rosier
17783901c3e75009f2ec7b4e67c354170dadab9e5a02Chad Rosier  // We can get here in the case when we have a binary operation on a non-legal
17793901c3e75009f2ec7b4e67c354170dadab9e5a02Chad Rosier  // type and the target independent selector doesn't know how to handle it.
17803901c3e75009f2ec7b4e67c354170dadab9e5a02Chad Rosier  if (DestVT != MVT::i16 && DestVT != MVT::i8 && DestVT != MVT::i1)
17813901c3e75009f2ec7b4e67c354170dadab9e5a02Chad Rosier    return false;
1782efc967e04459753a588ebf5820e526d790fe1cfaJush Lu
17836fde8756215a725578b6afe678757f60d7f55d06Chad Rosier  unsigned Opc;
17846fde8756215a725578b6afe678757f60d7f55d06Chad Rosier  switch (ISDOpcode) {
17856fde8756215a725578b6afe678757f60d7f55d06Chad Rosier    default: return false;
17866fde8756215a725578b6afe678757f60d7f55d06Chad Rosier    case ISD::ADD:
17876fde8756215a725578b6afe678757f60d7f55d06Chad Rosier      Opc = isThumb2 ? ARM::t2ADDrr : ARM::ADDrr;
17886fde8756215a725578b6afe678757f60d7f55d06Chad Rosier      break;
17896fde8756215a725578b6afe678757f60d7f55d06Chad Rosier    case ISD::OR:
17906fde8756215a725578b6afe678757f60d7f55d06Chad Rosier      Opc = isThumb2 ? ARM::t2ORRrr : ARM::ORRrr;
17916fde8756215a725578b6afe678757f60d7f55d06Chad Rosier      break;
1792743e19983effd486c1911f5b797aea7133ea154cChad Rosier    case ISD::SUB:
1793743e19983effd486c1911f5b797aea7133ea154cChad Rosier      Opc = isThumb2 ? ARM::t2SUBrr : ARM::SUBrr;
1794743e19983effd486c1911f5b797aea7133ea154cChad Rosier      break;
17956fde8756215a725578b6afe678757f60d7f55d06Chad Rosier  }
17966fde8756215a725578b6afe678757f60d7f55d06Chad Rosier
17973901c3e75009f2ec7b4e67c354170dadab9e5a02Chad Rosier  unsigned SrcReg1 = getRegForValue(I->getOperand(0));
17983901c3e75009f2ec7b4e67c354170dadab9e5a02Chad Rosier  if (SrcReg1 == 0) return false;
17993901c3e75009f2ec7b4e67c354170dadab9e5a02Chad Rosier
18003901c3e75009f2ec7b4e67c354170dadab9e5a02Chad Rosier  // TODO: Often the 2nd operand is an immediate, which can be encoded directly
18013901c3e75009f2ec7b4e67c354170dadab9e5a02Chad Rosier  // in the instruction, rather then materializing the value in a register.
18023901c3e75009f2ec7b4e67c354170dadab9e5a02Chad Rosier  unsigned SrcReg2 = getRegForValue(I->getOperand(1));
18033901c3e75009f2ec7b4e67c354170dadab9e5a02Chad Rosier  if (SrcReg2 == 0) return false;
18043901c3e75009f2ec7b4e67c354170dadab9e5a02Chad Rosier
18053901c3e75009f2ec7b4e67c354170dadab9e5a02Chad Rosier  unsigned ResultReg = createResultReg(TLI.getRegClassFor(MVT::i32));
18063901c3e75009f2ec7b4e67c354170dadab9e5a02Chad Rosier  AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
18073901c3e75009f2ec7b4e67c354170dadab9e5a02Chad Rosier                          TII.get(Opc), ResultReg)
18083901c3e75009f2ec7b4e67c354170dadab9e5a02Chad Rosier                  .addReg(SrcReg1).addReg(SrcReg2));
18093901c3e75009f2ec7b4e67c354170dadab9e5a02Chad Rosier  UpdateValueMap(I, ResultReg);
18103901c3e75009f2ec7b4e67c354170dadab9e5a02Chad Rosier  return true;
18113901c3e75009f2ec7b4e67c354170dadab9e5a02Chad Rosier}
18123901c3e75009f2ec7b4e67c354170dadab9e5a02Chad Rosier
18133901c3e75009f2ec7b4e67c354170dadab9e5a02Chad Rosierbool ARMFastISel::SelectBinaryFPOp(const Instruction *I, unsigned ISDOpcode) {
1814316a5aa0a510e6183dd1981dd8bf328ffe7361f5Chad Rosier  EVT FPVT = TLI.getValueType(I->getType(), true);
1815316a5aa0a510e6183dd1981dd8bf328ffe7361f5Chad Rosier  if (!FPVT.isSimple()) return false;
1816316a5aa0a510e6183dd1981dd8bf328ffe7361f5Chad Rosier  MVT VT = FPVT.getSimpleVT();
1817ac1a19e18ad73198ae54cc4bc08000523031f84aEric Christopher
1818bc39b829f2a1f1f0ce3cfe7f9dd99c3402ad2e62Eric Christopher  // We can get here in the case when we want to use NEON for our fp
1819bc39b829f2a1f1f0ce3cfe7f9dd99c3402ad2e62Eric Christopher  // operations, but can't figure out how to. Just use the vfp instructions
1820bc39b829f2a1f1f0ce3cfe7f9dd99c3402ad2e62Eric Christopher  // if we have them.
1821bc39b829f2a1f1f0ce3cfe7f9dd99c3402ad2e62Eric Christopher  // FIXME: It'd be nice to use NEON instructions.
1822db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  Type *Ty = I->getType();
1823bd6bf0848ee651a3cf4ea868b7a7605e37b4e028Eric Christopher  bool isFloat = (Ty->isDoubleTy() || Ty->isFloatTy());
1824bd6bf0848ee651a3cf4ea868b7a7605e37b4e028Eric Christopher  if (isFloat && !Subtarget->hasVFP2())
1825bd6bf0848ee651a3cf4ea868b7a7605e37b4e028Eric Christopher    return false;
1826ac1a19e18ad73198ae54cc4bc08000523031f84aEric Christopher
1827bc39b829f2a1f1f0ce3cfe7f9dd99c3402ad2e62Eric Christopher  unsigned Opc;
1828cdfad36b401be6fc709ea4051f9de58e1a30bcc9Duncan Sands  bool is64bit = VT == MVT::f64 || VT == MVT::i64;
1829bc39b829f2a1f1f0ce3cfe7f9dd99c3402ad2e62Eric Christopher  switch (ISDOpcode) {
1830bc39b829f2a1f1f0ce3cfe7f9dd99c3402ad2e62Eric Christopher    default: return false;
1831bc39b829f2a1f1f0ce3cfe7f9dd99c3402ad2e62Eric Christopher    case ISD::FADD:
1832bd6bf0848ee651a3cf4ea868b7a7605e37b4e028Eric Christopher      Opc = is64bit ? ARM::VADDD : ARM::VADDS;
1833bc39b829f2a1f1f0ce3cfe7f9dd99c3402ad2e62Eric Christopher      break;
1834bc39b829f2a1f1f0ce3cfe7f9dd99c3402ad2e62Eric Christopher    case ISD::FSUB:
1835bd6bf0848ee651a3cf4ea868b7a7605e37b4e028Eric Christopher      Opc = is64bit ? ARM::VSUBD : ARM::VSUBS;
1836bc39b829f2a1f1f0ce3cfe7f9dd99c3402ad2e62Eric Christopher      break;
1837bc39b829f2a1f1f0ce3cfe7f9dd99c3402ad2e62Eric Christopher    case ISD::FMUL:
1838bd6bf0848ee651a3cf4ea868b7a7605e37b4e028Eric Christopher      Opc = is64bit ? ARM::VMULD : ARM::VMULS;
1839bc39b829f2a1f1f0ce3cfe7f9dd99c3402ad2e62Eric Christopher      break;
1840bc39b829f2a1f1f0ce3cfe7f9dd99c3402ad2e62Eric Christopher  }
1841508a1f4db16baea5c0d5b1c4797d005dff1ee30fChad Rosier  unsigned Op1 = getRegForValue(I->getOperand(0));
1842508a1f4db16baea5c0d5b1c4797d005dff1ee30fChad Rosier  if (Op1 == 0) return false;
1843508a1f4db16baea5c0d5b1c4797d005dff1ee30fChad Rosier
1844508a1f4db16baea5c0d5b1c4797d005dff1ee30fChad Rosier  unsigned Op2 = getRegForValue(I->getOperand(1));
1845508a1f4db16baea5c0d5b1c4797d005dff1ee30fChad Rosier  if (Op2 == 0) return false;
1846508a1f4db16baea5c0d5b1c4797d005dff1ee30fChad Rosier
1847316a5aa0a510e6183dd1981dd8bf328ffe7361f5Chad Rosier  unsigned ResultReg = createResultReg(TLI.getRegClassFor(VT.SimpleTy));
1848bc39b829f2a1f1f0ce3cfe7f9dd99c3402ad2e62Eric Christopher  AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
1849bc39b829f2a1f1f0ce3cfe7f9dd99c3402ad2e62Eric Christopher                          TII.get(Opc), ResultReg)
1850bc39b829f2a1f1f0ce3cfe7f9dd99c3402ad2e62Eric Christopher                  .addReg(Op1).addReg(Op2));
1851ce07b5458d87d5f5ad306a1d86785537e9a3ce0cEric Christopher  UpdateValueMap(I, ResultReg);
1852bc39b829f2a1f1f0ce3cfe7f9dd99c3402ad2e62Eric Christopher  return true;
1853bc39b829f2a1f1f0ce3cfe7f9dd99c3402ad2e62Eric Christopher}
1854bc39b829f2a1f1f0ce3cfe7f9dd99c3402ad2e62Eric Christopher
1855d10cd7b31464a73e3a19b9fada80b9567b04d314Eric Christopher// Call Handling Code
1856d10cd7b31464a73e3a19b9fada80b9567b04d314Eric Christopher
1857ee649839a243bb29b59b322203b982b2f132e7c5Jush Lu// This is largely taken directly from CCAssignFnForNode
1858d10cd7b31464a73e3a19b9fada80b9567b04d314Eric Christopher// TODO: We may not support all of this.
1859ee649839a243bb29b59b322203b982b2f132e7c5Jush LuCCAssignFn *ARMFastISel::CCAssignFnForCall(CallingConv::ID CC,
1860ee649839a243bb29b59b322203b982b2f132e7c5Jush Lu                                           bool Return,
1861ee649839a243bb29b59b322203b982b2f132e7c5Jush Lu                                           bool isVarArg) {
1862d10cd7b31464a73e3a19b9fada80b9567b04d314Eric Christopher  switch (CC) {
1863d10cd7b31464a73e3a19b9fada80b9567b04d314Eric Christopher  default:
1864d10cd7b31464a73e3a19b9fada80b9567b04d314Eric Christopher    llvm_unreachable("Unsupported calling convention");
1865d10cd7b31464a73e3a19b9fada80b9567b04d314Eric Christopher  case CallingConv::Fast:
18662ff4e9d5afa2074b91940a601fba0a0c154f6a83Jush Lu    if (Subtarget->hasVFP2() && !isVarArg) {
18672ff4e9d5afa2074b91940a601fba0a0c154f6a83Jush Lu      if (!Subtarget->isAAPCS_ABI())
18682ff4e9d5afa2074b91940a601fba0a0c154f6a83Jush Lu        return (Return ? RetFastCC_ARM_APCS : FastCC_ARM_APCS);
18692ff4e9d5afa2074b91940a601fba0a0c154f6a83Jush Lu      // For AAPCS ABI targets, just use VFP variant of the calling convention.
18702ff4e9d5afa2074b91940a601fba0a0c154f6a83Jush Lu      return (Return ? RetCC_ARM_AAPCS_VFP : CC_ARM_AAPCS_VFP);
18712ff4e9d5afa2074b91940a601fba0a0c154f6a83Jush Lu    }
18721f8b40d51c0e1bb7fce5a69c2fadc656bfef3092Evan Cheng    // Fallthrough
18731f8b40d51c0e1bb7fce5a69c2fadc656bfef3092Evan Cheng  case CallingConv::C:
1874d10cd7b31464a73e3a19b9fada80b9567b04d314Eric Christopher    // Use target triple & subtarget features to do actual dispatch.
1875d10cd7b31464a73e3a19b9fada80b9567b04d314Eric Christopher    if (Subtarget->isAAPCS_ABI()) {
1876d10cd7b31464a73e3a19b9fada80b9567b04d314Eric Christopher      if (Subtarget->hasVFP2() &&
1877ee649839a243bb29b59b322203b982b2f132e7c5Jush Lu          TM.Options.FloatABIType == FloatABI::Hard && !isVarArg)
1878d10cd7b31464a73e3a19b9fada80b9567b04d314Eric Christopher        return (Return ? RetCC_ARM_AAPCS_VFP: CC_ARM_AAPCS_VFP);
1879d10cd7b31464a73e3a19b9fada80b9567b04d314Eric Christopher      else
1880d10cd7b31464a73e3a19b9fada80b9567b04d314Eric Christopher        return (Return ? RetCC_ARM_AAPCS: CC_ARM_AAPCS);
1881d10cd7b31464a73e3a19b9fada80b9567b04d314Eric Christopher    } else
1882d10cd7b31464a73e3a19b9fada80b9567b04d314Eric Christopher        return (Return ? RetCC_ARM_APCS: CC_ARM_APCS);
1883d10cd7b31464a73e3a19b9fada80b9567b04d314Eric Christopher  case CallingConv::ARM_AAPCS_VFP:
1884ee649839a243bb29b59b322203b982b2f132e7c5Jush Lu    if (!isVarArg)
1885ee649839a243bb29b59b322203b982b2f132e7c5Jush Lu      return (Return ? RetCC_ARM_AAPCS_VFP: CC_ARM_AAPCS_VFP);
1886ee649839a243bb29b59b322203b982b2f132e7c5Jush Lu    // Fall through to soft float variant, variadic functions don't
1887ee649839a243bb29b59b322203b982b2f132e7c5Jush Lu    // use hard floating point ABI.
1888d10cd7b31464a73e3a19b9fada80b9567b04d314Eric Christopher  case CallingConv::ARM_AAPCS:
1889d10cd7b31464a73e3a19b9fada80b9567b04d314Eric Christopher    return (Return ? RetCC_ARM_AAPCS: CC_ARM_AAPCS);
1890d10cd7b31464a73e3a19b9fada80b9567b04d314Eric Christopher  case CallingConv::ARM_APCS:
1891d10cd7b31464a73e3a19b9fada80b9567b04d314Eric Christopher    return (Return ? RetCC_ARM_APCS: CC_ARM_APCS);
1892e94ac8871a1ac79bece57335d2abece0feed9c02Eric Christopher  case CallingConv::GHC:
1893e94ac8871a1ac79bece57335d2abece0feed9c02Eric Christopher    if (Return)
1894e94ac8871a1ac79bece57335d2abece0feed9c02Eric Christopher      llvm_unreachable("Can't return in GHC call convention");
1895e94ac8871a1ac79bece57335d2abece0feed9c02Eric Christopher    else
1896e94ac8871a1ac79bece57335d2abece0feed9c02Eric Christopher      return CC_ARM_APCS_GHC;
1897d10cd7b31464a73e3a19b9fada80b9567b04d314Eric Christopher  }
1898d10cd7b31464a73e3a19b9fada80b9567b04d314Eric Christopher}
1899d10cd7b31464a73e3a19b9fada80b9567b04d314Eric Christopher
1900a9a7a1a9a557cc03d1fed6cba3f27520be5274c0Eric Christopherbool ARMFastISel::ProcessCallArgs(SmallVectorImpl<Value*> &Args,
1901a9a7a1a9a557cc03d1fed6cba3f27520be5274c0Eric Christopher                                  SmallVectorImpl<unsigned> &ArgRegs,
19021440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands                                  SmallVectorImpl<MVT> &ArgVTs,
1903a9a7a1a9a557cc03d1fed6cba3f27520be5274c0Eric Christopher                                  SmallVectorImpl<ISD::ArgFlagsTy> &ArgFlags,
1904a9a7a1a9a557cc03d1fed6cba3f27520be5274c0Eric Christopher                                  SmallVectorImpl<unsigned> &RegArgs,
1905a9a7a1a9a557cc03d1fed6cba3f27520be5274c0Eric Christopher                                  CallingConv::ID CC,
1906ee649839a243bb29b59b322203b982b2f132e7c5Jush Lu                                  unsigned &NumBytes,
1907ee649839a243bb29b59b322203b982b2f132e7c5Jush Lu                                  bool isVarArg) {
1908a9a7a1a9a557cc03d1fed6cba3f27520be5274c0Eric Christopher  SmallVector<CCValAssign, 16> ArgLocs;
1909ee649839a243bb29b59b322203b982b2f132e7c5Jush Lu  CCState CCInfo(CC, isVarArg, *FuncInfo.MF, TM, ArgLocs, *Context);
1910ee649839a243bb29b59b322203b982b2f132e7c5Jush Lu  CCInfo.AnalyzeCallOperands(ArgVTs, ArgFlags,
1911ee649839a243bb29b59b322203b982b2f132e7c5Jush Lu                             CCAssignFnForCall(CC, false, isVarArg));
1912a9a7a1a9a557cc03d1fed6cba3f27520be5274c0Eric Christopher
19135aeff3171c173dec9a6e6f89e428a0a78698c43eBill Wendling  // Check that we can handle all of the arguments. If we can't, then bail out
19145aeff3171c173dec9a6e6f89e428a0a78698c43eBill Wendling  // now before we add code to the MBB.
19155aeff3171c173dec9a6e6f89e428a0a78698c43eBill Wendling  for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
19165aeff3171c173dec9a6e6f89e428a0a78698c43eBill Wendling    CCValAssign &VA = ArgLocs[i];
19175aeff3171c173dec9a6e6f89e428a0a78698c43eBill Wendling    MVT ArgVT = ArgVTs[VA.getValNo()];
19185aeff3171c173dec9a6e6f89e428a0a78698c43eBill Wendling
19195aeff3171c173dec9a6e6f89e428a0a78698c43eBill Wendling    // We don't handle NEON/vector parameters yet.
19205aeff3171c173dec9a6e6f89e428a0a78698c43eBill Wendling    if (ArgVT.isVector() || ArgVT.getSizeInBits() > 64)
19215aeff3171c173dec9a6e6f89e428a0a78698c43eBill Wendling      return false;
19225aeff3171c173dec9a6e6f89e428a0a78698c43eBill Wendling
19235aeff3171c173dec9a6e6f89e428a0a78698c43eBill Wendling    // Now copy/store arg to correct locations.
19245aeff3171c173dec9a6e6f89e428a0a78698c43eBill Wendling    if (VA.isRegLoc() && !VA.needsCustom()) {
19255aeff3171c173dec9a6e6f89e428a0a78698c43eBill Wendling      continue;
19265aeff3171c173dec9a6e6f89e428a0a78698c43eBill Wendling    } else if (VA.needsCustom()) {
19275aeff3171c173dec9a6e6f89e428a0a78698c43eBill Wendling      // TODO: We need custom lowering for vector (v2f64) args.
19285aeff3171c173dec9a6e6f89e428a0a78698c43eBill Wendling      if (VA.getLocVT() != MVT::f64 ||
19295aeff3171c173dec9a6e6f89e428a0a78698c43eBill Wendling          // TODO: Only handle register args for now.
19305aeff3171c173dec9a6e6f89e428a0a78698c43eBill Wendling          !VA.isRegLoc() || !ArgLocs[++i].isRegLoc())
19315aeff3171c173dec9a6e6f89e428a0a78698c43eBill Wendling        return false;
19325aeff3171c173dec9a6e6f89e428a0a78698c43eBill Wendling    } else {
19335aeff3171c173dec9a6e6f89e428a0a78698c43eBill Wendling      switch (static_cast<EVT>(ArgVT).getSimpleVT().SimpleTy) {
19345aeff3171c173dec9a6e6f89e428a0a78698c43eBill Wendling      default:
19355aeff3171c173dec9a6e6f89e428a0a78698c43eBill Wendling        return false;
19365aeff3171c173dec9a6e6f89e428a0a78698c43eBill Wendling      case MVT::i1:
19375aeff3171c173dec9a6e6f89e428a0a78698c43eBill Wendling      case MVT::i8:
19385aeff3171c173dec9a6e6f89e428a0a78698c43eBill Wendling      case MVT::i16:
19395aeff3171c173dec9a6e6f89e428a0a78698c43eBill Wendling      case MVT::i32:
19405aeff3171c173dec9a6e6f89e428a0a78698c43eBill Wendling        break;
19415aeff3171c173dec9a6e6f89e428a0a78698c43eBill Wendling      case MVT::f32:
19425aeff3171c173dec9a6e6f89e428a0a78698c43eBill Wendling        if (!Subtarget->hasVFP2())
19435aeff3171c173dec9a6e6f89e428a0a78698c43eBill Wendling          return false;
19445aeff3171c173dec9a6e6f89e428a0a78698c43eBill Wendling        break;
19455aeff3171c173dec9a6e6f89e428a0a78698c43eBill Wendling      case MVT::f64:
19465aeff3171c173dec9a6e6f89e428a0a78698c43eBill Wendling        if (!Subtarget->hasVFP2())
19475aeff3171c173dec9a6e6f89e428a0a78698c43eBill Wendling          return false;
19485aeff3171c173dec9a6e6f89e428a0a78698c43eBill Wendling        break;
19495aeff3171c173dec9a6e6f89e428a0a78698c43eBill Wendling      }
19505aeff3171c173dec9a6e6f89e428a0a78698c43eBill Wendling    }
19515aeff3171c173dec9a6e6f89e428a0a78698c43eBill Wendling  }
19525aeff3171c173dec9a6e6f89e428a0a78698c43eBill Wendling
19535aeff3171c173dec9a6e6f89e428a0a78698c43eBill Wendling  // At the point, we are able to handle the call's arguments in fast isel.
19545aeff3171c173dec9a6e6f89e428a0a78698c43eBill Wendling
1955a9a7a1a9a557cc03d1fed6cba3f27520be5274c0Eric Christopher  // Get a count of how many bytes are to be pushed on the stack.
1956a9a7a1a9a557cc03d1fed6cba3f27520be5274c0Eric Christopher  NumBytes = CCInfo.getNextStackOffset();
1957a9a7a1a9a557cc03d1fed6cba3f27520be5274c0Eric Christopher
1958a9a7a1a9a557cc03d1fed6cba3f27520be5274c0Eric Christopher  // Issue CALLSEQ_START
1959d5b03f252c0db6b49a242abab63d7c5a260fceaeEvan Cheng  unsigned AdjStackDown = TII.getCallFrameSetupOpcode();
1960fb0b892f7ebee68760645dd220f88bd9177cf2e4Eric Christopher  AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
1961fb0b892f7ebee68760645dd220f88bd9177cf2e4Eric Christopher                          TII.get(AdjStackDown))
1962fb0b892f7ebee68760645dd220f88bd9177cf2e4Eric Christopher                  .addImm(NumBytes));
1963a9a7a1a9a557cc03d1fed6cba3f27520be5274c0Eric Christopher
1964a9a7a1a9a557cc03d1fed6cba3f27520be5274c0Eric Christopher  // Process the args.
1965a9a7a1a9a557cc03d1fed6cba3f27520be5274c0Eric Christopher  for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
1966a9a7a1a9a557cc03d1fed6cba3f27520be5274c0Eric Christopher    CCValAssign &VA = ArgLocs[i];
1967a9a7a1a9a557cc03d1fed6cba3f27520be5274c0Eric Christopher    unsigned Arg = ArgRegs[VA.getValNo()];
19681440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands    MVT ArgVT = ArgVTs[VA.getValNo()];
1969a9a7a1a9a557cc03d1fed6cba3f27520be5274c0Eric Christopher
19705aeff3171c173dec9a6e6f89e428a0a78698c43eBill Wendling    assert((!ArgVT.isVector() && ArgVT.getSizeInBits() <= 64) &&
19715aeff3171c173dec9a6e6f89e428a0a78698c43eBill Wendling           "We don't handle NEON/vector parameters yet.");
1972a4633f5d7458f4d04e4bf89be48d3b14e1fae044Eric Christopher
1973f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher    // Handle arg promotion, etc.
1974a9a7a1a9a557cc03d1fed6cba3f27520be5274c0Eric Christopher    switch (VA.getLocInfo()) {
1975a9a7a1a9a557cc03d1fed6cba3f27520be5274c0Eric Christopher      case CCValAssign::Full: break;
1976fa87d6675212d5ca04725b7e541156f58c4ab40bEric Christopher      case CCValAssign::SExt: {
1977b74c865841481074539bdf4de35024939854f2e6Chad Rosier        MVT DestVT = VA.getLocVT();
19785793a6586d94a5032a815af97113c3ba47cbdf8aChad Rosier        Arg = ARMEmitIntExt(ArgVT, Arg, DestVT, /*isZExt*/false);
19795793a6586d94a5032a815af97113c3ba47cbdf8aChad Rosier        assert (Arg != 0 && "Failed to emit a sext");
1980b74c865841481074539bdf4de35024939854f2e6Chad Rosier        ArgVT = DestVT;
1981fa87d6675212d5ca04725b7e541156f58c4ab40bEric Christopher        break;
1982fa87d6675212d5ca04725b7e541156f58c4ab40bEric Christopher      }
198342536af5ce152593f489ca88bd0732218594d536Chad Rosier      case CCValAssign::AExt:
198442536af5ce152593f489ca88bd0732218594d536Chad Rosier        // Intentional fall-through.  Handle AExt and ZExt.
1985fa87d6675212d5ca04725b7e541156f58c4ab40bEric Christopher      case CCValAssign::ZExt: {
1986b74c865841481074539bdf4de35024939854f2e6Chad Rosier        MVT DestVT = VA.getLocVT();
19875793a6586d94a5032a815af97113c3ba47cbdf8aChad Rosier        Arg = ARMEmitIntExt(ArgVT, Arg, DestVT, /*isZExt*/true);
19885793a6586d94a5032a815af97113c3ba47cbdf8aChad Rosier        assert (Arg != 0 && "Failed to emit a sext");
1989b74c865841481074539bdf4de35024939854f2e6Chad Rosier        ArgVT = DestVT;
1990fa87d6675212d5ca04725b7e541156f58c4ab40bEric Christopher        break;
1991fa87d6675212d5ca04725b7e541156f58c4ab40bEric Christopher      }
1992fa87d6675212d5ca04725b7e541156f58c4ab40bEric Christopher      case CCValAssign::BCvt: {
1993bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck        unsigned BC = FastEmit_r(ArgVT, VA.getLocVT(), ISD::BITCAST, Arg,
19941440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands                                 /*TODO: Kill=*/false);
1995fa87d6675212d5ca04725b7e541156f58c4ab40bEric Christopher        assert(BC != 0 && "Failed to emit a bitcast!");
1996fa87d6675212d5ca04725b7e541156f58c4ab40bEric Christopher        Arg = BC;
1997fa87d6675212d5ca04725b7e541156f58c4ab40bEric Christopher        ArgVT = VA.getLocVT();
1998fa87d6675212d5ca04725b7e541156f58c4ab40bEric Christopher        break;
1999fa87d6675212d5ca04725b7e541156f58c4ab40bEric Christopher      }
2000fa87d6675212d5ca04725b7e541156f58c4ab40bEric Christopher      default: llvm_unreachable("Unknown arg promotion!");
2001a9a7a1a9a557cc03d1fed6cba3f27520be5274c0Eric Christopher    }
2002a9a7a1a9a557cc03d1fed6cba3f27520be5274c0Eric Christopher
2003a9a7a1a9a557cc03d1fed6cba3f27520be5274c0Eric Christopher    // Now copy/store arg to correct locations.
2004fb0b892f7ebee68760645dd220f88bd9177cf2e4Eric Christopher    if (VA.isRegLoc() && !VA.needsCustom()) {
2005a9a7a1a9a557cc03d1fed6cba3f27520be5274c0Eric Christopher      BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(TargetOpcode::COPY),
2006f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher              VA.getLocReg())
200742536af5ce152593f489ca88bd0732218594d536Chad Rosier        .addReg(Arg);
2008a9a7a1a9a557cc03d1fed6cba3f27520be5274c0Eric Christopher      RegArgs.push_back(VA.getLocReg());
20092d8f6fe610fa859370c38cfbe38ff809a3a417deEric Christopher    } else if (VA.needsCustom()) {
20102d8f6fe610fa859370c38cfbe38ff809a3a417deEric Christopher      // TODO: We need custom lowering for vector (v2f64) args.
20115aeff3171c173dec9a6e6f89e428a0a78698c43eBill Wendling      assert(VA.getLocVT() == MVT::f64 &&
20125aeff3171c173dec9a6e6f89e428a0a78698c43eBill Wendling             "Custom lowering for v2f64 args not available");
20136b15639e267575a2c95f89d6b266e0fcd9231d91Jim Grosbach
20142d8f6fe610fa859370c38cfbe38ff809a3a417deEric Christopher      CCValAssign &NextVA = ArgLocs[++i];
20152d8f6fe610fa859370c38cfbe38ff809a3a417deEric Christopher
20165aeff3171c173dec9a6e6f89e428a0a78698c43eBill Wendling      assert(VA.isRegLoc() && NextVA.isRegLoc() &&
20175aeff3171c173dec9a6e6f89e428a0a78698c43eBill Wendling             "We only handle register args!");
20182d8f6fe610fa859370c38cfbe38ff809a3a417deEric Christopher
20192d8f6fe610fa859370c38cfbe38ff809a3a417deEric Christopher      AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
20202d8f6fe610fa859370c38cfbe38ff809a3a417deEric Christopher                              TII.get(ARM::VMOVRRD), VA.getLocReg())
20212d8f6fe610fa859370c38cfbe38ff809a3a417deEric Christopher                      .addReg(NextVA.getLocReg(), RegState::Define)
20222d8f6fe610fa859370c38cfbe38ff809a3a417deEric Christopher                      .addReg(Arg));
20232d8f6fe610fa859370c38cfbe38ff809a3a417deEric Christopher      RegArgs.push_back(VA.getLocReg());
20242d8f6fe610fa859370c38cfbe38ff809a3a417deEric Christopher      RegArgs.push_back(NextVA.getLocReg());
2025a9a7a1a9a557cc03d1fed6cba3f27520be5274c0Eric Christopher    } else {
20265b924809e4a62ddc0221cd355e834ecec22bbf40Eric Christopher      assert(VA.isMemLoc());
20275b924809e4a62ddc0221cd355e834ecec22bbf40Eric Christopher      // Need to store on the stack.
20280d58122e1221665d421a53741ef638505ecbe745Eric Christopher      Address Addr;
20290d58122e1221665d421a53741ef638505ecbe745Eric Christopher      Addr.BaseType = Address::RegBase;
20300d58122e1221665d421a53741ef638505ecbe745Eric Christopher      Addr.Base.Reg = ARM::SP;
20310d58122e1221665d421a53741ef638505ecbe745Eric Christopher      Addr.Offset = VA.getLocMemOffset();
20325b924809e4a62ddc0221cd355e834ecec22bbf40Eric Christopher
20335aeff3171c173dec9a6e6f89e428a0a78698c43eBill Wendling      bool EmitRet = ARMEmitStore(ArgVT, Arg, Addr); (void)EmitRet;
20345aeff3171c173dec9a6e6f89e428a0a78698c43eBill Wendling      assert(EmitRet && "Could not emit a store for argument!");
2035a9a7a1a9a557cc03d1fed6cba3f27520be5274c0Eric Christopher    }
2036a9a7a1a9a557cc03d1fed6cba3f27520be5274c0Eric Christopher  }
20375aeff3171c173dec9a6e6f89e428a0a78698c43eBill Wendling
2038a9a7a1a9a557cc03d1fed6cba3f27520be5274c0Eric Christopher  return true;
2039a9a7a1a9a557cc03d1fed6cba3f27520be5274c0Eric Christopher}
2040a9a7a1a9a557cc03d1fed6cba3f27520be5274c0Eric Christopher
20411440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sandsbool ARMFastISel::FinishCall(MVT RetVT, SmallVectorImpl<unsigned> &UsedRegs,
2042a9a7a1a9a557cc03d1fed6cba3f27520be5274c0Eric Christopher                             const Instruction *I, CallingConv::ID CC,
2043ee649839a243bb29b59b322203b982b2f132e7c5Jush Lu                             unsigned &NumBytes, bool isVarArg) {
2044a9a7a1a9a557cc03d1fed6cba3f27520be5274c0Eric Christopher  // Issue CALLSEQ_END
2045d5b03f252c0db6b49a242abab63d7c5a260fceaeEvan Cheng  unsigned AdjStackUp = TII.getCallFrameDestroyOpcode();
2046fb0b892f7ebee68760645dd220f88bd9177cf2e4Eric Christopher  AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
2047fb0b892f7ebee68760645dd220f88bd9177cf2e4Eric Christopher                          TII.get(AdjStackUp))
2048fb0b892f7ebee68760645dd220f88bd9177cf2e4Eric Christopher                  .addImm(NumBytes).addImm(0));
2049a9a7a1a9a557cc03d1fed6cba3f27520be5274c0Eric Christopher
2050a9a7a1a9a557cc03d1fed6cba3f27520be5274c0Eric Christopher  // Now the return value.
20511440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands  if (RetVT != MVT::isVoid) {
2052a9a7a1a9a557cc03d1fed6cba3f27520be5274c0Eric Christopher    SmallVector<CCValAssign, 16> RVLocs;
2053ee649839a243bb29b59b322203b982b2f132e7c5Jush Lu    CCState CCInfo(CC, isVarArg, *FuncInfo.MF, TM, RVLocs, *Context);
2054ee649839a243bb29b59b322203b982b2f132e7c5Jush Lu    CCInfo.AnalyzeCallResult(RetVT, CCAssignFnForCall(CC, true, isVarArg));
2055a9a7a1a9a557cc03d1fed6cba3f27520be5274c0Eric Christopher
2056a9a7a1a9a557cc03d1fed6cba3f27520be5274c0Eric Christopher    // Copy all of the result registers out of their specified physreg.
20571440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands    if (RVLocs.size() == 2 && RetVT == MVT::f64) {
205814df88282bf897403db6ac1dc20ad01a0ae79835Eric Christopher      // For this move we copy into two registers and then move into the
205914df88282bf897403db6ac1dc20ad01a0ae79835Eric Christopher      // double fp reg we want.
2060a61b17c18a67f1b3faef2f2108379c4337ce9bb7Patrik Hagglund      MVT DestVT = RVLocs[0].getValVT();
206144d23825d61d530b8d562329ec8fc2d4f843bb8dCraig Topper      const TargetRegisterClass* DstRC = TLI.getRegClassFor(DestVT);
206214df88282bf897403db6ac1dc20ad01a0ae79835Eric Christopher      unsigned ResultReg = createResultReg(DstRC);
206314df88282bf897403db6ac1dc20ad01a0ae79835Eric Christopher      AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
206414df88282bf897403db6ac1dc20ad01a0ae79835Eric Christopher                              TII.get(ARM::VMOVDRR), ResultReg)
20653659ac22c0dcb64d69aa9b80d9979caf0cab2e4fEric Christopher                      .addReg(RVLocs[0].getLocReg())
20663659ac22c0dcb64d69aa9b80d9979caf0cab2e4fEric Christopher                      .addReg(RVLocs[1].getLocReg()));
2067dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher
20683659ac22c0dcb64d69aa9b80d9979caf0cab2e4fEric Christopher      UsedRegs.push_back(RVLocs[0].getLocReg());
20693659ac22c0dcb64d69aa9b80d9979caf0cab2e4fEric Christopher      UsedRegs.push_back(RVLocs[1].getLocReg());
20706b15639e267575a2c95f89d6b266e0fcd9231d91Jim Grosbach
2071dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher      // Finally update the result.
207214df88282bf897403db6ac1dc20ad01a0ae79835Eric Christopher      UpdateValueMap(I, ResultReg);
20732a2e9d54e95f01eaa5626dcdf57950e9e6f95f2cChad Rosier    } else {
20742a2e9d54e95f01eaa5626dcdf57950e9e6f95f2cChad Rosier      assert(RVLocs.size() == 1 &&"Can't handle non-double multi-reg retvals!");
2075a61b17c18a67f1b3faef2f2108379c4337ce9bb7Patrik Hagglund      MVT CopyVT = RVLocs[0].getValVT();
20760eff39f2e25e9d8dd52b1eb7fa4e7cc6cc77875fChad Rosier
20770eff39f2e25e9d8dd52b1eb7fa4e7cc6cc77875fChad Rosier      // Special handling for extended integers.
20780eff39f2e25e9d8dd52b1eb7fa4e7cc6cc77875fChad Rosier      if (RetVT == MVT::i1 || RetVT == MVT::i8 || RetVT == MVT::i16)
20790eff39f2e25e9d8dd52b1eb7fa4e7cc6cc77875fChad Rosier        CopyVT = MVT::i32;
20800eff39f2e25e9d8dd52b1eb7fa4e7cc6cc77875fChad Rosier
208144d23825d61d530b8d562329ec8fc2d4f843bb8dCraig Topper      const TargetRegisterClass* DstRC = TLI.getRegClassFor(CopyVT);
2082a9a7a1a9a557cc03d1fed6cba3f27520be5274c0Eric Christopher
208314df88282bf897403db6ac1dc20ad01a0ae79835Eric Christopher      unsigned ResultReg = createResultReg(DstRC);
208414df88282bf897403db6ac1dc20ad01a0ae79835Eric Christopher      BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(TargetOpcode::COPY),
208514df88282bf897403db6ac1dc20ad01a0ae79835Eric Christopher              ResultReg).addReg(RVLocs[0].getLocReg());
208614df88282bf897403db6ac1dc20ad01a0ae79835Eric Christopher      UsedRegs.push_back(RVLocs[0].getLocReg());
2087a9a7a1a9a557cc03d1fed6cba3f27520be5274c0Eric Christopher
2088dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher      // Finally update the result.
208914df88282bf897403db6ac1dc20ad01a0ae79835Eric Christopher      UpdateValueMap(I, ResultReg);
209014df88282bf897403db6ac1dc20ad01a0ae79835Eric Christopher    }
2091a9a7a1a9a557cc03d1fed6cba3f27520be5274c0Eric Christopher  }
2092a9a7a1a9a557cc03d1fed6cba3f27520be5274c0Eric Christopher
2093dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher  return true;
2094a9a7a1a9a557cc03d1fed6cba3f27520be5274c0Eric Christopher}
2095a9a7a1a9a557cc03d1fed6cba3f27520be5274c0Eric Christopher
20964f512efee9198eb38bf190b0c3fe50429a065d15Eric Christopherbool ARMFastISel::SelectRet(const Instruction *I) {
20974f512efee9198eb38bf190b0c3fe50429a065d15Eric Christopher  const ReturnInst *Ret = cast<ReturnInst>(I);
20984f512efee9198eb38bf190b0c3fe50429a065d15Eric Christopher  const Function &F = *I->getParent()->getParent();
20996b15639e267575a2c95f89d6b266e0fcd9231d91Jim Grosbach
21004f512efee9198eb38bf190b0c3fe50429a065d15Eric Christopher  if (!FuncInfo.CanLowerReturn)
21014f512efee9198eb38bf190b0c3fe50429a065d15Eric Christopher    return false;
21026b15639e267575a2c95f89d6b266e0fcd9231d91Jim Grosbach
2103fc7432744476281511704c7e07bf89e20c215601Jakob Stoklund Olesen  // Build a list of return value registers.
2104fc7432744476281511704c7e07bf89e20c215601Jakob Stoklund Olesen  SmallVector<unsigned, 4> RetRegs;
2105fc7432744476281511704c7e07bf89e20c215601Jakob Stoklund Olesen
21064f512efee9198eb38bf190b0c3fe50429a065d15Eric Christopher  CallingConv::ID CC = F.getCallingConv();
21074f512efee9198eb38bf190b0c3fe50429a065d15Eric Christopher  if (Ret->getNumOperands() > 0) {
21084f512efee9198eb38bf190b0c3fe50429a065d15Eric Christopher    SmallVector<ISD::OutputArg, 4> Outs;
21098b62abdd7b9c8fc5d78dad86093f4afdfeba949dBill Wendling    GetReturnInfo(F.getReturnType(), F.getAttributes(), Outs, TLI);
21104f512efee9198eb38bf190b0c3fe50429a065d15Eric Christopher
21114f512efee9198eb38bf190b0c3fe50429a065d15Eric Christopher    // Analyze operands of the call, assigning locations to each operand.
21124f512efee9198eb38bf190b0c3fe50429a065d15Eric Christopher    SmallVector<CCValAssign, 16> ValLocs;
2113b04546ff5b1a7a03eec1076900c945223bf494ccJim Grosbach    CCState CCInfo(CC, F.isVarArg(), *FuncInfo.MF, TM, ValLocs,I->getContext());
2114ee649839a243bb29b59b322203b982b2f132e7c5Jush Lu    CCInfo.AnalyzeReturn(Outs, CCAssignFnForCall(CC, true /* is Ret */,
2115ee649839a243bb29b59b322203b982b2f132e7c5Jush Lu                                                 F.isVarArg()));
21164f512efee9198eb38bf190b0c3fe50429a065d15Eric Christopher
21174f512efee9198eb38bf190b0c3fe50429a065d15Eric Christopher    const Value *RV = Ret->getOperand(0);
21184f512efee9198eb38bf190b0c3fe50429a065d15Eric Christopher    unsigned Reg = getRegForValue(RV);
21194f512efee9198eb38bf190b0c3fe50429a065d15Eric Christopher    if (Reg == 0)
21204f512efee9198eb38bf190b0c3fe50429a065d15Eric Christopher      return false;
21214f512efee9198eb38bf190b0c3fe50429a065d15Eric Christopher
21224f512efee9198eb38bf190b0c3fe50429a065d15Eric Christopher    // Only handle a single return value for now.
21234f512efee9198eb38bf190b0c3fe50429a065d15Eric Christopher    if (ValLocs.size() != 1)
21244f512efee9198eb38bf190b0c3fe50429a065d15Eric Christopher      return false;
21254f512efee9198eb38bf190b0c3fe50429a065d15Eric Christopher
21264f512efee9198eb38bf190b0c3fe50429a065d15Eric Christopher    CCValAssign &VA = ValLocs[0];
21276b15639e267575a2c95f89d6b266e0fcd9231d91Jim Grosbach
21284f512efee9198eb38bf190b0c3fe50429a065d15Eric Christopher    // Don't bother handling odd stuff for now.
21294f512efee9198eb38bf190b0c3fe50429a065d15Eric Christopher    if (VA.getLocInfo() != CCValAssign::Full)
21304f512efee9198eb38bf190b0c3fe50429a065d15Eric Christopher      return false;
21314f512efee9198eb38bf190b0c3fe50429a065d15Eric Christopher    // Only handle register returns for now.
21324f512efee9198eb38bf190b0c3fe50429a065d15Eric Christopher    if (!VA.isRegLoc())
21334f512efee9198eb38bf190b0c3fe50429a065d15Eric Christopher      return false;
21346b15639e267575a2c95f89d6b266e0fcd9231d91Jim Grosbach
21354f512efee9198eb38bf190b0c3fe50429a065d15Eric Christopher    unsigned SrcReg = Reg + VA.getValNo();
2136316a5aa0a510e6183dd1981dd8bf328ffe7361f5Chad Rosier    EVT RVEVT = TLI.getValueType(RV->getType());
2137316a5aa0a510e6183dd1981dd8bf328ffe7361f5Chad Rosier    if (!RVEVT.isSimple()) return false;
2138316a5aa0a510e6183dd1981dd8bf328ffe7361f5Chad Rosier    MVT RVVT = RVEVT.getSimpleVT();
2139a61b17c18a67f1b3faef2f2108379c4337ce9bb7Patrik Hagglund    MVT DestVT = VA.getValVT();
2140f470cbbad204caa85275873004151b92fba24375Chad Rosier    // Special handling for extended integers.
2141f470cbbad204caa85275873004151b92fba24375Chad Rosier    if (RVVT != DestVT) {
2142f470cbbad204caa85275873004151b92fba24375Chad Rosier      if (RVVT != MVT::i1 && RVVT != MVT::i8 && RVVT != MVT::i16)
2143f470cbbad204caa85275873004151b92fba24375Chad Rosier        return false;
2144f470cbbad204caa85275873004151b92fba24375Chad Rosier
2145f470cbbad204caa85275873004151b92fba24375Chad Rosier      assert(DestVT == MVT::i32 && "ARM should always ext to i32");
2146f470cbbad204caa85275873004151b92fba24375Chad Rosier
2147b8703fe265d44a3eb909c289cb5d31b840ca893cChad Rosier      // Perform extension if flagged as either zext or sext.  Otherwise, do
2148b8703fe265d44a3eb909c289cb5d31b840ca893cChad Rosier      // nothing.
2149b8703fe265d44a3eb909c289cb5d31b840ca893cChad Rosier      if (Outs[0].Flags.isZExt() || Outs[0].Flags.isSExt()) {
2150b8703fe265d44a3eb909c289cb5d31b840ca893cChad Rosier        SrcReg = ARMEmitIntExt(RVVT, SrcReg, DestVT, Outs[0].Flags.isZExt());
2151b8703fe265d44a3eb909c289cb5d31b840ca893cChad Rosier        if (SrcReg == 0) return false;
2152b8703fe265d44a3eb909c289cb5d31b840ca893cChad Rosier      }
2153f470cbbad204caa85275873004151b92fba24375Chad Rosier    }
2154f470cbbad204caa85275873004151b92fba24375Chad Rosier
2155f470cbbad204caa85275873004151b92fba24375Chad Rosier    // Make the copy.
21564f512efee9198eb38bf190b0c3fe50429a065d15Eric Christopher    unsigned DstReg = VA.getLocReg();
21574f512efee9198eb38bf190b0c3fe50429a065d15Eric Christopher    const TargetRegisterClass* SrcRC = MRI.getRegClass(SrcReg);
21584f512efee9198eb38bf190b0c3fe50429a065d15Eric Christopher    // Avoid a cross-class copy. This is very unlikely.
21594f512efee9198eb38bf190b0c3fe50429a065d15Eric Christopher    if (!SrcRC->contains(DstReg))
21604f512efee9198eb38bf190b0c3fe50429a065d15Eric Christopher      return false;
21614f512efee9198eb38bf190b0c3fe50429a065d15Eric Christopher    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(TargetOpcode::COPY),
21624f512efee9198eb38bf190b0c3fe50429a065d15Eric Christopher            DstReg).addReg(SrcReg);
21634f512efee9198eb38bf190b0c3fe50429a065d15Eric Christopher
2164fc7432744476281511704c7e07bf89e20c215601Jakob Stoklund Olesen    // Add register to return instruction.
2165fc7432744476281511704c7e07bf89e20c215601Jakob Stoklund Olesen    RetRegs.push_back(VA.getLocReg());
21664f512efee9198eb38bf190b0c3fe50429a065d15Eric Christopher  }
21676b15639e267575a2c95f89d6b266e0fcd9231d91Jim Grosbach
216866dc8ca04b719f3ab4aa650609dbd56b055ecb34Chad Rosier  unsigned RetOpc = isThumb2 ? ARM::tBX_RET : ARM::BX_RET;
2169fc7432744476281511704c7e07bf89e20c215601Jakob Stoklund Olesen  MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
2170fc7432744476281511704c7e07bf89e20c215601Jakob Stoklund Olesen                                    TII.get(RetOpc));
2171fc7432744476281511704c7e07bf89e20c215601Jakob Stoklund Olesen  AddOptionalDefs(MIB);
2172fc7432744476281511704c7e07bf89e20c215601Jakob Stoklund Olesen  for (unsigned i = 0, e = RetRegs.size(); i != e; ++i)
2173fc7432744476281511704c7e07bf89e20c215601Jakob Stoklund Olesen    MIB.addReg(RetRegs[i], RegState::Implicit);
21744f512efee9198eb38bf190b0c3fe50429a065d15Eric Christopher  return true;
21754f512efee9198eb38bf190b0c3fe50429a065d15Eric Christopher}
21764f512efee9198eb38bf190b0c3fe50429a065d15Eric Christopher
217749d6fc02efc45932e4d889fa56bbbfeefafbdc85Chad Rosierunsigned ARMFastISel::ARMSelectCallOp(bool UseReg) {
217849d6fc02efc45932e4d889fa56bbbfeefafbdc85Chad Rosier  if (UseReg)
217949d6fc02efc45932e4d889fa56bbbfeefafbdc85Chad Rosier    return isThumb2 ? ARM::tBLXr : ARM::BLX;
218049d6fc02efc45932e4d889fa56bbbfeefafbdc85Chad Rosier  else
218149d6fc02efc45932e4d889fa56bbbfeefafbdc85Chad Rosier    return isThumb2 ? ARM::tBL : ARM::BL;
218249d6fc02efc45932e4d889fa56bbbfeefafbdc85Chad Rosier}
218349d6fc02efc45932e4d889fa56bbbfeefafbdc85Chad Rosier
218449d6fc02efc45932e4d889fa56bbbfeefafbdc85Chad Rosierunsigned ARMFastISel::getLibcallReg(const Twine &Name) {
218549d6fc02efc45932e4d889fa56bbbfeefafbdc85Chad Rosier  GlobalValue *GV = new GlobalVariable(Type::getInt32Ty(*Context), false,
218649d6fc02efc45932e4d889fa56bbbfeefafbdc85Chad Rosier                                       GlobalValue::ExternalLinkage, 0, Name);
2187316a5aa0a510e6183dd1981dd8bf328ffe7361f5Chad Rosier  EVT LCREVT = TLI.getValueType(GV->getType());
2188316a5aa0a510e6183dd1981dd8bf328ffe7361f5Chad Rosier  if (!LCREVT.isSimple()) return 0;
2189316a5aa0a510e6183dd1981dd8bf328ffe7361f5Chad Rosier  return ARMMaterializeGV(GV, LCREVT.getSimpleVT());
2190872f4a224711ef55b821746fc7a24b9260fee370Eric Christopher}
2191872f4a224711ef55b821746fc7a24b9260fee370Eric Christopher
2192bb3e5dad6685dd54625edae789d1a703f4107a69Eric Christopher// A quick function that will emit a call for a named libcall in F with the
2193bb3e5dad6685dd54625edae789d1a703f4107a69Eric Christopher// vector of passed arguments for the Instruction in I. We can assume that we
2194dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher// can emit a call for any libcall we can produce. This is an abridged version
2195dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher// of the full call infrastructure since we won't need to worry about things
2196bb3e5dad6685dd54625edae789d1a703f4107a69Eric Christopher// like computed function pointers or strange arguments at call sites.
2197bb3e5dad6685dd54625edae789d1a703f4107a69Eric Christopher// TODO: Try to unify this and the normal call bits for ARM, then try to unify
2198bb3e5dad6685dd54625edae789d1a703f4107a69Eric Christopher// with X86.
21997ed8ec94d96cc87e768fd5ebe4ddeb04dd56e8abEric Christopherbool ARMFastISel::ARMEmitLibcall(const Instruction *I, RTLIB::Libcall Call) {
22007ed8ec94d96cc87e768fd5ebe4ddeb04dd56e8abEric Christopher  CallingConv::ID CC = TLI.getLibcallCallingConv(Call);
2201dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher
2202bb3e5dad6685dd54625edae789d1a703f4107a69Eric Christopher  // Handle *simple* calls for now.
2203db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  Type *RetTy = I->getType();
22041440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands  MVT RetVT;
2205bb3e5dad6685dd54625edae789d1a703f4107a69Eric Christopher  if (RetTy->isVoidTy())
2206bb3e5dad6685dd54625edae789d1a703f4107a69Eric Christopher    RetVT = MVT::isVoid;
2207bb3e5dad6685dd54625edae789d1a703f4107a69Eric Christopher  else if (!isTypeLegal(RetTy, RetVT))
2208bb3e5dad6685dd54625edae789d1a703f4107a69Eric Christopher    return false;
2209dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher
22102a2e9d54e95f01eaa5626dcdf57950e9e6f95f2cChad Rosier  // Can't handle non-double multi-reg retvals.
2211efc967e04459753a588ebf5820e526d790fe1cfaJush Lu  if (RetVT != MVT::isVoid && RetVT != MVT::i32) {
22122a2e9d54e95f01eaa5626dcdf57950e9e6f95f2cChad Rosier    SmallVector<CCValAssign, 16> RVLocs;
22132a2e9d54e95f01eaa5626dcdf57950e9e6f95f2cChad Rosier    CCState CCInfo(CC, false, *FuncInfo.MF, TM, RVLocs, *Context);
2214ee649839a243bb29b59b322203b982b2f132e7c5Jush Lu    CCInfo.AnalyzeCallResult(RetVT, CCAssignFnForCall(CC, true, false));
22152a2e9d54e95f01eaa5626dcdf57950e9e6f95f2cChad Rosier    if (RVLocs.size() >= 2 && RetVT != MVT::f64)
22162a2e9d54e95f01eaa5626dcdf57950e9e6f95f2cChad Rosier      return false;
22172a2e9d54e95f01eaa5626dcdf57950e9e6f95f2cChad Rosier  }
22182a2e9d54e95f01eaa5626dcdf57950e9e6f95f2cChad Rosier
2219a9a7a1a9a557cc03d1fed6cba3f27520be5274c0Eric Christopher  // Set up the argument vectors.
2220bb3e5dad6685dd54625edae789d1a703f4107a69Eric Christopher  SmallVector<Value*, 8> Args;
2221bb3e5dad6685dd54625edae789d1a703f4107a69Eric Christopher  SmallVector<unsigned, 8> ArgRegs;
22221440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands  SmallVector<MVT, 8> ArgVTs;
2223bb3e5dad6685dd54625edae789d1a703f4107a69Eric Christopher  SmallVector<ISD::ArgFlagsTy, 8> ArgFlags;
2224bb3e5dad6685dd54625edae789d1a703f4107a69Eric Christopher  Args.reserve(I->getNumOperands());
2225bb3e5dad6685dd54625edae789d1a703f4107a69Eric Christopher  ArgRegs.reserve(I->getNumOperands());
2226bb3e5dad6685dd54625edae789d1a703f4107a69Eric Christopher  ArgVTs.reserve(I->getNumOperands());
2227bb3e5dad6685dd54625edae789d1a703f4107a69Eric Christopher  ArgFlags.reserve(I->getNumOperands());
22287ed8ec94d96cc87e768fd5ebe4ddeb04dd56e8abEric Christopher  for (unsigned i = 0; i < I->getNumOperands(); ++i) {
2229bb3e5dad6685dd54625edae789d1a703f4107a69Eric Christopher    Value *Op = I->getOperand(i);
2230bb3e5dad6685dd54625edae789d1a703f4107a69Eric Christopher    unsigned Arg = getRegForValue(Op);
2231bb3e5dad6685dd54625edae789d1a703f4107a69Eric Christopher    if (Arg == 0) return false;
2232dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher
2233db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner    Type *ArgTy = Op->getType();
22341440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands    MVT ArgVT;
2235bb3e5dad6685dd54625edae789d1a703f4107a69Eric Christopher    if (!isTypeLegal(ArgTy, ArgVT)) return false;
2236dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher
2237bb3e5dad6685dd54625edae789d1a703f4107a69Eric Christopher    ISD::ArgFlagsTy Flags;
2238bb3e5dad6685dd54625edae789d1a703f4107a69Eric Christopher    unsigned OriginalAlignment = TD.getABITypeAlignment(ArgTy);
2239bb3e5dad6685dd54625edae789d1a703f4107a69Eric Christopher    Flags.setOrigAlign(OriginalAlignment);
2240dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher
2241bb3e5dad6685dd54625edae789d1a703f4107a69Eric Christopher    Args.push_back(Op);
2242bb3e5dad6685dd54625edae789d1a703f4107a69Eric Christopher    ArgRegs.push_back(Arg);
2243bb3e5dad6685dd54625edae789d1a703f4107a69Eric Christopher    ArgVTs.push_back(ArgVT);
2244bb3e5dad6685dd54625edae789d1a703f4107a69Eric Christopher    ArgFlags.push_back(Flags);
2245bb3e5dad6685dd54625edae789d1a703f4107a69Eric Christopher  }
2246dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher
2247a9a7a1a9a557cc03d1fed6cba3f27520be5274c0Eric Christopher  // Handle the arguments now that we've gotten them.
2248bb3e5dad6685dd54625edae789d1a703f4107a69Eric Christopher  SmallVector<unsigned, 4> RegArgs;
2249a9a7a1a9a557cc03d1fed6cba3f27520be5274c0Eric Christopher  unsigned NumBytes;
2250ee649839a243bb29b59b322203b982b2f132e7c5Jush Lu  if (!ProcessCallArgs(Args, ArgRegs, ArgVTs, ArgFlags,
2251ee649839a243bb29b59b322203b982b2f132e7c5Jush Lu                       RegArgs, CC, NumBytes, false))
2252a9a7a1a9a557cc03d1fed6cba3f27520be5274c0Eric Christopher    return false;
2253dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher
225449d6fc02efc45932e4d889fa56bbbfeefafbdc85Chad Rosier  unsigned CalleeReg = 0;
225549d6fc02efc45932e4d889fa56bbbfeefafbdc85Chad Rosier  if (EnableARMLongCalls) {
225649d6fc02efc45932e4d889fa56bbbfeefafbdc85Chad Rosier    CalleeReg = getLibcallReg(TLI.getLibcallName(Call));
225749d6fc02efc45932e4d889fa56bbbfeefafbdc85Chad Rosier    if (CalleeReg == 0) return false;
225849d6fc02efc45932e4d889fa56bbbfeefafbdc85Chad Rosier  }
225949d6fc02efc45932e4d889fa56bbbfeefafbdc85Chad Rosier
2260f16936e5923156863906c915de657b134db4fb16Jakob Stoklund Olesen  // Issue the call.
226149d6fc02efc45932e4d889fa56bbbfeefafbdc85Chad Rosier  unsigned CallOpc = ARMSelectCallOp(EnableARMLongCalls);
226249d6fc02efc45932e4d889fa56bbbfeefafbdc85Chad Rosier  MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt,
226349d6fc02efc45932e4d889fa56bbbfeefafbdc85Chad Rosier                                    DL, TII.get(CallOpc));
22640745b649ed5c362f1c2f7db59254a76041ddef05Jakob Stoklund Olesen  // BL / BLX don't take a predicate, but tBL / tBLX do.
22650745b649ed5c362f1c2f7db59254a76041ddef05Jakob Stoklund Olesen  if (isThumb2)
226649d6fc02efc45932e4d889fa56bbbfeefafbdc85Chad Rosier    AddDefaultPred(MIB);
22670745b649ed5c362f1c2f7db59254a76041ddef05Jakob Stoklund Olesen  if (EnableARMLongCalls)
22680745b649ed5c362f1c2f7db59254a76041ddef05Jakob Stoklund Olesen    MIB.addReg(CalleeReg);
22690745b649ed5c362f1c2f7db59254a76041ddef05Jakob Stoklund Olesen  else
22700745b649ed5c362f1c2f7db59254a76041ddef05Jakob Stoklund Olesen    MIB.addExternalSymbol(TLI.getLibcallName(Call));
2271dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher
2272bb3e5dad6685dd54625edae789d1a703f4107a69Eric Christopher  // Add implicit physical register uses to the call.
2273bb3e5dad6685dd54625edae789d1a703f4107a69Eric Christopher  for (unsigned i = 0, e = RegArgs.size(); i != e; ++i)
22740745b649ed5c362f1c2f7db59254a76041ddef05Jakob Stoklund Olesen    MIB.addReg(RegArgs[i], RegState::Implicit);
2275dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher
2276c54f6348861517398f17e85f41b30c4dd079fc3dJakob Stoklund Olesen  // Add a register mask with the call-preserved registers.
2277c54f6348861517398f17e85f41b30c4dd079fc3dJakob Stoklund Olesen  // Proper defs for return values will be added by setPhysRegsDeadExcept().
2278c54f6348861517398f17e85f41b30c4dd079fc3dJakob Stoklund Olesen  MIB.addRegMask(TRI.getCallPreservedMask(CC));
2279c54f6348861517398f17e85f41b30c4dd079fc3dJakob Stoklund Olesen
2280a9a7a1a9a557cc03d1fed6cba3f27520be5274c0Eric Christopher  // Finish off the call including any return values.
2281dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher  SmallVector<unsigned, 4> UsedRegs;
2282ee649839a243bb29b59b322203b982b2f132e7c5Jush Lu  if (!FinishCall(RetVT, UsedRegs, I, CC, NumBytes, false)) return false;
2283dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher
2284bb3e5dad6685dd54625edae789d1a703f4107a69Eric Christopher  // Set all unused physreg defs as dead.
2285bb3e5dad6685dd54625edae789d1a703f4107a69Eric Christopher  static_cast<MachineInstr *>(MIB)->setPhysRegsDeadExcept(UsedRegs, TRI);
2286dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher
2287bb3e5dad6685dd54625edae789d1a703f4107a69Eric Christopher  return true;
2288bb3e5dad6685dd54625edae789d1a703f4107a69Eric Christopher}
2289bb3e5dad6685dd54625edae789d1a703f4107a69Eric Christopher
229011add26ec2bdf5109f0ff2ee19d237664687b914Chad Rosierbool ARMFastISel::SelectCall(const Instruction *I,
229111add26ec2bdf5109f0ff2ee19d237664687b914Chad Rosier                             const char *IntrMemName = 0) {
2292f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher  const CallInst *CI = cast<CallInst>(I);
2293f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher  const Value *Callee = CI->getCalledValue();
2294f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher
229511add26ec2bdf5109f0ff2ee19d237664687b914Chad Rosier  // Can't handle inline asm.
229611add26ec2bdf5109f0ff2ee19d237664687b914Chad Rosier  if (isa<InlineAsm>(Callee)) return false;
2297f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher
2298425e951734c3a0615e22ec94ffa51cc16ce6e483Chad Rosier  // Allow SelectionDAG isel to handle tail calls.
2299425e951734c3a0615e22ec94ffa51cc16ce6e483Chad Rosier  if (CI->isTailCall()) return false;
2300425e951734c3a0615e22ec94ffa51cc16ce6e483Chad Rosier
2301f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher  // Check the calling convention.
2302f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher  ImmutableCallSite CS(CI);
2303f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher  CallingConv::ID CC = CS.getCallingConv();
23044cf34c6c041cebc1d816d178654c6bbb7737cc4eEric Christopher
2305f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher  // TODO: Avoid some calling conventions?
2306dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher
2307db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  PointerType *PT = cast<PointerType>(CS.getCalledValue()->getType());
2308db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  FunctionType *FTy = cast<FunctionType>(PT->getElementType());
2309ee649839a243bb29b59b322203b982b2f132e7c5Jush Lu  bool isVarArg = FTy->isVarArg();
2310dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher
2311f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher  // Handle *simple* calls for now.
2312db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  Type *RetTy = I->getType();
23131440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands  MVT RetVT;
2314f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher  if (RetTy->isVoidTy())
2315f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher    RetVT = MVT::isVoid;
23160eff39f2e25e9d8dd52b1eb7fa4e7cc6cc77875fChad Rosier  else if (!isTypeLegal(RetTy, RetVT) && RetVT != MVT::i16 &&
23170eff39f2e25e9d8dd52b1eb7fa4e7cc6cc77875fChad Rosier           RetVT != MVT::i8  && RetVT != MVT::i1)
2318f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher    return false;
2319dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher
23202a2e9d54e95f01eaa5626dcdf57950e9e6f95f2cChad Rosier  // Can't handle non-double multi-reg retvals.
23212a2e9d54e95f01eaa5626dcdf57950e9e6f95f2cChad Rosier  if (RetVT != MVT::isVoid && RetVT != MVT::i1 && RetVT != MVT::i8 &&
23222a2e9d54e95f01eaa5626dcdf57950e9e6f95f2cChad Rosier      RetVT != MVT::i16 && RetVT != MVT::i32) {
23232a2e9d54e95f01eaa5626dcdf57950e9e6f95f2cChad Rosier    SmallVector<CCValAssign, 16> RVLocs;
2324ee649839a243bb29b59b322203b982b2f132e7c5Jush Lu    CCState CCInfo(CC, isVarArg, *FuncInfo.MF, TM, RVLocs, *Context);
2325ee649839a243bb29b59b322203b982b2f132e7c5Jush Lu    CCInfo.AnalyzeCallResult(RetVT, CCAssignFnForCall(CC, true, isVarArg));
23262a2e9d54e95f01eaa5626dcdf57950e9e6f95f2cChad Rosier    if (RVLocs.size() >= 2 && RetVT != MVT::f64)
23272a2e9d54e95f01eaa5626dcdf57950e9e6f95f2cChad Rosier      return false;
23282a2e9d54e95f01eaa5626dcdf57950e9e6f95f2cChad Rosier  }
23292a2e9d54e95f01eaa5626dcdf57950e9e6f95f2cChad Rosier
2330f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher  // Set up the argument vectors.
2331f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher  SmallVector<Value*, 8> Args;
2332f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher  SmallVector<unsigned, 8> ArgRegs;
23331440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands  SmallVector<MVT, 8> ArgVTs;
2334f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher  SmallVector<ISD::ArgFlagsTy, 8> ArgFlags;
233592fd01736484262fef049b7358366d8eab2f857eChad Rosier  unsigned arg_size = CS.arg_size();
233692fd01736484262fef049b7358366d8eab2f857eChad Rosier  Args.reserve(arg_size);
233792fd01736484262fef049b7358366d8eab2f857eChad Rosier  ArgRegs.reserve(arg_size);
233892fd01736484262fef049b7358366d8eab2f857eChad Rosier  ArgVTs.reserve(arg_size);
233992fd01736484262fef049b7358366d8eab2f857eChad Rosier  ArgFlags.reserve(arg_size);
2340f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher  for (ImmutableCallSite::arg_iterator i = CS.arg_begin(), e = CS.arg_end();
2341f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher       i != e; ++i) {
234211add26ec2bdf5109f0ff2ee19d237664687b914Chad Rosier    // If we're lowering a memory intrinsic instead of a regular call, skip the
234311add26ec2bdf5109f0ff2ee19d237664687b914Chad Rosier    // last two arguments, which shouldn't be passed to the underlying function.
234411add26ec2bdf5109f0ff2ee19d237664687b914Chad Rosier    if (IntrMemName && e-i <= 2)
234511add26ec2bdf5109f0ff2ee19d237664687b914Chad Rosier      break;
2346dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher
2347f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher    ISD::ArgFlagsTy Flags;
2348f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher    unsigned AttrInd = i - CS.arg_begin() + 1;
2349034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling    if (CS.paramHasAttr(AttrInd, Attribute::SExt))
2350f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher      Flags.setSExt();
2351034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling    if (CS.paramHasAttr(AttrInd, Attribute::ZExt))
2352f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher      Flags.setZExt();
2353f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher
23548e4a2e4f730e691e116a4b2cee3a2c760a54ac09Chad Rosier    // FIXME: Only handle *easy* calls for now.
2355034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling    if (CS.paramHasAttr(AttrInd, Attribute::InReg) ||
2356034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling        CS.paramHasAttr(AttrInd, Attribute::StructRet) ||
2357034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling        CS.paramHasAttr(AttrInd, Attribute::Nest) ||
2358034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling        CS.paramHasAttr(AttrInd, Attribute::ByVal))
2359f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher      return false;
2360f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher
2361db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner    Type *ArgTy = (*i)->getType();
23621440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands    MVT ArgVT;
236342536af5ce152593f489ca88bd0732218594d536Chad Rosier    if (!isTypeLegal(ArgTy, ArgVT) && ArgVT != MVT::i16 && ArgVT != MVT::i8 &&
236442536af5ce152593f489ca88bd0732218594d536Chad Rosier        ArgVT != MVT::i1)
2365f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher      return false;
2366424fe0e422826f4962b58428b6aef48e1a66c30aChad Rosier
2367424fe0e422826f4962b58428b6aef48e1a66c30aChad Rosier    unsigned Arg = getRegForValue(*i);
2368424fe0e422826f4962b58428b6aef48e1a66c30aChad Rosier    if (Arg == 0)
2369424fe0e422826f4962b58428b6aef48e1a66c30aChad Rosier      return false;
2370424fe0e422826f4962b58428b6aef48e1a66c30aChad Rosier
2371f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher    unsigned OriginalAlignment = TD.getABITypeAlignment(ArgTy);
2372f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher    Flags.setOrigAlign(OriginalAlignment);
2373dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher
2374f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher    Args.push_back(*i);
2375f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher    ArgRegs.push_back(Arg);
2376f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher    ArgVTs.push_back(ArgVT);
2377f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher    ArgFlags.push_back(Flags);
2378f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher  }
2379dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher
2380f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher  // Handle the arguments now that we've gotten them.
2381f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher  SmallVector<unsigned, 4> RegArgs;
2382f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher  unsigned NumBytes;
2383ee649839a243bb29b59b322203b982b2f132e7c5Jush Lu  if (!ProcessCallArgs(Args, ArgRegs, ArgVTs, ArgFlags,
2384ee649839a243bb29b59b322203b982b2f132e7c5Jush Lu                       RegArgs, CC, NumBytes, isVarArg))
2385f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher    return false;
2386dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher
238749d6fc02efc45932e4d889fa56bbbfeefafbdc85Chad Rosier  bool UseReg = false;
23881c8fccbc12e6348c8003aff9b89078324257fc4eChad Rosier  const GlobalValue *GV = dyn_cast<GlobalValue>(Callee);
238949d6fc02efc45932e4d889fa56bbbfeefafbdc85Chad Rosier  if (!GV || EnableARMLongCalls) UseReg = true;
239049d6fc02efc45932e4d889fa56bbbfeefafbdc85Chad Rosier
23911c8fccbc12e6348c8003aff9b89078324257fc4eChad Rosier  unsigned CalleeReg = 0;
239249d6fc02efc45932e4d889fa56bbbfeefafbdc85Chad Rosier  if (UseReg) {
239349d6fc02efc45932e4d889fa56bbbfeefafbdc85Chad Rosier    if (IntrMemName)
239449d6fc02efc45932e4d889fa56bbbfeefafbdc85Chad Rosier      CalleeReg = getLibcallReg(IntrMemName);
239549d6fc02efc45932e4d889fa56bbbfeefafbdc85Chad Rosier    else
239649d6fc02efc45932e4d889fa56bbbfeefafbdc85Chad Rosier      CalleeReg = getRegForValue(Callee);
23971c8fccbc12e6348c8003aff9b89078324257fc4eChad Rosier
23981c8fccbc12e6348c8003aff9b89078324257fc4eChad Rosier    if (CalleeReg == 0) return false;
23991c8fccbc12e6348c8003aff9b89078324257fc4eChad Rosier  }
24001c8fccbc12e6348c8003aff9b89078324257fc4eChad Rosier
240149d6fc02efc45932e4d889fa56bbbfeefafbdc85Chad Rosier  // Issue the call.
240249d6fc02efc45932e4d889fa56bbbfeefafbdc85Chad Rosier  unsigned CallOpc = ARMSelectCallOp(UseReg);
240349d6fc02efc45932e4d889fa56bbbfeefafbdc85Chad Rosier  MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt,
240449d6fc02efc45932e4d889fa56bbbfeefafbdc85Chad Rosier                                    DL, TII.get(CallOpc));
240549d6fc02efc45932e4d889fa56bbbfeefafbdc85Chad Rosier
24060745b649ed5c362f1c2f7db59254a76041ddef05Jakob Stoklund Olesen  // ARM calls don't take a predicate, but tBL / tBLX do.
24070745b649ed5c362f1c2f7db59254a76041ddef05Jakob Stoklund Olesen  if(isThumb2)
240849d6fc02efc45932e4d889fa56bbbfeefafbdc85Chad Rosier    AddDefaultPred(MIB);
24090745b649ed5c362f1c2f7db59254a76041ddef05Jakob Stoklund Olesen  if (UseReg)
24100745b649ed5c362f1c2f7db59254a76041ddef05Jakob Stoklund Olesen    MIB.addReg(CalleeReg);
24110745b649ed5c362f1c2f7db59254a76041ddef05Jakob Stoklund Olesen  else if (!IntrMemName)
24120745b649ed5c362f1c2f7db59254a76041ddef05Jakob Stoklund Olesen    MIB.addGlobalAddress(GV, 0, 0);
24130745b649ed5c362f1c2f7db59254a76041ddef05Jakob Stoklund Olesen  else
24140745b649ed5c362f1c2f7db59254a76041ddef05Jakob Stoklund Olesen    MIB.addExternalSymbol(IntrMemName, 0);
2415efc967e04459753a588ebf5820e526d790fe1cfaJush Lu
2416f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher  // Add implicit physical register uses to the call.
2417f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher  for (unsigned i = 0, e = RegArgs.size(); i != e; ++i)
24180745b649ed5c362f1c2f7db59254a76041ddef05Jakob Stoklund Olesen    MIB.addReg(RegArgs[i], RegState::Implicit);
2419dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher
2420c54f6348861517398f17e85f41b30c4dd079fc3dJakob Stoklund Olesen  // Add a register mask with the call-preserved registers.
2421c54f6348861517398f17e85f41b30c4dd079fc3dJakob Stoklund Olesen  // Proper defs for return values will be added by setPhysRegsDeadExcept().
2422c54f6348861517398f17e85f41b30c4dd079fc3dJakob Stoklund Olesen  MIB.addRegMask(TRI.getCallPreservedMask(CC));
2423c54f6348861517398f17e85f41b30c4dd079fc3dJakob Stoklund Olesen
2424f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher  // Finish off the call including any return values.
2425dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher  SmallVector<unsigned, 4> UsedRegs;
2426ee649839a243bb29b59b322203b982b2f132e7c5Jush Lu  if (!FinishCall(RetVT, UsedRegs, I, CC, NumBytes, isVarArg))
2427ee649839a243bb29b59b322203b982b2f132e7c5Jush Lu    return false;
2428dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher
2429f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher  // Set all unused physreg defs as dead.
2430f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher  static_cast<MachineInstr *>(MIB)->setPhysRegsDeadExcept(UsedRegs, TRI);
2431dccd2c3c4346dd6625b80fcac9caa1be99731c9cEric Christopher
2432f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher  return true;
2433f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher}
2434f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher
24352c42b8c912b62071c27454182cdef60e3b584083Chad Rosierbool ARMFastISel::ARMIsMemCpySmall(uint64_t Len) {
2436909cb4f2f2d227ea01852cb318c80a79c46bc9bfChad Rosier  return Len <= 16;
2437909cb4f2f2d227ea01852cb318c80a79c46bc9bfChad Rosier}
2438909cb4f2f2d227ea01852cb318c80a79c46bc9bfChad Rosier
2439d4f020a3af325630973df8d3a084d0b0e3b68ebcJim Grosbachbool ARMFastISel::ARMTryEmitSmallMemCpy(Address Dest, Address Src,
2440c9758b13668013dea491a08b4f0c9256263927c2Chad Rosier                                        uint64_t Len, unsigned Alignment) {
2441909cb4f2f2d227ea01852cb318c80a79c46bc9bfChad Rosier  // Make sure we don't bloat code by inlining very large memcpy's.
24422c42b8c912b62071c27454182cdef60e3b584083Chad Rosier  if (!ARMIsMemCpySmall(Len))
2443909cb4f2f2d227ea01852cb318c80a79c46bc9bfChad Rosier    return false;
2444909cb4f2f2d227ea01852cb318c80a79c46bc9bfChad Rosier
2445909cb4f2f2d227ea01852cb318c80a79c46bc9bfChad Rosier  while (Len) {
2446909cb4f2f2d227ea01852cb318c80a79c46bc9bfChad Rosier    MVT VT;
2447c9758b13668013dea491a08b4f0c9256263927c2Chad Rosier    if (!Alignment || Alignment >= 4) {
2448c9758b13668013dea491a08b4f0c9256263927c2Chad Rosier      if (Len >= 4)
2449c9758b13668013dea491a08b4f0c9256263927c2Chad Rosier        VT = MVT::i32;
2450c9758b13668013dea491a08b4f0c9256263927c2Chad Rosier      else if (Len >= 2)
2451c9758b13668013dea491a08b4f0c9256263927c2Chad Rosier        VT = MVT::i16;
2452c9758b13668013dea491a08b4f0c9256263927c2Chad Rosier      else {
2453c9758b13668013dea491a08b4f0c9256263927c2Chad Rosier        assert (Len == 1 && "Expected a length of 1!");
2454c9758b13668013dea491a08b4f0c9256263927c2Chad Rosier        VT = MVT::i8;
2455c9758b13668013dea491a08b4f0c9256263927c2Chad Rosier      }
2456c9758b13668013dea491a08b4f0c9256263927c2Chad Rosier    } else {
2457c9758b13668013dea491a08b4f0c9256263927c2Chad Rosier      // Bound based on alignment.
2458c9758b13668013dea491a08b4f0c9256263927c2Chad Rosier      if (Len >= 2 && Alignment == 2)
2459c9758b13668013dea491a08b4f0c9256263927c2Chad Rosier        VT = MVT::i16;
2460c9758b13668013dea491a08b4f0c9256263927c2Chad Rosier      else {
2461c9758b13668013dea491a08b4f0c9256263927c2Chad Rosier        VT = MVT::i8;
2462c9758b13668013dea491a08b4f0c9256263927c2Chad Rosier      }
2463909cb4f2f2d227ea01852cb318c80a79c46bc9bfChad Rosier    }
2464909cb4f2f2d227ea01852cb318c80a79c46bc9bfChad Rosier
2465909cb4f2f2d227ea01852cb318c80a79c46bc9bfChad Rosier    bool RV;
2466909cb4f2f2d227ea01852cb318c80a79c46bc9bfChad Rosier    unsigned ResultReg;
2467909cb4f2f2d227ea01852cb318c80a79c46bc9bfChad Rosier    RV = ARMEmitLoad(VT, ResultReg, Src);
2468fae699a580380b910740e1cb17ab950ba91ce4a1Eric Christopher    assert (RV == true && "Should be able to handle this load.");
2469909cb4f2f2d227ea01852cb318c80a79c46bc9bfChad Rosier    RV = ARMEmitStore(VT, ResultReg, Dest);
2470fae699a580380b910740e1cb17ab950ba91ce4a1Eric Christopher    assert (RV == true && "Should be able to handle this store.");
24715b8a1db7ea6510a2589f710d50754599da742de9Duncan Sands    (void)RV;
2472909cb4f2f2d227ea01852cb318c80a79c46bc9bfChad Rosier
2473909cb4f2f2d227ea01852cb318c80a79c46bc9bfChad Rosier    unsigned Size = VT.getSizeInBits()/8;
2474909cb4f2f2d227ea01852cb318c80a79c46bc9bfChad Rosier    Len -= Size;
2475909cb4f2f2d227ea01852cb318c80a79c46bc9bfChad Rosier    Dest.Offset += Size;
2476909cb4f2f2d227ea01852cb318c80a79c46bc9bfChad Rosier    Src.Offset += Size;
2477909cb4f2f2d227ea01852cb318c80a79c46bc9bfChad Rosier  }
2478909cb4f2f2d227ea01852cb318c80a79c46bc9bfChad Rosier
2479909cb4f2f2d227ea01852cb318c80a79c46bc9bfChad Rosier  return true;
2480909cb4f2f2d227ea01852cb318c80a79c46bc9bfChad Rosier}
2481909cb4f2f2d227ea01852cb318c80a79c46bc9bfChad Rosier
248211add26ec2bdf5109f0ff2ee19d237664687b914Chad Rosierbool ARMFastISel::SelectIntrinsicCall(const IntrinsicInst &I) {
248311add26ec2bdf5109f0ff2ee19d237664687b914Chad Rosier  // FIXME: Handle more intrinsics.
248411add26ec2bdf5109f0ff2ee19d237664687b914Chad Rosier  switch (I.getIntrinsicID()) {
248511add26ec2bdf5109f0ff2ee19d237664687b914Chad Rosier  default: return false;
2486ada759d5fa8a3ecc0e97d88761badfba9193587fChad Rosier  case Intrinsic::frameaddress: {
2487ada759d5fa8a3ecc0e97d88761badfba9193587fChad Rosier    MachineFrameInfo *MFI = FuncInfo.MF->getFrameInfo();
2488ada759d5fa8a3ecc0e97d88761badfba9193587fChad Rosier    MFI->setFrameAddressIsTaken(true);
2489ada759d5fa8a3ecc0e97d88761badfba9193587fChad Rosier
2490ada759d5fa8a3ecc0e97d88761badfba9193587fChad Rosier    unsigned LdrOpc;
2491ada759d5fa8a3ecc0e97d88761badfba9193587fChad Rosier    const TargetRegisterClass *RC;
2492ada759d5fa8a3ecc0e97d88761badfba9193587fChad Rosier    if (isThumb2) {
2493ada759d5fa8a3ecc0e97d88761badfba9193587fChad Rosier      LdrOpc =  ARM::t2LDRi12;
2494ada759d5fa8a3ecc0e97d88761badfba9193587fChad Rosier      RC = (const TargetRegisterClass*)&ARM::tGPRRegClass;
2495ada759d5fa8a3ecc0e97d88761badfba9193587fChad Rosier    } else {
2496ada759d5fa8a3ecc0e97d88761badfba9193587fChad Rosier      LdrOpc =  ARM::LDRi12;
2497ada759d5fa8a3ecc0e97d88761badfba9193587fChad Rosier      RC = (const TargetRegisterClass*)&ARM::GPRRegClass;
2498ada759d5fa8a3ecc0e97d88761badfba9193587fChad Rosier    }
2499ada759d5fa8a3ecc0e97d88761badfba9193587fChad Rosier
2500ada759d5fa8a3ecc0e97d88761badfba9193587fChad Rosier    const ARMBaseRegisterInfo *RegInfo =
2501ada759d5fa8a3ecc0e97d88761badfba9193587fChad Rosier          static_cast<const ARMBaseRegisterInfo*>(TM.getRegisterInfo());
2502ada759d5fa8a3ecc0e97d88761badfba9193587fChad Rosier    unsigned FramePtr = RegInfo->getFrameRegister(*(FuncInfo.MF));
2503ada759d5fa8a3ecc0e97d88761badfba9193587fChad Rosier    unsigned SrcReg = FramePtr;
2504ada759d5fa8a3ecc0e97d88761badfba9193587fChad Rosier
2505ada759d5fa8a3ecc0e97d88761badfba9193587fChad Rosier    // Recursively load frame address
2506ada759d5fa8a3ecc0e97d88761badfba9193587fChad Rosier    // ldr r0 [fp]
2507ada759d5fa8a3ecc0e97d88761badfba9193587fChad Rosier    // ldr r0 [r0]
2508ada759d5fa8a3ecc0e97d88761badfba9193587fChad Rosier    // ldr r0 [r0]
2509ada759d5fa8a3ecc0e97d88761badfba9193587fChad Rosier    // ...
2510ada759d5fa8a3ecc0e97d88761badfba9193587fChad Rosier    unsigned DestReg;
2511ada759d5fa8a3ecc0e97d88761badfba9193587fChad Rosier    unsigned Depth = cast<ConstantInt>(I.getOperand(0))->getZExtValue();
2512ada759d5fa8a3ecc0e97d88761badfba9193587fChad Rosier    while (Depth--) {
2513ada759d5fa8a3ecc0e97d88761badfba9193587fChad Rosier      DestReg = createResultReg(RC);
2514ada759d5fa8a3ecc0e97d88761badfba9193587fChad Rosier      AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
2515ada759d5fa8a3ecc0e97d88761badfba9193587fChad Rosier                              TII.get(LdrOpc), DestReg)
2516ada759d5fa8a3ecc0e97d88761badfba9193587fChad Rosier                      .addReg(SrcReg).addImm(0));
2517ada759d5fa8a3ecc0e97d88761badfba9193587fChad Rosier      SrcReg = DestReg;
2518ada759d5fa8a3ecc0e97d88761badfba9193587fChad Rosier    }
2519bbff4ee92d91de4c7ee6657a1eea95c5ed8105deChad Rosier    UpdateValueMap(&I, SrcReg);
2520ada759d5fa8a3ecc0e97d88761badfba9193587fChad Rosier    return true;
2521ada759d5fa8a3ecc0e97d88761badfba9193587fChad Rosier  }
252211add26ec2bdf5109f0ff2ee19d237664687b914Chad Rosier  case Intrinsic::memcpy:
252311add26ec2bdf5109f0ff2ee19d237664687b914Chad Rosier  case Intrinsic::memmove: {
252411add26ec2bdf5109f0ff2ee19d237664687b914Chad Rosier    const MemTransferInst &MTI = cast<MemTransferInst>(I);
252511add26ec2bdf5109f0ff2ee19d237664687b914Chad Rosier    // Don't handle volatile.
252611add26ec2bdf5109f0ff2ee19d237664687b914Chad Rosier    if (MTI.isVolatile())
252711add26ec2bdf5109f0ff2ee19d237664687b914Chad Rosier      return false;
2528909cb4f2f2d227ea01852cb318c80a79c46bc9bfChad Rosier
2529909cb4f2f2d227ea01852cb318c80a79c46bc9bfChad Rosier    // Disable inlining for memmove before calls to ComputeAddress.  Otherwise,
2530909cb4f2f2d227ea01852cb318c80a79c46bc9bfChad Rosier    // we would emit dead code because we don't currently handle memmoves.
2531909cb4f2f2d227ea01852cb318c80a79c46bc9bfChad Rosier    bool isMemCpy = (I.getIntrinsicID() == Intrinsic::memcpy);
2532909cb4f2f2d227ea01852cb318c80a79c46bc9bfChad Rosier    if (isa<ConstantInt>(MTI.getLength()) && isMemCpy) {
25332c42b8c912b62071c27454182cdef60e3b584083Chad Rosier      // Small memcpy's are common enough that we want to do them without a call
25342c42b8c912b62071c27454182cdef60e3b584083Chad Rosier      // if possible.
2535909cb4f2f2d227ea01852cb318c80a79c46bc9bfChad Rosier      uint64_t Len = cast<ConstantInt>(MTI.getLength())->getZExtValue();
25362c42b8c912b62071c27454182cdef60e3b584083Chad Rosier      if (ARMIsMemCpySmall(Len)) {
2537909cb4f2f2d227ea01852cb318c80a79c46bc9bfChad Rosier        Address Dest, Src;
2538909cb4f2f2d227ea01852cb318c80a79c46bc9bfChad Rosier        if (!ARMComputeAddress(MTI.getRawDest(), Dest) ||
2539909cb4f2f2d227ea01852cb318c80a79c46bc9bfChad Rosier            !ARMComputeAddress(MTI.getRawSource(), Src))
2540909cb4f2f2d227ea01852cb318c80a79c46bc9bfChad Rosier          return false;
2541c9758b13668013dea491a08b4f0c9256263927c2Chad Rosier        unsigned Alignment = MTI.getAlignment();
2542c9758b13668013dea491a08b4f0c9256263927c2Chad Rosier        if (ARMTryEmitSmallMemCpy(Dest, Src, Len, Alignment))
2543909cb4f2f2d227ea01852cb318c80a79c46bc9bfChad Rosier          return true;
2544909cb4f2f2d227ea01852cb318c80a79c46bc9bfChad Rosier      }
2545909cb4f2f2d227ea01852cb318c80a79c46bc9bfChad Rosier    }
2546efc967e04459753a588ebf5820e526d790fe1cfaJush Lu
254711add26ec2bdf5109f0ff2ee19d237664687b914Chad Rosier    if (!MTI.getLength()->getType()->isIntegerTy(32))
254811add26ec2bdf5109f0ff2ee19d237664687b914Chad Rosier      return false;
2549efc967e04459753a588ebf5820e526d790fe1cfaJush Lu
255011add26ec2bdf5109f0ff2ee19d237664687b914Chad Rosier    if (MTI.getSourceAddressSpace() > 255 || MTI.getDestAddressSpace() > 255)
255111add26ec2bdf5109f0ff2ee19d237664687b914Chad Rosier      return false;
255211add26ec2bdf5109f0ff2ee19d237664687b914Chad Rosier
255311add26ec2bdf5109f0ff2ee19d237664687b914Chad Rosier    const char *IntrMemName = isa<MemCpyInst>(I) ? "memcpy" : "memmove";
255411add26ec2bdf5109f0ff2ee19d237664687b914Chad Rosier    return SelectCall(&I, IntrMemName);
255511add26ec2bdf5109f0ff2ee19d237664687b914Chad Rosier  }
255611add26ec2bdf5109f0ff2ee19d237664687b914Chad Rosier  case Intrinsic::memset: {
255711add26ec2bdf5109f0ff2ee19d237664687b914Chad Rosier    const MemSetInst &MSI = cast<MemSetInst>(I);
255811add26ec2bdf5109f0ff2ee19d237664687b914Chad Rosier    // Don't handle volatile.
255911add26ec2bdf5109f0ff2ee19d237664687b914Chad Rosier    if (MSI.isVolatile())
256011add26ec2bdf5109f0ff2ee19d237664687b914Chad Rosier      return false;
2561efc967e04459753a588ebf5820e526d790fe1cfaJush Lu
256211add26ec2bdf5109f0ff2ee19d237664687b914Chad Rosier    if (!MSI.getLength()->getType()->isIntegerTy(32))
256311add26ec2bdf5109f0ff2ee19d237664687b914Chad Rosier      return false;
2564efc967e04459753a588ebf5820e526d790fe1cfaJush Lu
256511add26ec2bdf5109f0ff2ee19d237664687b914Chad Rosier    if (MSI.getDestAddressSpace() > 255)
256611add26ec2bdf5109f0ff2ee19d237664687b914Chad Rosier      return false;
2567efc967e04459753a588ebf5820e526d790fe1cfaJush Lu
256811add26ec2bdf5109f0ff2ee19d237664687b914Chad Rosier    return SelectCall(&I, "memset");
256911add26ec2bdf5109f0ff2ee19d237664687b914Chad Rosier  }
2570226ddf5278dd9a9d2d74d859d387bf5b6bac1926Chad Rosier  case Intrinsic::trap: {
25710f156af8312a0f3ce88e5c006bf2a52691039cebEli Bendersky    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(
25720f156af8312a0f3ce88e5c006bf2a52691039cebEli Bendersky      Subtarget->useNaClTrap() ? ARM::TRAPNaCl : ARM::TRAP));
2573226ddf5278dd9a9d2d74d859d387bf5b6bac1926Chad Rosier    return true;
2574226ddf5278dd9a9d2d74d859d387bf5b6bac1926Chad Rosier  }
257511add26ec2bdf5109f0ff2ee19d237664687b914Chad Rosier  }
257611add26ec2bdf5109f0ff2ee19d237664687b914Chad Rosier}
257711add26ec2bdf5109f0ff2ee19d237664687b914Chad Rosier
25780d7b231c9b0acf2ea6bb99f75672751f64c6c6dbChad Rosierbool ARMFastISel::SelectTrunc(const Instruction *I) {
2579efc967e04459753a588ebf5820e526d790fe1cfaJush Lu  // The high bits for a type smaller than the register size are assumed to be
25800d7b231c9b0acf2ea6bb99f75672751f64c6c6dbChad Rosier  // undefined.
25810d7b231c9b0acf2ea6bb99f75672751f64c6c6dbChad Rosier  Value *Op = I->getOperand(0);
25820d7b231c9b0acf2ea6bb99f75672751f64c6c6dbChad Rosier
25830d7b231c9b0acf2ea6bb99f75672751f64c6c6dbChad Rosier  EVT SrcVT, DestVT;
25840d7b231c9b0acf2ea6bb99f75672751f64c6c6dbChad Rosier  SrcVT = TLI.getValueType(Op->getType(), true);
25850d7b231c9b0acf2ea6bb99f75672751f64c6c6dbChad Rosier  DestVT = TLI.getValueType(I->getType(), true);
25860d7b231c9b0acf2ea6bb99f75672751f64c6c6dbChad Rosier
25870d7b231c9b0acf2ea6bb99f75672751f64c6c6dbChad Rosier  if (SrcVT != MVT::i32 && SrcVT != MVT::i16 && SrcVT != MVT::i8)
25880d7b231c9b0acf2ea6bb99f75672751f64c6c6dbChad Rosier    return false;
25890d7b231c9b0acf2ea6bb99f75672751f64c6c6dbChad Rosier  if (DestVT != MVT::i16 && DestVT != MVT::i8 && DestVT != MVT::i1)
25900d7b231c9b0acf2ea6bb99f75672751f64c6c6dbChad Rosier    return false;
25910d7b231c9b0acf2ea6bb99f75672751f64c6c6dbChad Rosier
25920d7b231c9b0acf2ea6bb99f75672751f64c6c6dbChad Rosier  unsigned SrcReg = getRegForValue(Op);
25930d7b231c9b0acf2ea6bb99f75672751f64c6c6dbChad Rosier  if (!SrcReg) return false;
25940d7b231c9b0acf2ea6bb99f75672751f64c6c6dbChad Rosier
25950d7b231c9b0acf2ea6bb99f75672751f64c6c6dbChad Rosier  // Because the high bits are undefined, a truncate doesn't generate
25960d7b231c9b0acf2ea6bb99f75672751f64c6c6dbChad Rosier  // any code.
25970d7b231c9b0acf2ea6bb99f75672751f64c6c6dbChad Rosier  UpdateValueMap(I, SrcReg);
25980d7b231c9b0acf2ea6bb99f75672751f64c6c6dbChad Rosier  return true;
25990d7b231c9b0acf2ea6bb99f75672751f64c6c6dbChad Rosier}
26000d7b231c9b0acf2ea6bb99f75672751f64c6c6dbChad Rosier
2601316a5aa0a510e6183dd1981dd8bf328ffe7361f5Chad Rosierunsigned ARMFastISel::ARMEmitIntExt(MVT SrcVT, unsigned SrcReg, MVT DestVT,
260287633026d65acf8253e953bdcfd20bc351631f61Chad Rosier                                    bool isZExt) {
260376927d7303046058c627691bd45d6bff608f49f4Eli Friedman  if (DestVT != MVT::i32 && DestVT != MVT::i16 && DestVT != MVT::i8)
260487633026d65acf8253e953bdcfd20bc351631f61Chad Rosier    return 0;
260576927d7303046058c627691bd45d6bff608f49f4Eli Friedman
260676927d7303046058c627691bd45d6bff608f49f4Eli Friedman  unsigned Opc;
260776927d7303046058c627691bd45d6bff608f49f4Eli Friedman  bool isBoolZext = false;
2608fc17ddd889e3dcb608e8e97c4c791755c21d7b14Chad Rosier  const TargetRegisterClass *RC = TLI.getRegClassFor(MVT::i32);
2609a61b17c18a67f1b3faef2f2108379c4337ce9bb7Patrik Hagglund  switch (SrcVT.SimpleTy) {
261087633026d65acf8253e953bdcfd20bc351631f61Chad Rosier  default: return 0;
261176927d7303046058c627691bd45d6bff608f49f4Eli Friedman  case MVT::i16:
261287633026d65acf8253e953bdcfd20bc351631f61Chad Rosier    if (!Subtarget->hasV6Ops()) return 0;
26136e99a8cb37916dbd2fcc9d150fee006d383a4c54Chad Rosier    RC = isThumb2 ? &ARM::rGPRRegClass : &ARM::GPRnopcRegClass;
26146e99a8cb37916dbd2fcc9d150fee006d383a4c54Chad Rosier    if (isZExt)
261566dc8ca04b719f3ab4aa650609dbd56b055ecb34Chad Rosier      Opc = isThumb2 ? ARM::t2UXTH : ARM::UXTH;
26166e99a8cb37916dbd2fcc9d150fee006d383a4c54Chad Rosier    else
261766dc8ca04b719f3ab4aa650609dbd56b055ecb34Chad Rosier      Opc = isThumb2 ? ARM::t2SXTH : ARM::SXTH;
261876927d7303046058c627691bd45d6bff608f49f4Eli Friedman    break;
261976927d7303046058c627691bd45d6bff608f49f4Eli Friedman  case MVT::i8:
262087633026d65acf8253e953bdcfd20bc351631f61Chad Rosier    if (!Subtarget->hasV6Ops()) return 0;
26216e99a8cb37916dbd2fcc9d150fee006d383a4c54Chad Rosier    RC = isThumb2 ? &ARM::rGPRRegClass : &ARM::GPRnopcRegClass;
26226e99a8cb37916dbd2fcc9d150fee006d383a4c54Chad Rosier    if (isZExt)
262366dc8ca04b719f3ab4aa650609dbd56b055ecb34Chad Rosier      Opc = isThumb2 ? ARM::t2UXTB : ARM::UXTB;
26246e99a8cb37916dbd2fcc9d150fee006d383a4c54Chad Rosier    else
262566dc8ca04b719f3ab4aa650609dbd56b055ecb34Chad Rosier      Opc = isThumb2 ? ARM::t2SXTB : ARM::SXTB;
262676927d7303046058c627691bd45d6bff608f49f4Eli Friedman    break;
262776927d7303046058c627691bd45d6bff608f49f4Eli Friedman  case MVT::i1:
262887633026d65acf8253e953bdcfd20bc351631f61Chad Rosier    if (isZExt) {
2629fc17ddd889e3dcb608e8e97c4c791755c21d7b14Chad Rosier      RC = isThumb2 ? &ARM::rGPRRegClass : &ARM::GPRRegClass;
26306e99a8cb37916dbd2fcc9d150fee006d383a4c54Chad Rosier      Opc = isThumb2 ? ARM::t2ANDri : ARM::ANDri;
263176927d7303046058c627691bd45d6bff608f49f4Eli Friedman      isBoolZext = true;
263276927d7303046058c627691bd45d6bff608f49f4Eli Friedman      break;
263376927d7303046058c627691bd45d6bff608f49f4Eli Friedman    }
263487633026d65acf8253e953bdcfd20bc351631f61Chad Rosier    return 0;
263576927d7303046058c627691bd45d6bff608f49f4Eli Friedman  }
263676927d7303046058c627691bd45d6bff608f49f4Eli Friedman
2637fc17ddd889e3dcb608e8e97c4c791755c21d7b14Chad Rosier  unsigned ResultReg = createResultReg(RC);
263876927d7303046058c627691bd45d6bff608f49f4Eli Friedman  MachineInstrBuilder MIB;
263987633026d65acf8253e953bdcfd20bc351631f61Chad Rosier  MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc), ResultReg)
264076927d7303046058c627691bd45d6bff608f49f4Eli Friedman        .addReg(SrcReg);
264176927d7303046058c627691bd45d6bff608f49f4Eli Friedman  if (isBoolZext)
264276927d7303046058c627691bd45d6bff608f49f4Eli Friedman    MIB.addImm(1);
2643c5a8c861c9f008d777f5da6a77c253fea2bfe2f1Jim Grosbach  else
2644c5a8c861c9f008d777f5da6a77c253fea2bfe2f1Jim Grosbach    MIB.addImm(0);
264576927d7303046058c627691bd45d6bff608f49f4Eli Friedman  AddOptionalDefs(MIB);
264687633026d65acf8253e953bdcfd20bc351631f61Chad Rosier  return ResultReg;
264787633026d65acf8253e953bdcfd20bc351631f61Chad Rosier}
264887633026d65acf8253e953bdcfd20bc351631f61Chad Rosier
264987633026d65acf8253e953bdcfd20bc351631f61Chad Rosierbool ARMFastISel::SelectIntExt(const Instruction *I) {
265087633026d65acf8253e953bdcfd20bc351631f61Chad Rosier  // On ARM, in general, integer casts don't involve legal types; this code
265187633026d65acf8253e953bdcfd20bc351631f61Chad Rosier  // handles promotable integers.
265287633026d65acf8253e953bdcfd20bc351631f61Chad Rosier  Type *DestTy = I->getType();
265387633026d65acf8253e953bdcfd20bc351631f61Chad Rosier  Value *Src = I->getOperand(0);
265487633026d65acf8253e953bdcfd20bc351631f61Chad Rosier  Type *SrcTy = Src->getType();
265587633026d65acf8253e953bdcfd20bc351631f61Chad Rosier
265687633026d65acf8253e953bdcfd20bc351631f61Chad Rosier  bool isZExt = isa<ZExtInst>(I);
265787633026d65acf8253e953bdcfd20bc351631f61Chad Rosier  unsigned SrcReg = getRegForValue(Src);
265887633026d65acf8253e953bdcfd20bc351631f61Chad Rosier  if (!SrcReg) return false;
265987633026d65acf8253e953bdcfd20bc351631f61Chad Rosier
2660316a5aa0a510e6183dd1981dd8bf328ffe7361f5Chad Rosier  EVT SrcEVT, DestEVT;
2661316a5aa0a510e6183dd1981dd8bf328ffe7361f5Chad Rosier  SrcEVT = TLI.getValueType(SrcTy, true);
2662316a5aa0a510e6183dd1981dd8bf328ffe7361f5Chad Rosier  DestEVT = TLI.getValueType(DestTy, true);
2663316a5aa0a510e6183dd1981dd8bf328ffe7361f5Chad Rosier  if (!SrcEVT.isSimple()) return false;
2664316a5aa0a510e6183dd1981dd8bf328ffe7361f5Chad Rosier  if (!DestEVT.isSimple()) return false;
26653d170e64ca1af491e2aa58f882f93b8e8111eef8Patrik Hagglund
2666316a5aa0a510e6183dd1981dd8bf328ffe7361f5Chad Rosier  MVT SrcVT = SrcEVT.getSimpleVT();
2667316a5aa0a510e6183dd1981dd8bf328ffe7361f5Chad Rosier  MVT DestVT = DestEVT.getSimpleVT();
266887633026d65acf8253e953bdcfd20bc351631f61Chad Rosier  unsigned ResultReg = ARMEmitIntExt(SrcVT, SrcReg, DestVT, isZExt);
266987633026d65acf8253e953bdcfd20bc351631f61Chad Rosier  if (ResultReg == 0) return false;
267087633026d65acf8253e953bdcfd20bc351631f61Chad Rosier  UpdateValueMap(I, ResultReg);
267176927d7303046058c627691bd45d6bff608f49f4Eli Friedman  return true;
267276927d7303046058c627691bd45d6bff608f49f4Eli Friedman}
267376927d7303046058c627691bd45d6bff608f49f4Eli Friedman
26742946549a2817681f9117662139cc0f2241939965Jush Lubool ARMFastISel::SelectShift(const Instruction *I,
26752946549a2817681f9117662139cc0f2241939965Jush Lu                              ARM_AM::ShiftOpc ShiftTy) {
26762946549a2817681f9117662139cc0f2241939965Jush Lu  // We handle thumb2 mode by target independent selector
26772946549a2817681f9117662139cc0f2241939965Jush Lu  // or SelectionDAG ISel.
26782946549a2817681f9117662139cc0f2241939965Jush Lu  if (isThumb2)
26792946549a2817681f9117662139cc0f2241939965Jush Lu    return false;
26802946549a2817681f9117662139cc0f2241939965Jush Lu
26812946549a2817681f9117662139cc0f2241939965Jush Lu  // Only handle i32 now.
26822946549a2817681f9117662139cc0f2241939965Jush Lu  EVT DestVT = TLI.getValueType(I->getType(), true);
26832946549a2817681f9117662139cc0f2241939965Jush Lu  if (DestVT != MVT::i32)
26842946549a2817681f9117662139cc0f2241939965Jush Lu    return false;
26852946549a2817681f9117662139cc0f2241939965Jush Lu
26862946549a2817681f9117662139cc0f2241939965Jush Lu  unsigned Opc = ARM::MOVsr;
26872946549a2817681f9117662139cc0f2241939965Jush Lu  unsigned ShiftImm;
26882946549a2817681f9117662139cc0f2241939965Jush Lu  Value *Src2Value = I->getOperand(1);
26892946549a2817681f9117662139cc0f2241939965Jush Lu  if (const ConstantInt *CI = dyn_cast<ConstantInt>(Src2Value)) {
26902946549a2817681f9117662139cc0f2241939965Jush Lu    ShiftImm = CI->getZExtValue();
26912946549a2817681f9117662139cc0f2241939965Jush Lu
26922946549a2817681f9117662139cc0f2241939965Jush Lu    // Fall back to selection DAG isel if the shift amount
26932946549a2817681f9117662139cc0f2241939965Jush Lu    // is zero or greater than the width of the value type.
26942946549a2817681f9117662139cc0f2241939965Jush Lu    if (ShiftImm == 0 || ShiftImm >=32)
26952946549a2817681f9117662139cc0f2241939965Jush Lu      return false;
26962946549a2817681f9117662139cc0f2241939965Jush Lu
26972946549a2817681f9117662139cc0f2241939965Jush Lu    Opc = ARM::MOVsi;
26982946549a2817681f9117662139cc0f2241939965Jush Lu  }
26992946549a2817681f9117662139cc0f2241939965Jush Lu
27002946549a2817681f9117662139cc0f2241939965Jush Lu  Value *Src1Value = I->getOperand(0);
27012946549a2817681f9117662139cc0f2241939965Jush Lu  unsigned Reg1 = getRegForValue(Src1Value);
27022946549a2817681f9117662139cc0f2241939965Jush Lu  if (Reg1 == 0) return false;
27032946549a2817681f9117662139cc0f2241939965Jush Lu
2704e757640df0615510dbc42921cf6271aa76c405eeNadav Rotem  unsigned Reg2 = 0;
27052946549a2817681f9117662139cc0f2241939965Jush Lu  if (Opc == ARM::MOVsr) {
27062946549a2817681f9117662139cc0f2241939965Jush Lu    Reg2 = getRegForValue(Src2Value);
27072946549a2817681f9117662139cc0f2241939965Jush Lu    if (Reg2 == 0) return false;
27082946549a2817681f9117662139cc0f2241939965Jush Lu  }
27092946549a2817681f9117662139cc0f2241939965Jush Lu
27102946549a2817681f9117662139cc0f2241939965Jush Lu  unsigned ResultReg = createResultReg(TLI.getRegClassFor(MVT::i32));
27112946549a2817681f9117662139cc0f2241939965Jush Lu  if(ResultReg == 0) return false;
27122946549a2817681f9117662139cc0f2241939965Jush Lu
27132946549a2817681f9117662139cc0f2241939965Jush Lu  MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
27142946549a2817681f9117662139cc0f2241939965Jush Lu                                    TII.get(Opc), ResultReg)
27152946549a2817681f9117662139cc0f2241939965Jush Lu                            .addReg(Reg1);
27162946549a2817681f9117662139cc0f2241939965Jush Lu
27172946549a2817681f9117662139cc0f2241939965Jush Lu  if (Opc == ARM::MOVsi)
27182946549a2817681f9117662139cc0f2241939965Jush Lu    MIB.addImm(ARM_AM::getSORegOpc(ShiftTy, ShiftImm));
27192946549a2817681f9117662139cc0f2241939965Jush Lu  else if (Opc == ARM::MOVsr) {
27202946549a2817681f9117662139cc0f2241939965Jush Lu    MIB.addReg(Reg2);
27212946549a2817681f9117662139cc0f2241939965Jush Lu    MIB.addImm(ARM_AM::getSORegOpc(ShiftTy, 0));
27222946549a2817681f9117662139cc0f2241939965Jush Lu  }
27232946549a2817681f9117662139cc0f2241939965Jush Lu
27242946549a2817681f9117662139cc0f2241939965Jush Lu  AddOptionalDefs(MIB);
27252946549a2817681f9117662139cc0f2241939965Jush Lu  UpdateValueMap(I, ResultReg);
27262946549a2817681f9117662139cc0f2241939965Jush Lu  return true;
27272946549a2817681f9117662139cc0f2241939965Jush Lu}
27282946549a2817681f9117662139cc0f2241939965Jush Lu
272956d2b72884f98001cefdf8de61d6d7fc00d3df90Eric Christopher// TODO: SoftFP support.
2730ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopherbool ARMFastISel::TargetSelectInstruction(const Instruction *I) {
2731ac1a19e18ad73198ae54cc4bc08000523031f84aEric Christopher
2732ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopher  switch (I->getOpcode()) {
27338300712c1e73dc106242f0007e0e0e4dd9ea38ceEric Christopher    case Instruction::Load:
273443b62beb4cac4337a080c2d3fb8f218a7ffb59c3Eric Christopher      return SelectLoad(I);
2735543cf05b9cb98f50a22cf05137d97bb3bb61f94aEric Christopher    case Instruction::Store:
273643b62beb4cac4337a080c2d3fb8f218a7ffb59c3Eric Christopher      return SelectStore(I);
2737e5734105daf799dea671666059f7ecab6abb389fEric Christopher    case Instruction::Br:
273843b62beb4cac4337a080c2d3fb8f218a7ffb59c3Eric Christopher      return SelectBranch(I);
273960c8fa6bb9db791acf6846fe250c184e3f1df168Chad Rosier    case Instruction::IndirectBr:
274060c8fa6bb9db791acf6846fe250c184e3f1df168Chad Rosier      return SelectIndirectBr(I);
2741d43393ae34ba7e39239d593742eb63086b68f29aEric Christopher    case Instruction::ICmp:
2742d43393ae34ba7e39239d593742eb63086b68f29aEric Christopher    case Instruction::FCmp:
274343b62beb4cac4337a080c2d3fb8f218a7ffb59c3Eric Christopher      return SelectCmp(I);
27444620360842bd8cddc5b1bad7f2f04214c91ac9cbEric Christopher    case Instruction::FPExt:
274543b62beb4cac4337a080c2d3fb8f218a7ffb59c3Eric Christopher      return SelectFPExt(I);
2746ce07b5458d87d5f5ad306a1d86785537e9a3ce0cEric Christopher    case Instruction::FPTrunc:
274743b62beb4cac4337a080c2d3fb8f218a7ffb59c3Eric Christopher      return SelectFPTrunc(I);
27489a040492f7ed084e12a19d56995855c9b5b1d3aaEric Christopher    case Instruction::SIToFP:
2749ae46a3362d6c7fd2d4b1bf3b40982d289d7418fbChad Rosier      return SelectIToFP(I, /*isSigned*/ true);
275036b7beb42921c428fc9f5b5a9cc9feb7fe7dd4b3Chad Rosier    case Instruction::UIToFP:
2751ae46a3362d6c7fd2d4b1bf3b40982d289d7418fbChad Rosier      return SelectIToFP(I, /*isSigned*/ false);
27529a040492f7ed084e12a19d56995855c9b5b1d3aaEric Christopher    case Instruction::FPToSI:
2753ae46a3362d6c7fd2d4b1bf3b40982d289d7418fbChad Rosier      return SelectFPToI(I, /*isSigned*/ true);
2754ee8901c08fb27e98078326706a49dba70e1768a3Chad Rosier    case Instruction::FPToUI:
2755ae46a3362d6c7fd2d4b1bf3b40982d289d7418fbChad Rosier      return SelectFPToI(I, /*isSigned*/ false);
27563901c3e75009f2ec7b4e67c354170dadab9e5a02Chad Rosier    case Instruction::Add:
27573901c3e75009f2ec7b4e67c354170dadab9e5a02Chad Rosier      return SelectBinaryIntOp(I, ISD::ADD);
27586fde8756215a725578b6afe678757f60d7f55d06Chad Rosier    case Instruction::Or:
27596fde8756215a725578b6afe678757f60d7f55d06Chad Rosier      return SelectBinaryIntOp(I, ISD::OR);
2760743e19983effd486c1911f5b797aea7133ea154cChad Rosier    case Instruction::Sub:
2761743e19983effd486c1911f5b797aea7133ea154cChad Rosier      return SelectBinaryIntOp(I, ISD::SUB);
2762bc39b829f2a1f1f0ce3cfe7f9dd99c3402ad2e62Eric Christopher    case Instruction::FAdd:
27633901c3e75009f2ec7b4e67c354170dadab9e5a02Chad Rosier      return SelectBinaryFPOp(I, ISD::FADD);
2764bc39b829f2a1f1f0ce3cfe7f9dd99c3402ad2e62Eric Christopher    case Instruction::FSub:
27653901c3e75009f2ec7b4e67c354170dadab9e5a02Chad Rosier      return SelectBinaryFPOp(I, ISD::FSUB);
2766bc39b829f2a1f1f0ce3cfe7f9dd99c3402ad2e62Eric Christopher    case Instruction::FMul:
27673901c3e75009f2ec7b4e67c354170dadab9e5a02Chad Rosier      return SelectBinaryFPOp(I, ISD::FMUL);
2768bb3e5dad6685dd54625edae789d1a703f4107a69Eric Christopher    case Instruction::SDiv:
27697ccb30b5964675a70559ec25a6bff32f7dea1025Chad Rosier      return SelectDiv(I, /*isSigned*/ true);
27707ccb30b5964675a70559ec25a6bff32f7dea1025Chad Rosier    case Instruction::UDiv:
27717ccb30b5964675a70559ec25a6bff32f7dea1025Chad Rosier      return SelectDiv(I, /*isSigned*/ false);
27726a880d6ba8e489fc85d18cfbc5f8f6187d438630Eric Christopher    case Instruction::SRem:
2773769422f0fce4def419c8cdb72ee967437ffd2f4fChad Rosier      return SelectRem(I, /*isSigned*/ true);
2774769422f0fce4def419c8cdb72ee967437ffd2f4fChad Rosier    case Instruction::URem:
2775769422f0fce4def419c8cdb72ee967437ffd2f4fChad Rosier      return SelectRem(I, /*isSigned*/ false);
2776f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher    case Instruction::Call:
277711add26ec2bdf5109f0ff2ee19d237664687b914Chad Rosier      if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I))
277811add26ec2bdf5109f0ff2ee19d237664687b914Chad Rosier        return SelectIntrinsicCall(*II);
2779f9764fa14fc6e168956bd53e696e8aa4e7b5d42eEric Christopher      return SelectCall(I);
27803bbd396853c7645791417bc795bab4662235ec10Eric Christopher    case Instruction::Select:
27813bbd396853c7645791417bc795bab4662235ec10Eric Christopher      return SelectSelect(I);
27824f512efee9198eb38bf190b0c3fe50429a065d15Eric Christopher    case Instruction::Ret:
27834f512efee9198eb38bf190b0c3fe50429a065d15Eric Christopher      return SelectRet(I);
278476927d7303046058c627691bd45d6bff608f49f4Eli Friedman    case Instruction::Trunc:
27850d7b231c9b0acf2ea6bb99f75672751f64c6c6dbChad Rosier      return SelectTrunc(I);
278676927d7303046058c627691bd45d6bff608f49f4Eli Friedman    case Instruction::ZExt:
278776927d7303046058c627691bd45d6bff608f49f4Eli Friedman    case Instruction::SExt:
27880d7b231c9b0acf2ea6bb99f75672751f64c6c6dbChad Rosier      return SelectIntExt(I);
27892946549a2817681f9117662139cc0f2241939965Jush Lu    case Instruction::Shl:
27902946549a2817681f9117662139cc0f2241939965Jush Lu      return SelectShift(I, ARM_AM::lsl);
27912946549a2817681f9117662139cc0f2241939965Jush Lu    case Instruction::LShr:
27922946549a2817681f9117662139cc0f2241939965Jush Lu      return SelectShift(I, ARM_AM::lsr);
27932946549a2817681f9117662139cc0f2241939965Jush Lu    case Instruction::AShr:
27942946549a2817681f9117662139cc0f2241939965Jush Lu      return SelectShift(I, ARM_AM::asr);
2795ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopher    default: break;
2796ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopher  }
2797ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopher  return false;
2798ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopher}
2799ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopher
2800b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier/// TryToFoldLoad - The specified machine instr operand is a vreg, and that
2801b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier/// vreg is being provided by the specified load instruction.  If possible,
2802b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier/// try to fold the load as an operand to the instruction, returning true if
2803b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier/// successful.
2804b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosierbool ARMFastISel::TryToFoldLoad(MachineInstr *MI, unsigned OpNo,
2805b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier                                const LoadInst *LI) {
2806b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier  // Verify we have a legal type before going any further.
2807b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier  MVT VT;
2808b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier  if (!isLoadTypeLegal(LI->getType(), VT))
2809b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier    return false;
2810b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier
2811b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier  // Combine load followed by zero- or sign-extend.
2812b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier  // ldrb r1, [r0]       ldrb r1, [r0]
2813b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier  // uxtb r2, r1     =>
2814b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier  // mov  r3, r2         mov  r3, r1
2815b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier  bool isZExt = true;
2816b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier  switch(MI->getOpcode()) {
2817b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier    default: return false;
2818b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier    case ARM::SXTH:
2819b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier    case ARM::t2SXTH:
2820b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier      isZExt = false;
2821b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier    case ARM::UXTH:
2822b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier    case ARM::t2UXTH:
2823b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier      if (VT != MVT::i16)
2824b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier        return false;
2825b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier    break;
2826b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier    case ARM::SXTB:
2827b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier    case ARM::t2SXTB:
2828b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier      isZExt = false;
2829b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier    case ARM::UXTB:
2830b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier    case ARM::t2UXTB:
2831b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier      if (VT != MVT::i8)
2832b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier        return false;
2833b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier    break;
2834b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier  }
2835b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier  // See if we can handle this address.
2836b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier  Address Addr;
2837b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier  if (!ARMComputeAddress(LI->getOperand(0), Addr)) return false;
2838efc967e04459753a588ebf5820e526d790fe1cfaJush Lu
2839b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier  unsigned ResultReg = MI->getOperand(0).getReg();
28408a9bce978fa4ca60d3a0ba42a1d44c41463a3c33Chad Rosier  if (!ARMEmitLoad(VT, ResultReg, Addr, LI->getAlignment(), isZExt, false))
2841b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier    return false;
2842b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier  MI->eraseFromParent();
2843b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier  return true;
2844b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier}
2845b29b950bf227b65e193abf924f77ef3fa4eceaaeChad Rosier
28468f50647662560167b88851f92c3c891d2e7c1696Jush Luunsigned ARMFastISel::ARMLowerPICELF(const GlobalValue *GV,
2847a61b17c18a67f1b3faef2f2108379c4337ce9bb7Patrik Hagglund                                     unsigned Align, MVT VT) {
28488f50647662560167b88851f92c3c891d2e7c1696Jush Lu  bool UseGOTOFF = GV->hasLocalLinkage() || GV->hasHiddenVisibility();
28498f50647662560167b88851f92c3c891d2e7c1696Jush Lu  ARMConstantPoolConstant *CPV =
28508f50647662560167b88851f92c3c891d2e7c1696Jush Lu    ARMConstantPoolConstant::Create(GV, UseGOTOFF ? ARMCP::GOTOFF : ARMCP::GOT);
28518f50647662560167b88851f92c3c891d2e7c1696Jush Lu  unsigned Idx = MCP.getConstantPoolIndex(CPV, Align);
28528f50647662560167b88851f92c3c891d2e7c1696Jush Lu
28538f50647662560167b88851f92c3c891d2e7c1696Jush Lu  unsigned Opc;
28548f50647662560167b88851f92c3c891d2e7c1696Jush Lu  unsigned DestReg1 = createResultReg(TLI.getRegClassFor(VT));
28558f50647662560167b88851f92c3c891d2e7c1696Jush Lu  // Load value.
28568f50647662560167b88851f92c3c891d2e7c1696Jush Lu  if (isThumb2) {
28578f50647662560167b88851f92c3c891d2e7c1696Jush Lu    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
28588f50647662560167b88851f92c3c891d2e7c1696Jush Lu                            TII.get(ARM::t2LDRpci), DestReg1)
28598f50647662560167b88851f92c3c891d2e7c1696Jush Lu                    .addConstantPoolIndex(Idx));
28608f50647662560167b88851f92c3c891d2e7c1696Jush Lu    Opc = UseGOTOFF ? ARM::t2ADDrr : ARM::t2LDRs;
28618f50647662560167b88851f92c3c891d2e7c1696Jush Lu  } else {
28628f50647662560167b88851f92c3c891d2e7c1696Jush Lu    // The extra immediate is for addrmode2.
28638f50647662560167b88851f92c3c891d2e7c1696Jush Lu    AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt,
28648f50647662560167b88851f92c3c891d2e7c1696Jush Lu                            DL, TII.get(ARM::LDRcp), DestReg1)
28658f50647662560167b88851f92c3c891d2e7c1696Jush Lu                    .addConstantPoolIndex(Idx).addImm(0));
28668f50647662560167b88851f92c3c891d2e7c1696Jush Lu    Opc = UseGOTOFF ? ARM::ADDrr : ARM::LDRrs;
28678f50647662560167b88851f92c3c891d2e7c1696Jush Lu  }
28688f50647662560167b88851f92c3c891d2e7c1696Jush Lu
28698f50647662560167b88851f92c3c891d2e7c1696Jush Lu  unsigned GlobalBaseReg = AFI->getGlobalBaseReg();
28708f50647662560167b88851f92c3c891d2e7c1696Jush Lu  if (GlobalBaseReg == 0) {
28718f50647662560167b88851f92c3c891d2e7c1696Jush Lu    GlobalBaseReg = MRI.createVirtualRegister(TLI.getRegClassFor(VT));
28728f50647662560167b88851f92c3c891d2e7c1696Jush Lu    AFI->setGlobalBaseReg(GlobalBaseReg);
28738f50647662560167b88851f92c3c891d2e7c1696Jush Lu  }
28748f50647662560167b88851f92c3c891d2e7c1696Jush Lu
28758f50647662560167b88851f92c3c891d2e7c1696Jush Lu  unsigned DestReg2 = createResultReg(TLI.getRegClassFor(VT));
28768f50647662560167b88851f92c3c891d2e7c1696Jush Lu  MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt,
28778f50647662560167b88851f92c3c891d2e7c1696Jush Lu                                    DL, TII.get(Opc), DestReg2)
28788f50647662560167b88851f92c3c891d2e7c1696Jush Lu                            .addReg(DestReg1)
28798f50647662560167b88851f92c3c891d2e7c1696Jush Lu                            .addReg(GlobalBaseReg);
28808f50647662560167b88851f92c3c891d2e7c1696Jush Lu  if (!UseGOTOFF)
28818f50647662560167b88851f92c3c891d2e7c1696Jush Lu    MIB.addImm(0);
28828f50647662560167b88851f92c3c891d2e7c1696Jush Lu  AddOptionalDefs(MIB);
28838f50647662560167b88851f92c3c891d2e7c1696Jush Lu
28848f50647662560167b88851f92c3c891d2e7c1696Jush Lu  return DestReg2;
28858f50647662560167b88851f92c3c891d2e7c1696Jush Lu}
28868f50647662560167b88851f92c3c891d2e7c1696Jush Lu
2887092e5e75661fdd5d54a748fb00fab59d21031268Evan Chengbool ARMFastISel::FastLowerArguments() {
2888092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng  if (!FuncInfo.CanLowerReturn)
2889092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng    return false;
2890092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng
2891092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng  const Function *F = FuncInfo.Fn;
2892092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng  if (F->isVarArg())
2893092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng    return false;
2894092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng
2895092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng  CallingConv::ID CC = F->getCallingConv();
2896092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng  switch (CC) {
2897092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng  default:
2898092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng    return false;
2899092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng  case CallingConv::Fast:
2900092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng  case CallingConv::C:
2901092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng  case CallingConv::ARM_AAPCS_VFP:
2902092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng  case CallingConv::ARM_AAPCS:
2903092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng  case CallingConv::ARM_APCS:
2904092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng    break;
2905092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng  }
2906092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng
2907092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng  // Only handle simple cases. i.e. Up to 4 i8/i16/i32 scalar arguments
2908092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng  // which are passed in r0 - r3.
2909092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng  unsigned Idx = 1;
2910092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng  for (Function::const_arg_iterator I = F->arg_begin(), E = F->arg_end();
2911092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng       I != E; ++I, ++Idx) {
2912092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng    if (Idx > 4)
2913092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng      return false;
2914092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng
2915092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng    if (F->getAttributes().hasAttribute(Idx, Attribute::InReg) ||
2916092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng        F->getAttributes().hasAttribute(Idx, Attribute::StructRet) ||
2917092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng        F->getAttributes().hasAttribute(Idx, Attribute::ByVal))
2918092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng      return false;
2919092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng
2920092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng    Type *ArgTy = I->getType();
2921092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng    if (ArgTy->isStructTy() || ArgTy->isArrayTy() || ArgTy->isVectorTy())
2922092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng      return false;
2923092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng
2924092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng    EVT ArgVT = TLI.getValueType(ArgTy);
2925fe88aa0d148510e41bc3080dea4febcb1445855cChad Rosier    if (!ArgVT.isSimple()) return false;
2926092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng    switch (ArgVT.getSimpleVT().SimpleTy) {
2927092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng    case MVT::i8:
2928092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng    case MVT::i16:
2929092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng    case MVT::i32:
2930092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng      break;
2931092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng    default:
2932092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng      return false;
2933092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng    }
2934092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng  }
2935092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng
2936092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng
2937092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng  static const uint16_t GPRArgRegs[] = {
2938092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng    ARM::R0, ARM::R1, ARM::R2, ARM::R3
2939092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng  };
2940092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng
2941092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng  const TargetRegisterClass *RC = TLI.getRegClassFor(MVT::i32);
2942092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng  Idx = 0;
2943092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng  for (Function::const_arg_iterator I = F->arg_begin(), E = F->arg_end();
2944092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng       I != E; ++I, ++Idx) {
2945092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng    if (I->use_empty())
2946092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng      continue;
2947092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng    unsigned SrcReg = GPRArgRegs[Idx];
2948092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng    unsigned DstReg = FuncInfo.MF->addLiveIn(SrcReg, RC);
2949092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng    // FIXME: Unfortunately it's necessary to emit a copy from the livein copy.
2950092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng    // Without this, EmitLiveInCopies may eliminate the livein if its only
2951092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng    // use is a bitcast (which isn't turned into an instruction).
2952092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng    unsigned ResultReg = createResultReg(RC);
2953092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(TargetOpcode::COPY),
2954092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng            ResultReg).addReg(DstReg, getKillRegState(true));
2955092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng    UpdateValueMap(I, ResultReg);
2956092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng  }
2957092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng
2958092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng  return true;
2959092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng}
2960092e5e75661fdd5d54a748fb00fab59d21031268Evan Cheng
2961ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christophernamespace llvm {
2962d49edb7ab098fa0c82f59efbcf1b4eb2958f8dc3Bob Wilson  FastISel *ARM::createFastISel(FunctionLoweringInfo &funcInfo,
2963d49edb7ab098fa0c82f59efbcf1b4eb2958f8dc3Bob Wilson                                const TargetLibraryInfo *libInfo) {
2964afff941211526a31f931aa9fcac84ae42ff60ef0Evan Cheng    // Completely untested on non-iOS.
2965feadddd6b6c029bc77d6c11a7a637689d15cc7b4Eric Christopher    const TargetMachine &TM = funcInfo.MF->getTarget();
296616cb3763c5a1dad7d6bcbf0fffdfc58c84b46f89Jim Grosbach
2967aaa8df4cad59e41bebba47ce2b4c74c1f0a23c77Eric Christopher    // Darwin and thumb1 only for now.
2968feadddd6b6c029bc77d6c11a7a637689d15cc7b4Eric Christopher    const ARMSubtarget *Subtarget = &TM.getSubtarget<ARMSubtarget>();
29692b3b335f2d2886bbffa005998972de689a9f3e21Chad Rosier    if (Subtarget->isTargetIOS() && !Subtarget->isThumb1Only())
2970d49edb7ab098fa0c82f59efbcf1b4eb2958f8dc3Bob Wilson      return new ARMFastISel(funcInfo, libInfo);
29710944795b8c84612303e9de00bc7e9ea362441227Evan Cheng    return 0;
2972ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopher  }
2973ab695889c67fb499bd902e8a969d0ff02ce66788Eric Christopher}
2974