1dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines//===-- AArch6464FastISel.cpp - AArch64 FastISel implementation -----------===//
236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//
336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//                     The LLVM Compiler Infrastructure
436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//
536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// This file is distributed under the University of Illinois Open Source
636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// License. See LICENSE.TXT for details.
736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//
836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//===----------------------------------------------------------------------===//
936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//
10dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// This file defines the AArch64-specific support for the FastISel class. Some
1136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// of the target-specific code is generated by tablegen in the file
12dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// AArch64GenFastISel.inc, which is #included here.
1336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//
1436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//===----------------------------------------------------------------------===//
1536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
16dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "AArch64.h"
17dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "AArch64TargetMachine.h"
18dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "AArch64Subtarget.h"
19dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "MCTargetDesc/AArch64AddressingModes.h"
2036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/CodeGen/CallingConvLower.h"
2136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/CodeGen/FastISel.h"
2236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/CodeGen/FunctionLoweringInfo.h"
2336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/CodeGen/MachineConstantPool.h"
2436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/CodeGen/MachineFrameInfo.h"
2536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/CodeGen/MachineInstrBuilder.h"
2636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/CodeGen/MachineRegisterInfo.h"
2736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/CallingConv.h"
2836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/DataLayout.h"
2936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/DerivedTypes.h"
3036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/Function.h"
3136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/GetElementPtrTypeIterator.h"
3236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/GlobalAlias.h"
3336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/GlobalVariable.h"
3436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/Instructions.h"
3536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/IntrinsicInst.h"
3636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/Operator.h"
3736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Support/CommandLine.h"
3836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesusing namespace llvm;
3936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
4036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesnamespace {
4136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
42dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesclass AArch64FastISel : public FastISel {
4336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
4436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  class Address {
4536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  public:
4636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    typedef enum {
4736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      RegBase,
4836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      FrameIndexBase
4936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    } BaseKind;
5036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
5136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  private:
5236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    BaseKind Kind;
5336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    union {
5436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      unsigned Reg;
5536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      int FI;
5636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    } Base;
5736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    int64_t Offset;
5836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
5936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  public:
6036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Address() : Kind(RegBase), Offset(0) { Base.Reg = 0; }
6136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    void setKind(BaseKind K) { Kind = K; }
6236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    BaseKind getKind() const { return Kind; }
6336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool isRegBase() const { return Kind == RegBase; }
6436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool isFIBase() const { return Kind == FrameIndexBase; }
6536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    void setReg(unsigned Reg) {
6636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      assert(isRegBase() && "Invalid base register access!");
6736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Base.Reg = Reg;
6836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
6936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned getReg() const {
7036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      assert(isRegBase() && "Invalid base register access!");
7136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return Base.Reg;
7236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
7336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    void setFI(unsigned FI) {
7436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      assert(isFIBase() && "Invalid base frame index  access!");
7536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Base.FI = FI;
7636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
7736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned getFI() const {
7836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      assert(isFIBase() && "Invalid base frame index access!");
7936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return Base.FI;
8036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
8136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    void setOffset(int64_t O) { Offset = O; }
8236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    int64_t getOffset() { return Offset; }
8336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
8436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool isValid() { return isFIBase() || (isRegBase() && getReg() != 0); }
8536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  };
8636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
87dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  /// Subtarget - Keep a pointer to the AArch64Subtarget around so that we can
8836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// make the right decision when generating code for different targets.
89dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const AArch64Subtarget *Subtarget;
9036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  LLVMContext *Context;
9136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
9236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesprivate:
9336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Selection routines.
9436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool SelectLoad(const Instruction *I);
9536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool SelectStore(const Instruction *I);
9636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool SelectBranch(const Instruction *I);
9736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool SelectIndirectBr(const Instruction *I);
9836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool SelectCmp(const Instruction *I);
9936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool SelectSelect(const Instruction *I);
10036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool SelectFPExt(const Instruction *I);
10136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool SelectFPTrunc(const Instruction *I);
10236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool SelectFPToInt(const Instruction *I, bool Signed);
10336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool SelectIntToFP(const Instruction *I, bool Signed);
10436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool SelectRem(const Instruction *I, unsigned ISDOpcode);
10536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool SelectCall(const Instruction *I, const char *IntrMemName);
10636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool SelectIntrinsicCall(const IntrinsicInst &I);
10736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool SelectRet(const Instruction *I);
10836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool SelectTrunc(const Instruction *I);
10936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool SelectIntExt(const Instruction *I);
11036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool SelectMul(const Instruction *I);
11136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
11236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Utility helper routines.
11336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool isTypeLegal(Type *Ty, MVT &VT);
11436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool isLoadStoreTypeLegal(Type *Ty, MVT &VT);
11536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool ComputeAddress(const Value *Obj, Address &Addr);
11636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool SimplifyAddress(Address &Addr, MVT VT, int64_t ScaleFactor,
11736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                       bool UseUnscaled);
11836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void AddLoadStoreOperands(Address &Addr, const MachineInstrBuilder &MIB,
11936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                            unsigned Flags, bool UseUnscaled);
12036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool IsMemCpySmall(uint64_t Len, unsigned Alignment);
12136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool TryEmitSmallMemCpy(Address Dest, Address Src, uint64_t Len,
12236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                          unsigned Alignment);
12336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Emit functions.
12436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool EmitCmp(Value *Src1Value, Value *Src2Value, bool isZExt);
12536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool EmitLoad(MVT VT, unsigned &ResultReg, Address Addr,
12636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                bool UseUnscaled = false);
12736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool EmitStore(MVT VT, unsigned SrcReg, Address Addr,
12836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                 bool UseUnscaled = false);
12936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned EmitIntExt(MVT SrcVT, unsigned SrcReg, MVT DestVT, bool isZExt);
13036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned Emiti1Ext(unsigned SrcReg, MVT DestVT, bool isZExt);
13136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
132dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned AArch64MaterializeFP(const ConstantFP *CFP, MVT VT);
133dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned AArch64MaterializeGV(const GlobalValue *GV);
13436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
13536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Call handling routines.
13636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesprivate:
13736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  CCAssignFn *CCAssignFnForCall(CallingConv::ID CC) const;
13836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool ProcessCallArgs(SmallVectorImpl<Value *> &Args,
13936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                       SmallVectorImpl<unsigned> &ArgRegs,
14036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                       SmallVectorImpl<MVT> &ArgVTs,
14136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                       SmallVectorImpl<ISD::ArgFlagsTy> &ArgFlags,
14236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                       SmallVectorImpl<unsigned> &RegArgs, CallingConv::ID CC,
14336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                       unsigned &NumBytes);
14436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool FinishCall(MVT RetVT, SmallVectorImpl<unsigned> &UsedRegs,
14536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                  const Instruction *I, CallingConv::ID CC, unsigned &NumBytes);
14636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
14736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinespublic:
14836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Backend specific FastISel code.
149dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned TargetMaterializeAlloca(const AllocaInst *AI) override;
150dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned TargetMaterializeConstant(const Constant *C) override;
15136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
152dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  explicit AArch64FastISel(FunctionLoweringInfo &funcInfo,
15336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                         const TargetLibraryInfo *libInfo)
15436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      : FastISel(funcInfo, libInfo) {
155dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Subtarget = &TM.getSubtarget<AArch64Subtarget>();
15636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Context = &funcInfo.Fn->getContext();
15736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
15836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
159dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool TargetSelectInstruction(const Instruction *I) override;
16036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
161dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "AArch64GenFastISel.inc"
16236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines};
16336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
16436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} // end anonymous namespace
16536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
166dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "AArch64GenCallingConv.inc"
16736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
168dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesCCAssignFn *AArch64FastISel::CCAssignFnForCall(CallingConv::ID CC) const {
16936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (CC == CallingConv::WebKit_JS)
170dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return CC_AArch64_WebKit_JS;
171dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return Subtarget->isTargetDarwin() ? CC_AArch64_DarwinPCS : CC_AArch64_AAPCS;
17236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
17336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
174dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesunsigned AArch64FastISel::TargetMaterializeAlloca(const AllocaInst *AI) {
17536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  assert(TLI.getValueType(AI->getType(), true) == MVT::i64 &&
17636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines         "Alloca should always return a pointer.");
17736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
17836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Don't handle dynamic allocas.
17936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!FuncInfo.StaticAllocaMap.count(AI))
18036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return 0;
18136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
18236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  DenseMap<const AllocaInst *, int>::iterator SI =
18336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      FuncInfo.StaticAllocaMap.find(AI);
18436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
18536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (SI != FuncInfo.StaticAllocaMap.end()) {
186dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned ResultReg = createResultReg(&AArch64::GPR64RegClass);
187dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AArch64::ADDXri),
18836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            ResultReg)
18936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        .addFrameIndex(SI->second)
19036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        .addImm(0)
19136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        .addImm(0);
19236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return ResultReg;
19336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
19436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
19536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return 0;
19636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
19736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
198dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesunsigned AArch64FastISel::AArch64MaterializeFP(const ConstantFP *CFP, MVT VT) {
199dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (VT != MVT::f32 && VT != MVT::f64)
200dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return 0;
201dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
20236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const APFloat Val = CFP->getValueAPF();
20336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool is64bit = (VT == MVT::f64);
20436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
20536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // This checks to see if we can use FMOV instructions to materialize
20636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // a constant, otherwise we have to materialize via the constant pool.
20736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (TLI.isFPImmLegal(Val, VT)) {
20836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    int Imm;
20936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned Opc;
21036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (is64bit) {
211dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Imm = AArch64_AM::getFP64Imm(Val);
212dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = AArch64::FMOVDi;
21336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    } else {
214dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Imm = AArch64_AM::getFP32Imm(Val);
215dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = AArch64::FMOVSi;
21636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
21736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned ResultReg = createResultReg(TLI.getRegClassFor(VT));
21836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ResultReg)
21936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        .addImm(Imm);
22036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return ResultReg;
22136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
22236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
22336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Materialize via constant pool.  MachineConstantPool wants an explicit
22436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // alignment.
22536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned Align = DL.getPrefTypeAlignment(CFP->getType());
22636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Align == 0)
22736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Align = DL.getTypeAllocSize(CFP->getType());
22836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
22936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned Idx = MCP.getConstantPoolIndex(cast<Constant>(CFP), Align);
230dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned ADRPReg = createResultReg(&AArch64::GPR64commonRegClass);
231dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AArch64::ADRP),
232dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          ADRPReg).addConstantPoolIndex(Idx, 0, AArch64II::MO_PAGE);
23336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
234dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned Opc = is64bit ? AArch64::LDRDui : AArch64::LDRSui;
23536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned ResultReg = createResultReg(TLI.getRegClassFor(VT));
23636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ResultReg)
23736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      .addReg(ADRPReg)
238dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .addConstantPoolIndex(Idx, 0, AArch64II::MO_PAGEOFF | AArch64II::MO_NC);
23936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return ResultReg;
24036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
24136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
242dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesunsigned AArch64FastISel::AArch64MaterializeGV(const GlobalValue *GV) {
243cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // We can't handle thread-local variables quickly yet.
244cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (GV->isThreadLocal())
245cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return 0;
246dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
247dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // MachO still uses GOT for large code-model accesses, but ELF requires
248dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // movz/movk sequences, which FastISel doesn't handle yet.
249dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (TM.getCodeModel() != CodeModel::Small && !Subtarget->isTargetMachO())
250dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return 0;
25136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
25236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned char OpFlags = Subtarget->ClassifyGlobalReference(GV, TM);
25336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
25436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EVT DestEVT = TLI.getValueType(GV->getType(), true);
25536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!DestEVT.isSimple())
25636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return 0;
25736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
258dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned ADRPReg = createResultReg(&AArch64::GPR64commonRegClass);
259dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned ResultReg;
26036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
261dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (OpFlags & AArch64II::MO_GOT) {
26236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // ADRP + LDRX
263dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AArch64::ADRP),
26436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            ADRPReg)
265dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .addGlobalAddress(GV, 0, AArch64II::MO_GOT | AArch64II::MO_PAGE);
266dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
267dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    ResultReg = createResultReg(&AArch64::GPR64RegClass);
268dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AArch64::LDRXui),
26936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            ResultReg)
27036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        .addReg(ADRPReg)
271dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .addGlobalAddress(GV, 0, AArch64II::MO_GOT | AArch64II::MO_PAGEOFF |
272dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                          AArch64II::MO_NC);
27336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  } else {
27436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // ADRP + ADDX
275dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AArch64::ADRP),
276dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            ADRPReg).addGlobalAddress(GV, 0, AArch64II::MO_PAGE);
277dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
278dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    ResultReg = createResultReg(&AArch64::GPR64spRegClass);
279dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AArch64::ADDXri),
28036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            ResultReg)
28136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        .addReg(ADRPReg)
282dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .addGlobalAddress(GV, 0, AArch64II::MO_PAGEOFF | AArch64II::MO_NC)
28336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        .addImm(0);
28436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
28536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return ResultReg;
28636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
28736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
288dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesunsigned AArch64FastISel::TargetMaterializeConstant(const Constant *C) {
28936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EVT CEVT = TLI.getValueType(C->getType(), true);
29036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
29136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Only handle simple types.
29236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!CEVT.isSimple())
29336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return 0;
29436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MVT VT = CEVT.getSimpleVT();
29536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
29636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // FIXME: Handle ConstantInt.
29736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (const ConstantFP *CFP = dyn_cast<ConstantFP>(C))
298dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return AArch64MaterializeFP(CFP, VT);
29936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  else if (const GlobalValue *GV = dyn_cast<GlobalValue>(C))
300dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return AArch64MaterializeGV(GV);
30136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
30236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return 0;
30336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
30436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
30536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// Computes the address to get to an object.
306dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64FastISel::ComputeAddress(const Value *Obj, Address &Addr) {
307dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const User *U = nullptr;
30836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned Opcode = Instruction::UserOp1;
30936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (const Instruction *I = dyn_cast<Instruction>(Obj)) {
31036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Don't walk into other basic blocks unless the object is an alloca from
31136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // another block, otherwise it may not have a virtual register assigned.
31236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (FuncInfo.StaticAllocaMap.count(static_cast<const AllocaInst *>(Obj)) ||
31336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        FuncInfo.MBBMap[I->getParent()] == FuncInfo.MBB) {
31436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Opcode = I->getOpcode();
31536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      U = I;
31636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
31736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  } else if (const ConstantExpr *C = dyn_cast<ConstantExpr>(Obj)) {
31836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Opcode = C->getOpcode();
31936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    U = C;
32036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
32136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
32236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (const PointerType *Ty = dyn_cast<PointerType>(Obj->getType()))
32336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (Ty->getAddressSpace() > 255)
32436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // Fast instruction selection doesn't support the special
32536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // address spaces.
32636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return false;
32736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
32836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  switch (Opcode) {
32936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  default:
33036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
33136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case Instruction::BitCast: {
33236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Look through bitcasts.
33336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return ComputeAddress(U->getOperand(0), Addr);
33436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
33536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case Instruction::IntToPtr: {
33636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Look past no-op inttoptrs.
33736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (TLI.getValueType(U->getOperand(0)->getType()) == TLI.getPointerTy())
33836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return ComputeAddress(U->getOperand(0), Addr);
33936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
34036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
34136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case Instruction::PtrToInt: {
34236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Look past no-op ptrtoints.
34336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (TLI.getValueType(U->getType()) == TLI.getPointerTy())
34436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return ComputeAddress(U->getOperand(0), Addr);
34536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
34636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
34736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case Instruction::GetElementPtr: {
34836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Address SavedAddr = Addr;
34936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    uint64_t TmpOffset = Addr.getOffset();
35036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
35136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Iterate through the GEP folding the constants into offsets where
35236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // we can.
35336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    gep_type_iterator GTI = gep_type_begin(U);
35436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    for (User::const_op_iterator i = U->op_begin() + 1, e = U->op_end(); i != e;
35536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines         ++i, ++GTI) {
35636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      const Value *Op = *i;
35736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (StructType *STy = dyn_cast<StructType>(*GTI)) {
35836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        const StructLayout *SL = DL.getStructLayout(STy);
35936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        unsigned Idx = cast<ConstantInt>(Op)->getZExtValue();
36036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        TmpOffset += SL->getElementOffset(Idx);
36136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      } else {
36236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        uint64_t S = DL.getTypeAllocSize(GTI.getIndexedType());
36336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        for (;;) {
36436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          if (const ConstantInt *CI = dyn_cast<ConstantInt>(Op)) {
36536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            // Constant-offset addressing.
36636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            TmpOffset += CI->getSExtValue() * S;
36736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            break;
36836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          }
36936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          if (canFoldAddIntoGEP(U, Op)) {
37036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            // A compatible add with a constant operand. Fold the constant.
37136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            ConstantInt *CI =
37236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                cast<ConstantInt>(cast<AddOperator>(Op)->getOperand(1));
37336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            TmpOffset += CI->getSExtValue() * S;
37436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            // Iterate on the other operand.
37536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            Op = cast<AddOperator>(Op)->getOperand(0);
37636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            continue;
37736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          }
37836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          // Unsupported
37936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          goto unsupported_gep;
38036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        }
38136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      }
38236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
38336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
38436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Try to grab the base operand now.
38536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Addr.setOffset(TmpOffset);
38636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (ComputeAddress(U->getOperand(0), Addr))
38736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return true;
38836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
38936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // We failed, restore everything and try the other options.
39036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Addr = SavedAddr;
39136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
39236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsupported_gep:
39336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
39436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
39536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case Instruction::Alloca: {
39636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const AllocaInst *AI = cast<AllocaInst>(Obj);
39736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    DenseMap<const AllocaInst *, int>::iterator SI =
39836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        FuncInfo.StaticAllocaMap.find(AI);
39936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (SI != FuncInfo.StaticAllocaMap.end()) {
40036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Addr.setKind(Address::FrameIndexBase);
40136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Addr.setFI(SI->second);
40236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return true;
40336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
40436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
40536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
40636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
40736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
40836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Try to get this in a register if nothing else has worked.
40936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!Addr.isValid())
41036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Addr.setReg(getRegForValue(Obj));
41136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return Addr.isValid();
41236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
41336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
414dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64FastISel::isTypeLegal(Type *Ty, MVT &VT) {
41536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EVT evt = TLI.getValueType(Ty, true);
41636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
41736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Only handle simple types.
41836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (evt == MVT::Other || !evt.isSimple())
41936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
42036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  VT = evt.getSimpleVT();
42136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
422dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // This is a legal type, but it's not something we handle in fast-isel.
423dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (VT == MVT::f128)
424dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return false;
425dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
426dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Handle all other legal types, i.e. a register that will directly hold this
42736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // value.
42836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return TLI.isTypeLegal(VT);
42936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
43036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
431dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64FastISel::isLoadStoreTypeLegal(Type *Ty, MVT &VT) {
43236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (isTypeLegal(Ty, VT))
43336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return true;
43436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
43536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // If this is a type than can be sign or zero-extended to a basic operation
43636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // go ahead and accept it now. For stores, this reflects truncation.
43736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (VT == MVT::i1 || VT == MVT::i8 || VT == MVT::i16)
43836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return true;
43936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
44036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return false;
44136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
44236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
443dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64FastISel::SimplifyAddress(Address &Addr, MVT VT,
444dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                      int64_t ScaleFactor, bool UseUnscaled) {
44536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool needsLowering = false;
44636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  int64_t Offset = Addr.getOffset();
44736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  switch (VT.SimpleTy) {
44836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  default:
44936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
45036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MVT::i1:
45136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MVT::i8:
45236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MVT::i16:
45336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MVT::i32:
45436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MVT::i64:
45536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MVT::f32:
45636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MVT::f64:
45736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (!UseUnscaled)
45836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // Using scaled, 12-bit, unsigned immediate offsets.
45936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      needsLowering = ((Offset & 0xfff) != Offset);
46036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    else
46136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // Using unscaled, 9-bit, signed immediate offsets.
46236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      needsLowering = (Offset > 256 || Offset < -256);
46336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
46436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
46536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
466cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  //If this is a stack pointer and the offset needs to be simplified then put
467cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // the alloca address into a register, set the base type back to register and
468cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // continue. This should almost never happen.
46936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (needsLowering && Addr.getKind() == Address::FrameIndexBase) {
470cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    unsigned ResultReg = createResultReg(&AArch64::GPR64RegClass);
471cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AArch64::ADDXri),
472cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines            ResultReg)
473cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        .addFrameIndex(Addr.getFI())
474cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        .addImm(0)
475cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        .addImm(0);
476cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    Addr.setKind(Address::RegBase);
477cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    Addr.setReg(ResultReg);
47836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
47936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
48036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Since the offset is too large for the load/store instruction get the
48136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // reg+offset into a register.
48236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (needsLowering) {
48336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    uint64_t UnscaledOffset = Addr.getOffset() * ScaleFactor;
48436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned ResultReg = FastEmit_ri_(MVT::i64, ISD::ADD, Addr.getReg(), false,
48536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                      UnscaledOffset, MVT::i64);
48636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (ResultReg == 0)
48736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return false;
48836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Addr.setReg(ResultReg);
48936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Addr.setOffset(0);
49036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
49136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return true;
49236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
49336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
494dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid AArch64FastISel::AddLoadStoreOperands(Address &Addr,
495dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                           const MachineInstrBuilder &MIB,
496dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                           unsigned Flags, bool UseUnscaled) {
49736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  int64_t Offset = Addr.getOffset();
49836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Frame base works a bit differently. Handle it separately.
49936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Addr.getKind() == Address::FrameIndexBase) {
50036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    int FI = Addr.getFI();
50136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // FIXME: We shouldn't be using getObjectSize/getObjectAlignment.  The size
50236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // and alignment should be based on the VT.
50336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    MachineMemOperand *MMO = FuncInfo.MF->getMachineMemOperand(
50436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        MachinePointerInfo::getFixedStack(FI, Offset), Flags,
50536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        MFI.getObjectSize(FI), MFI.getObjectAlignment(FI));
50636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Now add the rest of the operands.
50736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    MIB.addFrameIndex(FI).addImm(Offset).addMemOperand(MMO);
50836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  } else {
50936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Now add the rest of the operands.
51036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    MIB.addReg(Addr.getReg());
51136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    MIB.addImm(Offset);
51236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
51336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
51436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
515dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64FastISel::EmitLoad(MVT VT, unsigned &ResultReg, Address Addr,
516dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                               bool UseUnscaled) {
51736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Negative offsets require unscaled, 9-bit, signed immediate offsets.
51836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Otherwise, we try using scaled, 12-bit, unsigned immediate offsets.
51936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!UseUnscaled && Addr.getOffset() < 0)
52036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    UseUnscaled = true;
52136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
52236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned Opc;
52336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const TargetRegisterClass *RC;
52436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool VTIsi1 = false;
52536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  int64_t ScaleFactor = 0;
52636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  switch (VT.SimpleTy) {
52736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  default:
52836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
52936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MVT::i1:
53036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    VTIsi1 = true;
53136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Intentional fall-through.
53236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MVT::i8:
533dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Opc = UseUnscaled ? AArch64::LDURBBi : AArch64::LDRBBui;
534dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    RC = &AArch64::GPR32RegClass;
53536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    ScaleFactor = 1;
53636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
53736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MVT::i16:
538dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Opc = UseUnscaled ? AArch64::LDURHHi : AArch64::LDRHHui;
539dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    RC = &AArch64::GPR32RegClass;
54036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    ScaleFactor = 2;
54136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
54236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MVT::i32:
543dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Opc = UseUnscaled ? AArch64::LDURWi : AArch64::LDRWui;
544dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    RC = &AArch64::GPR32RegClass;
54536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    ScaleFactor = 4;
54636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
54736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MVT::i64:
548dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Opc = UseUnscaled ? AArch64::LDURXi : AArch64::LDRXui;
549dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    RC = &AArch64::GPR64RegClass;
55036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    ScaleFactor = 8;
55136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
55236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MVT::f32:
553dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Opc = UseUnscaled ? AArch64::LDURSi : AArch64::LDRSui;
55436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    RC = TLI.getRegClassFor(VT);
55536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    ScaleFactor = 4;
55636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
55736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MVT::f64:
558dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Opc = UseUnscaled ? AArch64::LDURDi : AArch64::LDRDui;
55936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    RC = TLI.getRegClassFor(VT);
56036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    ScaleFactor = 8;
56136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
56236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
56336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Scale the offset.
56436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!UseUnscaled) {
56536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    int64_t Offset = Addr.getOffset();
56636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (Offset & (ScaleFactor - 1))
56736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // Retry using an unscaled, 9-bit, signed immediate offset.
56836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return EmitLoad(VT, ResultReg, Addr, /*UseUnscaled*/ true);
56936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
57036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Addr.setOffset(Offset / ScaleFactor);
57136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
57236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
57336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Simplify this down to something we can handle.
57436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!SimplifyAddress(Addr, VT, UseUnscaled ? 1 : ScaleFactor, UseUnscaled))
57536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
57636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
57736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Create the base instruction, then add the operands.
57836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ResultReg = createResultReg(RC);
57936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
58036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                    TII.get(Opc), ResultReg);
58136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  AddLoadStoreOperands(Addr, MIB, MachineMemOperand::MOLoad, UseUnscaled);
58236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
58336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Loading an i1 requires special handling.
58436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (VTIsi1) {
585dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MRI.constrainRegClass(ResultReg, &AArch64::GPR32RegClass);
586dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned ANDReg = createResultReg(&AArch64::GPR32spRegClass);
587dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AArch64::ANDWri),
58836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            ANDReg)
58936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        .addReg(ResultReg)
590dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .addImm(AArch64_AM::encodeLogicalImmediate(1, 32));
59136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    ResultReg = ANDReg;
59236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
59336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return true;
59436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
59536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
596dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64FastISel::SelectLoad(const Instruction *I) {
59736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MVT VT;
59836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Verify we have a legal type before going any further.  Currently, we handle
59936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // simple types that will directly fit in a register (i32/f32/i64/f64) or
60036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // those that can be sign or zero-extended to a basic operation (i1/i8/i16).
60136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!isLoadStoreTypeLegal(I->getType(), VT) || cast<LoadInst>(I)->isAtomic())
60236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
60336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
60436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // See if we can handle this address.
60536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Address Addr;
60636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!ComputeAddress(I->getOperand(0), Addr))
60736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
60836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
60936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned ResultReg;
61036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!EmitLoad(VT, ResultReg, Addr))
61136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
61236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
61336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  UpdateValueMap(I, ResultReg);
61436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return true;
61536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
61636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
617dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64FastISel::EmitStore(MVT VT, unsigned SrcReg, Address Addr,
618dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                bool UseUnscaled) {
61936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Negative offsets require unscaled, 9-bit, signed immediate offsets.
62036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Otherwise, we try using scaled, 12-bit, unsigned immediate offsets.
62136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!UseUnscaled && Addr.getOffset() < 0)
62236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    UseUnscaled = true;
62336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
62436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned StrOpc;
62536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool VTIsi1 = false;
62636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  int64_t ScaleFactor = 0;
62736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Using scaled, 12-bit, unsigned immediate offsets.
62836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  switch (VT.SimpleTy) {
62936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  default:
63036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
63136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MVT::i1:
63236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    VTIsi1 = true;
63336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MVT::i8:
634dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    StrOpc = UseUnscaled ? AArch64::STURBBi : AArch64::STRBBui;
63536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    ScaleFactor = 1;
63636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
63736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MVT::i16:
638dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    StrOpc = UseUnscaled ? AArch64::STURHHi : AArch64::STRHHui;
63936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    ScaleFactor = 2;
64036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
64136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MVT::i32:
642dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    StrOpc = UseUnscaled ? AArch64::STURWi : AArch64::STRWui;
64336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    ScaleFactor = 4;
64436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
64536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MVT::i64:
646dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    StrOpc = UseUnscaled ? AArch64::STURXi : AArch64::STRXui;
64736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    ScaleFactor = 8;
64836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
64936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MVT::f32:
650dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    StrOpc = UseUnscaled ? AArch64::STURSi : AArch64::STRSui;
65136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    ScaleFactor = 4;
65236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
65336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MVT::f64:
654dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    StrOpc = UseUnscaled ? AArch64::STURDi : AArch64::STRDui;
65536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    ScaleFactor = 8;
65636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
65736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
65836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Scale the offset.
65936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!UseUnscaled) {
66036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    int64_t Offset = Addr.getOffset();
66136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (Offset & (ScaleFactor - 1))
66236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // Retry using an unscaled, 9-bit, signed immediate offset.
66336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return EmitStore(VT, SrcReg, Addr, /*UseUnscaled*/ true);
66436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
66536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Addr.setOffset(Offset / ScaleFactor);
66636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
66736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
66836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Simplify this down to something we can handle.
66936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!SimplifyAddress(Addr, VT, UseUnscaled ? 1 : ScaleFactor, UseUnscaled))
67036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
67136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
67236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Storing an i1 requires special handling.
67336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (VTIsi1) {
674dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MRI.constrainRegClass(SrcReg, &AArch64::GPR32RegClass);
675dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned ANDReg = createResultReg(&AArch64::GPR32spRegClass);
676dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AArch64::ANDWri),
67736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            ANDReg)
67836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        .addReg(SrcReg)
679dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .addImm(AArch64_AM::encodeLogicalImmediate(1, 32));
68036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    SrcReg = ANDReg;
68136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
68236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Create the base instruction, then add the operands.
68336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
68436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                    TII.get(StrOpc)).addReg(SrcReg);
68536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  AddLoadStoreOperands(Addr, MIB, MachineMemOperand::MOStore, UseUnscaled);
68636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return true;
68736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
68836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
689dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64FastISel::SelectStore(const Instruction *I) {
69036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MVT VT;
69136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Value *Op0 = I->getOperand(0);
69236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Verify we have a legal type before going any further.  Currently, we handle
69336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // simple types that will directly fit in a register (i32/f32/i64/f64) or
69436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // those that can be sign or zero-extended to a basic operation (i1/i8/i16).
69536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!isLoadStoreTypeLegal(Op0->getType(), VT) ||
69636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      cast<StoreInst>(I)->isAtomic())
69736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
69836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
69936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Get the value to be stored into a register.
70036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned SrcReg = getRegForValue(Op0);
70136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (SrcReg == 0)
70236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
70336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
70436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // See if we can handle this address.
70536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Address Addr;
70636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!ComputeAddress(I->getOperand(1), Addr))
70736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
70836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
70936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!EmitStore(VT, SrcReg, Addr))
71036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
71136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return true;
71236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
71336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
714dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic AArch64CC::CondCode getCompareCC(CmpInst::Predicate Pred) {
71536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  switch (Pred) {
71636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case CmpInst::FCMP_ONE:
71736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case CmpInst::FCMP_UEQ:
71836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  default:
71936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // AL is our "false" for now. The other two need more compares.
720dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return AArch64CC::AL;
72136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case CmpInst::ICMP_EQ:
72236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case CmpInst::FCMP_OEQ:
723dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return AArch64CC::EQ;
72436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case CmpInst::ICMP_SGT:
72536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case CmpInst::FCMP_OGT:
726dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return AArch64CC::GT;
72736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case CmpInst::ICMP_SGE:
72836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case CmpInst::FCMP_OGE:
729dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return AArch64CC::GE;
73036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case CmpInst::ICMP_UGT:
73136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case CmpInst::FCMP_UGT:
732dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return AArch64CC::HI;
73336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case CmpInst::FCMP_OLT:
734dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return AArch64CC::MI;
73536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case CmpInst::ICMP_ULE:
73636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case CmpInst::FCMP_OLE:
737dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return AArch64CC::LS;
73836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case CmpInst::FCMP_ORD:
739dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return AArch64CC::VC;
74036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case CmpInst::FCMP_UNO:
741dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return AArch64CC::VS;
74236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case CmpInst::FCMP_UGE:
743dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return AArch64CC::PL;
74436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case CmpInst::ICMP_SLT:
74536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case CmpInst::FCMP_ULT:
746dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return AArch64CC::LT;
74736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case CmpInst::ICMP_SLE:
74836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case CmpInst::FCMP_ULE:
749dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return AArch64CC::LE;
75036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case CmpInst::FCMP_UNE:
75136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case CmpInst::ICMP_NE:
752dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return AArch64CC::NE;
75336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case CmpInst::ICMP_UGE:
754dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return AArch64CC::HS;
75536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case CmpInst::ICMP_ULT:
756dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return AArch64CC::LO;
75736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
75836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
75936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
760dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64FastISel::SelectBranch(const Instruction *I) {
76136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const BranchInst *BI = cast<BranchInst>(I);
76236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MachineBasicBlock *TBB = FuncInfo.MBBMap[BI->getSuccessor(0)];
76336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MachineBasicBlock *FBB = FuncInfo.MBBMap[BI->getSuccessor(1)];
76436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
76536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (const CmpInst *CI = dyn_cast<CmpInst>(BI->getCondition())) {
76636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (CI->hasOneUse() && (CI->getParent() == I->getParent())) {
76736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // We may not handle every CC for now.
768dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      AArch64CC::CondCode CC = getCompareCC(CI->getPredicate());
769dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (CC == AArch64CC::AL)
77036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        return false;
77136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
77236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // Emit the cmp.
77336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (!EmitCmp(CI->getOperand(0), CI->getOperand(1), CI->isUnsigned()))
77436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        return false;
77536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
77636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // Emit the branch.
777dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AArch64::Bcc))
77836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          .addImm(CC)
77936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          .addMBB(TBB);
78036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      FuncInfo.MBB->addSuccessor(TBB);
78136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
78236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      FastEmitBranch(FBB, DbgLoc);
78336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return true;
78436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
78536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  } else if (TruncInst *TI = dyn_cast<TruncInst>(BI->getCondition())) {
78636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    MVT SrcVT;
78736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (TI->hasOneUse() && TI->getParent() == I->getParent() &&
78836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        (isLoadStoreTypeLegal(TI->getOperand(0)->getType(), SrcVT))) {
78936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      unsigned CondReg = getRegForValue(TI->getOperand(0));
79036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (CondReg == 0)
79136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        return false;
79236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
79336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // Issue an extract_subreg to get the lower 32-bits.
79436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (SrcVT == MVT::i64)
79536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        CondReg = FastEmitInst_extractsubreg(MVT::i32, CondReg, /*Kill=*/true,
796dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                             AArch64::sub_32);
79736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
798dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      MRI.constrainRegClass(CondReg, &AArch64::GPR32RegClass);
799dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      unsigned ANDReg = createResultReg(&AArch64::GPR32spRegClass);
800dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
801dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines              TII.get(AArch64::ANDWri), ANDReg)
80236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          .addReg(CondReg)
803dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addImm(AArch64_AM::encodeLogicalImmediate(1, 32));
804dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
805dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines              TII.get(AArch64::SUBSWri))
80636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          .addReg(ANDReg)
80736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          .addReg(ANDReg)
80836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          .addImm(0)
80936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          .addImm(0);
81036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
811dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      unsigned CC = AArch64CC::NE;
81236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (FuncInfo.MBB->isLayoutSuccessor(TBB)) {
81336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        std::swap(TBB, FBB);
814dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        CC = AArch64CC::EQ;
81536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      }
816dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AArch64::Bcc))
81736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          .addImm(CC)
81836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          .addMBB(TBB);
81936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      FuncInfo.MBB->addSuccessor(TBB);
82036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      FastEmitBranch(FBB, DbgLoc);
82136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return true;
82236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
82336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  } else if (const ConstantInt *CI =
82436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                 dyn_cast<ConstantInt>(BI->getCondition())) {
82536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    uint64_t Imm = CI->getZExtValue();
82636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    MachineBasicBlock *Target = (Imm == 0) ? FBB : TBB;
827dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AArch64::B))
82836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        .addMBB(Target);
82936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    FuncInfo.MBB->addSuccessor(Target);
83036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return true;
83136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
83236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
83336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned CondReg = getRegForValue(BI->getCondition());
83436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (CondReg == 0)
83536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
83636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
83736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // We've been divorced from our compare!  Our block was split, and
83836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // now our compare lives in a predecessor block.  We musn't
83936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // re-compare here, as the children of the compare aren't guaranteed
84036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // live across the block boundary (we *could* check for this).
84136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Regardless, the compare has been done in the predecessor block,
84236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // and it left a value for us in a virtual register.  Ergo, we test
84336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // the one-bit value left in the virtual register.
844dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AArch64::SUBSWri),
845dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          AArch64::WZR)
84636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      .addReg(CondReg)
84736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      .addImm(0)
84836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      .addImm(0);
84936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
850dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned CC = AArch64CC::NE;
85136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (FuncInfo.MBB->isLayoutSuccessor(TBB)) {
85236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    std::swap(TBB, FBB);
853dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    CC = AArch64CC::EQ;
85436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
85536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
856dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AArch64::Bcc))
85736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      .addImm(CC)
85836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      .addMBB(TBB);
85936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  FuncInfo.MBB->addSuccessor(TBB);
86036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  FastEmitBranch(FBB, DbgLoc);
86136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return true;
86236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
86336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
864dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64FastISel::SelectIndirectBr(const Instruction *I) {
86536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const IndirectBrInst *BI = cast<IndirectBrInst>(I);
86636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned AddrReg = getRegForValue(BI->getOperand(0));
86736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (AddrReg == 0)
86836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
86936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
87036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Emit the indirect branch.
871dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AArch64::BR))
87236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      .addReg(AddrReg);
87336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
87436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Make sure the CFG is up-to-date.
87536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  for (unsigned i = 0, e = BI->getNumSuccessors(); i != e; ++i)
87636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    FuncInfo.MBB->addSuccessor(FuncInfo.MBBMap[BI->getSuccessor(i)]);
87736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
87836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return true;
87936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
88036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
881dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64FastISel::EmitCmp(Value *Src1Value, Value *Src2Value, bool isZExt) {
88236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Type *Ty = Src1Value->getType();
88336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EVT SrcEVT = TLI.getValueType(Ty, true);
88436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!SrcEVT.isSimple())
88536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
88636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MVT SrcVT = SrcEVT.getSimpleVT();
88736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
88836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Check to see if the 2nd operand is a constant that we can encode directly
88936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // in the compare.
89036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint64_t Imm;
89136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool UseImm = false;
89236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool isNegativeImm = false;
89336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (const ConstantInt *ConstInt = dyn_cast<ConstantInt>(Src2Value)) {
89436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (SrcVT == MVT::i64 || SrcVT == MVT::i32 || SrcVT == MVT::i16 ||
89536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        SrcVT == MVT::i8 || SrcVT == MVT::i1) {
89636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      const APInt &CIVal = ConstInt->getValue();
89736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
89836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Imm = (isZExt) ? CIVal.getZExtValue() : CIVal.getSExtValue();
89936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (CIVal.isNegative()) {
90036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        isNegativeImm = true;
90136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        Imm = -Imm;
90236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      }
90336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // FIXME: We can handle more immediates using shifts.
90436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      UseImm = ((Imm & 0xfff) == Imm);
90536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
90636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  } else if (const ConstantFP *ConstFP = dyn_cast<ConstantFP>(Src2Value)) {
90736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (SrcVT == MVT::f32 || SrcVT == MVT::f64)
90836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (ConstFP->isZero() && !ConstFP->isNegative())
90936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        UseImm = true;
91036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
91136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
91236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned ZReg;
91336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned CmpOpc;
91436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool isICmp = true;
91536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool needsExt = false;
91636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  switch (SrcVT.SimpleTy) {
91736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  default:
91836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
91936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MVT::i1:
92036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MVT::i8:
92136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MVT::i16:
92236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    needsExt = true;
92336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Intentional fall-through.
92436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MVT::i32:
925dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    ZReg = AArch64::WZR;
92636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (UseImm)
927dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      CmpOpc = isNegativeImm ? AArch64::ADDSWri : AArch64::SUBSWri;
92836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    else
929dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      CmpOpc = AArch64::SUBSWrr;
93036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
93136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MVT::i64:
932dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    ZReg = AArch64::XZR;
93336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (UseImm)
934dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      CmpOpc = isNegativeImm ? AArch64::ADDSXri : AArch64::SUBSXri;
93536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    else
936dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      CmpOpc = AArch64::SUBSXrr;
93736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
93836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MVT::f32:
93936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    isICmp = false;
940dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    CmpOpc = UseImm ? AArch64::FCMPSri : AArch64::FCMPSrr;
94136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
94236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MVT::f64:
94336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    isICmp = false;
944dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    CmpOpc = UseImm ? AArch64::FCMPDri : AArch64::FCMPDrr;
94536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
94636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
94736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
94836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned SrcReg1 = getRegForValue(Src1Value);
94936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (SrcReg1 == 0)
95036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
95136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
95236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned SrcReg2;
95336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!UseImm) {
95436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    SrcReg2 = getRegForValue(Src2Value);
95536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (SrcReg2 == 0)
95636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return false;
95736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
95836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
95936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // We have i1, i8, or i16, we need to either zero extend or sign extend.
96036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (needsExt) {
96136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    SrcReg1 = EmitIntExt(SrcVT, SrcReg1, MVT::i32, isZExt);
96236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (SrcReg1 == 0)
96336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return false;
96436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (!UseImm) {
96536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      SrcReg2 = EmitIntExt(SrcVT, SrcReg2, MVT::i32, isZExt);
96636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (SrcReg2 == 0)
96736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        return false;
96836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
96936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
97036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
97136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (isICmp) {
97236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (UseImm)
97336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(CmpOpc))
97436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          .addReg(ZReg)
97536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          .addReg(SrcReg1)
97636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          .addImm(Imm)
97736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          .addImm(0);
97836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    else
97936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(CmpOpc))
98036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          .addReg(ZReg)
98136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          .addReg(SrcReg1)
98236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          .addReg(SrcReg2);
98336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  } else {
98436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (UseImm)
98536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(CmpOpc))
98636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          .addReg(SrcReg1);
98736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    else
98836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(CmpOpc))
98936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          .addReg(SrcReg1)
99036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          .addReg(SrcReg2);
99136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
99236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return true;
99336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
99436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
995dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64FastISel::SelectCmp(const Instruction *I) {
99636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const CmpInst *CI = cast<CmpInst>(I);
99736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
99836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // We may not handle every CC for now.
999dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  AArch64CC::CondCode CC = getCompareCC(CI->getPredicate());
1000dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (CC == AArch64CC::AL)
100136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
100236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
100336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Emit the cmp.
100436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!EmitCmp(CI->getOperand(0), CI->getOperand(1), CI->isUnsigned()))
100536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
100636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
100736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Now set a register based on the comparison.
1008dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  AArch64CC::CondCode invertedCC = getInvertedCondCode(CC);
1009dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned ResultReg = createResultReg(&AArch64::GPR32RegClass);
1010dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AArch64::CSINCWr),
101136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          ResultReg)
1012dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .addReg(AArch64::WZR)
1013dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .addReg(AArch64::WZR)
101436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      .addImm(invertedCC);
101536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
101636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  UpdateValueMap(I, ResultReg);
101736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return true;
101836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
101936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1020dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64FastISel::SelectSelect(const Instruction *I) {
102136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const SelectInst *SI = cast<SelectInst>(I);
102236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
102336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EVT DestEVT = TLI.getValueType(SI->getType(), true);
102436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!DestEVT.isSimple())
102536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
102636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
102736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MVT DestVT = DestEVT.getSimpleVT();
102836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (DestVT != MVT::i32 && DestVT != MVT::i64 && DestVT != MVT::f32 &&
102936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      DestVT != MVT::f64)
103036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
103136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
103236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned CondReg = getRegForValue(SI->getCondition());
103336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (CondReg == 0)
103436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
103536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned TrueReg = getRegForValue(SI->getTrueValue());
103636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (TrueReg == 0)
103736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
103836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned FalseReg = getRegForValue(SI->getFalseValue());
103936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (FalseReg == 0)
104036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
104136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1042dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1043dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MRI.constrainRegClass(CondReg, &AArch64::GPR32RegClass);
1044dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned ANDReg = createResultReg(&AArch64::GPR32spRegClass);
1045dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AArch64::ANDWri),
104636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          ANDReg)
104736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      .addReg(CondReg)
1048dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .addImm(AArch64_AM::encodeLogicalImmediate(1, 32));
104936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1050dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AArch64::SUBSWri))
105136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      .addReg(ANDReg)
105236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      .addReg(ANDReg)
105336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      .addImm(0)
105436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      .addImm(0);
105536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
105636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned SelectOpc;
105736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  switch (DestVT.SimpleTy) {
105836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  default:
105936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
106036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MVT::i32:
1061dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SelectOpc = AArch64::CSELWr;
106236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
106336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MVT::i64:
1064dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SelectOpc = AArch64::CSELXr;
106536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
106636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MVT::f32:
1067dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SelectOpc = AArch64::FCSELSrrr;
106836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
106936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MVT::f64:
1070dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SelectOpc = AArch64::FCSELDrrr;
107136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
107236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
107336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
107436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned ResultReg = createResultReg(TLI.getRegClassFor(DestVT));
107536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(SelectOpc),
107636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          ResultReg)
107736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      .addReg(TrueReg)
107836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      .addReg(FalseReg)
1079dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .addImm(AArch64CC::NE);
108036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
108136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  UpdateValueMap(I, ResultReg);
108236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return true;
108336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
108436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1085dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64FastISel::SelectFPExt(const Instruction *I) {
108636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Value *V = I->getOperand(0);
108736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!I->getType()->isDoubleTy() || !V->getType()->isFloatTy())
108836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
108936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
109036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned Op = getRegForValue(V);
109136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Op == 0)
109236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
109336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1094dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned ResultReg = createResultReg(&AArch64::FPR64RegClass);
1095dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AArch64::FCVTDSr),
109636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          ResultReg).addReg(Op);
109736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  UpdateValueMap(I, ResultReg);
109836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return true;
109936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
110036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1101dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64FastISel::SelectFPTrunc(const Instruction *I) {
110236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Value *V = I->getOperand(0);
110336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!I->getType()->isFloatTy() || !V->getType()->isDoubleTy())
110436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
110536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
110636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned Op = getRegForValue(V);
110736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Op == 0)
110836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
110936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1110dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned ResultReg = createResultReg(&AArch64::FPR32RegClass);
1111dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AArch64::FCVTSDr),
111236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          ResultReg).addReg(Op);
111336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  UpdateValueMap(I, ResultReg);
111436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return true;
111536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
111636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
111736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// FPToUI and FPToSI
1118dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64FastISel::SelectFPToInt(const Instruction *I, bool Signed) {
111936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MVT DestVT;
112036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!isTypeLegal(I->getType(), DestVT) || DestVT.isVector())
112136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
112236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
112336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned SrcReg = getRegForValue(I->getOperand(0));
112436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (SrcReg == 0)
112536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
112636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
112736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EVT SrcVT = TLI.getValueType(I->getOperand(0)->getType(), true);
1128dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (SrcVT == MVT::f128)
1129dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return false;
113036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
113136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned Opc;
113236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (SrcVT == MVT::f64) {
113336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (Signed)
1134dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = (DestVT == MVT::i32) ? AArch64::FCVTZSUWDr : AArch64::FCVTZSUXDr;
113536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    else
1136dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = (DestVT == MVT::i32) ? AArch64::FCVTZUUWDr : AArch64::FCVTZUUXDr;
113736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  } else {
113836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (Signed)
1139dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = (DestVT == MVT::i32) ? AArch64::FCVTZSUWSr : AArch64::FCVTZSUXSr;
114036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    else
1141dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = (DestVT == MVT::i32) ? AArch64::FCVTZUUWSr : AArch64::FCVTZUUXSr;
114236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
1143dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned ResultReg = createResultReg(
1144dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      DestVT == MVT::i32 ? &AArch64::GPR32RegClass : &AArch64::GPR64RegClass);
114536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ResultReg)
114636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      .addReg(SrcReg);
114736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  UpdateValueMap(I, ResultReg);
114836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return true;
114936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
115036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1151dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64FastISel::SelectIntToFP(const Instruction *I, bool Signed) {
115236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MVT DestVT;
115336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!isTypeLegal(I->getType(), DestVT) || DestVT.isVector())
115436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
1155dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  assert ((DestVT == MVT::f32 || DestVT == MVT::f64) &&
1156dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          "Unexpected value type.");
115736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
115836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned SrcReg = getRegForValue(I->getOperand(0));
115936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (SrcReg == 0)
116036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
116136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
116236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EVT SrcVT = TLI.getValueType(I->getOperand(0)->getType(), true);
116336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
116436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Handle sign-extension.
116536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (SrcVT == MVT::i16 || SrcVT == MVT::i8 || SrcVT == MVT::i1) {
116636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    SrcReg =
116736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        EmitIntExt(SrcVT.getSimpleVT(), SrcReg, MVT::i32, /*isZExt*/ !Signed);
116836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (SrcReg == 0)
116936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return false;
117036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
117136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1172dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MRI.constrainRegClass(SrcReg, SrcVT == MVT::i64 ? &AArch64::GPR64RegClass
1173dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                                  : &AArch64::GPR32RegClass);
1174dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
117536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned Opc;
117636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (SrcVT == MVT::i64) {
117736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (Signed)
1178dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = (DestVT == MVT::f32) ? AArch64::SCVTFUXSri : AArch64::SCVTFUXDri;
117936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    else
1180dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = (DestVT == MVT::f32) ? AArch64::UCVTFUXSri : AArch64::UCVTFUXDri;
118136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  } else {
118236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (Signed)
1183dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = (DestVT == MVT::f32) ? AArch64::SCVTFUWSri : AArch64::SCVTFUWDri;
118436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    else
1185dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = (DestVT == MVT::f32) ? AArch64::UCVTFUWSri : AArch64::UCVTFUWDri;
118636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
118736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
118836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned ResultReg = createResultReg(TLI.getRegClassFor(DestVT));
118936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ResultReg)
119036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      .addReg(SrcReg);
119136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  UpdateValueMap(I, ResultReg);
119236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return true;
119336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
119436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1195dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64FastISel::ProcessCallArgs(
1196dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SmallVectorImpl<Value *> &Args, SmallVectorImpl<unsigned> &ArgRegs,
1197dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SmallVectorImpl<MVT> &ArgVTs, SmallVectorImpl<ISD::ArgFlagsTy> &ArgFlags,
1198dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SmallVectorImpl<unsigned> &RegArgs, CallingConv::ID CC,
1199dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned &NumBytes) {
120036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  SmallVector<CCValAssign, 16> ArgLocs;
120136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  CCState CCInfo(CC, false, *FuncInfo.MF, TM, ArgLocs, *Context);
120236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  CCInfo.AnalyzeCallOperands(ArgVTs, ArgFlags, CCAssignFnForCall(CC));
120336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
120436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Get a count of how many bytes are to be pushed on the stack.
120536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  NumBytes = CCInfo.getNextStackOffset();
120636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
120736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Issue CALLSEQ_START
120836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned AdjStackDown = TII.getCallFrameSetupOpcode();
120936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AdjStackDown))
121036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      .addImm(NumBytes);
121136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
121236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Process the args.
121336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
121436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    CCValAssign &VA = ArgLocs[i];
121536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned Arg = ArgRegs[VA.getValNo()];
121636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    MVT ArgVT = ArgVTs[VA.getValNo()];
121736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
121836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Handle arg promotion: SExt, ZExt, AExt.
121936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    switch (VA.getLocInfo()) {
122036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case CCValAssign::Full:
122136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      break;
122236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case CCValAssign::SExt: {
122336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      MVT DestVT = VA.getLocVT();
122436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      MVT SrcVT = ArgVT;
122536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Arg = EmitIntExt(SrcVT, Arg, DestVT, /*isZExt*/ false);
122636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (Arg == 0)
122736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        return false;
122836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      break;
122936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
123036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case CCValAssign::AExt:
123136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Intentional fall-through.
123236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case CCValAssign::ZExt: {
123336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      MVT DestVT = VA.getLocVT();
123436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      MVT SrcVT = ArgVT;
123536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Arg = EmitIntExt(SrcVT, Arg, DestVT, /*isZExt*/ true);
123636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (Arg == 0)
123736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        return false;
123836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      break;
123936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
124036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    default:
124136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      llvm_unreachable("Unknown arg promotion!");
124236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
124336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
124436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Now copy/store arg to correct locations.
124536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (VA.isRegLoc() && !VA.needsCustom()) {
124636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
124736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines              TII.get(TargetOpcode::COPY), VA.getLocReg()).addReg(Arg);
124836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      RegArgs.push_back(VA.getLocReg());
124936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    } else if (VA.needsCustom()) {
125036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // FIXME: Handle custom args.
125136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return false;
125236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    } else {
125336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      assert(VA.isMemLoc() && "Assuming store on stack.");
125436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
125536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // Need to store on the stack.
1256cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      unsigned ArgSize = (ArgVT.getSizeInBits() + 7) / 8;
1257dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1258dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      unsigned BEAlign = 0;
1259dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (ArgSize < 8 && !Subtarget->isLittleEndian())
1260dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        BEAlign = 8 - ArgSize;
1261dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
126236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Address Addr;
126336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Addr.setKind(Address::RegBase);
1264dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Addr.setReg(AArch64::SP);
1265dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Addr.setOffset(VA.getLocMemOffset() + BEAlign);
126636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
126736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (!EmitStore(ArgVT, Arg, Addr))
126836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        return false;
126936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
127036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
127136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return true;
127236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
127336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1274dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64FastISel::FinishCall(MVT RetVT, SmallVectorImpl<unsigned> &UsedRegs,
1275dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                 const Instruction *I, CallingConv::ID CC,
1276dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                 unsigned &NumBytes) {
127736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Issue CALLSEQ_END
127836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned AdjStackUp = TII.getCallFrameDestroyOpcode();
127936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AdjStackUp))
128036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      .addImm(NumBytes)
128136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      .addImm(0);
128236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
128336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Now the return value.
128436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (RetVT != MVT::isVoid) {
128536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    SmallVector<CCValAssign, 16> RVLocs;
128636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    CCState CCInfo(CC, false, *FuncInfo.MF, TM, RVLocs, *Context);
128736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    CCInfo.AnalyzeCallResult(RetVT, CCAssignFnForCall(CC));
128836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
128936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Only handle a single return value.
129036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (RVLocs.size() != 1)
129136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return false;
129236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
129336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Copy all of the result registers out of their specified physreg.
129436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    MVT CopyVT = RVLocs[0].getValVT();
129536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned ResultReg = createResultReg(TLI.getRegClassFor(CopyVT));
129636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
129736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            TII.get(TargetOpcode::COPY),
129836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            ResultReg).addReg(RVLocs[0].getLocReg());
129936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    UsedRegs.push_back(RVLocs[0].getLocReg());
130036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
130136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Finally update the result.
130236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    UpdateValueMap(I, ResultReg);
130336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
130436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
130536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return true;
130636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
130736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1308dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64FastISel::SelectCall(const Instruction *I,
1309dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                 const char *IntrMemName = nullptr) {
131036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const CallInst *CI = cast<CallInst>(I);
131136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const Value *Callee = CI->getCalledValue();
131236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
131336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Don't handle inline asm or intrinsics.
131436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (isa<InlineAsm>(Callee))
131536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
131636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
131736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Only handle global variable Callees.
131836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const GlobalValue *GV = dyn_cast<GlobalValue>(Callee);
131936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!GV)
132036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
132136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
132236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Check the calling convention.
132336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ImmutableCallSite CS(CI);
132436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  CallingConv::ID CC = CS.getCallingConv();
132536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
132636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Let SDISel handle vararg functions.
132736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  PointerType *PT = cast<PointerType>(CS.getCalledValue()->getType());
132836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  FunctionType *FTy = cast<FunctionType>(PT->getElementType());
132936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (FTy->isVarArg())
133036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
133136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
133236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Handle *simple* calls for now.
133336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MVT RetVT;
133436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Type *RetTy = I->getType();
133536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (RetTy->isVoidTy())
133636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    RetVT = MVT::isVoid;
133736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  else if (!isTypeLegal(RetTy, RetVT))
133836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
133936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
134036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Set up the argument vectors.
134136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  SmallVector<Value *, 8> Args;
134236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  SmallVector<unsigned, 8> ArgRegs;
134336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  SmallVector<MVT, 8> ArgVTs;
134436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  SmallVector<ISD::ArgFlagsTy, 8> ArgFlags;
134536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Args.reserve(CS.arg_size());
134636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ArgRegs.reserve(CS.arg_size());
134736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ArgVTs.reserve(CS.arg_size());
134836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ArgFlags.reserve(CS.arg_size());
134936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
135036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  for (ImmutableCallSite::arg_iterator i = CS.arg_begin(), e = CS.arg_end();
135136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines       i != e; ++i) {
135236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // If we're lowering a memory intrinsic instead of a regular call, skip the
135336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // last two arguments, which shouldn't be passed to the underlying function.
135436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (IntrMemName && e - i <= 2)
135536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      break;
135636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
135736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned Arg = getRegForValue(*i);
135836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (Arg == 0)
135936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return false;
136036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
136136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    ISD::ArgFlagsTy Flags;
136236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned AttrInd = i - CS.arg_begin() + 1;
136336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (CS.paramHasAttr(AttrInd, Attribute::SExt))
136436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Flags.setSExt();
136536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (CS.paramHasAttr(AttrInd, Attribute::ZExt))
136636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Flags.setZExt();
136736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
136836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // FIXME: Only handle *easy* calls for now.
136936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (CS.paramHasAttr(AttrInd, Attribute::InReg) ||
137036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        CS.paramHasAttr(AttrInd, Attribute::StructRet) ||
137136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        CS.paramHasAttr(AttrInd, Attribute::Nest) ||
137236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        CS.paramHasAttr(AttrInd, Attribute::ByVal))
137336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return false;
137436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
137536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    MVT ArgVT;
137636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Type *ArgTy = (*i)->getType();
137736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (!isTypeLegal(ArgTy, ArgVT) &&
137836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        !(ArgVT == MVT::i1 || ArgVT == MVT::i8 || ArgVT == MVT::i16))
137936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return false;
138036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
138136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // We don't handle vector parameters yet.
138236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (ArgVT.isVector() || ArgVT.getSizeInBits() > 64)
138336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return false;
138436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
138536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned OriginalAlignment = DL.getABITypeAlignment(ArgTy);
138636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Flags.setOrigAlign(OriginalAlignment);
138736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
138836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Args.push_back(*i);
138936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    ArgRegs.push_back(Arg);
139036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    ArgVTs.push_back(ArgVT);
139136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    ArgFlags.push_back(Flags);
139236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
139336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
139436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Handle the arguments now that we've gotten them.
139536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  SmallVector<unsigned, 4> RegArgs;
139636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned NumBytes;
139736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!ProcessCallArgs(Args, ArgRegs, ArgVTs, ArgFlags, RegArgs, CC, NumBytes))
139836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
139936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
140036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Issue the call.
140136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MachineInstrBuilder MIB;
1402dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AArch64::BL));
140336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!IntrMemName)
140436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    MIB.addGlobalAddress(GV, 0, 0);
140536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  else
140636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    MIB.addExternalSymbol(IntrMemName, 0);
140736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
140836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Add implicit physical register uses to the call.
140936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  for (unsigned i = 0, e = RegArgs.size(); i != e; ++i)
141036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    MIB.addReg(RegArgs[i], RegState::Implicit);
141136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
141236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Add a register mask with the call-preserved registers.
141336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Proper defs for return values will be added by setPhysRegsDeadExcept().
141436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MIB.addRegMask(TRI.getCallPreservedMask(CS.getCallingConv()));
141536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
141636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Finish off the call including any return values.
141736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  SmallVector<unsigned, 4> UsedRegs;
141836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!FinishCall(RetVT, UsedRegs, I, CC, NumBytes))
141936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
142036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
142136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Set all unused physreg defs as dead.
142236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  static_cast<MachineInstr *>(MIB)->setPhysRegsDeadExcept(UsedRegs, TRI);
142336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
142436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return true;
142536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
142636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1427dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64FastISel::IsMemCpySmall(uint64_t Len, unsigned Alignment) {
142836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Alignment)
142936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return Len / Alignment <= 4;
143036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  else
143136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return Len < 32;
143236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
143336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1434dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64FastISel::TryEmitSmallMemCpy(Address Dest, Address Src,
1435dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                         uint64_t Len, unsigned Alignment) {
143636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Make sure we don't bloat code by inlining very large memcpy's.
143736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!IsMemCpySmall(Len, Alignment))
143836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
143936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
144036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  int64_t UnscaledOffset = 0;
144136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Address OrigDest = Dest;
144236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Address OrigSrc = Src;
144336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
144436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  while (Len) {
144536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    MVT VT;
144636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (!Alignment || Alignment >= 8) {
144736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (Len >= 8)
144836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        VT = MVT::i64;
144936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      else if (Len >= 4)
145036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        VT = MVT::i32;
145136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      else if (Len >= 2)
145236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        VT = MVT::i16;
145336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      else {
145436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        VT = MVT::i8;
145536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      }
145636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    } else {
145736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // Bound based on alignment.
145836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (Len >= 4 && Alignment == 4)
145936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        VT = MVT::i32;
146036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      else if (Len >= 2 && Alignment == 2)
146136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        VT = MVT::i16;
146236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      else {
146336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        VT = MVT::i8;
146436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      }
146536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
146636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
146736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool RV;
146836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned ResultReg;
146936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    RV = EmitLoad(VT, ResultReg, Src);
1470cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (!RV)
1471cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      return false;
1472cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
147336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    RV = EmitStore(VT, ResultReg, Dest);
1474cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (!RV)
1475cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      return false;
147636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
147736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    int64_t Size = VT.getSizeInBits() / 8;
147836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Len -= Size;
147936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    UnscaledOffset += Size;
148036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
148136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // We need to recompute the unscaled offset for each iteration.
148236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Dest.setOffset(OrigDest.getOffset() + UnscaledOffset);
148336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Src.setOffset(OrigSrc.getOffset() + UnscaledOffset);
148436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
148536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
148636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return true;
148736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
148836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1489dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64FastISel::SelectIntrinsicCall(const IntrinsicInst &I) {
149036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // FIXME: Handle more intrinsics.
149136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  switch (I.getIntrinsicID()) {
149236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  default:
149336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
149436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case Intrinsic::memcpy:
149536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case Intrinsic::memmove: {
149636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const MemTransferInst &MTI = cast<MemTransferInst>(I);
149736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Don't handle volatile.
149836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (MTI.isVolatile())
149936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return false;
150036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
150136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Disable inlining for memmove before calls to ComputeAddress.  Otherwise,
150236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // we would emit dead code because we don't currently handle memmoves.
150336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool isMemCpy = (I.getIntrinsicID() == Intrinsic::memcpy);
150436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (isa<ConstantInt>(MTI.getLength()) && isMemCpy) {
150536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // Small memcpy's are common enough that we want to do them without a call
150636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // if possible.
150736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      uint64_t Len = cast<ConstantInt>(MTI.getLength())->getZExtValue();
150836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      unsigned Alignment = MTI.getAlignment();
150936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (IsMemCpySmall(Len, Alignment)) {
151036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        Address Dest, Src;
151136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        if (!ComputeAddress(MTI.getRawDest(), Dest) ||
151236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            !ComputeAddress(MTI.getRawSource(), Src))
151336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          return false;
151436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        if (TryEmitSmallMemCpy(Dest, Src, Len, Alignment))
151536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          return true;
151636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      }
151736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
151836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
151936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (!MTI.getLength()->getType()->isIntegerTy(64))
152036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return false;
152136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
152236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (MTI.getSourceAddressSpace() > 255 || MTI.getDestAddressSpace() > 255)
152336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // Fast instruction selection doesn't support the special
152436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // address spaces.
152536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return false;
152636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
152736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const char *IntrMemName = isa<MemCpyInst>(I) ? "memcpy" : "memmove";
152836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return SelectCall(&I, IntrMemName);
152936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
153036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case Intrinsic::memset: {
153136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const MemSetInst &MSI = cast<MemSetInst>(I);
153236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Don't handle volatile.
153336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (MSI.isVolatile())
153436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return false;
153536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
153636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (!MSI.getLength()->getType()->isIntegerTy(64))
153736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return false;
153836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
153936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (MSI.getDestAddressSpace() > 255)
154036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // Fast instruction selection doesn't support the special
154136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // address spaces.
154236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return false;
154336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
154436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return SelectCall(&I, "memset");
154536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
154636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case Intrinsic::trap: {
1547dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AArch64::BRK))
154836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        .addImm(1);
154936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return true;
155036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
155136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
155236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return false;
155336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
155436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1555dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64FastISel::SelectRet(const Instruction *I) {
155636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const ReturnInst *Ret = cast<ReturnInst>(I);
155736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const Function &F = *I->getParent()->getParent();
155836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
155936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!FuncInfo.CanLowerReturn)
156036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
156136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
156236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (F.isVarArg())
156336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
156436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
156536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Build a list of return value registers.
156636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  SmallVector<unsigned, 4> RetRegs;
156736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
156836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Ret->getNumOperands() > 0) {
156936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    CallingConv::ID CC = F.getCallingConv();
157036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    SmallVector<ISD::OutputArg, 4> Outs;
157136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    GetReturnInfo(F.getReturnType(), F.getAttributes(), Outs, TLI);
157236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
157336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Analyze operands of the call, assigning locations to each operand.
157436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    SmallVector<CCValAssign, 16> ValLocs;
157536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    CCState CCInfo(CC, F.isVarArg(), *FuncInfo.MF, TM, ValLocs,
157636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                   I->getContext());
1577dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    CCAssignFn *RetCC = CC == CallingConv::WebKit_JS ? RetCC_AArch64_WebKit_JS
1578dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                                     : RetCC_AArch64_AAPCS;
157936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    CCInfo.AnalyzeReturn(Outs, RetCC);
158036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
158136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Only handle a single return value for now.
158236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (ValLocs.size() != 1)
158336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return false;
158436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
158536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    CCValAssign &VA = ValLocs[0];
158636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const Value *RV = Ret->getOperand(0);
158736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
158836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Don't bother handling odd stuff for now.
158936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (VA.getLocInfo() != CCValAssign::Full)
159036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return false;
159136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Only handle register returns for now.
159236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (!VA.isRegLoc())
159336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return false;
159436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned Reg = getRegForValue(RV);
159536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (Reg == 0)
159636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return false;
159736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
159836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned SrcReg = Reg + VA.getValNo();
159936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned DestReg = VA.getLocReg();
160036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Avoid a cross-class copy. This is very unlikely.
160136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (!MRI.getRegClass(SrcReg)->contains(DestReg))
160236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return false;
160336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
160436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    EVT RVEVT = TLI.getValueType(RV->getType());
160536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (!RVEVT.isSimple())
160636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return false;
1607dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1608dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Vectors (of > 1 lane) in big endian need tricky handling.
1609dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (RVEVT.isVector() && RVEVT.getVectorNumElements() > 1)
1610dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
1611dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
161236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    MVT RVVT = RVEVT.getSimpleVT();
1613dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (RVVT == MVT::f128)
1614dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
161536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    MVT DestVT = VA.getValVT();
161636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Special handling for extended integers.
161736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (RVVT != DestVT) {
161836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (RVVT != MVT::i1 && RVVT != MVT::i8 && RVVT != MVT::i16)
161936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        return false;
162036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
162136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (!Outs[0].Flags.isZExt() && !Outs[0].Flags.isSExt())
162236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        return false;
162336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
162436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      bool isZExt = Outs[0].Flags.isZExt();
162536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      SrcReg = EmitIntExt(RVVT, SrcReg, DestVT, isZExt);
162636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (SrcReg == 0)
162736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        return false;
162836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
162936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
163036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Make the copy.
163136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
163236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            TII.get(TargetOpcode::COPY), DestReg).addReg(SrcReg);
163336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
163436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Add register to return instruction.
163536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    RetRegs.push_back(VA.getLocReg());
163636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
163736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
163836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
1639dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                    TII.get(AArch64::RET_ReallyLR));
164036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  for (unsigned i = 0, e = RetRegs.size(); i != e; ++i)
164136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    MIB.addReg(RetRegs[i], RegState::Implicit);
164236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return true;
164336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
164436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1645dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64FastISel::SelectTrunc(const Instruction *I) {
164636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Type *DestTy = I->getType();
164736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Value *Op = I->getOperand(0);
164836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Type *SrcTy = Op->getType();
164936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
165036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EVT SrcEVT = TLI.getValueType(SrcTy, true);
165136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EVT DestEVT = TLI.getValueType(DestTy, true);
165236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!SrcEVT.isSimple())
165336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
165436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!DestEVT.isSimple())
165536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
165636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
165736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MVT SrcVT = SrcEVT.getSimpleVT();
165836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MVT DestVT = DestEVT.getSimpleVT();
165936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
166036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (SrcVT != MVT::i64 && SrcVT != MVT::i32 && SrcVT != MVT::i16 &&
166136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      SrcVT != MVT::i8)
166236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
166336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (DestVT != MVT::i32 && DestVT != MVT::i16 && DestVT != MVT::i8 &&
166436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      DestVT != MVT::i1)
166536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
166636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
166736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned SrcReg = getRegForValue(Op);
166836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!SrcReg)
166936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
167036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
167136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // If we're truncating from i64 to a smaller non-legal type then generate an
167236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // AND.  Otherwise, we know the high bits are undefined and a truncate doesn't
167336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // generate any code.
167436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (SrcVT == MVT::i64) {
167536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    uint64_t Mask = 0;
167636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    switch (DestVT.SimpleTy) {
167736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    default:
167836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // Trunc i64 to i32 is handled by the target-independent fast-isel.
167936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return false;
168036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case MVT::i1:
168136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Mask = 0x1;
168236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      break;
168336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case MVT::i8:
168436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Mask = 0xff;
168536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      break;
168636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case MVT::i16:
168736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Mask = 0xffff;
168836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      break;
168936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
169036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Issue an extract_subreg to get the lower 32-bits.
169136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned Reg32 = FastEmitInst_extractsubreg(MVT::i32, SrcReg, /*Kill=*/true,
1692dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                                AArch64::sub_32);
1693dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MRI.constrainRegClass(Reg32, &AArch64::GPR32RegClass);
169436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Create the AND instruction which performs the actual truncation.
1695dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned ANDReg = createResultReg(&AArch64::GPR32spRegClass);
1696dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AArch64::ANDWri),
169736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            ANDReg)
169836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        .addReg(Reg32)
1699dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .addImm(AArch64_AM::encodeLogicalImmediate(Mask, 32));
170036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    SrcReg = ANDReg;
170136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
170236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
170336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  UpdateValueMap(I, SrcReg);
170436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return true;
170536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
170636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1707dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesunsigned AArch64FastISel::Emiti1Ext(unsigned SrcReg, MVT DestVT, bool isZExt) {
170836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  assert((DestVT == MVT::i8 || DestVT == MVT::i16 || DestVT == MVT::i32 ||
170936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          DestVT == MVT::i64) &&
171036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines         "Unexpected value type.");
171136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Handle i8 and i16 as i32.
171236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (DestVT == MVT::i8 || DestVT == MVT::i16)
171336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    DestVT = MVT::i32;
171436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
171536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (isZExt) {
1716dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MRI.constrainRegClass(SrcReg, &AArch64::GPR32RegClass);
1717dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned ResultReg = createResultReg(&AArch64::GPR32spRegClass);
1718dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AArch64::ANDWri),
171936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            ResultReg)
172036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        .addReg(SrcReg)
1721dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .addImm(AArch64_AM::encodeLogicalImmediate(1, 32));
172236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
172336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (DestVT == MVT::i64) {
172436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // We're ZExt i1 to i64.  The ANDWri Wd, Ws, #1 implicitly clears the
172536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // upper 32 bits.  Emit a SUBREG_TO_REG to extend from Wd to Xd.
1726dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      unsigned Reg64 = MRI.createVirtualRegister(&AArch64::GPR64RegClass);
172736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
1728dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines              TII.get(AArch64::SUBREG_TO_REG), Reg64)
172936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          .addImm(0)
173036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          .addReg(ResultReg)
1731dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .addImm(AArch64::sub_32);
173236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      ResultReg = Reg64;
173336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
173436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return ResultReg;
173536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  } else {
173636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (DestVT == MVT::i64) {
173736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // FIXME: We're SExt i1 to i64.
173836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return 0;
173936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
1740dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned ResultReg = createResultReg(&AArch64::GPR32RegClass);
1741dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AArch64::SBFMWri),
174236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            ResultReg)
174336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        .addReg(SrcReg)
174436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        .addImm(0)
174536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        .addImm(0);
174636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return ResultReg;
174736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
174836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
174936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1750dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesunsigned AArch64FastISel::EmitIntExt(MVT SrcVT, unsigned SrcReg, MVT DestVT,
1751dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                     bool isZExt) {
175236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  assert(DestVT != MVT::i1 && "ZeroExt/SignExt an i1?");
1753cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1754cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // FastISel does not have plumbing to deal with extensions where the SrcVT or
1755cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // DestVT are odd things, so test to make sure that they are both types we can
1756cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // handle (i1/i8/i16/i32 for SrcVT and i8/i16/i32/i64 for DestVT), otherwise
1757cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // bail out to SelectionDAG.
1758cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (((DestVT != MVT::i8) && (DestVT != MVT::i16) &&
1759cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines       (DestVT != MVT::i32) && (DestVT != MVT::i64)) ||
1760cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      ((SrcVT !=  MVT::i1) && (SrcVT !=  MVT::i8) &&
1761cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines       (SrcVT !=  MVT::i16) && (SrcVT !=  MVT::i32)))
1762cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return 0;
1763cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
176436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned Opc;
176536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned Imm = 0;
176636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
176736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  switch (SrcVT.SimpleTy) {
176836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  default:
176936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return 0;
177036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MVT::i1:
177136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return Emiti1Ext(SrcReg, DestVT, isZExt);
177236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MVT::i8:
177336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (DestVT == MVT::i64)
1774dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = isZExt ? AArch64::UBFMXri : AArch64::SBFMXri;
177536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    else
1776dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = isZExt ? AArch64::UBFMWri : AArch64::SBFMWri;
177736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Imm = 7;
177836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
177936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MVT::i16:
178036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (DestVT == MVT::i64)
1781dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = isZExt ? AArch64::UBFMXri : AArch64::SBFMXri;
178236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    else
1783dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Opc = isZExt ? AArch64::UBFMWri : AArch64::SBFMWri;
178436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Imm = 15;
178536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
178636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MVT::i32:
178736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(DestVT == MVT::i64 && "IntExt i32 to i32?!?");
1788dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Opc = isZExt ? AArch64::UBFMXri : AArch64::SBFMXri;
178936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Imm = 31;
179036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
179136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
179236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
179336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Handle i8 and i16 as i32.
179436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (DestVT == MVT::i8 || DestVT == MVT::i16)
179536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    DestVT = MVT::i32;
1796dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  else if (DestVT == MVT::i64) {
1797dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned Src64 = MRI.createVirtualRegister(&AArch64::GPR64RegClass);
1798dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
1799dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            TII.get(AArch64::SUBREG_TO_REG), Src64)
1800dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .addImm(0)
1801dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .addReg(SrcReg)
1802dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .addImm(AArch64::sub_32);
1803dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SrcReg = Src64;
1804dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
180536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
180636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned ResultReg = createResultReg(TLI.getRegClassFor(DestVT));
180736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ResultReg)
180836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      .addReg(SrcReg)
180936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      .addImm(0)
181036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      .addImm(Imm);
181136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
181236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return ResultReg;
181336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
181436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1815dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64FastISel::SelectIntExt(const Instruction *I) {
181636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // On ARM, in general, integer casts don't involve legal types; this code
181736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // handles promotable integers.  The high bits for a type smaller than
181836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // the register size are assumed to be undefined.
181936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Type *DestTy = I->getType();
182036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Value *Src = I->getOperand(0);
182136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Type *SrcTy = Src->getType();
182236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
182336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool isZExt = isa<ZExtInst>(I);
182436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned SrcReg = getRegForValue(Src);
182536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!SrcReg)
182636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
182736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
182836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EVT SrcEVT = TLI.getValueType(SrcTy, true);
182936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EVT DestEVT = TLI.getValueType(DestTy, true);
183036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!SrcEVT.isSimple())
183136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
183236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!DestEVT.isSimple())
183336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
183436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
183536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MVT SrcVT = SrcEVT.getSimpleVT();
183636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MVT DestVT = DestEVT.getSimpleVT();
183736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned ResultReg = EmitIntExt(SrcVT, SrcReg, DestVT, isZExt);
183836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (ResultReg == 0)
183936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
184036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  UpdateValueMap(I, ResultReg);
184136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return true;
184236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
184336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1844dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64FastISel::SelectRem(const Instruction *I, unsigned ISDOpcode) {
184536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EVT DestEVT = TLI.getValueType(I->getType(), true);
184636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!DestEVT.isSimple())
184736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
184836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
184936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MVT DestVT = DestEVT.getSimpleVT();
185036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (DestVT != MVT::i64 && DestVT != MVT::i32)
185136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
185236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
185336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned DivOpc;
185436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool is64bit = (DestVT == MVT::i64);
185536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  switch (ISDOpcode) {
185636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  default:
185736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
185836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case ISD::SREM:
1859dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    DivOpc = is64bit ? AArch64::SDIVXr : AArch64::SDIVWr;
186036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
186136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case ISD::UREM:
1862dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    DivOpc = is64bit ? AArch64::UDIVXr : AArch64::UDIVWr;
186336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
186436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
1865dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned MSubOpc = is64bit ? AArch64::MSUBXrrr : AArch64::MSUBWrrr;
186636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned Src0Reg = getRegForValue(I->getOperand(0));
186736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!Src0Reg)
186836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
186936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
187036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned Src1Reg = getRegForValue(I->getOperand(1));
187136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!Src1Reg)
187236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
187336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1874dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned QuotReg = createResultReg(TLI.getRegClassFor(DestVT));
1875dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(DivOpc), QuotReg)
187636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      .addReg(Src0Reg)
187736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      .addReg(Src1Reg);
1878dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // The remainder is computed as numerator - (quotient * denominator) using the
187936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // MSUB instruction.
1880dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned ResultReg = createResultReg(TLI.getRegClassFor(DestVT));
188136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(MSubOpc), ResultReg)
1882dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      .addReg(QuotReg)
188336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      .addReg(Src1Reg)
188436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      .addReg(Src0Reg);
188536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  UpdateValueMap(I, ResultReg);
188636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return true;
188736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
188836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1889dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64FastISel::SelectMul(const Instruction *I) {
189036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EVT SrcEVT = TLI.getValueType(I->getOperand(0)->getType(), true);
189136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!SrcEVT.isSimple())
189236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
189336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MVT SrcVT = SrcEVT.getSimpleVT();
189436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
189536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Must be simple value type.  Don't handle vectors.
189636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (SrcVT != MVT::i64 && SrcVT != MVT::i32 && SrcVT != MVT::i16 &&
189736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      SrcVT != MVT::i8)
189836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
189936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
190036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned Opc;
190136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned ZReg;
190236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  switch (SrcVT.SimpleTy) {
190336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  default:
190436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
190536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MVT::i8:
190636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MVT::i16:
190736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MVT::i32:
1908dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    ZReg = AArch64::WZR;
1909dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Opc = AArch64::MADDWrrr;
1910cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    SrcVT = MVT::i32;
191136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
191236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MVT::i64:
1913dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    ZReg = AArch64::XZR;
1914dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Opc = AArch64::MADDXrrr;
191536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
191636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
191736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
191836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned Src0Reg = getRegForValue(I->getOperand(0));
191936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!Src0Reg)
192036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
192136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
192236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned Src1Reg = getRegForValue(I->getOperand(1));
192336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!Src1Reg)
192436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
192536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
192636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Create the base instruction, then add the operands.
192736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned ResultReg = createResultReg(TLI.getRegClassFor(SrcVT));
192836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ResultReg)
192936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      .addReg(Src0Reg)
193036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      .addReg(Src1Reg)
193136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      .addReg(ZReg);
193236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  UpdateValueMap(I, ResultReg);
193336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return true;
193436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
193536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1936dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool AArch64FastISel::TargetSelectInstruction(const Instruction *I) {
193736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  switch (I->getOpcode()) {
193836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  default:
193936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
194036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case Instruction::Load:
194136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return SelectLoad(I);
194236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case Instruction::Store:
194336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return SelectStore(I);
194436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case Instruction::Br:
194536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return SelectBranch(I);
194636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case Instruction::IndirectBr:
194736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return SelectIndirectBr(I);
194836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case Instruction::FCmp:
194936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case Instruction::ICmp:
195036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return SelectCmp(I);
195136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case Instruction::Select:
195236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return SelectSelect(I);
195336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case Instruction::FPExt:
195436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return SelectFPExt(I);
195536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case Instruction::FPTrunc:
195636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return SelectFPTrunc(I);
195736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case Instruction::FPToSI:
195836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return SelectFPToInt(I, /*Signed=*/true);
195936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case Instruction::FPToUI:
196036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return SelectFPToInt(I, /*Signed=*/false);
196136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case Instruction::SIToFP:
196236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return SelectIntToFP(I, /*Signed=*/true);
196336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case Instruction::UIToFP:
196436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return SelectIntToFP(I, /*Signed=*/false);
196536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case Instruction::SRem:
196636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return SelectRem(I, ISD::SREM);
196736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case Instruction::URem:
196836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return SelectRem(I, ISD::UREM);
196936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case Instruction::Call:
197036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I))
197136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return SelectIntrinsicCall(*II);
197236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return SelectCall(I);
197336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case Instruction::Ret:
197436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return SelectRet(I);
197536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case Instruction::Trunc:
197636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return SelectTrunc(I);
197736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case Instruction::ZExt:
197836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case Instruction::SExt:
197936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return SelectIntExt(I);
198036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case Instruction::Mul:
198136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // FIXME: This really should be handled by the target-independent selector.
198236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return SelectMul(I);
198336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
198436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return false;
198536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Silence warnings.
1986dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  (void)&CC_AArch64_DarwinPCS_VarArg;
198736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
198836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
198936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesnamespace llvm {
1990dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesllvm::FastISel *AArch64::createFastISel(FunctionLoweringInfo &funcInfo,
1991dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                        const TargetLibraryInfo *libInfo) {
1992dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return new AArch64FastISel(funcInfo, libInfo);
199336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
199436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
1995