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