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